endif
enddef
+# Apply the code action selected by the user.
export def HandleCodeAction(lspserver: dict<any>, selAction: dict<any>)
# textDocument/codeAction can return either Command[] or CodeAction[].
# If it is a CodeAction, it can have either an edit, a command or both.
endif
enddef
+# Process the list of code actions returned by the LSP server, ask the user to
+# choose one action from the list and then apply it.
+# If "query" is a number, then apply the corresponding action in the list.
+# If "query" is a regular expression starting with "/", then apply the action
+# matching the search string in the list.
+# If "query" is a regular string, then apply the action matching the string.
+# If "query" is an empty string, then if the "usePopupInCodeAction" option is
+# configured by the user, then display the list of items in a popup menu.
+# Otherwise display the items in an input list and prompt the user to select
+# an action.
export def ApplyCodeAction(lspserver: dict<any>, actionlist: list<dict<any>>, query: string): void
var actions = actionlist
},
})
else
- choice = inputlist(["Code action:"] + text)
+ choice = inputlist(['Code action:'] + text)
endif
if choice < 1 || choice > text->len()
endif
if completeItems->len() == 1
- && getline('.')->matchstr(completeItems[0].word .. '\>') != ''
+ && getline('.')->matchstr($'{completeItems[0].word}\>') != ''
# only one complete match. No need to show the completion popup
return
endif
if !diag->empty()
# 15 is a enough length not to cause line break
var max_width = &columns - 15
- var code = ""
+ var code = ''
if diag->has_key('code')
code = $'[{diag.code}] '
endif
- var msgNoLineBreak = code .. substitute(substitute(diag.message, "\n", " ", ""), "\\n", " ", "")
+ var msgNoLineBreak = code .. substitute(substitute(diag.message, "\n", ' ', ''), "\\n", ' ', '')
echo msgNoLineBreak[ : max_width]
else
- echo ""
+ echo ''
endif
enddef
else
# request failed
var emsg: string = msg.error.message
- emsg ..= ', code = ' .. msg.error.code
+ emsg ..= $', code = {msg.error.code}'
if msg.error->has_key('data')
- emsg = emsg .. ', data = ' .. msg.error.data->string()
+ emsg ..= $', data = {msg.error.data->string()}'
endif
util.ErrMsg($'Error(LSP): request {req.method} failed ({emsg})')
endif
# Show information about all the LSP servers
export def ShowServers()
for [ftype, lspserver] in ftypeServerMap->items()
- var msg = ftype .. " "
+ var msg = $'{ftype} '
if lspserver.running
msg ..= 'running'
else
endif
# Skip remote files
- if util.LspUriRemote(bnr->bufname()->fnamemodify(":p"))
+ if util.LspUriRemote(bnr->bufname()->fnamemodify(':p'))
return
endif
var query: string = queryArg
if query == ''
- query = input("Lookup symbol: ", expand('<cword>'))
+ query = input('Lookup symbol: ', expand('<cword>'))
if query == ''
return
endif
var dirName: string = dirArg
if dirName == ''
- dirName = input("Add Workspace Folder: ", getcwd(), 'dir')
+ dirName = input('Add Workspace Folder: ', getcwd(), 'dir')
if dirName == ''
return
endif
var dirName: string = dirArg
if dirName == ''
- dirName = input("Remove Workspace Folder: ", getcwd(), 'dir')
+ dirName = input('Remove Workspace Folder: ', getcwd(), 'dir')
if dirName == ''
return
endif
# Stop a LSP server
def StopServer(lspserver: dict<any>): number
if !lspserver.running
- util.WarnMsg("LSP server is not running")
+ util.WarnMsg('LSP server is not running')
return 0
endif
&& (request.id->trim() =~ '[^[:digit:]]\+'
|| request.id->trim() == ''))
|| (request.id->type() != v:t_string && request.id->type() != v:t_number)
- util.ErrMsg("Error: request.id of response to LSP server is not a correct number")
+ util.ErrMsg('Error: request.id of response to LSP server is not a correct number')
return
endif
var resp: dict<any> = lspserver.createResponse(
if reply->has_key('error')
# request failed
var emsg: string = reply.error.message
- emsg ..= ', code = ' .. reply.error.code
+ emsg ..= $', code = {reply.error.code}'
if reply.error->has_key('data')
- emsg ..= ', data = ' .. reply.error.data->string()
+ emsg ..= $', data = {reply.error.data->string()}'
endif
util.ErrMsg($'Error(LSP): request {method} failed ({emsg})')
endif
def GetCompletion(lspserver: dict<any>, triggerKind_arg: number, triggerChar: string): void
# Check whether LSP server supports completion
if !lspserver.isCompletionProvider
- util.ErrMsg("Error: LSP server does not support completion")
+ util.ErrMsg('Error: LSP server does not support completion')
return
endif
def ResolveCompletion(lspserver: dict<any>, item: dict<any>): void
# Check whether LSP server supports completion item resolve
if !lspserver.isCompletionResolveProvider
- util.ErrMsg("Error: LSP server does not support completion item resolve")
+ util.ErrMsg('Error: LSP server does not support completion item resolve')
return
endif
def GotoDefinition(lspserver: dict<any>, peek: bool, cmdmods: string)
# Check whether LSP server supports jumping to a definition
if !lspserver.isDefinitionProvider
- util.ErrMsg("Error: Jumping to a symbol definition is not supported")
+ util.ErrMsg('Error: Jumping to a symbol definition is not supported')
return
endif
def GotoDeclaration(lspserver: dict<any>, peek: bool, cmdmods: string)
# Check whether LSP server supports jumping to a declaration
if !lspserver.isDeclarationProvider
- util.ErrMsg("Error: Jumping to a symbol declaration is not supported")
+ util.ErrMsg('Error: Jumping to a symbol declaration is not supported')
return
endif
def GotoTypeDef(lspserver: dict<any>, peek: bool, cmdmods: string)
# Check whether LSP server supports jumping to a type definition
if !lspserver.isTypeDefinitionProvider
- util.ErrMsg("Error: Jumping to a symbol type definition is not supported")
+ util.ErrMsg('Error: Jumping to a symbol type definition is not supported')
return
endif
def GotoImplementation(lspserver: dict<any>, peek: bool, cmdmods: string)
# Check whether LSP server supports jumping to a implementation
if !lspserver.isImplementationProvider
- util.ErrMsg("Error: Jumping to a symbol implementation is not supported")
+ util.ErrMsg('Error: Jumping to a symbol implementation is not supported')
return
endif
def ShowSignature(lspserver: dict<any>): void
# Check whether LSP server supports signature help
if !lspserver.isSignatureHelpProvider
- util.ErrMsg("Error: LSP server does not support signature help")
+ util.ErrMsg('Error: LSP server does not support signature help')
return
endif
def ShowReferences(lspserver: dict<any>, peek: bool): void
# Check whether LSP server supports getting reference information
if !lspserver.isReferencesProvider
- util.ErrMsg("Error: LSP server does not support showing references")
+ util.ErrMsg('Error: LSP server does not support showing references')
return
endif
def DocHighlight(lspserver: dict<any>): void
# Check whether LSP server supports getting highlight information
if !lspserver.isDocumentHighlightProvider
- util.ErrMsg("Error: LSP server does not support document highlight")
+ util.ErrMsg('Error: LSP server does not support document highlight')
return
endif
def GetDocSymbols(lspserver: dict<any>, fname: string): void
# Check whether LSP server supports getting document symbol information
if !lspserver.isDocumentSymbolProvider
- util.ErrMsg("Error: LSP server does not support getting list of symbols")
+ util.ErrMsg('Error: LSP server does not support getting list of symbols')
return
endif
start_lnum: number, end_lnum: number)
# Check whether LSP server supports formatting documents
if !lspserver.isDocumentFormattingProvider
- util.ErrMsg("Error: LSP server does not support formatting documents")
+ util.ErrMsg('Error: LSP server does not support formatting documents')
return
endif
def IncomingCalls(lspserver: dict<any>, fname: string)
# Check whether LSP server supports call hierarchy
if !lspserver.isCallHierarchyProvider
- util.ErrMsg("Error: LSP server does not support call hierarchy")
+ util.ErrMsg('Error: LSP server does not support call hierarchy')
return
endif
def OutgoingCalls(lspserver: dict<any>, fname: string)
# Check whether LSP server supports call hierarchy
if !lspserver.isCallHierarchyProvider
- util.ErrMsg("Error: LSP server does not support call hierarchy")
+ util.ErrMsg('Error: LSP server does not support call hierarchy')
return
endif
def InlayHintsShow(lspserver: dict<any>)
# Check whether LSP server supports type hierarchy
if !lspserver.isInlayHintProvider && !lspserver.isClangdInlayHintsProvider
- util.ErrMsg("Error: LSP server does not support inlay hint")
+ util.ErrMsg('Error: LSP server does not support inlay hint')
return
endif
def TypeHiearchy(lspserver: dict<any>, direction: number)
# Check whether LSP server supports type hierarchy
if !lspserver.isTypeHierarchyProvider
- util.ErrMsg("Error: LSP server does not support type hierarchy")
+ util.ErrMsg('Error: LSP server does not support type hierarchy')
return
endif
def RenameSymbol(lspserver: dict<any>, newName: string)
# Check whether LSP server supports rename operation
if !lspserver.isRenameProvider
- util.ErrMsg("Error: LSP server does not support rename operation")
+ util.ErrMsg('Error: LSP server does not support rename operation')
return
endif
line2: number, query: string)
# Check whether LSP server supports code action operation
if !lspserver.isCodeActionProvider
- util.ErrMsg("Error: LSP server does not support code action operation")
+ util.ErrMsg('Error: LSP server does not support code action operation')
return
endif
def WorkspaceQuerySymbols(lspserver: dict<any>, query: string)
# Check whether the LSP server supports listing workspace symbols
if !lspserver.isWorkspaceSymbolProvider
- util.ErrMsg("Error: LSP server does not support listing workspace symbols")
+ util.ErrMsg('Error: LSP server does not support listing workspace symbols')
return
endif
def SelectionRange(lspserver: dict<any>, fname: string)
# Check whether LSP server supports selection ranges
if !lspserver.isSelectionRangeProvider
- util.ErrMsg("Error: LSP server does not support selection ranges")
+ util.ErrMsg('Error: LSP server does not support selection ranges')
return
endif
def SelectionExpand(lspserver: dict<any>)
# Check whether LSP server supports selection ranges
if !lspserver.isSelectionRangeProvider
- util.ErrMsg("Error: LSP server does not support selection ranges")
+ util.ErrMsg('Error: LSP server does not support selection ranges')
return
endif
def SelectionShrink(lspserver: dict<any>)
# Check whether LSP server supports selection ranges
if !lspserver.isSelectionRangeProvider
- util.ErrMsg("Error: LSP server does not support selection ranges")
+ util.ErrMsg('Error: LSP server does not support selection ranges')
return
endif
def FoldRange(lspserver: dict<any>, fname: string)
# Check whether LSP server supports fold ranges
if !lspserver.isFoldingRangeProvider
- util.ErrMsg("Error: LSP server does not support folding")
+ util.ErrMsg('Error: LSP server does not support folding')
return
endif
def GetNextInlineBlock(text: string, blocks: list<any>, rel_pos: number): dict<any>
var result = {
- text: "",
+ text: '',
props: []
}
var cur = blocks->remove(0)
def ParseInlines(text: string, rel_pos: number = 0): dict<any>
var formatted = {
- text: "",
+ text: '',
props: []
}
var code_spans = GetCodeSpans(text)
def CreateContainerBlock(match: list<any>, start_lnum: number): dict<any>
if match[0][0] == '>'
return {
- type: "quote_block",
+ type: 'quote_block',
lnum: start_lnum,
indent: 0
}
else
return {
- type: "list_item",
+ type: 'list_item',
lnum: start_lnum,
marker: $' {match[0]->matchstr("\\S\\+")} ',
indent: match[2]
# new open leaf block
def CreateLeafBlock(block_type: string, line: string, ...opt: list<any>): dict<any>
- if block_type == "fenced_code"
+ if block_type == 'fenced_code'
var token = line->matchlist(code_fence)
return {
type: block_type,
language: token[2],
text: []
}
- elseif block_type == "indented_code"
+ elseif block_type == 'indented_code'
return {
type: block_type,
text: [line->matchstr(code_indent)]
}
- elseif block_type == "paragraph"
+ elseif block_type == 'paragraph'
return {
type: block_type,
text: [line->matchstr(paragraph)]
}
- elseif block_type == "heading"
+ elseif block_type == 'heading'
return {
type: block_type,
level: opt[0],
text: line
}
- elseif block_type == "table"
+ elseif block_type == 'table'
return {
type: block_type,
header: line,
enddef
def NeedBlankLine(prev: string, cur: string): bool
- if prev == "hr" || cur == "hr"
+ if prev == 'hr' || cur == 'hr'
return v:false
- elseif prev == "heading" || cur == "heading"
+ elseif prev == 'heading' || cur == 'heading'
return v:true
- elseif prev == "paragraph" && cur == "paragraph"
+ elseif prev == 'paragraph' && cur == 'paragraph'
return v:true
elseif prev != cur
return v:true
return v:false
enddef
-var last_block: string = ""
+var last_block: string = ''
def CloseBlocks(document: dict<list<any>>, blocks: list<dict<any>>, start: number = 0): void
if start >= blocks->len()
return
endif
var line: dict<any> = {
- text: "",
+ text: '',
props: []
}
if !document.content->empty() && NeedBlankLine(last_block, blocks[0].type)
- document.content->add({text: "", props: []})
+ document.content->add({text: '', props: []})
endif
last_block = blocks[0].type
for i in start->range()
- if blocks[i]->has_key("marker")
+ if blocks[i]->has_key('marker')
if blocks[i].marker =~ '\S'
line.props->add(GetMarkerProp('list_item',
line.text->len() + 1,
endfor
for block in blocks->remove(start, -1)
if block.type =~ 'quote_block\|list_item'
- if block->has_key("marker")
+ if block->has_key('marker')
if block.marker =~ '\S'
line.props->add(GetMarkerProp('list_item',
line.text->len() + 1,
else
# leaf block
if block.type =~ '_code'
- if block.type == "indented_code"
+ if block.type == 'indented_code'
while !block.text->empty() && block.text[0] !~ '\S'
block.text->remove(0)
endwhile
indent->len() + max_len + 1))
endif
endif
- elseif block.type == "heading"
+ elseif block.type == 'heading'
line.props->add(GetMarkerProp('heading',
line.text->len() + 1,
block.text->len(),
line.text ..= format.text
line.props += line.props
document.content->add(line)
- elseif block.type == "table"
+ elseif block.type == 'table'
var indent = line.text
var head = block.header->split('\\\@1<!|')
var col1 = head->remove(0)
line.props->add(GetMarkerProp('table_header',
line.text->len() + 2,
format.text->len()))
- line.text ..= "|" .. format.text
+ line.text ..= $'|{format.text}'
line.props += format.props
endfor
document.content->add(line)
data.props->add(GetMarkerProp('table_sep',
data.text->len() + 1,
1))
- data.text ..= "|" .. format.text
+ data.text ..= $'|{format.text}'
data.props += format.props
endfor
document.content->add(data)
endfor
- elseif block.type == "paragraph"
- var format = ParseInlines(block.text->join(" "), line.text->len())
+ elseif block.type == 'paragraph'
+ var format = ParseInlines(block.text->join(' '), line.text->len())
line.text ..= format.text
line.props += format.props
document.content->add(line)
# for each open block check if current line continue it
while cur < open_blocks->len()
- if open_blocks[cur].type == "quote_block"
+ if open_blocks[cur].type == 'quote_block'
var marker = line->matchstrpos(block_quote)
if marker[1] == -1
break
endif
line = line[marker[2] :]
- elseif open_blocks[cur].type == "list_item"
+ elseif open_blocks[cur].type == 'list_item'
var marker = line->matchstrpos($'^ \{{{open_blocks[cur].indent}}}')
if marker[1] == -1
break
endif
line = line[marker[2] :]
- elseif open_blocks[cur].type == "fenced_code"
+ elseif open_blocks[cur].type == 'fenced_code'
if line =~ $'^ \{{,3}}{open_blocks[cur].fence}{open_blocks[cur].fence[0]}* *$'
CloseBlocks(document, open_blocks, cur)
else
endif
cur = -1
break
- elseif open_blocks[cur].type == "indented_code"
+ elseif open_blocks[cur].type == 'indented_code'
var marker = line->matchstrpos(code_indent)
if marker[1] >= 0
open_blocks[cur].text->add(marker[0])
cur = -1
endif
break
- elseif open_blocks[cur].type == "paragraph"
+ elseif open_blocks[cur].type == 'paragraph'
if line =~ setext_heading
var marker = line->matchstrpos(setext_heading)
open_blocks->add(CreateLeafBlock(
- "heading",
- open_blocks->remove(cur).text->join(" "),
+ 'heading',
+ open_blocks->remove(cur).text->join(' '),
setext_heading_level[marker[0]]))
CloseBlocks(document, open_blocks, cur)
cur = -1
# may be a table
var marker = line->matchstr(table_delimiter)
if !marker->empty()
- if open_blocks[cur].text[0]->split('\\\@1<!|')->len() == marker->split("|")->len()
+ if open_blocks[cur].text[0]->split('\\\@1<!|')->len() == marker->split('|')->len()
open_blocks->add(CreateLeafBlock(
- "table",
+ 'table',
open_blocks->remove(cur).text[0],
marker))
cur = -1
# a themaic break close all previous blocks
if line =~ thematic_break
CloseBlocks(document, open_blocks)
- if &g:encoding == "utf-8"
+ if &g:encoding == 'utf-8'
document.content->add({text: "\u2500"->repeat(width)})
else
- document.content->add({text: "-"->repeat(width)})
+ document.content->add({text: '-'->repeat(width)})
endif
- last_block = "hr"
+ last_block = 'hr'
continue
endif
# check for leaf block
if line =~ code_fence
CloseBlocks(document, open_blocks, cur)
- open_blocks->add(CreateLeafBlock("fenced_code", line))
+ open_blocks->add(CreateLeafBlock('fenced_code', line))
elseif line =~ blank_line
if open_blocks->empty()
continue
endif
- if open_blocks[-1].type == "paragraph"
+ if open_blocks[-1].type == 'paragraph'
CloseBlocks(document, open_blocks, min([cur, open_blocks->len() - 1]))
- elseif open_blocks[-1].type == "table"
+ elseif open_blocks[-1].type == 'table'
CloseBlocks(document, open_blocks, open_blocks->len() - 1)
elseif open_blocks[-1].type =~ '_code'
open_blocks[-1].text->add(line)
endif
elseif line =~ code_indent
if open_blocks->empty()
- open_blocks->add(CreateLeafBlock("indented_code", line))
+ open_blocks->add(CreateLeafBlock('indented_code', line))
elseif open_blocks[-1].type =~ '_code'
open_blocks[-1].text->add(line->matchstr(code_indent))
- elseif open_blocks[-1].type == "paragraph"
+ elseif open_blocks[-1].type == 'paragraph'
open_blocks[-1].text->add(line->matchstr(paragraph))
else
CloseBlocks(document, open_blocks, cur)
- open_blocks->add(CreateLeafBlock("indented_code", line))
+ open_blocks->add(CreateLeafBlock('indented_code', line))
endif
elseif line =~ atx_heading
CloseBlocks(document, open_blocks, cur)
var token = line->matchlist(atx_heading)
- open_blocks->add(CreateLeafBlock("heading", token[2], token[1]->len()))
+ open_blocks->add(CreateLeafBlock('heading', token[2], token[1]->len()))
CloseBlocks(document, open_blocks, cur)
elseif !open_blocks->empty()
- if open_blocks[-1].type == "table"
+ if open_blocks[-1].type == 'table'
open_blocks[-1].text->add(line)
- elseif open_blocks[-1].type == "paragraph"
+ elseif open_blocks[-1].type == 'paragraph'
open_blocks[-1].text->add(line->matchstr(paragraph))
else
CloseBlocks(document, open_blocks, cur)
- open_blocks->add(CreateLeafBlock("paragraph", line))
+ open_blocks->add(CreateLeafBlock('paragraph', line))
endif
else
- open_blocks->add(CreateLeafBlock("paragraph", line))
+ open_blocks->add(CreateLeafBlock('paragraph', line))
endif
endfor
# reply for this buffer is available. Modify the current selection.
var selRange: dict<any> = lspserver.selection.selRange
- var startpos: list<number> = getcharpos("v")
- var endpos: list<number> = getcharpos(".")
+ var startpos: list<number> = getcharpos('v')
+ var endpos: list<number> = getcharpos('.')
var idx: number = lspserver.selection.index
# Locate the range in the LSP reply for the current selection
maxwidth: 60,
mapping: false,
fixed: 1,
- close: "button",
+ close: 'button',
filter: function(FilterSymbols, [lspserver]),
callback: JumpToWorkspaceSymbol
}
#util.WarnMsg("set_lines: Invalid range, A = " .. A->string()
# .. ", B = " .. B->string() .. ", numlines = " .. numlines
# .. ", new lines = " .. new_lines->string())
- var msg = "set_lines: Invalid range, A = " .. A->string()
- msg ..= ", B = " .. B->string() .. ", numlines = " .. numlines
- msg ..= ", new lines = " .. new_lines->string()
+ var msg = $"set_lines: Invalid range, A = {A->string()}"
+ msg ..= $", B = {B->string()}, numlines = {numlines}"
+ msg ..= $", new lines = {new_lines->string()}"
util.WarnMsg(msg)
return lines
endif
var new_lines_len: number = new_lines->len()
- #echomsg 'i_0 = ' .. i_0 .. ', i_n = ' .. i_n .. ', new_lines = ' .. string(new_lines)
+ #echomsg $"i_0 = {i_0}, i_n = {i_n}, new_lines = {string(new_lines)}"
var n: number = i_n - i_0 + 1
if n != new_lines_len
if n > new_lines_len
lines->extend(repeat([''], new_lines_len - n), i_0)
endif
endif
- #echomsg "lines(1) = " .. string(lines)
+ #echomsg $"lines(1) = {string(lines)}"
# replace the previous lines with the new lines
for i in new_lines_len->range()
lines[i_0 + i] = new_lines[i]
endfor
- #echomsg "lines(2) = " .. string(lines)
+ #echomsg $"lines(2) = {string(lines)}"
# append the suffix (if any) to the last line
if suffix != ''
var i = i_0 + new_lines_len - 1
lines[i] = lines[i] .. suffix
endif
- #echomsg "lines(3) = " .. string(lines)
+ #echomsg $"lines(3) = {string(lines)}"
# prepend the prefix (if any) to the first line
if prefix != ''
lines[i_0] = prefix .. lines[i_0]
endif
- #echomsg "lines(4) = " .. string(lines)
+ #echomsg $"lines(4) = {string(lines)}"
return lines
enddef
lines->add('')
endif
- #echomsg 'lines(1) = ' .. string(lines)
+ #echomsg $'lines(1) = {string(lines)}'
#echomsg updated_edits
for e in updated_edits
lines = Set_lines(lines, A, B, e.lines)
endfor
- #echomsg 'lines(2) = ' .. string(lines)
+ #echomsg $'lines(2) = {string(lines)}'
# If the last line is empty and we need to set EOL, then remove it.
if set_eol && lines[-1]->len() == 0
lines->remove(-1)
endif
- #echomsg 'ApplyTextEdits: start_line = ' .. start_line .. ', finish_line = ' .. finish_line
- #echomsg 'lines = ' .. string(lines)
+ #echomsg $'ApplyTextEdits: start_line = {start_line}, finish_line = {finish_line}'
+ #echomsg $'lines = {string(lines)}'
# Delete all the lines that need to be modified
bnr->deletebufline(start_line + 1, finish_line + 1)
items = super ? typeHier.parents : typeHier.children
for item in items
- TypeTreeGenerate(super, item, pfx_arg .. '| ', typeTree, typeUriMap)
+ TypeTreeGenerate(super, item, $'{pfx_arg}| ', typeTree, typeUriMap)
endfor
enddef