endif
enddef
+# process the 'textDocument/selectionRange' reply from the LSP server
+def s:processSelectionRangeReply(lspserver: dict<any>, req: dict<any>, reply: dict<any>)
+ if reply.result->empty()
+ return
+ endif
+
+ var r: dict<dict<number>> = 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<any>, req: dict<any>, reply: dict<any>)
+ 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<any>, req: dict<any>, reply: dict<any>)
if reply.result->empty()
'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')
}
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<any> = 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<any> = 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
var req = lspserver.createRequest('initialize')
var clientCaps: dict<any> = {
- 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<any> = {}
lspserver.workspaceFolders->remove(idx)
enddef
+# select the text around the current cursor location
+def s:selectionRange(lspserver: dict<any>, 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<any>, 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<string>): dict<any>
var lspserver: dict<any> = {
path: path,
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
command! -nargs=0 -bar LspWorkspaceListFolders call lsp#listWorkspaceFolders()
command! -nargs=1 -bar -complete=dir LspWorkspaceAddFolder call lsp#addWorkspaceFolder(<q-args>)
command! -nargs=1 -bar -complete=dir LspWorkspaceRemoveFolder call lsp#removeWorkspaceFolder(<q-args>)
-
+command! -nargs=0 -bar LspSelectionRange call lsp#selectionRange()
+command! -nargs=0 -bar LspFold call lsp#foldDocument()