diff options
Diffstat (limited to 'runtime')
-rw-r--r-- | runtime/doc/change.txt | 4 | ||||
-rw-r--r-- | runtime/doc/vim_diff.txt | 3 | ||||
-rw-r--r-- | runtime/ftplugin/markdown.vim | 46 | ||||
-rw-r--r-- | runtime/lua/vim/lsp.lua | 95 | ||||
-rw-r--r-- | runtime/lua/vim/lsp/protocol.lua | 14 | ||||
-rw-r--r-- | runtime/syntax/markdown.vim | 66 |
6 files changed, 163 insertions, 65 deletions
diff --git a/runtime/doc/change.txt b/runtime/doc/change.txt index dcebbc524c..5c67359002 100644 --- a/runtime/doc/change.txt +++ b/runtime/doc/change.txt @@ -1615,6 +1615,10 @@ B When joining lines, don't insert a space between two multi-byte characters. Overruled by the 'M' flag. 1 Don't break a line after a one-letter word. It's broken before it instead (if possible). +] Respect textwidth rigorously. With this flag set, no line can be + longer than textwidth, unless line-break-prohibition rules make this + impossible. Mainly for CJK scripts and works only if 'encoding' is + "utf-8". j Where it makes sense, remove a comment leader when joining lines. For example, joining: int i; // the index ~ diff --git a/runtime/doc/vim_diff.txt b/runtime/doc/vim_diff.txt index ae60c1c5e8..1fcb6611b4 100644 --- a/runtime/doc/vim_diff.txt +++ b/runtime/doc/vim_diff.txt @@ -450,6 +450,9 @@ Eval: *js_decode()* *v:none* (used by Vim to represent JavaScript "undefined"); use |v:null| instead. +Events: + *SigUSR1* Use |Signal| to detect `SIGUSR1` signal instead. + Highlight groups: *hl-StatusLineTerm* *hl-StatusLineTermNC* are unnecessary because Nvim supports 'winhighlight' window-local highlights. diff --git a/runtime/ftplugin/markdown.vim b/runtime/ftplugin/markdown.vim index 277ba94e8b..fc1d9e068b 100644 --- a/runtime/ftplugin/markdown.vim +++ b/runtime/ftplugin/markdown.vim @@ -1,7 +1,7 @@ " Vim filetype plugin " Language: Markdown " Maintainer: Tim Pope <vimNOSPAM@tpope.org> -" Last Change: 2016 Aug 29 +" Last Change: 2019 Dec 05 if exists("b:did_ftplugin") finish @@ -9,7 +9,7 @@ endif runtime! ftplugin/html.vim ftplugin/html_*.vim ftplugin/html/*.vim -setlocal comments=fb:*,fb:-,fb:+,n:> commentstring=>\ %s +setlocal comments=fb:*,fb:-,fb:+,n:> commentstring=<!--%s--> setlocal formatoptions+=tcqln formatoptions-=r formatoptions-=o setlocal formatlistpat=^\\s*\\d\\+\\.\\s\\+\\\|^[-*+]\\s\\+\\\|^\\[^\\ze[^\\]]\\+\\]: @@ -19,32 +19,56 @@ else let b:undo_ftplugin = "setl cms< com< fo< flp<" endif -function! MarkdownFold() +function! s:NotCodeBlock(lnum) abort + return synIDattr(synID(v:lnum, 1, 1), 'name') !=# 'markdownCode' +endfunction + +function! MarkdownFold() abort let line = getline(v:lnum) - " Regular headers - let depth = match(line, '\(^#\+\)\@<=\( .*$\)\@=') - if depth > 0 - return ">" . depth + if line =~# '^#\+ ' && s:NotCodeBlock(v:lnum) + return ">" . match(line, ' ') endif - " Setext style headings let nextline = getline(v:lnum + 1) - if (line =~ '^.\+$') && (nextline =~ '^=\+$') + if (line =~ '^.\+$') && (nextline =~ '^=\+$') && s:NotCodeBlock(v:lnum + 1) return ">1" endif - if (line =~ '^.\+$') && (nextline =~ '^-\+$') + if (line =~ '^.\+$') && (nextline =~ '^-\+$') && s:NotCodeBlock(v:lnum + 1) return ">2" endif return "=" endfunction +function! s:HashIndent(lnum) abort + let hash_header = matchstr(getline(a:lnum), '^#\{1,6}') + if len(hash_header) + return hash_header + else + let nextline = getline(a:lnum + 1) + if nextline =~# '^=\+\s*$' + return '#' + elseif nextline =~# '^-\+\s*$' + return '##' + endif + endif +endfunction + +function! MarkdownFoldText() abort + let hash_indent = s:HashIndent(v:foldstart) + let title = substitute(getline(v:foldstart), '^#\+\s*', '', '') + let foldsize = (v:foldend - v:foldstart + 1) + let linecount = '['.foldsize.' lines]' + return hash_indent.' '.title.' '.linecount +endfunction + if has("folding") && exists("g:markdown_folding") setlocal foldexpr=MarkdownFold() setlocal foldmethod=expr - let b:undo_ftplugin .= " foldexpr< foldmethod<" + setlocal foldtext=MarkdownFoldText() + let b:undo_ftplugin .= " foldexpr< foldmethod< foldtext<" endif " vim:set sw=2: diff --git a/runtime/lua/vim/lsp.lua b/runtime/lua/vim/lsp.lua index 95d9c585ee..fad213212a 100644 --- a/runtime/lua/vim/lsp.lua +++ b/runtime/lua/vim/lsp.lua @@ -25,6 +25,27 @@ local lsp = { -- format_rpc_error = lsp_rpc.format_rpc_error; } +-- maps request name to the required resolved_capability in the client. +lsp._request_name_to_capability = { + ['textDocument/hover'] = 'hover'; + ['textDocument/signatureHelp'] = 'signature_help'; + ['textDocument/definition'] = 'goto_definition'; + ['textDocument/implementation'] = 'implementation'; + ['textDocument/declaration'] = 'declaration'; + ['textDocument/typeDefinition'] = 'type_definition'; + ['textDocument/documentSymbol'] = 'document_symbol'; + ['textDocument/workspaceSymbol'] = 'workspace_symbol'; + ['textDocument/prepareCallHierarchy'] = 'call_hierarchy'; + ['textDocument/rename'] = 'rename'; + ['textDocument/codeAction'] = 'code_action'; + ['workspace/executeCommand'] = 'execute_command'; + ['textDocument/references'] = 'find_references'; + ['textDocument/rangeFormatting'] = 'document_range_formatting'; + ['textDocument/formatting'] = 'document_formatting'; + ['textDocument/completion'] = 'completion'; + ['textDocument/documentHighlight'] = 'document_highlight'; +} + -- TODO improve handling of scratch buffers with LSP attached. --@private @@ -51,6 +72,16 @@ local function resolve_bufnr(bufnr) end --@private +--- callback called by the client when trying to call a method that's not +--- supported in any of the servers registered for the current buffer. +--@param method (string) name of the method +function lsp._unsupported_method(method) + local msg = string.format("method %s is not supported by any of the servers registered for the current buffer", method) + log.warn(msg) + return lsp.rpc_response_error(protocol.ErrorCodes.MethodNotFound, msg) +end + +--@private --- Checks whether a given path is a directory. --- --@param filename (string) path to check @@ -575,6 +606,15 @@ function lsp.start_client(config) -- These are the cleaned up capabilities we use for dynamically deciding -- when to send certain events to clients. client.resolved_capabilities = protocol.resolve_capabilities(client.server_capabilities) + client.supports_method = function(method) + local required_capability = lsp._request_name_to_capability[method] + -- if we don't know about the method, assume that the client supports it. + if not required_capability then + return true + end + + return client.resolved_capabilities[required_capability] + end if config.on_init then local status, err = pcall(config.on_init, client, result) if not status then @@ -598,19 +638,6 @@ function lsp.start_client(config) end --@private - --- Throws error for a method that is not supported by the current LSP - --- server. - --- - --@param method (string) an LSP method name not supported by the LSP server. - --@returns (error) a 'MethodNotFound' JSON-RPC error response. - local function unsupported_method(method) - local msg = "server doesn't support "..method - local _ = log.warn() and log.warn(msg) - err_message(msg) - return lsp.rpc_response_error(protocol.ErrorCodes.MethodNotFound, msg) - end - - --@private --- Sends a request to the server. --- --- This is a thin wrapper around {client.rpc.request} with some additional @@ -637,20 +664,6 @@ function lsp.start_client(config) or error(string.format("not found: %q request callback for client %q.", method, client.name)) end local _ = log.debug() and log.debug(log_prefix, "client.request", client_id, method, params, callback, bufnr) - -- TODO keep these checks or just let it go anyway? - if (not client.resolved_capabilities.hover and method == 'textDocument/hover') - or (not client.resolved_capabilities.signature_help and method == 'textDocument/signatureHelp') - or (not client.resolved_capabilities.goto_definition and method == 'textDocument/definition') - or (not client.resolved_capabilities.implementation and method == 'textDocument/implementation') - or (not client.resolved_capabilities.declaration and method == 'textDocument/declaration') - or (not client.resolved_capabilities.type_definition and method == 'textDocument/typeDefinition') - or (not client.resolved_capabilities.document_symbol and method == 'textDocument/documentSymbol') - or (not client.resolved_capabilities.workspace_symbol and method == 'textDocument/workspaceSymbol') - or (not client.resolved_capabilities.call_hierarchy and method == 'textDocument/prepareCallHierarchy') - then - callback(unsupported_method(method), method, nil, client_id, bufnr) - return - end return rpc.request(method, params, function(err, result) callback(err, method, result, client_id, bufnr) end) @@ -997,16 +1010,32 @@ function lsp.buf_request(bufnr, method, params, callback) callback = { callback, 'f', true }; } local client_request_ids = {} - for_each_buffer_client(bufnr, function(client, client_id, resolved_bufnr) - local request_success, request_id = client.request(method, params, callback, resolved_bufnr) - -- This could only fail if the client shut down in the time since we looked - -- it up and we did the request, which should be rare. - if request_success then - client_request_ids[client_id] = request_id + local method_supported = false + for_each_buffer_client(bufnr, function(client, client_id, resolved_bufnr) + if client.supports_method(method) then + method_supported = true + local request_success, request_id = client.request(method, params, callback, resolved_bufnr) + + -- This could only fail if the client shut down in the time since we looked + -- it up and we did the request, which should be rare. + if request_success then + client_request_ids[client_id] = request_id + end end end) + -- if no clients support the given method, call the callback with the proper + -- error message. + if not method_supported then + local unsupported_err = lsp._unsupported_method(method) + local cb = callback or lsp.callbacks['method'] + if cb then + cb(unsupported_err, method, bufnr) + end + return + end + local function _cancel_all_requests() for client_id, request_id in pairs(client_request_ids) do local client = active_clients[client_id] diff --git a/runtime/lua/vim/lsp/protocol.lua b/runtime/lua/vim/lsp/protocol.lua index 4e926381e0..2773f59b45 100644 --- a/runtime/lua/vim/lsp/protocol.lua +++ b/runtime/lua/vim/lsp/protocol.lua @@ -703,6 +703,10 @@ function protocol.make_client_capabilities() }; hierarchicalDocumentSymbolSupport = true; }; + rename = { + dynamicRegistration = false; + prepareSupport = true; + }; }; workspace = { symbol = { @@ -914,6 +918,7 @@ function protocol.resolve_capabilities(server_capabilities) return nil, string.format("Invalid type for textDocumentSync: %q", type(textDocumentSync)) end end + general_properties.completion = server_capabilities.completionProvider ~= nil general_properties.hover = server_capabilities.hoverProvider or false general_properties.goto_definition = server_capabilities.definitionProvider or false general_properties.find_references = server_capabilities.referencesProvider or false @@ -923,6 +928,15 @@ function protocol.resolve_capabilities(server_capabilities) general_properties.document_formatting = server_capabilities.documentFormattingProvider or false general_properties.document_range_formatting = server_capabilities.documentRangeFormattingProvider or false general_properties.call_hierarchy = server_capabilities.callHierarchyProvider or false + general_properties.execute_command = server_capabilities.executeCommandProvider ~= nil + + if server_capabilities.renameProvider == nil then + general_properties.rename = false + elseif type(server_capabilities.renameProvider) == 'boolean' then + general_properties.rename = server_capabilities.renameProvider + else + general_properties.rename = true + end if server_capabilities.codeActionProvider == nil then general_properties.code_action = false diff --git a/runtime/syntax/markdown.vim b/runtime/syntax/markdown.vim index 1955a7443e..17b61c2fa4 100644 --- a/runtime/syntax/markdown.vim +++ b/runtime/syntax/markdown.vim @@ -2,7 +2,7 @@ " Language: Markdown " Maintainer: Tim Pope <vimNOSPAM@tpope.org> " Filenames: *.markdown -" Last Change: 2016 Aug 29 +" Last Change: 2020 Jan 14 if exists("b:current_syntax") finish @@ -18,37 +18,46 @@ unlet! b:current_syntax if !exists('g:markdown_fenced_languages') let g:markdown_fenced_languages = [] endif +let s:done_include = {} for s:type in map(copy(g:markdown_fenced_languages),'matchstr(v:val,"[^=]*$")') + if has_key(s:done_include, matchstr(s:type,'[^.]*')) + continue + endif if s:type =~ '\.' let b:{matchstr(s:type,'[^.]*')}_subtype = matchstr(s:type,'\.\zs.*') endif exe 'syn include @markdownHighlight'.substitute(s:type,'\.','','g').' syntax/'.matchstr(s:type,'[^.]*').'.vim' unlet! b:current_syntax + let s:done_include[matchstr(s:type,'[^.]*')] = 1 endfor unlet! s:type +unlet! s:done_include -syn sync minlines=10 +if !exists('g:markdown_minlines') + let g:markdown_minlines = 50 +endif +execute 'syn sync minlines=' . g:markdown_minlines syn case ignore -syn match markdownValid '[<>]\c[a-z/$!]\@!' -syn match markdownValid '&\%(#\=\w*;\)\@!' +syn match markdownValid '[<>]\c[a-z/$!]\@!' transparent contains=NONE +syn match markdownValid '&\%(#\=\w*;\)\@!' transparent contains=NONE syn match markdownLineStart "^[<@]\@!" nextgroup=@markdownBlock,htmlSpecialChar syn cluster markdownBlock contains=markdownH1,markdownH2,markdownH3,markdownH4,markdownH5,markdownH6,markdownBlockquote,markdownListMarker,markdownOrderedListMarker,markdownCodeBlock,markdownRule -syn cluster markdownInline contains=markdownLineBreak,markdownLinkText,markdownItalic,markdownBold,markdownCode,markdownEscape,@htmlTop,markdownError +syn cluster markdownInline contains=markdownLineBreak,markdownLinkText,markdownItalic,markdownBold,markdownCode,markdownEscape,@htmlTop,markdownError,markdownValid syn match markdownH1 "^.\+\n=\+$" contained contains=@markdownInline,markdownHeadingRule,markdownAutomaticLink syn match markdownH2 "^.\+\n-\+$" contained contains=@markdownInline,markdownHeadingRule,markdownAutomaticLink syn match markdownHeadingRule "^[=-]\+$" contained -syn region markdownH1 matchgroup=markdownHeadingDelimiter start="##\@!" end="#*\s*$" keepend oneline contains=@markdownInline,markdownAutomaticLink contained -syn region markdownH2 matchgroup=markdownHeadingDelimiter start="###\@!" end="#*\s*$" keepend oneline contains=@markdownInline,markdownAutomaticLink contained -syn region markdownH3 matchgroup=markdownHeadingDelimiter start="####\@!" end="#*\s*$" keepend oneline contains=@markdownInline,markdownAutomaticLink contained -syn region markdownH4 matchgroup=markdownHeadingDelimiter start="#####\@!" end="#*\s*$" keepend oneline contains=@markdownInline,markdownAutomaticLink contained -syn region markdownH5 matchgroup=markdownHeadingDelimiter start="######\@!" end="#*\s*$" keepend oneline contains=@markdownInline,markdownAutomaticLink contained -syn region markdownH6 matchgroup=markdownHeadingDelimiter start="#######\@!" end="#*\s*$" keepend oneline contains=@markdownInline,markdownAutomaticLink contained +syn region markdownH1 matchgroup=markdownH1Delimiter start="##\@!" end="#*\s*$" keepend oneline contains=@markdownInline,markdownAutomaticLink contained +syn region markdownH2 matchgroup=markdownH2Delimiter start="###\@!" end="#*\s*$" keepend oneline contains=@markdownInline,markdownAutomaticLink contained +syn region markdownH3 matchgroup=markdownH3Delimiter start="####\@!" end="#*\s*$" keepend oneline contains=@markdownInline,markdownAutomaticLink contained +syn region markdownH4 matchgroup=markdownH4Delimiter start="#####\@!" end="#*\s*$" keepend oneline contains=@markdownInline,markdownAutomaticLink contained +syn region markdownH5 matchgroup=markdownH5Delimiter start="######\@!" end="#*\s*$" keepend oneline contains=@markdownInline,markdownAutomaticLink contained +syn region markdownH6 matchgroup=markdownH6Delimiter start="#######\@!" end="#*\s*$" keepend oneline contains=@markdownInline,markdownAutomaticLink contained syn match markdownBlockquote ">\%(\s\|$\)" contained nextgroup=@markdownBlock @@ -70,31 +79,40 @@ syn region markdownUrlTitle matchgroup=markdownUrlTitleDelimiter start=+"+ end=+ syn region markdownUrlTitle matchgroup=markdownUrlTitleDelimiter start=+'+ end=+'+ keepend contained syn region markdownUrlTitle matchgroup=markdownUrlTitleDelimiter start=+(+ end=+)+ keepend contained -syn region markdownLinkText matchgroup=markdownLinkTextDelimiter start="!\=\[\%(\_[^]]*]\%( \=[[(]\)\)\@=" end="\]\%( \=[[(]\)\@=" nextgroup=markdownLink,markdownId skipwhite contains=@markdownInline,markdownLineStart +syn region markdownLinkText matchgroup=markdownLinkTextDelimiter start="!\=\[\%(\%(\_[^][]\|\[\_[^][]*\]\)*]\%( \=[[(]\)\)\@=" end="\]\%( \=[[(]\)\@=" nextgroup=markdownLink,markdownId skipwhite contains=@markdownInline,markdownLineStart syn region markdownLink matchgroup=markdownLinkDelimiter start="(" end=")" contains=markdownUrl keepend contained syn region markdownId matchgroup=markdownIdDelimiter start="\[" end="\]" keepend contained syn region markdownAutomaticLink matchgroup=markdownUrlDelimiter start="<\%(\w\+:\|[[:alnum:]_+-]\+@\)\@=" end=">" keepend oneline -let s:concealends = has('conceal') ? ' concealends' : '' -exe 'syn region markdownItalic matchgroup=markdownItalicDelimiter start="\S\@<=\*\|\*\S\@=" end="\S\@<=\*\|\*\S\@=" keepend contains=markdownLineStart' . s:concealends -exe 'syn region markdownItalic matchgroup=markdownItalicDelimiter start="\S\@<=_\|_\S\@=" end="\S\@<=_\|_\S\@=" keepend contains=markdownLineStart' . s:concealends -exe 'syn region markdownBold matchgroup=markdownBoldDelimiter start="\S\@<=\*\*\|\*\*\S\@=" end="\S\@<=\*\*\|\*\*\S\@=" keepend contains=markdownLineStart,markdownItalic' . s:concealends -exe 'syn region markdownBold matchgroup=markdownBoldDelimiter start="\S\@<=__\|__\S\@=" end="\S\@<=__\|__\S\@=" keepend contains=markdownLineStart,markdownItalic' . s:concealends -exe 'syn region markdownBoldItalic matchgroup=markdownBoldItalicDelimiter start="\S\@<=\*\*\*\|\*\*\*\S\@=" end="\S\@<=\*\*\*\|\*\*\*\S\@=" keepend contains=markdownLineStart' . s:concealends -exe 'syn region markdownBoldItalic matchgroup=markdownBoldItalicDelimiter start="\S\@<=___\|___\S\@=" end="\S\@<=___\|___\S\@=" keepend contains=markdownLineStart' . s:concealends +let s:concealends = '' +if has('conceal') && get(g:, 'markdown_syntax_conceal', 1) == 1 + let s:concealends = ' concealends' +endif +exe 'syn region markdownItalic matchgroup=markdownItalicDelimiter start="\S\@<=\*\|\*\S\@=" end="\S\@<=\*\|\*\S\@=" skip="\\\*" contains=markdownLineStart,@Spell' . s:concealends +exe 'syn region markdownItalic matchgroup=markdownItalicDelimiter start="\w\@<!_\S\@=" end="\S\@<=_\w\@!" skip="\\_" contains=markdownLineStart,@Spell' . s:concealends +exe 'syn region markdownBold matchgroup=markdownBoldDelimiter start="\S\@<=\*\*\|\*\*\S\@=" end="\S\@<=\*\*\|\*\*\S\@=" skip="\\\*" contains=markdownLineStart,markdownItalic,@Spell' . s:concealends +exe 'syn region markdownBold matchgroup=markdownBoldDelimiter start="\w\@<!__\S\@=" end="\S\@<=__\w\@!" skip="\\_" contains=markdownLineStart,markdownItalic,@Spell' . s:concealends +exe 'syn region markdownBoldItalic matchgroup=markdownBoldItalicDelimiter start="\S\@<=\*\*\*\|\*\*\*\S\@=" end="\S\@<=\*\*\*\|\*\*\*\S\@=" skip="\\\*" contains=markdownLineStart,@Spell' . s:concealends +exe 'syn region markdownBoldItalic matchgroup=markdownBoldItalicDelimiter start="\w\@<!___\S\@=" end="\S\@<=___\w\@!" skip="\\_" contains=markdownLineStart,@Spell' . s:concealends syn region markdownCode matchgroup=markdownCodeDelimiter start="`" end="`" keepend contains=markdownLineStart syn region markdownCode matchgroup=markdownCodeDelimiter start="`` \=" end=" \=``" keepend contains=markdownLineStart -syn region markdownCode matchgroup=markdownCodeDelimiter start="^\s*```.*$" end="^\s*```\ze\s*$" keepend +syn region markdownCode matchgroup=markdownCodeDelimiter start="^\s*````*.*$" end="^\s*````*\ze\s*$" keepend syn match markdownFootnote "\[^[^\]]\+\]" syn match markdownFootnoteDefinition "^\[^[^\]]\+\]:" if main_syntax ==# 'markdown' + let s:done_include = {} for s:type in g:markdown_fenced_languages - exe 'syn region markdownHighlight'.substitute(matchstr(s:type,'[^=]*$'),'\..*','','').' matchgroup=markdownCodeDelimiter start="^\s*```\s*'.matchstr(s:type,'[^=]*').'\>.*$" end="^\s*```\ze\s*$" keepend contains=@markdownHighlight'.substitute(matchstr(s:type,'[^=]*$'),'\.','','g') + if has_key(s:done_include, matchstr(s:type,'[^.]*')) + continue + endif + exe 'syn region markdownHighlight'.substitute(matchstr(s:type,'[^=]*$'),'\..*','','').' matchgroup=markdownCodeDelimiter start="^\s*````*\s*\%({.\{-}\.\)\='.matchstr(s:type,'[^=]*').'}\=\S\@!.*$" end="^\s*````*\ze\s*$" keepend contains=@markdownHighlight'.substitute(matchstr(s:type,'[^=]*$'),'\.','','g') . s:concealends + let s:done_include[matchstr(s:type,'[^.]*')] = 1 endfor unlet! s:type + unlet! s:done_include endif syn match markdownEscape "\\[][\\`*_{}()<>#+.!-]" @@ -107,6 +125,12 @@ hi def link markdownH4 htmlH4 hi def link markdownH5 htmlH5 hi def link markdownH6 htmlH6 hi def link markdownHeadingRule markdownRule +hi def link markdownH1Delimiter markdownHeadingDelimiter +hi def link markdownH2Delimiter markdownHeadingDelimiter +hi def link markdownH3Delimiter markdownHeadingDelimiter +hi def link markdownH4Delimiter markdownHeadingDelimiter +hi def link markdownH5Delimiter markdownHeadingDelimiter +hi def link markdownH6Delimiter markdownHeadingDelimiter hi def link markdownHeadingDelimiter Delimiter hi def link markdownOrderedListMarker markdownListMarker hi def link markdownListMarker htmlTagName |