Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: completeFunctionCalls adds brackets when writing JSX #240

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,10 @@ function M.handler(request, response, params)
local context = params.context or {}
local trigger_character = context.triggerCharacter
local requested_bufnr = vim.uri_to_bufnr(text_document.uri)
local filename = vim.uri_to_fname(text_document.uri)
local filetype = vim.bo[requested_bufnr].filetype
local is_valid_context_for_function_snippet =
utils.is_valid_context_for_function_snippet(requested_bufnr, params.position, filename, request)

-- tsserver protocol reference:
-- https//github.com/microsoft/TypeScript/blob/8b482b513d87c6fcda8ece18b99f8a01cff5c605/lib/protocol.d.ts#L1631
Expand Down Expand Up @@ -110,7 +113,11 @@ function M.handler(request, response, params)
end
end

local should_create_function_snippet = utils.should_create_function_snippet(kind, filetype)
local should_create_function_snippet = utils.should_create_function_snippet(
kind,
insertText,
filetype
) and is_valid_context_for_function_snippet
local should_create_snippet = item.isSnippet or should_create_function_snippet
local label = is_optional and (item.name .. "?") or item.name
label = should_create_function_snippet and (label .. "(...)") or label
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,12 @@ end
function M.handler(request, response, params)
local requested_bufnr = vim.uri_to_bufnr(vim.uri_from_fname(params.data.file))
local filetype = vim.bo[requested_bufnr].filetype
local is_valid_context_for_function_snippet = utils.is_valid_context_for_function_snippet(
requested_bufnr,
params.data,
Copy link
Author

@m-gail m-gail Feb 26, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After using this PR for a bit, I've noticed that the position here does under some circumstances not get updated between when it first appears as a completion item and when it is chosen as a completion.
For example, when you are in insert mode and press backspace, the results and positions remain the same, which can lead to some unexpected behavior like this (| indicates cursor position):

# go into insert mode
{fooBarBaz|}<Component></Component>
# press backspace once, if you complete now, a snippet is used correctly
{fooBarBa|}<Component></Component>
# press backspace two more times, if you complete now, a snippet is not used
# even though it should be
# because the position is still the same as in step 1, but there is a '<'
# on that position now
{fooBar|}<Component></Component>

The problem could be solved, by querying the current cursor position from nvim here, instead of using the params, but I'm not sure if there is a better solution to this.

params.data.file,
request
)

-- tsserver protocol reference:
-- https://github.com/microsoft/TypeScript/blob/549e61d0af1ba885be29d69f341e7d3a00686071/lib/protocol.d.ts#L1661
Expand Down Expand Up @@ -173,7 +179,10 @@ function M.handler(request, response, params)
-- or neovim even handle that for now i skip this
})

if utils.should_create_function_snippet(item.kind, item.insertText, filetype) then
if
utils.should_create_function_snippet(item.kind, item.insertText, filetype)
and is_valid_context_for_function_snippet
then
create_snippet(item, details.displayParts)
end

Expand Down
35 changes: 35 additions & 0 deletions lua/typescript-tools/protocol/utils.lua
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,41 @@ function M.should_create_function_snippet(kind, insertText, filetype)
and not string.find(insertText, "%$")
end

---@param bufnr number
---@param position LspPosition
---@return boolean
local function is_completing_jsx(bufnr, position)
local line = vim.api.nvim_buf_get_lines(bufnr, position.line, position.line + 1, false)[1]
local line_before_position = line:sub(1, position.character)
return line_before_position:match "^.*<[%w%._$]*$"
end

---@param position LspPosition
---@param file string
---@param request TsserverRequest
---@return boolean
local function should_omit_function_snippet_in_context(position, file, request)
request {
command = c.CommandTypes.Quickinfo,
arguments = vim.tbl_extend("force", {
file = file,
}, M.convert_lsp_position_to_tsserver(position)),
}

local body = coroutine.yield()

return vim.tbl_contains({ "var", "let", "const", "alias" }, body.kind)
end

---@param bufnr number
---@param position LspPosition
---@param request TsserverRequest
---@return boolean
function M.is_valid_context_for_function_snippet(bufnr, position, file, request)
return not is_completing_jsx(bufnr, position)
and not should_omit_function_snippet_in_context(position, file, request)
end

---@param content string
---@param kind "plaintext"|"markdown"|nil
function M.make_markup_content(content, kind)
Expand Down
Loading