diff options
author | hrsh7th <hrsh7th@gmail.com> | 2021-09-14 20:31:41 +0900 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-09-14 04:31:41 -0700 |
commit | 516775e9d84c5eda9c1d014ff052132737361d90 (patch) | |
tree | 640be5a4d36340039e9223ce00b19489e7e4ae28 /runtime/lua/vim/lsp/util.lua | |
parent | b8cce77702777bb876b2cef7e28662cf4539265e (diff) | |
download | rneovim-516775e9d84c5eda9c1d014ff052132737361d90.tar.gz rneovim-516775e9d84c5eda9c1d014ff052132737361d90.tar.bz2 rneovim-516775e9d84c5eda9c1d014ff052132737361d90.zip |
fix(lsp): correctly parse LSP snippets #15579
Fixes #15522
Diffstat (limited to 'runtime/lua/vim/lsp/util.lua')
-rw-r--r-- | runtime/lua/vim/lsp/util.lua | 75 |
1 files changed, 10 insertions, 65 deletions
diff --git a/runtime/lua/vim/lsp/util.lua b/runtime/lua/vim/lsp/util.lua index a4c8b69f6c..5a22a311e0 100644 --- a/runtime/lua/vim/lsp/util.lua +++ b/runtime/lua/vim/lsp/util.lua @@ -1,4 +1,5 @@ local protocol = require 'vim.lsp.protocol' +local snippet = require 'vim.lsp._snippet' local vim = vim local validate = vim.validate local api = vim.api @@ -523,74 +524,18 @@ function M.apply_text_document_edit(text_document_edit, index) M.apply_text_edits(text_document_edit.edits, bufnr) end ----@private ---- Recursively parses snippets in a completion entry. ---- ----@param input (string) Snippet text to parse for snippets ----@param inner (bool) Whether this function is being called recursively ----@returns 2-tuple of strings: The first is the parsed result, the second is the ----unparsed rest of the input -local function parse_snippet_rec(input, inner) - local res = "" - - local close, closeend = nil, nil - if inner then - close, closeend = input:find("}", 1, true) - while close ~= nil and input:sub(close-1,close-1) == "\\" do - close, closeend = input:find("}", closeend+1, true) - end - end - - local didx = input:find('$', 1, true) - if didx == nil and close == nil then - return input, "" - elseif close ~=nil and (didx == nil or close < didx) then - -- No inner placeholders - return input:sub(0, close-1), input:sub(closeend+1) - end - - res = res .. input:sub(0, didx-1) - input = input:sub(didx+1) - - local tabstop, tabstopend = input:find('^%d+') - local placeholder, placeholderend = input:find('^{%d+:') - local choice, choiceend = input:find('^{%d+|') - - if tabstop then - input = input:sub(tabstopend+1) - elseif choice then - input = input:sub(choiceend+1) - close, closeend = input:find("|}", 1, true) - - res = res .. input:sub(0, close-1) - input = input:sub(closeend+1) - elseif placeholder then - -- TODO: add support for variables - input = input:sub(placeholderend+1) - - -- placeholders and variables are recursive - while input ~= "" do - local r, tail = parse_snippet_rec(input, true) - r = r:gsub("\\}", "}") - - res = res .. r - input = tail - end - else - res = res .. "$" - end - - return res, input -end - --- Parses snippets in a completion entry. --- ----@param input (string) unparsed snippet ----@returns (string) parsed snippet +---@param input string unparsed snippet +---@returns string parsed snippet function M.parse_snippet(input) - local res, _ = parse_snippet_rec(input, false) - - return res + local ok, parsed = pcall(function() + return tostring(snippet.parse(input)) + end) + if not ok then + return input + end + return parsed end ---@private |