Initialize result slices as empty arrays so JSON output is [] not null#12
Open
delphinus wants to merge 2 commits into
Open
Initialize result slices as empty arrays so JSON output is [] not null#12delphinus wants to merge 2 commits into
[] not null#12delphinus wants to merge 2 commits into
Conversation
…null`
Three handlers declare their result slices with `var ... []T`, which
leaves them as nil if the loop body never appends. When marshalled to
JSON, a nil Go slice becomes `null`, not `[]`.
For textDocument/completion, this is a spec violation:
CompletionList.items is typed as CompletionItem[], non-nullable. Strict
LSP clients can choke on `{"isIncomplete": false, "items": null}`.
For workspace/symbol and textDocument/documentSymbol, top-level null is
technically valid LSP, but `[]` is the more common convention. The same
one-line change keeps the three handlers consistent.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Asserts that the JSON-encoded textDocument/completion response contains `"items":[]` (and never `"items":null`) when the tag table has no matches for the current word, so the spec violation cannot regress. The test enters the main path of handleCompletion (cursor inside a word) rather than the early-return branch that already used an empty literal. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
delphinus
added a commit
to delphinus/dotfiles
that referenced
this pull request
May 4, 2026
ctags-lsp returns `{ items = vim.NIL }` (JSON null) when there are no
candidates instead of the spec-conformant `{ items = {} }`. blink.cmp's
LSP source treats vim.NIL as truthy and then `ipairs(vim.NIL)` errors,
which propagates through async.task.all and discards completion
responses from ALL attached LSP clients (so a `vim.` query in Lua would
silently lose lua_ls output too).
Wrap client.request via on_init so the broken response is normalized
before reaching blink.cmp. Drop this workaround after
netmute/ctags-lsp#12 is merged and rolled out.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Three handlers declare their result slices with
var ... []T, which leavesthem as nil if the loop body never appends. When marshalled to JSON, a nil
Go slice becomes
null, not[].For
textDocument/completion, this is a spec violation.CompletionList.itemsis typed asCompletionItem[], non-nullable. Strict LSP clients can choke on{"isIncomplete": false, "items": null}. I hit this in blink.cmp.For
workspace/symbolandtextDocument/documentSymbol, top-levelnullis technically valid LSP, but[]is the more common convention. The same one-line change keeps the three handlers consistent.Diff
No behavior change in Go (
len,range,appendall behave identically;no
nilcomparisons in the codebase). Tiny extra heap allocation perrequest (~24 bytes for a slice header). Existing tests pass.