From: Yegappan Lakshmanan Date: Thu, 31 Dec 2020 21:23:39 +0000 (-0800) Subject: Add support selection ranges and folding X-Git-Url: http://www.git.stargrave.org/?a=commitdiff_plain;h=ed87b4d0c5432a1972a8e951567fd615c066666a;p=vim-lsp.git Add support selection ranges and folding --- diff --git a/autoload/handlers.vim b/autoload/handlers.vim index 89bca56..2b2a31e 100644 --- a/autoload/handlers.vim +++ b/autoload/handlers.vim @@ -713,6 +713,36 @@ def s:processCodeActionReply(lspserver: dict, req: dict, reply: dict, req: dict, reply: dict) + if reply.result->empty() + return + endif + + var r: dict> = reply.result[0].range + + setpos("'<", [0, r.start.line + 1, r.start.character + 1, 0]) + setpos("'>", [0, r.end.line + 1, r.end.character, 0]) + :normal gv +enddef + +# process the 'textDocument/foldingRange' reply from the LSP server +def s:processFoldingRangeReply(lspserver: dict, req: dict, reply: dict) + if reply.result->empty() + return + endif + + # result: FoldingRange[] + for foldRange in reply.result + exe ':' .. (foldRange.startLine + 1) .. ',' .. (foldRange.endLine + 2) .. 'fold' + :foldopen! + endfor + + if &foldcolumn == 0 + :setlocal foldcolumn=2 + endif +enddef + # process the 'workspace/executeCommand' reply from the LSP server def s:processWorkspaceExecuteReply(lspserver: dict, req: dict, reply: dict) if reply.result->empty() @@ -751,6 +781,8 @@ export def ProcessReply(lspserver: dict, req: dict, reply: dict): 'textDocument/rangeFormatting': function('s:processFormatReply'), 'textDocument/rename': function('s:processRenameReply'), 'textDocument/codeAction': function('s:processCodeActionReply'), + 'textDocument/selectionRange': function('s:processSelectionRangeReply'), + 'textDocument/foldingRange': function('s:processFoldingRangeReply'), 'workspace/executeCommand': function('s:processWorkspaceExecuteReply'), 'workspace/symbol': function('s:processWorkspaceSymbolReply') } diff --git a/autoload/lsp.vim b/autoload/lsp.vim index 95e41df..b1295bb 100644 --- a/autoload/lsp.vim +++ b/autoload/lsp.vim @@ -755,4 +755,60 @@ def lsp#removeWorkspaceFolder(dirArg: string) lspserver.removeWorkspaceFolder(dirName) enddef +# visually select a range of positions around the current cursor. +def lsp#selectionRange() + var ftype = &filetype + if ftype == '' + return + endif + + var lspserver: dict = s:lspGetServer(ftype) + if lspserver->empty() + ErrMsg('Error: LSP server for "' .. ftype .. '" filetype is not found') + return + endif + if !lspserver.running + ErrMsg('Error: LSP server for "' .. ftype .. '" filetype is not running') + return + endif + + var fname = @% + if fname == '' + return + endif + + # TODO: Also support passing a range + lspserver.selectionRange(fname) +enddef + +# fold the entire document +def lsp#foldDocument() + var ftype = &filetype + if ftype == '' + return + endif + + var lspserver: dict = s:lspGetServer(ftype) + if lspserver->empty() + ErrMsg('Error: LSP server for "' .. ftype .. '" filetype is not found') + return + endif + if !lspserver.running + ErrMsg('Error: LSP server for "' .. ftype .. '" filetype is not running') + return + endif + + var fname = @% + if fname == '' + return + endif + + if &foldmethod != 'manual' + ErrMsg("Error: Only works when 'foldmethod' is 'manual'") + return + endif + + lspserver.foldRange(fname) +enddef + # vim: shiftwidth=2 softtabstop=2 diff --git a/autoload/lspserver.vim b/autoload/lspserver.vim index 12cb8b4..619fa34 100644 --- a/autoload/lspserver.vim +++ b/autoload/lspserver.vim @@ -73,14 +73,16 @@ def s:initServer(lspserver: dict) var req = lspserver.createRequest('initialize') var clientCaps: dict = { - workspace: { - workspaceFolders: v:true, - applyEdit: v:true, - }, - textDocument: {}, - window: {}, - general: {} - } + workspace: { + workspaceFolders: v:true, + applyEdit: v:true, + }, + textDocument: { + foldingRange: {lineFoldingOnly: v:true} + }, + window: {}, + general: {} + } # interface 'InitializeParams' var initparams: dict = {} @@ -655,6 +657,39 @@ def s:removeWorkspaceFolder(lspserver: dict, dirName: string): void lspserver.workspaceFolders->remove(idx) enddef +# select the text around the current cursor location +def s:selectionRange(lspserver: dict, fname: string) + # Check whether LSP server supports selection ranges + if !lspserver.caps->has_key('selectionRangeProvider') + || !lspserver.caps.selectionRangeProvider + ErrMsg("Error: LSP server does not support selection ranges") + return + endif + + var req = lspserver.createRequest('textDocument/selectionRange') + # interface SelectionRangeParams + # interface TextDocumentIdentifier + req.params->extend({textDocument: {uri: LspFileToUri(fname)}}) + req.params->extend({positions: [s:getLspPosition()]}) + lspserver.sendMessage(req) +enddef + +# fold the entire document +def s:foldRange(lspserver: dict, fname: string) + # Check whether LSP server supports fold ranges + if !lspserver.caps->has_key('foldingRangeProvider') + || !lspserver.caps.foldingRangeProvider + ErrMsg("Error: LSP server does not support folding") + return + endif + + var req = lspserver.createRequest('textDocument/foldingRange') + # interface FoldingRangeParams + # interface TextDocumentIdentifier + req.params->extend({textDocument: {uri: LspFileToUri(fname)}}) + lspserver.sendMessage(req) +enddef + export def NewLspServer(path: string, args: list): dict var lspserver: dict = { path: path, @@ -706,7 +741,9 @@ export def NewLspServer(path: string, args: list): dict codeAction: function('s:codeAction', [lspserver]), workspaceSymbols: function('s:workspaceSymbols', [lspserver]), addWorkspaceFolder: function('s:addWorkspaceFolder', [lspserver]), - removeWorkspaceFolder: function('s:removeWorkspaceFolder', [lspserver]) + removeWorkspaceFolder: function('s:removeWorkspaceFolder', [lspserver]), + selectionRange: function('s:selectionRange', [lspserver]), + foldRange: function('s:foldRange', [lspserver]) }) return lspserver diff --git a/plugin/lsp.vim b/plugin/lsp.vim index 06ca1c4..b97d0f3 100644 --- a/plugin/lsp.vim +++ b/plugin/lsp.vim @@ -39,4 +39,5 @@ command! -nargs=0 -bar LspShowWorkspaceSymbols call lsp#showWorkspaceSymbols() command! -nargs=0 -bar LspWorkspaceListFolders call lsp#listWorkspaceFolders() command! -nargs=1 -bar -complete=dir LspWorkspaceAddFolder call lsp#addWorkspaceFolder() command! -nargs=1 -bar -complete=dir LspWorkspaceRemoveFolder call lsp#removeWorkspaceFolder() - +command! -nargs=0 -bar LspSelectionRange call lsp#selectionRange() +command! -nargs=0 -bar LspFold call lsp#foldDocument()