From 8c8cf52da832d19704f345854ba756c3180e816c Mon Sep 17 00:00:00 2001 From: SerhiiCho Date: Fri, 7 Nov 2025 19:54:29 +0200 Subject: [PATCH 1/6] chore: remove unused file --- textwire.tw | 17 ----------------- 1 file changed, 17 deletions(-) delete mode 100644 textwire.tw diff --git a/textwire.tw b/textwire.tw deleted file mode 100644 index e705063..0000000 --- a/textwire.tw +++ /dev/null @@ -1,17 +0,0 @@ -
- @if(true) - {{ "upper string".upper() }} - @elseif(false) - {{ "lower string".lower() }} - @end - - @if(true) - @each(i in 1..10) - {{ i }} - @else - Not found - @end - @else - - @end -
From 90834854082ce42dd0893fe918dfb8688fd2c582 Mon Sep 17 00:00:00 2001 From: SerhiiCho Date: Fri, 7 Nov 2025 19:54:43 +0200 Subject: [PATCH 2/6] refactor: Containerfile --- Containerfile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Containerfile b/Containerfile index 928bbad..2df5b52 100644 --- a/Containerfile +++ b/Containerfile @@ -1,13 +1,13 @@ -FROM golang:1.24-alpine +FROM golang:1.25-alpine WORKDIR /app RUN apk add --no-cache make -COPY go.mod go.sum . +COPY go.* . RUN go mod download COPY . . -CMD ["sh"] \ No newline at end of file +CMD ["sh"] From 710caf07d46b58187a9910707a3ec79a0fb22e57 Mon Sep 17 00:00:00 2001 From: SerhiiCho Date: Fri, 7 Nov 2025 19:55:39 +0200 Subject: [PATCH 3/6] chore: add loop directives now showup only in loops --- .gitignore | 1 + CHANGELOG.md | 9 ++++-- analysis/completion.go | 63 ++++++++++++++++++++++++++++++++++-------- 3 files changed, 59 insertions(+), 14 deletions(-) diff --git a/.gitignore b/.gitignore index ff95e9e..f9fce8f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ log.txt main +Session.vim diff --git a/CHANGELOG.md b/CHANGELOG.md index 4edfaf7..38083de 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,14 +1,17 @@ # Release Notes +## v0.4.0 (2025-11-07) +- ✨ Loop directives like `@break`, `@continue`, `@breakIf`, `@continueIf` are now getting suggested only inside of loops. + ## v0.3.1 (2025-06-14) -- 🐛 Update LSP textwire to the latest version which will fix `@break($1)` snippet to `@break` +- 🐛 Updated LSP textwire to the latest version which will fix `@break($1)` snippet to `@break` ## v0.3.0 (2025-06-14) -- 🐛 Update LSP textwire to the latest version which will fix crashing LSP when you make a syntax error in your Textwire code +- 🐛 Updated LSP textwire to the latest version which will fix crashing LSP when you make a syntax error in your Textwire code - ✨ Autocomplete snippets that appear after you hit enter are now more complex. Instead of simple autocomple like `@if` you know get the full if statement and the cursor placed inside condition. It allows you to hit tab to move to the next place in a snippet ## v0.2.0 (2025-05-30) -- ✨ Add autocompletion for loop object. Now if you type `loop.` inside of a loop, it will show available properties on the object +- ✨ Added autocompletion for loop object. Now if you type `loop.` inside of a loop, it will show available properties on the object ## v0.1.4 (2025-05-17) - ✨ Autocomplete suggestions show code example with syntax highlighting. Before, it was just displayed as text diff --git a/analysis/completion.go b/analysis/completion.go index ef8489f..9b5bdf0 100644 --- a/analysis/completion.go +++ b/analysis/completion.go @@ -2,6 +2,7 @@ package analysis import ( "regexp" + "slices" "strings" "github.com/textwire/lsp/internal/logger" @@ -35,18 +36,9 @@ func (s *State) Completion(id int, uri string, pos lsp.Position) (lsp.Completion var err error if directiveMatch != nil { - completionItems, err = completions.GetDirectives(locale) + completionItems, err = handleDirectivesAutocomplete(doc, pos, uri) } else if strings.HasSuffix(textBeforeCursor, "loop.") { - doc = removeTrailingChar(doc, pos.Line, pos.Character, '.') - - isInsideLoop, errors := twLsp.IsInLoop(doc, uri, pos.Line, pos.Character) - if len(errors) > 0 { - logger.Error.Println(errors[0]) - } - - if isInsideLoop { - completionItems, err = completions.GetLoopObjFields(locale) - } + completionItems, err = handleLoopObjectAutocomplete(doc, pos, uri) } if err != nil { @@ -57,6 +49,55 @@ func (s *State) Completion(id int, uri string, pos lsp.Position) (lsp.Completion return s.completionResponse(id, s.makeCompletions(completionItems)), nil } +func handleDirectivesAutocomplete(doc string, pos lsp.Position, uri string) ([]completions.Completion, error) { + dirs, err := completions.GetDirectives(locale) + if err != nil { + return []completions.Completion{}, err + } + + isInsideLoop, errors := twLsp.IsInLoop(doc, uri, pos.Line, pos.Character) + if len(errors) > 0 { + logger.Error.Println(errors[0]) + } + + if isInsideLoop { + return dirs, nil + } + + filteredDirs := make([]completions.Completion, 0, len(dirs)) + loopDirs := []string{"@break", "@breakIf", "@continue", "@continueIf"} + + for _, dir := range dirs { + if slices.Contains(loopDirs, dir.Label) { + continue + } + + filteredDirs = append(filteredDirs, dir) + } + + return filteredDirs, nil +} + +func handleLoopObjectAutocomplete(doc string, pos lsp.Position, uri string) ([]completions.Completion, error) { + doc = removeTrailingChar(doc, pos.Line, pos.Character, '.') + + isInsideLoop, errors := twLsp.IsInLoop(doc, uri, pos.Line, pos.Character) + if len(errors) > 0 { + logger.Error.Println(errors[0]) + } + + if !isInsideLoop { + return []completions.Completion{}, nil + } + + fields, err := completions.GetLoopObjFields(locale) + if err != nil { + return []completions.Completion{}, err + } + + return fields, nil +} + func removeTrailingChar(doc string, line, col uint, char byte) string { lines := strings.Split(doc, "\n") if int(line) >= len(lines) { From 11fdfdc0c7335b7eb85f0080e410470dea0453f9 Mon Sep 17 00:00:00 2001 From: SerhiiCho Date: Sat, 8 Nov 2025 13:26:18 +0200 Subject: [PATCH 4/6] chore: add github actions test job --- .github/workflows/test.yml | 26 ++++++++++++++++++++++++++ CHANGELOG.md | 3 ++- 2 files changed, 28 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/test.yml diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 0000000..4b6c788 --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,26 @@ +name: Test + +on: + push: + branches: [master] + pull_request: + branches: [master] + +jobs: + build: + name: Build + runs-on: ubuntu-latest + + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Set up Go + uses: actions/setup-go@v5 + with: + go-version: 1.23 + + - name: Test + run: make test diff --git a/CHANGELOG.md b/CHANGELOG.md index 38083de..f05984b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,8 @@ # Release Notes -## v0.4.0 (2025-11-07) +## v0.4.0 (2025-11-08) - ✨ Loop directives like `@break`, `@continue`, `@breakIf`, `@continueIf` are now getting suggested only inside of loops. +- 🧑‍💻 Added testing GitHub Actions job to run tests. ## v0.3.1 (2025-06-14) - 🐛 Updated LSP textwire to the latest version which will fix `@break($1)` snippet to `@break` From b2f05bcb924d522deb0ba4a91ca9a7cfb2aa3f4d Mon Sep 17 00:00:00 2001 From: SerhiiCho Date: Sat, 8 Nov 2025 16:23:26 +0200 Subject: [PATCH 5/6] chore: change `make test` to `make` --- .github/workflows/test.yml | 2 +- Makefile | 2 +- rpc/rpc_test.go | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 4b6c788..3fd6388 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -23,4 +23,4 @@ jobs: go-version: 1.23 - name: Test - run: make test + run: make diff --git a/Makefile b/Makefile index 1699f4e..b1a67e5 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -w.PHONY: test +.PHONY: test test: @echo "🚀 Running tests..." go test ./... diff --git a/rpc/rpc_test.go b/rpc/rpc_test.go index 60f9e19..d6073a3 100644 --- a/rpc/rpc_test.go +++ b/rpc/rpc_test.go @@ -22,7 +22,7 @@ func TestDecodeMessage(t *testing.T) { expectMethod := "hi" incomingMsg := fmt.Sprintf("Content-Length: %d\r\n\r\n{\"Method\":\"%s\"}", expectLen, expectMethod) - method, content, err := DecodeMessage([]byte(incomingMsg) ) + method, content, err := DecodeMessage([]byte(incomingMsg)) if err != nil { t.Fatal(err) } From eedc693cfd2baf042f6aac332634f5f49b9cc1aa Mon Sep 17 00:00:00 2001 From: SerhiiCho Date: Sat, 8 Nov 2025 16:51:46 +0200 Subject: [PATCH 6/6] chore: add formatting check to gh actions --- .github/workflows/test.yml | 3 +++ Makefile | 9 +++++++++ 2 files changed, 12 insertions(+) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 3fd6388..ad240cf 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -22,5 +22,8 @@ jobs: with: go-version: 1.23 + - name: Check formatting + run: make check-fmt + - name: Test run: make diff --git a/Makefile b/Makefile index b1a67e5..83d8899 100644 --- a/Makefile +++ b/Makefile @@ -8,4 +8,13 @@ test: build: go build main.go +.PHONE: check-fmt +check-fmt: + unformatted=$$(gofmt -l .); \ + if [ -n "$$unformatted" ]; then \ + echo "The following files are not formatted properly:"; \ + echo "$$unformatted"; \ + exit 1; \ + fi + .DEFAULT_GOAL := test