diff --git a/lua/typescript-tools/protocol/text_document/completion/init.lua b/lua/typescript-tools/protocol/text_document/completion/init.lua index e7a20f1..bd10f61 100644 --- a/lua/typescript-tools/protocol/text_document/completion/init.lua +++ b/lua/typescript-tools/protocol/text_document/completion/init.lua @@ -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 @@ -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 diff --git a/lua/typescript-tools/protocol/text_document/completion/resolve.lua b/lua/typescript-tools/protocol/text_document/completion/resolve.lua index 115269b..6328bb6 100644 --- a/lua/typescript-tools/protocol/text_document/completion/resolve.lua +++ b/lua/typescript-tools/protocol/text_document/completion/resolve.lua @@ -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, + params.data.file, + request + ) -- tsserver protocol reference: -- https://github.com/microsoft/TypeScript/blob/549e61d0af1ba885be29d69f341e7d3a00686071/lib/protocol.d.ts#L1661 @@ -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 diff --git a/lua/typescript-tools/protocol/utils.lua b/lua/typescript-tools/protocol/utils.lua index a3707e1..02c1d5c 100644 --- a/lua/typescript-tools/protocol/utils.lua +++ b/lua/typescript-tools/protocol/utils.lua @@ -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)