From 06347a64cac5e33574713a59ace9d1d0ea4b6f82 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Sat, 25 May 2024 05:19:46 +0800 Subject: vim-patch:9.1.0443: Can't use blockwise selection with width for getregion() (#28985) Problem: Can't use a blockwise selection with a width for getregion(). Solution: Add support for blockwise selection with width like the return value of getregtype() or the "regtype" value of TextYankPost (zeertzjq). closes: vim/vim#14842 https://github.com/vim/vim/commit/afc2295c2201ae87bfbb42d5f5315ad0583ccabf --- runtime/doc/builtin.txt | 11 +++++------ runtime/lua/vim/_meta/vimfn.lua | 11 +++++------ 2 files changed, 10 insertions(+), 12 deletions(-) (limited to 'runtime') diff --git a/runtime/doc/builtin.txt b/runtime/doc/builtin.txt index ff7d5f9ce8..5b1dd2ca47 100644 --- a/runtime/doc/builtin.txt +++ b/runtime/doc/builtin.txt @@ -2930,14 +2930,13 @@ getregion({pos1}, {pos2} [, {opts}]) *getregion()* The optional argument {opts} is a Dict and supports the following items: - type Specify the region's selection type - (default: "v"): - "v" for |charwise| mode - "V" for |linewise| mode - "" for |blockwise-visual| mode + type Specify the region's selection type. + See |getregtype()| for possible values, + except it cannot be an empty string. + (default: "v") exclusive If |TRUE|, use exclusive selection - for the end position + for the end position. (default: follow 'selection') You can get the last selection type by |visualmode()|. diff --git a/runtime/lua/vim/_meta/vimfn.lua b/runtime/lua/vim/_meta/vimfn.lua index f4daacfb7d..d1455fa993 100644 --- a/runtime/lua/vim/_meta/vimfn.lua +++ b/runtime/lua/vim/_meta/vimfn.lua @@ -3536,14 +3536,13 @@ function vim.fn.getreginfo(regname) end --- The optional argument {opts} is a Dict and supports the --- following items: --- ---- type Specify the region's selection type ---- (default: "v"): ---- "v" for |charwise| mode ---- "V" for |linewise| mode ---- "" for |blockwise-visual| mode +--- type Specify the region's selection type. +--- See |getregtype()| for possible values, +--- except it cannot be an empty string. +--- (default: "v") --- --- exclusive If |TRUE|, use exclusive selection ---- for the end position +--- for the end position. --- (default: follow 'selection') --- --- You can get the last selection type by |visualmode()|. -- cgit From 5d26934c7cda191f0b519c1326fa318b857ffcb8 Mon Sep 17 00:00:00 2001 From: Gregory Anders <8965202+gpanders@users.noreply.github.com> Date: Fri, 24 May 2024 18:31:25 -0500 Subject: feat(lsp): update LSP healthcheck format (#28980) This is mostly an aesthetic change, although there are a few new pieces of information included. Originally I wanted to investigate including server capabilities in the healthcheck, but until we have the ability to fold/unfold text in health checks that would be too much information. --- runtime/lua/vim/lsp/health.lua | 83 +++++++++++++++++++++++++++++++++++++----- 1 file changed, 73 insertions(+), 10 deletions(-) (limited to 'runtime') diff --git a/runtime/lua/vim/lsp/health.lua b/runtime/lua/vim/lsp/health.lua index a79ae76eb9..b5dc710cc6 100644 --- a/runtime/lua/vim/lsp/health.lua +++ b/runtime/lua/vim/lsp/health.lua @@ -33,16 +33,22 @@ local function check_active_clients() local clients = vim.lsp.get_clients() if next(clients) then for _, client in pairs(clients) do - local attached_to = table.concat(vim.tbl_keys(client.attached_buffers or {}), ',') - report_info( + local cmd ---@type string + if type(client.config.cmd) == 'table' then + cmd = table.concat(client.config.cmd --[[@as table]], ' ') + elseif type(client.config.cmd) == 'function' then + cmd = tostring(client.config.cmd) + end + report_info(table.concat({ + string.format('%s (id: %d)', client.name, client.id), + string.format(' Root directory: %s', vim.fn.fnamemodify(client.root_dir, ':~')), + string.format(' Command: %s', cmd), + string.format(' Settings: %s', vim.inspect(client.settings, { newline = '\n ' })), string.format( - '%s (id=%s, root_dir=%s, attached_to=[%s])', - client.name, - client.id, - vim.fn.fnamemodify(client.root_dir, ':~'), - attached_to - ) - ) + ' Attached buffers: %s', + vim.iter(pairs(client.attached_buffers)):map(tostring):join(', ') + ), + }, '\n')) end else report_info('No active clients') @@ -50,7 +56,7 @@ local function check_active_clients() end local function check_watcher() - vim.health.start('vim.lsp: File watcher') + vim.health.start('vim.lsp: File Watcher') -- Only run the check if file watching has been enabled by a client. local clients = vim.lsp.get_clients() @@ -94,11 +100,68 @@ local function check_watcher() end end +local function check_position_encodings() + vim.health.start('vim.lsp: Position Encodings') + local clients = vim.lsp.get_clients() + if next(clients) then + local position_encodings = {} ---@type table> + for _, client in pairs(clients) do + for bufnr in pairs(client.attached_buffers) do + if not position_encodings[bufnr] then + position_encodings[bufnr] = {} + end + if not position_encodings[bufnr][client.offset_encoding] then + position_encodings[bufnr][client.offset_encoding] = {} + end + table.insert(position_encodings[bufnr][client.offset_encoding], client.id) + end + end + + -- Check if any buffers are attached to multiple clients with different position encodings + local buffers = {} ---@type integer[] + for bufnr, encodings in pairs(position_encodings) do + local list = {} ---@type string[] + for k in pairs(encodings) do + list[#list + 1] = k + end + + if #list > 1 then + buffers[#buffers + 1] = bufnr + end + end + + if #buffers > 0 then + local lines = + { 'Found buffers attached to multiple clients with different position encodings.' } + for _, bufnr in ipairs(buffers) do + local encodings = position_encodings[bufnr] + local parts = {} + for encoding, client_ids in pairs(encodings) do + table.insert( + parts, + string.format('%s (client id(s): %s)', encoding:upper(), table.concat(client_ids, ', ')) + ) + end + table.insert(lines, string.format('- Buffer %d: %s', bufnr, table.concat(parts, ', '))) + end + report_warn( + table.concat(lines, '\n'), + 'Use the positionEncodings client capability to ensure all clients use the same position encoding' + ) + else + report_info('No buffers contain mixed position encodings') + end + else + report_info('No active clients') + end +end + --- Performs a healthcheck for LSP function M.check() check_log() check_active_clients() check_watcher() + check_position_encodings() end return M -- cgit From 8b2b1fba2abfb99186e3a1f0123251a3e2eae3fe Mon Sep 17 00:00:00 2001 From: glepnir Date: Fri, 3 May 2024 15:53:13 +0800 Subject: fix(float): missing default highlight for title Problem: there is missing default title highlight when highlight not defined in title text chunk. Solution: when attr is not set use default title highlight group. --- runtime/doc/api.txt | 6 ++++-- runtime/lua/vim/_meta/api.lua | 6 ++++-- 2 files changed, 8 insertions(+), 4 deletions(-) (limited to 'runtime') diff --git a/runtime/doc/api.txt b/runtime/doc/api.txt index 86f4c3875c..2ca34150f3 100644 --- a/runtime/doc/api.txt +++ b/runtime/doc/api.txt @@ -3270,13 +3270,15 @@ nvim_open_win({buffer}, {enter}, {config}) *nvim_open_win()* < • title: Title (optional) in window border, string or list. List should consist of `[text, highlight]` tuples. If - string, the default highlight group is `FloatTitle`. + string, or a tuple lacks a highlight, the default + highlight group is `FloatTitle`. • title_pos: Title position. Must be set with `title` option. Value can be one of "left", "center", or "right". Default is `"left"`. • footer: Footer (optional) in window border, string or list. List should consist of `[text, highlight]` tuples. - If string, the default highlight group is `FloatFooter`. + If string, or a tuple lacks a highlight, the default + highlight group is `FloatFooter`. • footer_pos: Footer position. Must be set with `footer` option. Value can be one of "left", "center", or "right". Default is `"left"`. diff --git a/runtime/lua/vim/_meta/api.lua b/runtime/lua/vim/_meta/api.lua index 64c67be076..ae43863316 100644 --- a/runtime/lua/vim/_meta/api.lua +++ b/runtime/lua/vim/_meta/api.lua @@ -1731,13 +1731,15 @@ function vim.api.nvim_open_term(buffer, opts) end --- --- • title: Title (optional) in window border, string or list. --- List should consist of `[text, highlight]` tuples. If ---- string, the default highlight group is `FloatTitle`. +--- string, or a tuple lacks a highlight, the default +--- highlight group is `FloatTitle`. --- • title_pos: Title position. Must be set with `title` --- option. Value can be one of "left", "center", or "right". --- Default is `"left"`. --- • footer: Footer (optional) in window border, string or --- list. List should consist of `[text, highlight]` tuples. ---- If string, the default highlight group is `FloatFooter`. +--- If string, or a tuple lacks a highlight, the default +--- highlight group is `FloatFooter`. --- • footer_pos: Footer position. Must be set with `footer` --- option. Value can be one of "left", "center", or "right". --- Default is `"left"`. -- cgit From 4c7fd323ec40de2c0884b2bd290d7470cda0826d Mon Sep 17 00:00:00 2001 From: Christian Clason Date: Fri, 24 May 2024 18:15:12 +0200 Subject: vim-patch:b1ffc52: runtime(i3config/swayconfig): fix floating_modifier highlight (vim/vim#14841) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit https://github.com/vim/vim/commit/b1ffc52694756efef339f01bbb1fc6ef4eaf16da Co-authored-by: Josef Litoš <54900518+JosefLitos@users.noreply.github.com> --- runtime/syntax/i3config.vim | 6 +++--- runtime/syntax/swayconfig.vim | 10 +++++----- 2 files changed, 8 insertions(+), 8 deletions(-) (limited to 'runtime') diff --git a/runtime/syntax/i3config.vim b/runtime/syntax/i3config.vim index f4d789e418..c95cb879ad 100644 --- a/runtime/syntax/i3config.vim +++ b/runtime/syntax/i3config.vim @@ -2,8 +2,8 @@ " Language: i3 config file " Original Author: Josef Litos (JosefLitos/i3config.vim) " Maintainer: Quentin Hibon (github user hiqua) -" Version: 1.2.3 -" Last Change: 2024-05-23 +" Version: 1.2.4 +" Last Change: 2024-05-24 " References: " http://i3wm.org/docs/userguide.html#configuring @@ -67,7 +67,7 @@ syn keyword i3ConfigBindKeyword bindsym bindcode contained skipwhite nextgroup=i syn region i3ConfigModeBlock matchgroup=i3ConfigKeyword start=/mode\ze\( --pango_markup\)\? \([^'" {]\+\|'[^']\+'\|".\+"\)\s\+{$/ end=/^}\zs$/ contained contains=i3ConfigShParam,@i3ConfigStrVar,i3ConfigBindKeyword,i3ConfigComment,i3ConfigParen fold keepend extend " 4.7 Floating modifier -syn match i3ConfigKeyword /^floating_modifier [$0-9A-Za-z]*$/ contains=i3ConfigVariable,i3ConfigBindModkey +syn match i3ConfigKeyword /floating_modifier [$A-Z][0-9A-Za-z]*$/ contained contains=i3ConfigVariable,i3ConfigBindModkey " 4.8 Floating window size syn keyword i3ConfigSizeSpecial x contained diff --git a/runtime/syntax/swayconfig.vim b/runtime/syntax/swayconfig.vim index 401412adfd..d09d476a5a 100644 --- a/runtime/syntax/swayconfig.vim +++ b/runtime/syntax/swayconfig.vim @@ -2,8 +2,8 @@ " Language: sway config file " Original Author: Josef Litos (JosefLitos/i3config.vim) " Maintainer: James Eapen -" Version: 1.2.3 -" Last Change: 2024-05-23 +" Version: 1.2.4 +" Last Change: 2024-05-24 " References: " http://i3wm.org/docs/userguide.html#configuring @@ -34,12 +34,12 @@ syn region i3ConfigBindArgument start=/--input-device=['"]/ end=/\s/ contained c syn region i3ConfigBindCombo matchgroup=i3ConfigParen start=/{$/ end=/^\s*}$/ contained contains=i3ConfigBindArgument,i3ConfigBindCombo,i3ConfigComment fold keepend extend " hack for blocks with start outside parsing range -syn region swayConfigBlockOrphan start=/^\s\+\(--[a-z-]\+ \)*\([A-Z$][$a-zA-Z0-9_+]\+\|[a-z]\) [a-z[]/ skip=/\\$\|$\n^\s*}$/ end=/$/ contains=i3ConfigBindArgument,i3ConfigBindCombo,i3ConfigParen keepend extend +syn region swayConfigBlockOrphan start=/^\s\+\(--[a-z-]\+ \)*\([$A-Z][$0-9A-Za-z_+]\+\|[a-z]\) [a-z[]/ skip=/\\$\|$\n^\s*}$/ end=/$/ contains=i3ConfigBindArgument,i3ConfigBindCombo,i3ConfigParen keepend extend syn region i3ConfigExec start=/ {$/ end=/^\s*}$/ contained contains=i3ConfigExecAction,@i3ConfigSh,i3ConfigComment fold keepend extend syn keyword swayConfigFloatingModifierOpts normal inverse none contained -syn match i3ConfigKeyword /floating_modifier \(none\|[$a-zA-Z0-9+]\+ \(normal\|inverse\)\)$/ contained contains=i3ConfigVariable,i3ConfigBindModkey,swayConfigFloatingModifierOpts +syn match i3ConfigKeyword /floating_modifier \(none\|[$A-Z][0-9A-Za-z]\+ \(normal\|inverse\)\)$/ contained contains=i3ConfigVariable,i3ConfigBindModkey,swayConfigFloatingModifierOpts syn match swayConfigI3Param /--i3/ contains=i3ConfigShParam skipwhite nextgroup=i3ConfigEdgeOpts syn keyword i3ConfigKeyword hide_edge_borders contained skipwhite nextgroup=swayConfigI3Param,i3ConfigEdgeOpts @@ -71,7 +71,7 @@ syn keyword i3ConfigBindKeyword bindswitch contained skipwhite nextgroup=swayCon syn region swayConfigBlockOrphan start=/^\s\+\(lid\|tablet\):/ skip=/\\$\|$\n^\s*}$/ end=/$/ contains=swayConfigBindswitchArgument,swayConfigBindswitchType,i3ConfigParen keepend extend " Bindgesture -syn match swayConfigBindgestureArgument /--\(exact\|input-device=[:0-9a-zA-Z_/-]\+\|no-warn\) / contained nextgroup=swayConfigBindgestureArgument,swayConfigBindgestureCombo +syn match swayConfigBindgestureArgument /--\(exact\|input-device=[:0-9A-Za-z_/-]\+\|no-warn\) / contained nextgroup=swayConfigBindgestureArgument,swayConfigBindgestureCombo syn keyword swayConfigBindgestureType hold swipe pinch contained syn keyword swayConfigBindgestureDir up down left right inward outward clockwise counterclockwise contained syn match swayConfigBindgestureCombo /\(hold\(:[1-5]\)\?\|swipe\(:[3-5]\)\?\(:up\|:down\|:left\|:right\)\?\|pinch\(:[2-5]\)\?:\(+\?\(inward\|outward\|clockwise\|counterclockwise\|up\|down\|left\|right\)\)\+\) / contained contains=i3ConfigNumber,swayConfigBindgestureType,i3ConfigColonOperator,swayConfigBindgestureDir,i3ConfigBindModifier nextgroup=swayConfigBindgestureCombo,i3ConfigBind -- cgit From b43244adafa0f4d86409d1101754d5e23782c158 Mon Sep 17 00:00:00 2001 From: Christian Clason Date: Fri, 24 May 2024 19:09:31 +0200 Subject: vim-patch:5e45715: runtime(typescript): update outdated syntax files fixes: vim/vim#14721 fixes: HerringtonDarkholme/yats.vim#277 closes: vim/vim#14840 https://github.com/vim/vim/commit/5e4571508480c8f51748e49fb05c1891db0cb803 Co-authored-by: rhysd --- runtime/doc/syntax.txt | 13 ++ runtime/syntax/shared/typescriptcommon.vim | 192 ++++++++++++++++------------- runtime/syntax/typescript.vim | 2 +- runtime/syntax/typescriptreact.vim | 6 +- 4 files changed, 121 insertions(+), 92 deletions(-) (limited to 'runtime') diff --git a/runtime/doc/syntax.txt b/runtime/doc/syntax.txt index 7893822a66..06d7ad8f7e 100644 --- a/runtime/doc/syntax.txt +++ b/runtime/doc/syntax.txt @@ -3289,6 +3289,19 @@ set "tf_minlines" to the value you desire. Example: > :let tf_minlines = your choice < +TYPESCRIPT *typescript.vim* *ft-typescript-syntax* + *typescriptreact.vim* *ft-typescriptreact-syntax* + +There is one option to control the TypeScript syntax highlighting. + + *g:typescript_host_keyword* +When this variable is set to 1, host-specific APIs such as `addEventListener` +are highlighted. To disable set it to zero in your .vimrc: > + + let g:typescript_host_keyword = 0 +< +The default value is 1. + VIM *vim.vim* *ft-vim-syntax* *g:vimsyn_minlines* *g:vimsyn_maxlines* There is a trade-off between more accurate syntax highlighting versus screen diff --git a/runtime/syntax/shared/typescriptcommon.vim b/runtime/syntax/shared/typescriptcommon.vim index d06525115e..3af79a38fb 100644 --- a/runtime/syntax/shared/typescriptcommon.vim +++ b/runtime/syntax/shared/typescriptcommon.vim @@ -1,7 +1,7 @@ " Vim syntax file " Language: TypeScript and TypeScriptReact " Maintainer: Herrington Darkholme -" Last Change: 2023 Aug 24 +" Last Change: 2024 May 24 " Based On: Herrington Darkholme's yats.vim " Changes: See https://github.com/HerringtonDarkholme/yats.vim " Credits: See yats.vim on github @@ -49,13 +49,13 @@ syntax match typescriptProp contained /\K\k*!\?/ \ nextgroup=@afterIdentifier \ skipwhite skipempty -syntax region typescriptIndexExpr contained matchgroup=typescriptProperty start=/\[/rs=s+1 end=/]/he=e-1 contains=@typescriptValue nextgroup=@typescriptSymbols,typescriptDotNotation,typescriptFuncCallArg skipwhite skipempty +syntax region typescriptIndexExpr contained matchgroup=typescriptProperty start=/\[/ end=/]/ contains=@typescriptValue,typescriptCastKeyword nextgroup=@typescriptSymbols,typescriptDotNotation,typescriptFuncCallArg skipwhite skipempty syntax match typescriptDotNotation /\.\|?\.\|!\./ nextgroup=typescriptProp skipnl syntax match typescriptDotStyleNotation /\.style\./ nextgroup=typescriptDOMStyle transparent " syntax match typescriptFuncCall contained /[a-zA-Z]\k*\ze(/ nextgroup=typescriptFuncCallArg syntax region typescriptParenExp matchgroup=typescriptParens start=/(/ end=/)/ contains=@typescriptComments,@typescriptValue,typescriptCastKeyword nextgroup=@typescriptSymbols skipwhite skipempty -syntax region typescriptFuncCallArg contained matchgroup=typescriptParens start=/(/ end=/)/ contains=@typescriptValue,@typescriptComments nextgroup=@typescriptSymbols,typescriptDotNotation skipwhite skipempty skipnl +syntax region typescriptFuncCallArg contained matchgroup=typescriptParens start=/(/ end=/)/ contains=@typescriptValue,@typescriptComments,typescriptCastKeyword nextgroup=@typescriptSymbols,typescriptDotNotation skipwhite skipempty skipnl syntax region typescriptEventFuncCallArg contained matchgroup=typescriptParens start=/(/ end=/)/ contains=@typescriptEventExpression syntax region typescriptEventString contained start=/\z(["']\)/ skip=/\\\\\|\\\z1\|\\\n/ end=/\z1\|$/ contains=typescriptASCII,@events @@ -116,20 +116,33 @@ syntax match typescriptASCII contained /\\\d\d\d/ syntax region typescriptTemplateSubstitution matchgroup=typescriptTemplateSB \ start=/\${/ end=/}/ - \ contains=@typescriptValue + \ contains=@typescriptValue,typescriptCastKeyword \ contained -syntax region typescriptString +syntax region typescriptString \ start=+\z(["']\)+ skip=+\\\%(\z1\|$\)+ end=+\z1+ end=+$+ \ contains=typescriptSpecial,@Spell + \ nextgroup=@typescriptSymbols + \ skipwhite skipempty \ extend syntax match typescriptSpecial contained "\v\\%(x\x\x|u%(\x{4}|\{\x{1,6}})|c\u|.)" -" From vim runtime -" -syntax region typescriptRegexpString start=+/[^/*]+me=e-1 skip=+\\\\\|\\/+ end=+/[gimuy]\{0,5\}\s*$+ end=+/[gimuy]\{0,5\}\s*[;.,)\]}:]+me=e-1 nextgroup=typescriptDotNotation oneline +" From pangloss/vim-javascript +" +syntax region typescriptRegexpCharClass contained start=+\[+ skip=+\\.+ end=+\]+ contains=typescriptSpecial extend +syntax match typescriptRegexpBoundary contained "\v\c[$^]|\\b" +syntax match typescriptRegexpBackRef contained "\v\\[1-9]\d*" +syntax match typescriptRegexpQuantifier contained "\v[^\\]%([?*+]|\{\d+%(,\d*)?})\??"lc=1 +syntax match typescriptRegexpOr contained "|" +syntax match typescriptRegexpMod contained "\v\(\?[:=!>]"lc=1 +syntax region typescriptRegexpGroup contained start="[^\\]("lc=1 skip="\\.\|\[\(\\.\|[^]]\+\)\]" end=")" contains=typescriptRegexpCharClass,@typescriptRegexpSpecial keepend +syntax region typescriptRegexpString + \ start=+\%(\%(\" syntax match shellbang "^#!.*iojs\>" @@ -536,7 +561,7 @@ syntax region typescriptGenericFunc matchgroup=typescriptTypeBrackets \ contained skipwhite skipnl syntax region typescriptFuncType matchgroup=typescriptParens - \ start=/(/ end=/)\s*=>/me=e-2 + \ start=/(\(\k\+:\|)\)\@=/ end=/)\s*=>/me=e-2 \ contains=@typescriptParameterList \ nextgroup=typescriptFuncTypeArrow \ contained skipwhite skipnl oneline @@ -546,7 +571,6 @@ syntax match typescriptFuncTypeArrow /=>/ \ containedin=typescriptFuncType \ contained skipwhite skipnl - syntax keyword typescriptConstructorType new \ nextgroup=@typescriptFunctionType \ contained skipwhite skipnl @@ -623,25 +647,24 @@ syntax keyword typescriptReadonlyArrayKeyword readonly " extension -if get(g:, 'yats_host_keyword', 1) - syntax keyword typescriptGlobal containedin=typescriptIdentifierName Function Boolean - " use of nextgroup Suggested by Doug Kearns +if get(g:, 'typescript_host_keyword', 1) + syntax keyword typescriptGlobal containedin=typescriptIdentifierName Function Boolean nextgroup=typescriptFuncCallArg syntax keyword typescriptGlobal containedin=typescriptIdentifierName Error EvalError nextgroup=typescriptFuncCallArg - syntax keyword typescriptGlobal containedin=typescriptIdentifierName InternalError - syntax keyword typescriptGlobal containedin=typescriptIdentifierName RangeError ReferenceError - syntax keyword typescriptGlobal containedin=typescriptIdentifierName StopIteration - syntax keyword typescriptGlobal containedin=typescriptIdentifierName SyntaxError TypeError - syntax keyword typescriptGlobal containedin=typescriptIdentifierName URIError Date - syntax keyword typescriptGlobal containedin=typescriptIdentifierName Float32Array - syntax keyword typescriptGlobal containedin=typescriptIdentifierName Float64Array - syntax keyword typescriptGlobal containedin=typescriptIdentifierName Int16Array Int32Array - syntax keyword typescriptGlobal containedin=typescriptIdentifierName Int8Array Uint16Array - syntax keyword typescriptGlobal containedin=typescriptIdentifierName Uint32Array Uint8Array - syntax keyword typescriptGlobal containedin=typescriptIdentifierName Uint8ClampedArray - syntax keyword typescriptGlobal containedin=typescriptIdentifierName ParallelArray - syntax keyword typescriptGlobal containedin=typescriptIdentifierName ArrayBuffer DataView - syntax keyword typescriptGlobal containedin=typescriptIdentifierName Iterator Generator - syntax keyword typescriptGlobal containedin=typescriptIdentifierName Reflect Proxy + syntax keyword typescriptGlobal containedin=typescriptIdentifierName InternalError nextgroup=typescriptFuncCallArg + syntax keyword typescriptGlobal containedin=typescriptIdentifierName RangeError ReferenceError nextgroup=typescriptFuncCallArg + syntax keyword typescriptGlobal containedin=typescriptIdentifierName StopIteration nextgroup=typescriptFuncCallArg + syntax keyword typescriptGlobal containedin=typescriptIdentifierName SyntaxError TypeError nextgroup=typescriptFuncCallArg + syntax keyword typescriptGlobal containedin=typescriptIdentifierName URIError Date nextgroup=typescriptFuncCallArg + syntax keyword typescriptGlobal containedin=typescriptIdentifierName Float32Array nextgroup=typescriptFuncCallArg + syntax keyword typescriptGlobal containedin=typescriptIdentifierName Float64Array nextgroup=typescriptFuncCallArg + syntax keyword typescriptGlobal containedin=typescriptIdentifierName Int16Array Int32Array nextgroup=typescriptFuncCallArg + syntax keyword typescriptGlobal containedin=typescriptIdentifierName Int8Array Uint16Array nextgroup=typescriptFuncCallArg + syntax keyword typescriptGlobal containedin=typescriptIdentifierName Uint32Array Uint8Array nextgroup=typescriptFuncCallArg + syntax keyword typescriptGlobal containedin=typescriptIdentifierName Uint8ClampedArray nextgroup=typescriptFuncCallArg + syntax keyword typescriptGlobal containedin=typescriptIdentifierName ParallelArray nextgroup=typescriptFuncCallArg + syntax keyword typescriptGlobal containedin=typescriptIdentifierName ArrayBuffer DataView nextgroup=typescriptFuncCallArg + syntax keyword typescriptGlobal containedin=typescriptIdentifierName Iterator Generator nextgroup=typescriptFuncCallArg + syntax keyword typescriptGlobal containedin=typescriptIdentifierName Reflect Proxy nextgroup=typescriptFuncCallArg syntax keyword typescriptGlobal containedin=typescriptIdentifierName arguments hi def link typescriptGlobal Structure syntax keyword typescriptGlobalMethod containedin=typescriptIdentifierName eval uneval nextgroup=typescriptFuncCallArg @@ -675,12 +698,12 @@ if get(g:, 'yats_host_keyword', 1) hi def link typescriptStringStaticMethod Keyword syntax keyword typescriptStringMethod contained anchor charAt charCodeAt codePointAt nextgroup=typescriptFuncCallArg syntax keyword typescriptStringMethod contained concat endsWith includes indexOf lastIndexOf nextgroup=typescriptFuncCallArg - syntax keyword typescriptStringMethod contained link localeCompare match normalize nextgroup=typescriptFuncCallArg - syntax keyword typescriptStringMethod contained padStart padEnd repeat replace search nextgroup=typescriptFuncCallArg + syntax keyword typescriptStringMethod contained link localeCompare match matchAll normalize nextgroup=typescriptFuncCallArg + syntax keyword typescriptStringMethod contained padStart padEnd repeat replace replaceAll search nextgroup=typescriptFuncCallArg syntax keyword typescriptStringMethod contained slice split startsWith substr substring nextgroup=typescriptFuncCallArg syntax keyword typescriptStringMethod contained toLocaleLowerCase toLocaleUpperCase nextgroup=typescriptFuncCallArg syntax keyword typescriptStringMethod contained toLowerCase toString toUpperCase trim nextgroup=typescriptFuncCallArg - syntax keyword typescriptStringMethod contained valueOf nextgroup=typescriptFuncCallArg + syntax keyword typescriptStringMethod contained trimEnd trimStart valueOf nextgroup=typescriptFuncCallArg syntax cluster props add=typescriptStringMethod hi def link typescriptStringMethod Keyword @@ -689,18 +712,18 @@ if get(g:, 'yats_host_keyword', 1) syntax keyword typescriptArrayStaticMethod contained from isArray of nextgroup=typescriptFuncCallArg hi def link typescriptArrayStaticMethod Keyword syntax keyword typescriptArrayMethod contained concat copyWithin entries every fill nextgroup=typescriptFuncCallArg - syntax keyword typescriptArrayMethod contained filter find findIndex forEach indexOf nextgroup=typescriptFuncCallArg - syntax keyword typescriptArrayMethod contained includes join keys lastIndexOf map nextgroup=typescriptFuncCallArg + syntax keyword typescriptArrayMethod contained filter find findIndex flat flatMap forEach nextgroup=typescriptFuncCallArg + syntax keyword typescriptArrayMethod contained includes indexOf join keys lastIndexOf map nextgroup=typescriptFuncCallArg syntax keyword typescriptArrayMethod contained pop push reduce reduceRight reverse nextgroup=typescriptFuncCallArg syntax keyword typescriptArrayMethod contained shift slice some sort splice toLocaleString nextgroup=typescriptFuncCallArg - syntax keyword typescriptArrayMethod contained toSource toString unshift nextgroup=typescriptFuncCallArg + syntax keyword typescriptArrayMethod contained toSource toString unshift values nextgroup=typescriptFuncCallArg syntax cluster props add=typescriptArrayMethod hi def link typescriptArrayMethod Keyword syntax keyword typescriptGlobal containedin=typescriptIdentifierName Object nextgroup=typescriptGlobalObjectDot,typescriptFuncCallArg syntax match typescriptGlobalObjectDot /\./ contained nextgroup=typescriptObjectStaticMethod,typescriptProp syntax keyword typescriptObjectStaticMethod contained create defineProperties defineProperty nextgroup=typescriptFuncCallArg - syntax keyword typescriptObjectStaticMethod contained entries freeze getOwnPropertyDescriptors nextgroup=typescriptFuncCallArg + syntax keyword typescriptObjectStaticMethod contained entries freeze fromEntries getOwnPropertyDescriptors nextgroup=typescriptFuncCallArg syntax keyword typescriptObjectStaticMethod contained getOwnPropertyDescriptor getOwnPropertyNames nextgroup=typescriptFuncCallArg syntax keyword typescriptObjectStaticMethod contained getOwnPropertySymbols getPrototypeOf nextgroup=typescriptFuncCallArg syntax keyword typescriptObjectStaticMethod contained is isExtensible isFrozen isSealed nextgroup=typescriptFuncCallArg @@ -715,7 +738,7 @@ if get(g:, 'yats_host_keyword', 1) syntax keyword typescriptGlobal containedin=typescriptIdentifierName Symbol nextgroup=typescriptGlobalSymbolDot,typescriptFuncCallArg syntax match typescriptGlobalSymbolDot /\./ contained nextgroup=typescriptSymbolStaticProp,typescriptSymbolStaticMethod,typescriptProp - syntax keyword typescriptSymbolStaticProp contained length iterator match replace + syntax keyword typescriptSymbolStaticProp contained description length iterator match matchAll replace syntax keyword typescriptSymbolStaticProp contained search split hasInstance isConcatSpreadable syntax keyword typescriptSymbolStaticProp contained unscopables species toPrimitive syntax keyword typescriptSymbolStaticProp contained toStringTag @@ -771,7 +794,7 @@ if get(g:, 'yats_host_keyword', 1) syntax match typescriptGlobalRegExpDot /\./ contained nextgroup=typescriptRegExpStaticProp,typescriptProp syntax keyword typescriptRegExpStaticProp contained lastIndex hi def link typescriptRegExpStaticProp Keyword - syntax keyword typescriptRegExpProp contained global ignoreCase multiline source sticky + syntax keyword typescriptRegExpProp contained dotAll global ignoreCase multiline source sticky syntax cluster props add=typescriptRegExpProp hi def link typescriptRegExpProp Keyword syntax keyword typescriptRegExpMethod contained exec test nextgroup=typescriptFuncCallArg @@ -805,7 +828,7 @@ if get(g:, 'yats_host_keyword', 1) syntax keyword typescriptGlobal containedin=typescriptIdentifierName Promise nextgroup=typescriptGlobalPromiseDot,typescriptFuncCallArg syntax match typescriptGlobalPromiseDot /\./ contained nextgroup=typescriptPromiseStaticMethod,typescriptProp - syntax keyword typescriptPromiseStaticMethod contained resolve reject all race nextgroup=typescriptFuncCallArg + syntax keyword typescriptPromiseStaticMethod contained all allSettled any race reject resolve nextgroup=typescriptFuncCallArg hi def link typescriptPromiseStaticMethod Keyword syntax keyword typescriptPromiseMethod contained then catch finally nextgroup=typescriptFuncCallArg syntax cluster props add=typescriptPromiseMethod @@ -1232,7 +1255,8 @@ if get(g:, 'yats_host_keyword', 1) syntax cluster props add=typescriptBOMHistoryMethod hi def link typescriptBOMHistoryMethod Keyword - syntax keyword typescriptGlobal containedin=typescriptIdentifierName console + syntax keyword typescriptGlobal containedin=typescriptIdentifierName console nextgroup=typescriptGlobalConsoleDot + syntax match typescriptGlobalConsoleDot /\./ contained nextgroup=typescriptConsoleMethod,typescriptProp syntax keyword typescriptConsoleMethod contained count dir error group groupCollapsed nextgroup=typescriptFuncCallArg syntax keyword typescriptConsoleMethod contained groupEnd info log time timeEnd trace nextgroup=typescriptFuncCallArg syntax keyword typescriptConsoleMethod contained warn nextgroup=typescriptFuncCallArg @@ -1735,8 +1759,6 @@ if get(g:, 'yats_host_keyword', 1) syntax keyword typescriptServiceWorkerEvent contained install activate fetch syntax cluster events add=typescriptServiceWorkerEvent hi def link typescriptServiceWorkerEvent Title - - endif " patch @@ -1764,6 +1786,7 @@ syntax cluster typescriptPropertyMemberDeclaration contains= \ typescriptClassStatic, \ typescriptAccessibilityModifier, \ typescriptReadonlyModifier, + \ typescriptAutoAccessor, \ typescriptMethodAccessor, \ @typescriptMembers " \ typescriptMemberVariableDeclaration @@ -1780,7 +1803,9 @@ syntax keyword typescriptClassStatic static syntax keyword typescriptAccessibilityModifier public private protected contained -syntax keyword typescriptReadonlyModifier readonly contained +syntax keyword typescriptReadonlyModifier readonly override contained + +syntax keyword typescriptAutoAccessor accessor contained syntax region typescriptStringMember contained \ start=/\z(["']\)/ skip=/\\\\\|\\\z1\|\\\n/ end=/\z1/ @@ -1789,7 +1814,7 @@ syntax region typescriptStringMember contained syntax region typescriptComputedMember contained matchgroup=typescriptProperty \ start=/\[/rs=s+1 end=/]/ - \ contains=@typescriptValue,typescriptMember,typescriptMappedIn + \ contains=@typescriptValue,typescriptMember,typescriptMappedIn,typescriptCastKeyword \ nextgroup=@memberNextGroup \ skipwhite skipempty @@ -1861,7 +1886,7 @@ syntax match typescriptInterfaceComma /,/ contained nextgroup=typescriptInterfac "Block VariableStatement EmptyStatement ExpressionStatement IfStatement IterationStatement ContinueStatement BreakStatement ReturnStatement WithStatement LabelledStatement SwitchStatement ThrowStatement TryStatement DebuggerStatement syntax cluster typescriptStatement - \ contains=typescriptBlock,typescriptVariable, + \ contains=typescriptBlock,typescriptVariable,typescriptUsing, \ @typescriptTopExpression,typescriptAssign, \ typescriptConditional,typescriptRepeat,typescriptBranch, \ typescriptLabel,typescriptStatementKeyword, @@ -1899,16 +1924,14 @@ syntax cluster typescriptValue syntax cluster typescriptEventExpression contains=typescriptArrowFuncDef,typescriptParenExp,@typescriptValue,typescriptRegexpString,@typescriptEventTypes,typescriptOperator,typescriptGlobal,jsxRegion syntax keyword typescriptAsyncFuncKeyword async - \ nextgroup=typescriptFuncKeyword,typescriptArrowFuncDef + \ nextgroup=typescriptFuncKeyword,typescriptArrowFuncDef,typescriptArrowFuncTypeParameter \ skipwhite syntax keyword typescriptAsyncFuncKeyword await - \ nextgroup=@typescriptValue + \ nextgroup=@typescriptValue,typescriptUsing \ skipwhite -syntax keyword typescriptFuncKeyword function - \ nextgroup=typescriptAsyncFunc,typescriptFuncName,@typescriptCallSignature - \ skipwhite skipempty +syntax keyword typescriptFuncKeyword function nextgroup=typescriptAsyncFunc,typescriptFuncName,@typescriptCallSignature skipwhite skipempty syntax match typescriptAsyncFunc contained /*/ \ nextgroup=typescriptFuncName,@typescriptCallSignature @@ -1918,39 +1941,33 @@ syntax match typescriptFuncName contained /\K\k*/ \ nextgroup=@typescriptCallSignature \ skipwhite -" destructuring ({ a: ee }) => -syntax match typescriptArrowFuncDef contained /(\(\s*\({\_[^}]*}\|\k\+\)\(:\_[^)]\)\?,\?\)\+)\s*=>/ - \ contains=typescriptArrowFuncArg,typescriptArrowFunc - \ nextgroup=@typescriptExpression,typescriptBlock - \ skipwhite skipempty - -" matches `(a) =>` or `([a]) =>` or -" `( -" a) =>` -syntax match typescriptArrowFuncDef contained /(\(\_s*[a-zA-Z\$_\[.]\_[^)]*\)*)\s*=>/ +syntax match typescriptArrowFuncDef contained /\K\k*\s*=>/ \ contains=typescriptArrowFuncArg,typescriptArrowFunc \ nextgroup=@typescriptExpression,typescriptBlock \ skipwhite skipempty -syntax match typescriptArrowFuncDef contained /\K\k*\s*=>/ - \ contains=typescriptArrowFuncArg,typescriptArrowFunc +syntax match typescriptArrowFuncDef contained /(\%(\_[^()]\+\|(\_[^()]*)\)*)\_s*=>/ + \ contains=typescriptArrowFuncArg,typescriptArrowFunc,@typescriptCallSignature \ nextgroup=@typescriptExpression,typescriptBlock \ skipwhite skipempty -" TODO: optimize this pattern -syntax region typescriptArrowFuncDef contained start=/(\_[^(^)]*):/ end=/=>/ - \ contains=typescriptArrowFuncArg,typescriptArrowFunc,typescriptTypeAnnotation +syntax region typescriptArrowFuncDef contained start=/(\%(\_[^()]\+\|(\_[^()]*)\)*):/ matchgroup=typescriptArrowFunc end=/=>/ + \ contains=typescriptArrowFuncArg,typescriptTypeAnnotation,@typescriptCallSignature \ nextgroup=@typescriptExpression,typescriptBlock \ skipwhite skipempty keepend +syntax region typescriptArrowFuncTypeParameter start=// + \ contains=@typescriptTypeParameterCluster + \ nextgroup=typescriptArrowFuncDef + \ contained skipwhite skipnl + syntax match typescriptArrowFunc /=>/ syntax match typescriptArrowFuncArg contained /\K\k*/ -syntax region typescriptArrowFuncArg contained start=/<\|(/ end=/\ze=>/ contains=@typescriptCallSignature syntax region typescriptReturnAnnotation contained start=/:/ end=/{/me=e-1 contains=@typescriptType nextgroup=typescriptBlock -syntax region typescriptFuncImpl contained start=/function\>/ end=/{/me=e-1 +syntax region typescriptFuncImpl contained start=/function\>/ end=/{\|;\|\n/me=e-1 \ contains=typescriptFuncKeyword \ nextgroup=typescriptBlock @@ -1970,7 +1987,7 @@ syntax match typescriptDecorator /@\([_$a-zA-Z][_$a-zA-Z0-9]*\.\)*[_$a-zA-Z][_$a \ nextgroup=typescriptFuncCallArg,typescriptTypeArguments \ contains=@_semantic,typescriptDotNotation -" Define the default highlighting. + hi def link typescriptReserved Error hi def link typescriptEndColons Exception @@ -2013,6 +2030,7 @@ hi def link typescriptDefault typescriptCase hi def link typescriptBranch Conditional hi def link typescriptIdentifier Structure hi def link typescriptVariable Identifier +hi def link typescriptUsing Identifier hi def link typescriptDestructureVariable PreProc hi def link typescriptEnumKeyword Identifier hi def link typescriptRepeat Repeat @@ -2050,16 +2068,13 @@ hi def link typescriptFuncKeyword Keyword hi def link typescriptAsyncFunc Keyword hi def link typescriptArrowFunc Type hi def link typescriptFuncName Function -hi def link typescriptFuncArg PreProc +hi def link typescriptFuncCallArg PreProc hi def link typescriptArrowFuncArg PreProc hi def link typescriptFuncComma Operator hi def link typescriptClassKeyword Keyword hi def link typescriptClassExtends Keyword -" hi def link typescriptClassName Function hi def link typescriptAbstract Special -" hi def link typescriptClassHeritage Function -" hi def link typescriptInterfaceHeritage Function hi def link typescriptClassStatic StorageClass hi def link typescriptReadonlyModifier Keyword hi def link typescriptInterfaceKeyword Keyword @@ -2077,6 +2092,7 @@ hi def link typescriptFuncTypeArrow Function hi def link typescriptConstructorType Function hi def link typescriptTypeQuery Keyword hi def link typescriptAccessibilityModifier Keyword +hi def link typescriptAutoAccessor Keyword hi def link typescriptOptionalMark PreProc hi def link typescriptFuncType Special hi def link typescriptMappedIn Special diff --git a/runtime/syntax/typescript.vim b/runtime/syntax/typescript.vim index 5389c21497..03520fd56a 100644 --- a/runtime/syntax/typescript.vim +++ b/runtime/syntax/typescript.vim @@ -1,7 +1,7 @@ " Vim syntax file " Language: TypeScript " Maintainer: Herrington Darkholme -" Last Change: 2023 Aug 13 +" Last Change: 2024 May 24 " Based On: Herrington Darkholme's yats.vim " Changes: Go to https://github.com/HerringtonDarkholme/yats.vim for recent changes. " Origin: https://github.com/othree/yajs diff --git a/runtime/syntax/typescriptreact.vim b/runtime/syntax/typescriptreact.vim index 1c510459f5..9dc9a2b797 100644 --- a/runtime/syntax/typescriptreact.vim +++ b/runtime/syntax/typescriptreact.vim @@ -1,7 +1,7 @@ " Vim syntax file " Language: TypeScript with React (JSX) " Maintainer: The Vim Project -" Last Change: 2023 Aug 13 +" Last Change: 2024 May 24 " Based On: Herrington Darkholme's yats.vim " Changes: See https://github.com/HerringtonDarkholme/yats.vim " Credits: See yats.vim on github @@ -118,13 +118,13 @@ syntax match tsxEqual +=+ display contained " " s~~~~~~e -syntax region tsxString contained start=+"+ end=+"+ contains=tsxEntity,@Spell display +syntax region tsxString contained start=+["']+ end=+["']+ contains=tsxEntity,@Spell display " " s~~~~~~~~~~~~~~e syntax region tsxEscJs \ contained - \ contains=@typescriptValue,@tsxComment + \ contains=@typescriptValue,@tsxComment,typescriptObjectSpread \ matchgroup=typescriptBraces \ start=+{+ \ end=+}+ -- cgit From 4757d497f3c85cc343f7dcbc09f95e43ba5c1314 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Sat, 25 May 2024 16:53:10 +0800 Subject: vim-patch:9.1.0444: Not enough tests for getregion() with multibyte chars (#29000) Problem: Not enough tests for getregion() with multibyte chars. Solution: Add a few more tests (zeertzjq). closes: vim/vim#14844 https://github.com/vim/vim/commit/dff55a335889c746a79974f7c52cdcdebad682c2 --- runtime/doc/builtin.txt | 3 ++- runtime/lua/vim/_meta/vimfn.lua | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) (limited to 'runtime') diff --git a/runtime/doc/builtin.txt b/runtime/doc/builtin.txt index 5b1dd2ca47..1a762c6ec0 100644 --- a/runtime/doc/builtin.txt +++ b/runtime/doc/builtin.txt @@ -2932,7 +2932,8 @@ getregion({pos1}, {pos2} [, {opts}]) *getregion()* type Specify the region's selection type. See |getregtype()| for possible values, - except it cannot be an empty string. + except that the width can be omitted + and an empty string cannot be used. (default: "v") exclusive If |TRUE|, use exclusive selection diff --git a/runtime/lua/vim/_meta/vimfn.lua b/runtime/lua/vim/_meta/vimfn.lua index d1455fa993..f256f63768 100644 --- a/runtime/lua/vim/_meta/vimfn.lua +++ b/runtime/lua/vim/_meta/vimfn.lua @@ -3538,7 +3538,8 @@ function vim.fn.getreginfo(regname) end --- --- type Specify the region's selection type. --- See |getregtype()| for possible values, ---- except it cannot be an empty string. +--- except that the width can be omitted +--- and an empty string cannot be used. --- (default: "v") --- --- exclusive If |TRUE|, use exclusive selection -- cgit From bdb81afab3e5c43a33267666c2689feb284f6b52 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Sat, 25 May 2024 20:37:33 +0800 Subject: refactor(lua): rewrite vim.highlight.range() (#28986) - Use getregionpos(). - Use a single extmark for non-blockwise selection. --- runtime/doc/lua.txt | 4 ++-- runtime/lua/vim/highlight.lua | 55 +++++++++++++++++++++++++++++++++---------- 2 files changed, 44 insertions(+), 15 deletions(-) (limited to 'runtime') diff --git a/runtime/doc/lua.txt b/runtime/doc/lua.txt index 3d8453c5a2..64a3014388 100644 --- a/runtime/doc/lua.txt +++ b/runtime/doc/lua.txt @@ -646,8 +646,8 @@ vim.highlight.range({bufnr}, {ns}, {higroup}, {start}, {finish}, {opts}) • {finish} (`integer[]|string`) End of region as a (line, column) tuple or string accepted by |getpos()| • {opts} (`table?`) A table with the following fields: - • {regtype}? (`string`, default: `'charwise'`) Type of - range. See |setreg()| + • {regtype}? (`string`, default: `'v'` i.e. charwise) Type + of range. See |getregtype()| • {inclusive}? (`boolean`, default: `false`) Indicates whether the range is end-inclusive • {priority}? (`integer`, default: diff --git a/runtime/lua/vim/highlight.lua b/runtime/lua/vim/highlight.lua index f278bd357f..89298ce568 100644 --- a/runtime/lua/vim/highlight.lua +++ b/runtime/lua/vim/highlight.lua @@ -20,8 +20,8 @@ M.priorities = { --- @class vim.highlight.range.Opts --- @inlinedoc --- ---- Type of range. See [setreg()] ---- (default: `'charwise'`) +--- Type of range. See [getregtype()] +--- (default: `'v'` i.e. charwise) --- @field regtype? string --- --- Indicates whether the range is end-inclusive @@ -49,20 +49,49 @@ function M.range(bufnr, ns, higroup, start, finish, opts) local priority = opts.priority or M.priorities.user local scoped = opts._scoped or false - -- TODO: in case of 'v', 'V' (not block), this should calculate equivalent - -- bounds (row, col, end_row, end_col) as multiline regions are natively - -- supported now - local region = vim.region(bufnr, start, finish, regtype, inclusive) - for linenr, cols in pairs(region) do - local end_row - if cols[2] == -1 then - end_row = linenr + 1 - cols[2] = 0 + local pos1 = type(start) == 'string' and vim.fn.getpos(start) + or { bufnr, start[1] + 1, start[2] + 1, 0 } + local pos2 = type(finish) == 'string' and vim.fn.getpos(finish) + or { bufnr, finish[1] + 1, finish[2] + 1, 0 } + + local buf_line_count = vim.api.nvim_buf_line_count(bufnr) + pos1[2] = math.min(pos1[2], buf_line_count) + pos2[2] = math.min(pos2[2], buf_line_count) + + if pos1[2] <= 0 or pos1[3] <= 0 or pos2[2] <= 0 or pos2[3] <= 0 then + return + end + + vim.api.nvim_buf_call(bufnr, function() + local max_col1 = vim.fn.col({ pos1[2], '$' }) + pos1[3] = math.min(pos1[3], max_col1) + local max_col2 = vim.fn.col({ pos2[2], '$' }) + pos2[3] = math.min(pos2[3], max_col2) + end) + + local region = vim.fn.getregionpos(pos1, pos2, { + type = regtype, + exclusive = not inclusive, + eol = true, + }) + -- For non-blockwise selection, use a single extmark. + if regtype == 'v' or regtype == 'V' then + region = { { region[1][1], region[#region][2] } } + end + + for _, res in ipairs(region) do + local start_row = res[1][2] - 1 + local start_col = res[1][3] - 1 + local end_row = res[2][2] - 1 + local end_col = res[2][3] + if regtype == 'V' then + end_row = end_row + 1 + end_col = 0 end - api.nvim_buf_set_extmark(bufnr, ns, linenr, cols[1], { + api.nvim_buf_set_extmark(bufnr, ns, start_row, start_col, { hl_group = higroup, end_row = end_row, - end_col = cols[2], + end_col = end_col, priority = priority, strict = false, scoped = scoped, -- cgit From fdeb01cd77404aba446c67af32134a2ff793a14b Mon Sep 17 00:00:00 2001 From: Rafael Kitover Date: Sat, 25 May 2024 12:44:39 +0000 Subject: feat(main): expand file ~\ or ~/ prefix on Windows (#28515) In command_line_scan() for MSWIN, expand "~\" or "~/" prefixed paths to the USERPROFILE environment variable for the user's profile directory. Fix #23901 Signed-off-by: Rafael Kitover --- runtime/doc/news.txt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'runtime') diff --git a/runtime/doc/news.txt b/runtime/doc/news.txt index 708e127136..2d4017e3c4 100644 --- a/runtime/doc/news.txt +++ b/runtime/doc/news.txt @@ -87,7 +87,9 @@ DEFAULTS EDITOR -• TODO +* On Windows, filename arguments on the command-line prefixed with "~\" or + "~/" are now expanded to the user's profile directory, not a relative path + to a literal "~" directory. EVENTS -- cgit From 520c2657bb6832dc527bff94f313a1cc458238a4 Mon Sep 17 00:00:00 2001 From: dundargoc Date: Sat, 25 May 2024 17:56:05 +0200 Subject: refactor: move provider-related to where they are used --- runtime/lua/vim/health.lua | 108 -------------------------- runtime/lua/vim/provider/health.lua | 150 ++++++++++++++++++++++++++++++------ 2 files changed, 127 insertions(+), 131 deletions(-) (limited to 'runtime') diff --git a/runtime/lua/vim/health.lua b/runtime/lua/vim/health.lua index f40f04a064..afeba2ee9d 100644 --- a/runtime/lua/vim/health.lua +++ b/runtime/lua/vim/health.lua @@ -275,114 +275,6 @@ function M.error(msg, ...) collect_output(input) end -function M._provider_disabled(provider) - local loaded_var = 'loaded_' .. provider .. '_provider' - local v = vim.g[loaded_var] - if v == 0 then - M.info('Disabled (' .. loaded_var .. '=' .. v .. ').') - return true - end - return false -end - --- Handler for s:system() function. -local function system_handler(self, _, data, event) - if event == 'stderr' then - if self.add_stderr_to_output then - self.output = self.output .. table.concat(data, '') - else - self.stderr = self.stderr .. table.concat(data, '') - end - elseif event == 'stdout' then - self.output = self.output .. table.concat(data, '') - end -end - --- Attempts to construct a shell command from an args list. --- Only for display, to help users debug a failed command. -local function shellify(cmd) - if type(cmd) ~= 'table' then - return cmd - end - local escaped = {} - for i, v in ipairs(cmd) do - if v:match('[^A-Za-z_/.-]') then - escaped[i] = vim.fn.shellescape(v) - else - escaped[i] = v - end - end - return table.concat(escaped, ' ') -end - -function M._cmd_ok(cmd) - local out = vim.fn.system(cmd) - return vim.v.shell_error == 0, out -end - ---- Run a system command and timeout after 30 seconds. ---- ---- @param cmd table List of command arguments to execute ---- @param args? table Optional arguments: ---- - stdin (string): Data to write to the job's stdin ---- - stderr (boolean): Append stderr to stdout ---- - ignore_error (boolean): If true, ignore error output ---- - timeout (number): Number of seconds to wait before timing out (default 30) -function M._system(cmd, args) - args = args or {} - local stdin = args.stdin or '' - local stderr = vim.F.if_nil(args.stderr, false) - local ignore_error = vim.F.if_nil(args.ignore_error, false) - - local shell_error_code = 0 - local opts = { - add_stderr_to_output = stderr, - output = '', - stderr = '', - on_stdout = system_handler, - on_stderr = system_handler, - on_exit = function(_, data) - shell_error_code = data - end, - } - local jobid = vim.fn.jobstart(cmd, opts) - - if jobid < 1 then - local message = - string.format('Command error (job=%d): %s (in %s)', jobid, shellify(cmd), vim.uv.cwd()) - error(message) - return opts.output, 1 - end - - if stdin:find('^%s$') then - vim.fn.chansend(jobid, stdin) - end - - local res = vim.fn.jobwait({ jobid }, vim.F.if_nil(args.timeout, 30) * 1000) - if res[1] == -1 then - error('Command timed out: ' .. shellify(cmd)) - vim.fn.jobstop(jobid) - elseif shell_error_code ~= 0 and not ignore_error then - local emsg = string.format( - 'Command error (job=%d, exit code %d): %s (in %s)', - jobid, - shell_error_code, - shellify(cmd), - vim.uv.cwd() - ) - if opts.output:find('%S') then - emsg = string.format('%s\noutput: %s', emsg, opts.output) - end - if opts.stderr:find('%S') then - emsg = string.format('%s\nstderr: %s', emsg, opts.stderr) - end - error(emsg) - end - - -- return opts.output - return vim.trim(vim.fn.system(cmd)), shell_error_code -end - local path2name = function(path) if path:match('%.lua$') then -- Lua: transform "../lua/vim/lsp/health.lua" into "vim.lsp" diff --git a/runtime/lua/vim/provider/health.lua b/runtime/lua/vim/provider/health.lua index 63e0da448a..d6932f651e 100644 --- a/runtime/lua/vim/provider/health.lua +++ b/runtime/lua/vim/provider/health.lua @@ -3,6 +3,112 @@ local iswin = vim.uv.os_uname().sysname == 'Windows_NT' local M = {} +local function cmd_ok(cmd) + local out = vim.fn.system(cmd) + return vim.v.shell_error == 0, out +end + +-- Attempts to construct a shell command from an args list. +-- Only for display, to help users debug a failed command. +local function shellify(cmd) + if type(cmd) ~= 'table' then + return cmd + end + local escaped = {} + for i, v in ipairs(cmd) do + if v:match('[^A-Za-z_/.-]') then + escaped[i] = vim.fn.shellescape(v) + else + escaped[i] = v + end + end + return table.concat(escaped, ' ') +end + +-- Handler for s:system() function. +local function system_handler(self, _, data, event) + if event == 'stderr' then + if self.add_stderr_to_output then + self.output = self.output .. table.concat(data, '') + else + self.stderr = self.stderr .. table.concat(data, '') + end + elseif event == 'stdout' then + self.output = self.output .. table.concat(data, '') + end +end + +--- @param cmd table List of command arguments to execute +--- @param args? table Optional arguments: +--- - stdin (string): Data to write to the job's stdin +--- - stderr (boolean): Append stderr to stdout +--- - ignore_error (boolean): If true, ignore error output +--- - timeout (number): Number of seconds to wait before timing out (default 30) +local function system(cmd, args) + args = args or {} + local stdin = args.stdin or '' + local stderr = vim.F.if_nil(args.stderr, false) + local ignore_error = vim.F.if_nil(args.ignore_error, false) + + local shell_error_code = 0 + local opts = { + add_stderr_to_output = stderr, + output = '', + stderr = '', + on_stdout = system_handler, + on_stderr = system_handler, + on_exit = function(_, data) + shell_error_code = data + end, + } + local jobid = vim.fn.jobstart(cmd, opts) + + if jobid < 1 then + local message = + string.format('Command error (job=%d): %s (in %s)', jobid, shellify(cmd), vim.uv.cwd()) + error(message) + return opts.output, 1 + end + + if stdin:find('^%s$') then + vim.fn.chansend(jobid, stdin) + end + + local res = vim.fn.jobwait({ jobid }, vim.F.if_nil(args.timeout, 30) * 1000) + if res[1] == -1 then + error('Command timed out: ' .. shellify(cmd)) + vim.fn.jobstop(jobid) + elseif shell_error_code ~= 0 and not ignore_error then + local emsg = string.format( + 'Command error (job=%d, exit code %d): %s (in %s)', + jobid, + shell_error_code, + shellify(cmd), + vim.uv.cwd() + ) + if opts.output:find('%S') then + emsg = string.format('%s\noutput: %s', emsg, opts.output) + end + if opts.stderr:find('%S') then + emsg = string.format('%s\nstderr: %s', emsg, opts.stderr) + end + error(emsg) + end + + -- return opts.output + return vim.trim(vim.fn.system(cmd)), shell_error_code +end + +local function provider_disabled(provider) + local loaded_var = 'loaded_' .. provider .. '_provider' + local v = vim.g[loaded_var] + if v == 0 then + health.info('Disabled (' .. loaded_var .. '=' .. v .. ').') + return true + end + return false +end + local function clipboard() health.start('Clipboard (optional)') @@ -10,7 +116,7 @@ local function clipboard() os.getenv('TMUX') and vim.fn.executable('tmux') == 1 and vim.fn.executable('pbpaste') == 1 - and not health._cmd_ok('pbpaste') + and not cmd_ok('pbpaste') then local tmux_version = string.match(vim.fn.system('tmux -V'), '%d+%.%d+') local advice = { @@ -40,7 +146,7 @@ end local function node() health.start('Node.js provider (optional)') - if health._provider_disabled('node') then + if provider_disabled('node') then return end @@ -60,7 +166,7 @@ local function node() end -- local node_v = vim.fn.split(system({'node', '-v'}), "\n")[1] or '' - local ok, node_v = health._cmd_ok({ 'node', '-v' }) + local ok, node_v = cmd_ok({ 'node', '-v' }) health.info('Node.js: ' .. node_v) if not ok or vim.version.lt(node_v, '6.0.0') then health.warn('Nvim node.js host does not support Node ' .. node_v) @@ -97,7 +203,7 @@ local function node() iswin and 'cmd /c ' .. manager .. ' info neovim --json' or manager .. ' info neovim --json' ) local latest_npm - ok, latest_npm = health._cmd_ok(vim.split(latest_npm_cmd, ' ')) + ok, latest_npm = cmd_ok(vim.split(latest_npm_cmd, ' ')) if not ok or latest_npm:find('^%s$') then health.error( 'Failed to run: ' .. latest_npm_cmd, @@ -115,7 +221,7 @@ local function node() local current_npm_cmd = { 'node', host, '--version' } local current_npm - ok, current_npm = health._cmd_ok(current_npm_cmd) + ok, current_npm = cmd_ok(current_npm_cmd) if not ok then health.error( 'Failed to run: ' .. table.concat(current_npm_cmd, ' '), @@ -143,7 +249,7 @@ end local function perl() health.start('Perl provider (optional)') - if health._provider_disabled('perl') then + if provider_disabled('perl') then return end @@ -162,7 +268,7 @@ local function perl() -- we cannot use cpanm that is on the path, as it may not be for the perl -- set with g:perl_host_prog - local ok = health._cmd_ok({ perl_exec, '-W', '-MApp::cpanminus', '-e', '' }) + local ok = cmd_ok({ perl_exec, '-W', '-MApp::cpanminus', '-e', '' }) if not ok then return { perl_exec, '"App::cpanminus" module is not installed' } end @@ -174,7 +280,7 @@ local function perl() 'my $app = App::cpanminus::script->new; $app->parse_options ("--info", "-q", "Neovim::Ext"); exit $app->doit', } local latest_cpan - ok, latest_cpan = health._cmd_ok(latest_cpan_cmd) + ok, latest_cpan = cmd_ok(latest_cpan_cmd) if not ok or latest_cpan:find('^%s*$') then health.error( 'Failed to run: ' .. table.concat(latest_cpan_cmd, ' '), @@ -205,7 +311,7 @@ local function perl() local current_cpan_cmd = { perl_exec, '-W', '-MNeovim::Ext', '-e', 'print $Neovim::Ext::VERSION' } local current_cpan - ok, current_cpan = health._cmd_ok(current_cpan_cmd) + ok, current_cpan = cmd_ok(current_cpan_cmd) if not ok then health.error( 'Failed to run: ' .. table.concat(current_cpan_cmd, ' '), @@ -292,7 +398,7 @@ end local function download(url) local has_curl = vim.fn.executable('curl') == 1 if has_curl and vim.fn.system({ 'curl', '-V' }):find('Protocols:.*https') then - local out, rc = health._system({ 'curl', '-sL', url }, { stderr = true, ignore_error = true }) + local out, rc = system({ 'curl', '-sL', url }, { stderr = true, ignore_error = true }) if rc ~= 0 then return 'curl error with ' .. url .. ': ' .. rc else @@ -305,7 +411,7 @@ local function download(url) from urllib2 import urlopen\n\ response = urlopen('" .. url .. "')\n\ print(response.read().decode('utf8'))\n" - local out, rc = health._system({ 'python', '-c', script }) + local out, rc = system({ 'python', '-c', script }) if out == '' and rc ~= 0 then return 'python urllib.request error: ' .. rc else @@ -362,7 +468,7 @@ end local function version_info(python) local pypi_version = latest_pypi_version() - local python_version, rc = health._system({ + local python_version, rc = system({ python, '-c', 'import sys; print(".".join(str(x) for x in sys.version_info[:3]))', @@ -373,7 +479,7 @@ local function version_info(python) end local nvim_path - nvim_path, rc = health._system({ + nvim_path, rc = system({ python, '-c', 'import sys; sys.path = [p for p in sys.path if p != ""]; import neovim; print(neovim.__file__)', @@ -398,7 +504,7 @@ local function version_info(python) -- Try to get neovim.VERSION (added in 0.1.11dev). local nvim_version - nvim_version, rc = health._system({ + nvim_version, rc = system({ python, '-c', 'from neovim import VERSION as v; print("{}.{}.{}{}".format(v.major, v.minor, v.patch, v.prerelease))', @@ -445,7 +551,7 @@ local function python() local host_prog_var = pyname .. '_host_prog' local python_multiple = {} - if health._provider_disabled(pyname) then + if provider_disabled(pyname) then return end @@ -487,7 +593,7 @@ local function python() end if pyenv ~= '' then - python_exe = health._system({ pyenv, 'which', pyname }, { stderr = true }) + python_exe = system({ pyenv, 'which', pyname }, { stderr = true }) if python_exe == '' then health.warn('pyenv could not find ' .. pyname .. '.') end @@ -710,9 +816,7 @@ local function python() health.info(msg) health.info( 'Python version: ' - .. health._system( - 'python -c "import platform, sys; sys.stdout.write(platform.python_version())"' - ) + .. system('python -c "import platform, sys; sys.stdout.write(platform.python_version())"') ) health.ok('$VIRTUAL_ENV provides :!python.') end @@ -721,7 +825,7 @@ end local function ruby() health.start('Ruby provider (optional)') - if health._provider_disabled('ruby') then + if provider_disabled('ruby') then return end @@ -732,7 +836,7 @@ local function ruby() ) return end - health.info('Ruby: ' .. health._system({ 'ruby', '-v' })) + health.info('Ruby: ' .. system({ 'ruby', '-v' })) local host, _ = vim.provider.ruby.detect() if (not host) or host:find('^%s*$') then @@ -748,7 +852,7 @@ local function ruby() health.info('Host: ' .. host) local latest_gem_cmd = (iswin and 'cmd /c gem list -ra "^^neovim$"' or 'gem list -ra ^neovim$') - local ok, latest_gem = health._cmd_ok(vim.split(latest_gem_cmd, ' ')) + local ok, latest_gem = cmd_ok(vim.split(latest_gem_cmd, ' ')) if not ok or latest_gem:find('^%s*$') then health.error( 'Failed to run: ' .. latest_gem_cmd, @@ -761,7 +865,7 @@ local function ruby() local current_gem_cmd = { host, '--version' } local current_gem - ok, current_gem = health._cmd_ok(current_gem_cmd) + ok, current_gem = cmd_ok(current_gem_cmd) if not ok then health.error( 'Failed to run: ' .. table.concat(current_gem_cmd, ' '), -- cgit From f03b1622ad1b8e2df16504631f05e7577e217854 Mon Sep 17 00:00:00 2001 From: Mathias Fußenegger Date: Sat, 25 May 2024 21:22:41 +0200 Subject: fix(lsp): handle nil root_dir in health check (#29007) The root directory could show up as something like: Root directory: ~/path/to/cwd/v:null Despite being `nil` --- runtime/doc/lsp.txt | 2 +- runtime/lua/vim/lsp/client.lua | 3 +-- runtime/lua/vim/lsp/health.lua | 5 ++++- 3 files changed, 6 insertions(+), 4 deletions(-) (limited to 'runtime') diff --git a/runtime/doc/lsp.txt b/runtime/doc/lsp.txt index 50fffca497..a66b577b11 100644 --- a/runtime/doc/lsp.txt +++ b/runtime/doc/lsp.txt @@ -996,7 +996,7 @@ Lua module: vim.lsp.client *lsp-client* if the client supports workspace folders. It can be `null` if the client supports workspace folders but none are configured. - • {root_dir} (`string`) + • {root_dir} (`string?`) • {attached_buffers} (`table`) • {commands} (`table`) Table of command name to function which is diff --git a/runtime/lua/vim/lsp/client.lua b/runtime/lua/vim/lsp/client.lua index 4beb7fefda..58ea7d02b3 100644 --- a/runtime/lua/vim/lsp/client.lua +++ b/runtime/lua/vim/lsp/client.lua @@ -182,7 +182,7 @@ local validate = vim.validate --- It can be `null` if the client supports workspace folders but none are --- configured. --- @field workspace_folders lsp.WorkspaceFolder[]? ---- @field root_dir string +--- @field root_dir string? --- --- @field attached_buffers table --- @@ -470,7 +470,6 @@ function Client.create(config) _on_exit_cbs = ensure_list(config.on_exit), _on_attach_cbs = ensure_list(config.on_attach), _on_error_cb = config.on_error, - _root_dir = config.root_dir, _trace = get_trace(config.trace), --- Contains $/progress report messages. diff --git a/runtime/lua/vim/lsp/health.lua b/runtime/lua/vim/lsp/health.lua index b5dc710cc6..ffe595ab37 100644 --- a/runtime/lua/vim/lsp/health.lua +++ b/runtime/lua/vim/lsp/health.lua @@ -41,7 +41,10 @@ local function check_active_clients() end report_info(table.concat({ string.format('%s (id: %d)', client.name, client.id), - string.format(' Root directory: %s', vim.fn.fnamemodify(client.root_dir, ':~')), + string.format( + ' Root directory: %s', + client.root_dir and vim.fn.fnamemodify(client.root_dir, ':~') or nil + ), string.format(' Command: %s', cmd), string.format(' Settings: %s', vim.inspect(client.settings, { newline = '\n ' })), string.format( -- cgit From 7994fdba6a1e10aad0698dfabcbaf544b4d35eb4 Mon Sep 17 00:00:00 2001 From: Mathias Fußenegger Date: Sat, 25 May 2024 21:23:04 +0200 Subject: fix(snippet): don't override unnamed register on tabstop select (#28998) --- runtime/lua/vim/snippet.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'runtime') diff --git a/runtime/lua/vim/snippet.lua b/runtime/lua/vim/snippet.lua index 3d8f73f362..3fd2555046 100644 --- a/runtime/lua/vim/snippet.lua +++ b/runtime/lua/vim/snippet.lua @@ -315,7 +315,7 @@ local function select_tabstop(tabstop) move_cursor_to(range[1] + 1, range[2] + 1) feedkeys('v') move_cursor_to(range[3] + 1, range[4]) - feedkeys('o') + feedkeys('o_') end end -- cgit From eaaf3d9048f37b2bf5914d34f7348a1ba6ebe250 Mon Sep 17 00:00:00 2001 From: Christian Clason Date: Sat, 25 May 2024 23:21:30 +0200 Subject: vim-patch:0076ddc: runtime(debian): update Debian runtime files (vim/vim#14849) * Add space in template for 'commentstring' * Add 'comments' and 'commentstring' support to debcontrol * debversions: Move Ubuntu releases outside of standard support to unsupported Although trust, xenial, and bionic are not EOL yet, their standard support period has ended. Reported-by: Riley Bruins https://github.com/vim/vim/commit/0076ddc07dc1d97afcf3252fd361885abbaf23d5 Co-authored-by: James McCoy Co-authored-by: Riley Bruins --- runtime/ftplugin/deb822sources.vim | 4 ++-- runtime/ftplugin/debcontrol.vim | 7 +++++-- runtime/ftplugin/debsources.vim | 4 ++-- runtime/syntax/shared/debversions.vim | 9 +++++---- 4 files changed, 14 insertions(+), 10 deletions(-) (limited to 'runtime') diff --git a/runtime/ftplugin/deb822sources.vim b/runtime/ftplugin/deb822sources.vim index 4936f42bf9..31c81b1a5d 100644 --- a/runtime/ftplugin/deb822sources.vim +++ b/runtime/ftplugin/deb822sources.vim @@ -1,6 +1,6 @@ " Language: Debian sources.list " Maintainer: Debian Vim Maintainers -" Last Change: 2024 Mar 20 +" Last Change: 2024 May 25 " License: Vim License " URL: https://salsa.debian.org/vim-team/vim-debian/blob/main/ftplugin/deb822sources.vim @@ -10,7 +10,7 @@ endif let b:did_ftplugin=1 setlocal comments=:# -setlocal commentstring=#%s +setlocal commentstring=#\ %s setlocal formatoptions-=t let b:undo_ftplugin = 'setlocal comments< commentstring< formatoptions<' diff --git a/runtime/ftplugin/debcontrol.vim b/runtime/ftplugin/debcontrol.vim index bb710e597c..5b8292ba6e 100644 --- a/runtime/ftplugin/debcontrol.vim +++ b/runtime/ftplugin/debcontrol.vim @@ -2,7 +2,7 @@ " Language: Debian control files " Maintainer: Debian Vim Maintainers " Former Maintainer: Pierre Habouzit -" Last Change: 2023 Jan 16 +" Last Change: 2024 May 25 " URL: https://salsa.debian.org/vim-team/vim-debian/blob/main/ftplugin/debcontrol.vim " Do these settings once per buffer @@ -19,8 +19,11 @@ if exists('g:debcontrol_fold_enable') endif setlocal textwidth=0 +setlocal comments=:# +setlocal commentstring=#\ %s + " Clean unloading -let b:undo_ftplugin = 'setlocal tw< foldmethod< foldexpr< foldtext<' +let b:undo_ftplugin = 'setlocal tw< foldmethod< foldexpr< foldtext< comments< commentstring<' " }}}1 diff --git a/runtime/ftplugin/debsources.vim b/runtime/ftplugin/debsources.vim index cbb4fafd22..2c5ea3599f 100644 --- a/runtime/ftplugin/debsources.vim +++ b/runtime/ftplugin/debsources.vim @@ -1,6 +1,6 @@ " Language: Debian sources.list " Maintainer: Debian Vim Maintainers -" Last Change: 2023 Aug 30 +" Last Change: 2024 May 25 " License: Vim License " URL: https://salsa.debian.org/vim-team/vim-debian/blob/main/ftplugin/debsources.vim @@ -10,7 +10,7 @@ endif let b:did_ftplugin=1 setlocal comments=:# -setlocal commentstring=#%s +setlocal commentstring=#\ %s setlocal formatoptions-=t let b:undo_ftplugin = 'setlocal comments< commentstring< formatoptions<' diff --git a/runtime/syntax/shared/debversions.vim b/runtime/syntax/shared/debversions.vim index e18eca96b1..56f18b969a 100644 --- a/runtime/syntax/shared/debversions.vim +++ b/runtime/syntax/shared/debversions.vim @@ -1,7 +1,7 @@ " Vim syntax file " Language: Debian version information " Maintainer: Debian Vim Maintainers -" Last Change: 2024 Apr 27 +" Last Change: 2024 May 25 " URL: https://salsa.debian.org/vim-team/vim-debian/blob/main/syntax/shared/debversions.vim let s:cpo = &cpo @@ -11,7 +11,7 @@ let g:debSharedSupportedVersions = [ \ 'oldstable', 'stable', 'testing', 'unstable', 'experimental', 'sid', 'rc-buggy', \ 'bullseye', 'bookworm', 'trixie', 'forky', \ - \ 'trusty', 'xenial', 'bionic', 'focal', 'jammy', 'mantic', 'noble', 'oracular', + \ 'focal', 'jammy', 'mantic', 'noble', 'oracular', \ 'devel' \ ] let g:debSharedUnsupportedVersions = [ @@ -22,8 +22,9 @@ let g:debSharedUnsupportedVersions = [ \ 'warty', 'hoary', 'breezy', 'dapper', 'edgy', 'feisty', \ 'gutsy', 'hardy', 'intrepid', 'jaunty', 'karmic', 'lucid', \ 'maverick', 'natty', 'oneiric', 'precise', 'quantal', 'raring', 'saucy', - \ 'utopic', 'vivid', 'wily', 'yakkety', 'zesty', 'artful', 'cosmic', - \ 'disco', 'eoan', 'hirsute', 'impish', 'kinetic', 'lunar', 'groovy' + \ 'trusty', 'utopic', 'vivid', 'wily', 'xenial', 'yakkety', 'zesty', + \ 'artful', 'bionic', 'cosmic', 'disco', 'eoan', 'hirsute', + \ 'impish', 'kinetic', 'lunar', 'groovy' \ ] let &cpo=s:cpo -- cgit From 3d39ea3ea9b6e66640e59731d155d731218e7e62 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Sun, 26 May 2024 07:11:50 +0800 Subject: vim-patch:9.1.0442: hare runtime files outdated (#29011) Problem: hare runtime files outdated Solution: runtime(hare): update hare.vim to match upstream (Amelia Clarke) closes: vim/vim#14836 https://github.com/vim/vim/commit/35dfe58a540e2fb0eff953630f8e4fcbf4bc26ca Co-authored-by: Amelia Clarke --- runtime/autoload/hare.vim | 26 +++++ runtime/compiler/hare.vim | 23 ++--- runtime/doc/filetype.txt | 6 ++ runtime/doc/ft_hare.txt | 77 +++++++++++++++ runtime/ftplugin/hare.vim | 56 ++++++++--- runtime/ftplugin/haredoc.vim | 44 +++++++++ runtime/indent/hare.vim | 31 +++--- runtime/lua/vim/filetype.lua | 2 +- runtime/lua/vim/filetype/detect.lua | 24 +++++ runtime/syntax/hare.vim | 188 ++++++++++++++++++++---------------- runtime/syntax/haredoc.vim | 32 ++++++ 11 files changed, 386 insertions(+), 123 deletions(-) create mode 100644 runtime/autoload/hare.vim create mode 100644 runtime/doc/ft_hare.txt create mode 100644 runtime/ftplugin/haredoc.vim create mode 100644 runtime/syntax/haredoc.vim (limited to 'runtime') diff --git a/runtime/autoload/hare.vim b/runtime/autoload/hare.vim new file mode 100644 index 0000000000..c4581fccf9 --- /dev/null +++ b/runtime/autoload/hare.vim @@ -0,0 +1,26 @@ +" Vim autoload file. +" Language: Hare +" Maintainer: Amelia Clarke +" Last Updated: 2024-05-10 +" Upstream: https://git.sr.ht/~sircmpwn/hare.vim + +" Attempt to find the directory for a given Hare module. +function hare#FindModule(str) + let path = substitute(trim(a:str, ':', 2), '::', '/', 'g') + let dir = finddir(path) + while !empty(path) && empty(dir) + let path = substitute(path, '/\?\h\w*$', '', '') + let dir = finddir(path) + endwhile + return dir +endfunction + +" Return the value of HAREPATH if it exists. Otherwise use a reasonable default. +function hare#GetPath() + if empty($HAREPATH) + return '/usr/src/hare/stdlib,/usr/src/hare/third-party' + endif + return substitute($HAREPATH, ':', ',', 'g') +endfunction + +" vim: et sts=2 sw=2 ts=8 diff --git a/runtime/compiler/hare.vim b/runtime/compiler/hare.vim index c98bbb9c63..33edb3a281 100644 --- a/runtime/compiler/hare.vim +++ b/runtime/compiler/hare.vim @@ -1,28 +1,29 @@ -" Vim compiler file -" Compiler: Hare Compiler -" Maintainer: Amelia Clarke -" Last Change: 2022-09-21 -" 2024 Apr 05 by The Vim Project (removed :CompilerSet definition) +" Vim compiler file. +" Compiler: Hare +" Maintainer: Amelia Clarke +" Last Change: 2024-05-23 +" Upstream: https://git.sr.ht/~sircmpwn/hare.vim -if exists("g:current_compiler") +if exists('current_compiler') finish endif -let g:current_compiler = "hare" +let current_compiler = 'hare' let s:cpo_save = &cpo set cpo&vim -if filereadable("Makefile") || filereadable("makefile") +if filereadable('Makefile') || filereadable('makefile') CompilerSet makeprg=make else CompilerSet makeprg=hare\ build endif CompilerSet errorformat= - \Error\ %f:%l:%c:\ %m, - \Syntax\ error:\ %.%#\ at\ %f:%l:%c\\,\ %m, + \%f:%l:%c:\ syntax\ error:\ %m, + \%f:%l:%c:\ error:\ %m, \%-G%.%# let &cpo = s:cpo_save unlet s:cpo_save -" vim: tabstop=2 shiftwidth=2 expandtab + +" vim: et sts=2 sw=2 ts=8 diff --git a/runtime/doc/filetype.txt b/runtime/doc/filetype.txt index 5eae78744c..eddf14014a 100644 --- a/runtime/doc/filetype.txt +++ b/runtime/doc/filetype.txt @@ -602,6 +602,12 @@ The mapping can be disabled with: > let g:no_gprof_maps = 1 +HARE *ft-hare* + +Since the text for this plugin is rather long it has been put in a separate +file: |ft_hare.txt|. + + JAVA *ft-java-plugin* Whenever the variable "g:ftplugin_java_source_path" is defined and its value diff --git a/runtime/doc/ft_hare.txt b/runtime/doc/ft_hare.txt new file mode 100644 index 0000000000..937c5e0961 --- /dev/null +++ b/runtime/doc/ft_hare.txt @@ -0,0 +1,77 @@ +*ft_hare.txt* Support for the Hare programming language + +============================================================================== +CONTENTS *hare* + +1. Introduction |hare-intro| +2. Filetype plugin |hare-plugin| +3. Settings |hare-settings| + +============================================================================== +INTRODUCTION *hare-intro* + +This plugin provides syntax highlighting, indentation, and other functionality +for the Hare programming language. Support is also provided for README files +inside Hare modules, but this must be enabled by setting |g:filetype_haredoc|. + +============================================================================== +FILETYPE PLUGIN *hare-plugin* + +This plugin automatically sets the value of 'path' to include the contents of +the HAREPATH environment variable, allowing commands such as |gf| to directly +open standard library or third-party modules. If HAREPATH is not set, it +defaults to the recommended paths for most Unix-like filesystems, namely +/usr/src/hare/stdlib and /usr/src/hare/third-party. + +============================================================================== +SETTINGS *hare-settings* + +This plugin provides a small number of variables that you can define in your +vimrc to configure its behavior. + + *g:filetype_haredoc* +This plugin is able to automatically detect Hare modules and set the "haredoc" +filetype for any README files. As the recursive directory search used as a +heuristic has a minor performance impact, this feature is disabled by default +and must be specifically opted into: > + let g:filetype_haredoc = 1 +< +See |g:haredoc_search_depth| for ways to tweak the searching behavior. + + *g:hare_recommended_style* +The following options are set by default, in accordance with the official Hare +style guide: > + setlocal noexpandtab + setlocal shiftwidth=0 + setlocal softtabstop=0 + setlocal tabstop=8 + setlocal textwidth=80 +< +To disable this behavior: > + let g:hare_recommended_style = 0 +< + *g:hare_space_error* +By default, trailing whitespace and tabs preceded by space characters are +highlighted as errors. This is automatically turned off when in insert mode. +To disable this highlighting completely: > + let g:hare_space_error = 0 +< + *g:haredoc_search_depth* +By default, when |g:filetype_haredoc| is enabled, only the current directory +and its immediate subdirectories are searched for Hare files. The maximum +search depth may be adjusted with: > + let g:haredoc_search_depth = 2 +< + Value Effect~ + 0 Only search the current directory. + 1 Search the current directory and immediate + subdirectories. + 2 Search the current directory and two levels of + subdirectories. + +The maximum search depth can be set to any integer, but using values higher +than 2 is not recommended, and will likely provide no tangible benefit in most +situations. + +============================================================================== + vim:tw=78:ts=8:noet:ft=help:norl: diff --git a/runtime/ftplugin/hare.vim b/runtime/ftplugin/hare.vim index 0200ba5913..422bb7b4e8 100644 --- a/runtime/ftplugin/hare.vim +++ b/runtime/ftplugin/hare.vim @@ -1,35 +1,59 @@ -" Vim filetype plugin -" Language: Hare -" Maintainer: Amelia Clarke -" Previous Maintainer: Drew DeVault -" Last Updated: 2022-09-28 -" 2023 Aug 28 by Vim Project (undo_ftplugin) +" Vim filetype plugin. +" Language: Hare +" Maintainer: Amelia Clarke +" Last Updated: 2024-05-10 +" Upstream: https://git.sr.ht/~sircmpwn/hare.vim if exists('b:did_ftplugin') finish endif let b:did_ftplugin = 1 -" Formatting settings. -setlocal formatoptions-=t formatoptions+=croql/ +let s:cpo_save = &cpo +set cpo&vim + +" Set the default compiler. +compiler hare -" Miscellaneous. +" Formatting settings. setlocal comments=:// setlocal commentstring=//\ %s +setlocal formatlistpat=^\ \\?-\ +setlocal formatoptions+=croqnlj/ formatoptions-=t + +" Search for Hare modules. +setlocal include=^\\s*use\\> +setlocal includeexpr=hare#FindModule(v:fname) +setlocal isfname+=: setlocal suffixesadd=.ha -let b:undo_ftplugin = "setl cms< com< fo< sua<" +" Add HAREPATH to the default search paths. +setlocal path-=/usr/include,, +let &l:path .= ',' .. hare#GetPath() .. ',,' -" Hare recommended style. -if get(g:, "hare_recommended_style", 1) +let b:undo_ftplugin = 'setl cms< com< flp< fo< inc< inex< isf< pa< sua< mp<' + +" Follow the Hare style guide by default. +if get(g:, 'hare_recommended_style', 1) setlocal noexpandtab - setlocal shiftwidth=8 + setlocal shiftwidth=0 setlocal softtabstop=0 setlocal tabstop=8 setlocal textwidth=80 - let b:undo_ftplugin ..= " | setl et< sts< sw< ts< tw<" + let b:undo_ftplugin .= ' et< sts< sw< ts< tw<' endif -compiler hare +augroup hare.vim + autocmd! + + " Highlight whitespace errors by default. + if get(g:, 'hare_space_error', 1) + autocmd InsertEnter * hi link hareSpaceError NONE + autocmd InsertLeave * hi link hareSpaceError Error + endif +augroup END + +let &cpo = s:cpo_save +unlet s:cpo_save -" vim: et sw=2 sts=2 ts=8 +" vim: et sts=2 sw=2 ts=8 diff --git a/runtime/ftplugin/haredoc.vim b/runtime/ftplugin/haredoc.vim new file mode 100644 index 0000000000..69030b47ba --- /dev/null +++ b/runtime/ftplugin/haredoc.vim @@ -0,0 +1,44 @@ +" Vim filetype plugin. +" Language: Haredoc (Hare documentation format) +" Maintainer: Amelia Clarke +" Last Updated: 2024-05-02 +" Upstream: https://git.sr.ht/~selene/hare.vim + +if exists('b:did_ftplugin') + finish +endif +let b:did_ftplugin = 1 + +let s:cpo_save = &cpo +set cpo&vim + +" Formatting settings. +setlocal comments=:\ +setlocal formatlistpat=^\ \\?-\ +setlocal formatoptions+=tnlj formatoptions-=c formatoptions-=q + +" Search for Hare modules. +setlocal includeexpr=hare#FindModule(v:fname) +setlocal isfname+=: +setlocal suffixesadd=.ha + +" Add HAREPATH to the default search paths. +setlocal path-=/usr/include,, +let &l:path .= ',' .. hare#GetPath() .. ',,' + +let b:undo_ftplugin = 'setl com< flp< fo< inex< isf< pa< sua<' + +" Follow the Hare style guide by default. +if get(g:, 'hare_recommended_style', 1) + setlocal noexpandtab + setlocal shiftwidth=0 + setlocal softtabstop=0 + setlocal tabstop=8 + setlocal textwidth=80 + let b:undo_ftplugin .= ' et< sts< sw< ts< tw<' +endif + +let &cpo = s:cpo_save +unlet s:cpo_save + +" vim: et sts=2 sw=2 ts=8 diff --git a/runtime/indent/hare.vim b/runtime/indent/hare.vim index 0a9d8dafd8..1b51d1e80a 100644 --- a/runtime/indent/hare.vim +++ b/runtime/indent/hare.vim @@ -1,19 +1,16 @@ " Vim indent file -" Language: Hare -" Maintainer: Amelia Clarke -" Last Change: 2022 Sep 22 -" 2023 Aug 28 by Vim Project (undo_indent) +" Language: Hare +" Maintainer: Amelia Clarke +" Last Change: 2024-04-14 +" Upstream: https://git.sr.ht/~sircmpwn/hare.vim -if exists("b:did_indent") +if exists('b:did_indent') finish endif let b:did_indent = 1 -if !has("cindent") || !has("eval") - finish -endif - -setlocal cindent +let s:cpo_save = &cpo +set cpo&vim " L0 -> don't deindent labels " (s -> use one indent after a trailing ( @@ -41,7 +38,11 @@ setlocal cinwords=if,else,for,switch,match setlocal indentexpr=GetHareIndent() -let b:undo_indent = "setl cin< cino< cinw< inde< indk<" +let b:undo_indent = 'setl cino< cinw< inde< indk<' + +if exists('*GetHareIndent()') + finish +endif function! FloorCindent(lnum) return cindent(a:lnum) / shiftwidth() * shiftwidth() @@ -122,7 +123,8 @@ function! GetHareIndent() " Indent the body of a case. " If the previous line ended in a semicolon and the line before that was a " case, don't do any special indenting. - if prevline =~# '\v;\s*(//.*)?$' && prevprevline =~# '\v\=\>\s*(//.*)?$' && line !~# '\v^\s*}' + if prevline =~# '\v;\s*(//.*)?$' && prevprevline =~# '\v\=\>\s*(//.*)?$' + \ && line !~# '\v^\s*}' return indent(prevlnum) endif @@ -138,4 +140,7 @@ function! GetHareIndent() return l:indent endfunction -" vim: tabstop=2 shiftwidth=2 expandtab +let &cpo = s:cpo_save +unlet s:cpo_save + +" vim: et sw=2 sts=2 ts=8 diff --git a/runtime/lua/vim/filetype.lua b/runtime/lua/vim/filetype.lua index d1fdd0aa16..2ab6cc6059 100644 --- a/runtime/lua/vim/filetype.lua +++ b/runtime/lua/vim/filetype.lua @@ -1637,7 +1637,7 @@ local filename = { ['.xsdbcmdhistory'] = 'tcl', ['texmf.cnf'] = 'texmf', COPYING = 'text', - README = 'text', + README = detect_seq(detect.haredoc, 'text'), LICENSE = 'text', AUTHORS = 'text', tfrc = 'tf', diff --git a/runtime/lua/vim/filetype/detect.lua b/runtime/lua/vim/filetype/detect.lua index ba86d8de5a..58d2666564 100644 --- a/runtime/lua/vim/filetype/detect.lua +++ b/runtime/lua/vim/filetype/detect.lua @@ -650,6 +650,30 @@ function M.header(_, bufnr) end end +--- Recursively search for Hare source files in a directory and any +--- subdirectories, up to a given depth. +--- @param dir string +--- @param depth number +--- @return boolean +local function is_hare_module(dir, depth) + depth = math.max(depth, 0) + for name, _ in vim.fs.dir(dir, { depth = depth + 1 }) do + if name:find('%.ha$') then + return true + end + end + return false +end + +--- @type vim.filetype.mapfn +function M.haredoc(path, _) + if vim.g.filetype_haredoc then + if is_hare_module(vim.fs.dirname(path), vim.g.haredoc_search_depth or 1) then + return 'haredoc' + end + end +end + --- @type vim.filetype.mapfn function M.html(_, bufnr) for _, line in ipairs(getlines(bufnr, 1, 10)) do diff --git a/runtime/syntax/hare.vim b/runtime/syntax/hare.vim index 07cf33fb11..4c7ae92486 100644 --- a/runtime/syntax/hare.vim +++ b/runtime/syntax/hare.vim @@ -1,119 +1,142 @@ -" PRELUDE {{{1 -" Vim syntax file -" Language: Hare -" Maintainer: Amelia Clarke -" Last Change: 2022-09-21 +" Vim syntax file. +" Language: Hare +" Maintainer: Amelia Clarke +" Last Change: 2024-05-10 +" Upstream: https://git.sr.ht/~sircmpwn/hare.vim -if exists("b:current_syntax") +if exists('b:current_syntax') finish endif -let b:current_syntax = "hare" +syn include @haredoc syntax/haredoc.vim +let b:current_syntax = 'hare' -" SYNTAX {{{1 +" Syntax {{{1 syn case match +syn iskeyword @,48-57,@-@,_ -" KEYWORDS {{{2 -syn keyword hareConditional if else match switch +" Keywords {{{2 +syn keyword hareConditional else if match switch +syn keyword hareDefine def +syn keyword hareInclude use syn keyword hareKeyword break continue return yield +syn keyword hareKeyword case +syn keyword hareKeyword const let syn keyword hareKeyword defer +syn keyword hareKeyword export static syn keyword hareKeyword fn -syn keyword hareKeyword let -syn keyword hareLabel case syn keyword hareOperator as is syn keyword hareRepeat for -syn keyword hareStorageClass const def export nullable static -syn keyword hareStructure enum struct union syn keyword hareTypedef type -" C ABI. -syn keyword hareKeyword vastart vaarg vaend - -" BUILTINS {{{2 -syn keyword hareBuiltin abort +" Attributes. +syn keyword hareAttribute @fini @init @test +syn keyword hareAttribute @offset @packed +syn keyword hareAttribute @symbol +syn keyword hareAttribute @threadlocal + +" Builtins. +syn keyword hareBuiltin abort assert +syn keyword hareBuiltin align len offset syn keyword hareBuiltin alloc free syn keyword hareBuiltin append delete insert -syn keyword hareBuiltin assert -syn keyword hareBuiltin len offset +syn keyword hareBuiltin vaarg vaend vastart -" TYPES {{{2 +" Types {{{2 syn keyword hareType bool -syn keyword hareType char str +syn keyword hareType done syn keyword hareType f32 f64 -syn keyword hareType u8 u16 u32 u64 i8 i16 i32 i64 -syn keyword hareType uint int -syn keyword hareType rune +syn keyword hareType i8 i16 i32 i64 int +syn keyword hareType never +syn keyword hareType opaque +syn keyword hareType rune str +syn keyword hareType u8 u16 u32 u64 uint syn keyword hareType uintptr +syn keyword hareType valist syn keyword hareType void -" C ABI. -syn keyword hareType valist +" Other types. +syn keyword hareStorageClass nullable +syn keyword hareStructure enum struct union -" LITERALS {{{2 -syn keyword hareBoolean true false -syn keyword hareNull null - -" Number literals. -syn match hareNumber "\v(\.@1" display -syn match hareNumber "\v(\.@1" display -syn match hareNumber "\v(\.@1" display -syn match hareNumber "\v(\.@1" display - -" Floating-point number literals. -syn match hareFloat "\v<\d+\.\d+([Ee][+-]?\d+)?(f32|f64)?>" display -syn match hareFloat "\v<\d+([Ee][+-]?\d+)?(f32|f64)>" display - -" String and rune literals. -syn match hareEscape "\\[\\'"0abfnrtv]" contained display -syn match hareEscape "\v\\(x\x{2}|u\x{4}|U\x{8})" contained display -syn match hareFormat "\v\{\d*(\%\d*|(:[ 0+-]?\d*(\.\d+)?[Xbox]?))?}" contained display -syn match hareFormat "\({{\|}}\)" contained display -syn region hareRune start="'" end="'\|$" skip="\\'" contains=hareEscape display extend -syn region hareString start=+"+ end=+"\|$+ skip=+\\"+ contains=hareEscape,hareFormat display extend -syn region hareString start="`" end="`\|$" contains=hareFormat display - -" MISCELLANEOUS {{{2 -syn keyword hareTodo FIXME TODO XXX contained +" Literals {{{2 +syn keyword hareBoolean false true +syn keyword hareConstant null -" Attributes. -syn match hareAttribute "@[a-z]*" +" Integer literals. +syn match hareNumber '\v<%(0|[1-9]%(_?\d)*)%([Ee]\+?\d+)?%([iu]%(8|16|32|64)?|z)?>' display +syn match hareNumber '\v<0b[01]%(_?[01])*%([iu]%(8|16|32|64)?|z)?>' display +syn match hareNumber '\v<0o\o%(_?\o)*%([iu]%(8|16|32|64)?|z)?>' display +syn match hareNumber '\v<0x\x%(_?\x)*%([iu]%(8|16|32|64)?|z)?>' display -" Blocks. -syn region hareBlock start="{" end="}" fold transparent +" Floating-point literals. +syn match hareFloat '\v<%(0|[1-9]%(_?\d)*)\.\d%(_?\d)*%([Ee][+-]?\d+)?%(f32|f64)?>' display +syn match hareFloat '\v<%(0|[1-9]%(_?\d)*)%([Ee][+-]?\d+)?%(f32|f64)>' display +syn match hareFloat '\v<0x\x%(_?\x)*%(\.\x%(_?\x)*)?[Pp][+-]?\d+%(f32|f64)?>' display + +" Rune and string literals. +syn region hareRune start="'" skip="\\'" end="'" contains=hareEscape +syn region hareString start='"' skip='\\"' end='"' contains=hareEscape,hareFormat +syn region hareString start='`' end='`' contains=hareFormat + +" Escape sequences. +syn match hareEscape '\\[0abfnrtv\\'"]' contained +syn match hareEscape '\v\\%(x\x{2}|u\x{4}|U\x{8})' contained display + +" Format sequences. +syn match hareFormat '\v\{\d*%(:%(\.?\d+|[ +\-=Xbefgox]|F[.2ESUs]|_%(.|\\%([0abfnrtv\\'"]|x\x{2}|u\x{4}|U\x{8})))*)?}' contained contains=hareEscape display +syn match hareFormat '{\d*%\d*}' contained display +syn match hareFormat '{{\|}}' contained display + +" Miscellaneous {{{2 " Comments. -syn region hareComment start="//" end="$" contains=hareCommentDoc,hareTodo,@Spell display keepend -syn region hareCommentDoc start="\[\[" end="]]\|\ze\_s" contained display +syn region hareComment start='//' end='$' contains=hareTodo,@haredoc,@Spell display +syn keyword hareTodo FIXME TODO XXX contained + +" Identifiers. +syn match hareDelimiter '::' display +syn match hareName '\<\h\w*\>' nextgroup=@harePostfix skipempty skipwhite transparent -" The size keyword can be either a builtin or a type. -syn match hareBuiltin "\v\ze(\_s*//.*\_$)*\_s*\(" contains=hareComment -syn match hareType "\v((\_s*//.*\_$)*\_s*\()@!" contains=hareComment +" Labels. +syn match hareLabel ':\h\w*\>' display -" Trailing whitespace. -syn match hareSpaceError "\v\s+$" display excludenl -syn match hareSpaceError "\v\zs +\ze\t" display +" Match `size` as a type unless it is followed by an open paren. +syn match hareType '\' display +syn match hareBuiltin '\'hs=s+1 contained contains=hareNumber nextgroup=@harePostfix skipempty skipwhite +syn region hareIndex start='\[' end=']' contained nextgroup=@harePostfix skipempty skipwhite transparent +syn region hareParens start='(' end=')' nextgroup=@harePostfix skipempty skipwhite transparent -syn match hareErrorAssertion "\v(^([^/]|//@!)*\)\_s*)@<=!\=@!" -syn match hareQuestionMark "?" +" Whitespace errors. +syn match hareSpaceError '^ \+\ze\t' display +syn match hareSpaceError excludenl '\s\+$' containedin=ALL display -" DEFAULT HIGHLIGHTING {{{1 -hi def link hareAttribute Keyword +" Folding {{{3 +syn region hareBlock start='{' end='}' fold transparent + +" Default highlighting {{{1 +hi def link hareAttribute PreProc hi def link hareBoolean Boolean -hi def link hareBuiltin Function +hi def link hareBuiltin Operator hi def link hareComment Comment -hi def link hareCommentDoc SpecialComment hi def link hareConditional Conditional +hi def link hareConstant Constant +hi def link hareDefine Define +hi def link hareDelimiter Delimiter +hi def link hareErrorTest Special hi def link hareEscape SpecialChar hi def link hareFloat Float hi def link hareFormat SpecialChar +hi def link hareInclude Include hi def link hareKeyword Keyword -hi def link hareLabel Label -hi def link hareNull Constant +hi def link hareLabel Special hi def link hareNumber Number hi def link hareOperator Operator -hi def link hareQuestionMark Special hi def link hareRepeat Repeat hi def link hareRune Character hi def link hareStorageClass StorageClass @@ -122,12 +145,13 @@ hi def link hareStructure Structure hi def link hareTodo Todo hi def link hareType Type hi def link hareTypedef Typedef -hi def link hareUse PreProc -hi def link hareSpaceError Error -autocmd InsertEnter * hi link hareSpaceError NONE -autocmd InsertLeave * hi link hareSpaceError Error +" Highlight embedded haredoc references. +hi! def link haredocRefValid SpecialComment -hi def hareErrorAssertion ctermfg=red cterm=bold guifg=red gui=bold +" Highlight whitespace errors by default. +if get(g:, 'hare_space_error', 1) + hi def link hareSpaceError Error +endif -" vim: tabstop=8 shiftwidth=2 expandtab +" vim: et sts=2 sw=2 ts=8 diff --git a/runtime/syntax/haredoc.vim b/runtime/syntax/haredoc.vim new file mode 100644 index 0000000000..09c99c1d56 --- /dev/null +++ b/runtime/syntax/haredoc.vim @@ -0,0 +1,32 @@ +" Vim syntax file. +" Language: Haredoc (Hare documentation format) +" Maintainer: Amelia Clarke +" Last Change: 2024-05-10 +" Upstream: https://git.sr.ht/~selene/hare.vim + +if exists('b:current_syntax') + finish +endif +let b:current_syntax = 'haredoc' + +" Syntax {{{1 +syn case match +syn iskeyword @,48-57,_ + +" Code samples. +syn region haredocCodeSample excludenl start='\t\zs' end='$' contains=@NoSpell display + +" References to other declarations and modules. +syn region haredocRef start='\[\[' end=']]' contains=haredocRefValid,@NoSpell display keepend oneline +syn match haredocRefValid '\v\[\[\h\w*%(::\h\w*)*%(::)?]]' contained contains=@NoSpell display + +" Miscellaneous. +syn keyword haredocTodo FIXME TODO XXX + +" Default highlighting {{{1 +hi def link haredocCodeSample Comment +hi def link haredocRef Error +hi def link haredocRefValid Special +hi def link haredocTodo Todo + +" vim: et sts=2 sw=2 ts=8 -- cgit From 61b3a26e5b3d7fb6a19dd587994277bc4479307f Mon Sep 17 00:00:00 2001 From: Christian Clason Date: Sun, 26 May 2024 12:17:47 +0200 Subject: build(deps): bump tree-sitter-query to v0.4.0 --- runtime/queries/query/highlights.scm | 3 --- 1 file changed, 3 deletions(-) (limited to 'runtime') diff --git a/runtime/queries/query/highlights.scm b/runtime/queries/query/highlights.scm index 210d03dc33..c02ee3f2a0 100644 --- a/runtime/queries/query/highlights.scm +++ b/runtime/queries/query/highlights.scm @@ -5,9 +5,6 @@ (capture (identifier) @type) -(anonymous_node - (identifier) @string) - (predicate name: (identifier) @function.call) -- cgit From 2ed6423c7e9d4911343d3e2049908f4b78ec7a55 Mon Sep 17 00:00:00 2001 From: altermo <107814000+altermo@users.noreply.github.com> Date: Sun, 26 May 2024 12:56:32 +0200 Subject: fix(tohtml): replace ipairs with pairs --- runtime/lua/tohtml.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'runtime') diff --git a/runtime/lua/tohtml.lua b/runtime/lua/tohtml.lua index 505de720ba..5a6fc77e5c 100644 --- a/runtime/lua/tohtml.lua +++ b/runtime/lua/tohtml.lua @@ -521,7 +521,7 @@ local function _styletable_extmarks_virt_text(state, extmark) hl_mode = 'blend', hl_group = 'combine', } - for opt, val in ipairs(not_supported) do + for opt, val in pairs(not_supported) do if extmark[4][opt] == val then vim.notify_once( ('Info(TOhtml): extmark.%s="%s" is not supported, HTML may be incorrect'):format(opt, val) -- cgit From 8cd9feb50166202bf55315934f14f74e63c8fcb4 Mon Sep 17 00:00:00 2001 From: altermo <107814000+altermo@users.noreply.github.com> Date: Sun, 26 May 2024 13:08:57 +0200 Subject: fix(tohtml): ignore lsp inlay hints --- runtime/lua/tohtml.lua | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'runtime') diff --git a/runtime/lua/tohtml.lua b/runtime/lua/tohtml.lua index 5a6fc77e5c..f7d8538b8f 100644 --- a/runtime/lua/tohtml.lua +++ b/runtime/lua/tohtml.lua @@ -481,10 +481,17 @@ end --- @param state vim.tohtml.state --- @param extmark {[1]:integer,[2]:integer,[3]:integer,[4]:vim.api.keyset.set_extmark|any} -local function _styletable_extmarks_virt_text(state, extmark) +--- @param namespaces table +local function _styletable_extmarks_virt_text(state, extmark, namespaces) if not extmark[4].virt_text then return end + ---TODO(altermo) LSP semantic tokens (and some other extmarks) are only + ---generated in visible lines, and not in the whole buffer. + if (namespaces[extmark[4].ns_id] or ''):find('vim_lsp_inlayhint') then + vim.notify_once('Info(TOhtml): lsp inlay hints are not supported, HTML may be incorrect') + return + end local styletable = state.style --- @type integer,integer local row, col = extmark[2], extmark[3] @@ -586,7 +593,7 @@ local function styletable_extmarks(state) _styletable_extmarks_conceal(state, v) end for _, v in ipairs(extmarks) do - _styletable_extmarks_virt_text(state, v) + _styletable_extmarks_virt_text(state, v, namespaces) end for _, v in ipairs(extmarks) do _styletable_extmarks_virt_lines(state, v) -- cgit From 88c7997503e12088e134ba663fe352399f8fa104 Mon Sep 17 00:00:00 2001 From: altermo <107814000+altermo@users.noreply.github.com> Date: Sun, 26 May 2024 13:28:14 +0200 Subject: fix(tohtml): show how many warnings are hidden --- runtime/lua/tohtml.lua | 38 +++++++++++++++++++++++++++----------- 1 file changed, 27 insertions(+), 11 deletions(-) (limited to 'runtime') diff --git a/runtime/lua/tohtml.lua b/runtime/lua/tohtml.lua index f7d8538b8f..0fc349e86d 100644 --- a/runtime/lua/tohtml.lua +++ b/runtime/lua/tohtml.lua @@ -57,6 +57,26 @@ --- @field [3] any[][] virt_text --- @field [4] any[][] overlay_text +--- @type string[] +local notifications = {} + +---@param msg string +local function notify(msg) + if #notifications == 0 then + vim.schedule(function() + if #notifications > 1 then + vim.notify( + ('TOhtml: %s (+ %d more warnings)'):format(notifications[1], tostring(#notifications - 1)) + ) + elseif #notifications == 1 then + vim.notify('TOhtml: ' .. notifications[1]) + end + notifications = {} + end) + end + table.insert(notifications, msg) +end + local HIDE_ID = -1 -- stylua: ignore start local cterm_8_to_hex={ @@ -215,7 +235,7 @@ local function cterm_to_hex(colorstr) if hex then cterm_color_cache[color] = hex else - vim.notify_once("Info(TOhtml): Couldn't get terminal colors, using fallback") + notify("Couldn't get terminal colors, using fallback") local t_Co = tonumber(vim.api.nvim_eval('&t_Co')) if t_Co <= 8 then cterm_color_cache = cterm_8_to_hex @@ -241,7 +261,7 @@ local function get_background_color() end local hex = try_query_terminal_color('background') if not hex or not hex:match('#%x%x%x%x%x%x') then - vim.notify_once("Info(TOhtml): Couldn't get terminal background colors, using fallback") + notify("Couldn't get terminal background colors, using fallback") hex = vim.o.background == 'light' and '#ffffff' or '#000000' end background_color_cache = hex @@ -259,7 +279,7 @@ local function get_foreground_color() end local hex = try_query_terminal_color('foreground') if not hex or not hex:match('#%x%x%x%x%x%x') then - vim.notify_once("Info(TOhtml): Couldn't get terminal foreground colors, using fallback") + notify("Couldn't get terminal foreground colors, using fallback") hex = vim.o.background == 'light' and '#000000' or '#ffffff' end foreground_color_cache = hex @@ -467,7 +487,7 @@ local function _styletable_extmarks_highlight(state, extmark, namespaces) ---TODO(altermo) LSP semantic tokens (and some other extmarks) are only ---generated in visible lines, and not in the whole buffer. if (namespaces[extmark[4].ns_id] or ''):find('vim_lsp_semantic_tokens') then - vim.notify_once('Info(TOhtml): lsp semantic tokens are not supported, HTML may be incorrect') + notify('lsp semantic tokens are not supported, HTML may be incorrect') return end local srow, scol, erow, ecol = @@ -489,7 +509,7 @@ local function _styletable_extmarks_virt_text(state, extmark, namespaces) ---TODO(altermo) LSP semantic tokens (and some other extmarks) are only ---generated in visible lines, and not in the whole buffer. if (namespaces[extmark[4].ns_id] or ''):find('vim_lsp_inlayhint') then - vim.notify_once('Info(TOhtml): lsp inlay hints are not supported, HTML may be incorrect') + notify('lsp inlay hints are not supported, HTML may be incorrect') return end local styletable = state.style @@ -530,9 +550,7 @@ local function _styletable_extmarks_virt_text(state, extmark, namespaces) } for opt, val in pairs(not_supported) do if extmark[4][opt] == val then - vim.notify_once( - ('Info(TOhtml): extmark.%s="%s" is not supported, HTML may be incorrect'):format(opt, val) - ) + notify(('extmark.%s="%s" is not supported, HTML may be incorrect'):format(opt, val)) end end end @@ -618,9 +636,7 @@ local function styletable_folds(state) end end if has_folded and type(({ pcall(vim.api.nvim_eval, vim.o.foldtext) })[2]) == 'table' then - vim.notify_once( - 'Info(TOhtml): foldtext returning a table is half supported, HTML may be incorrect' - ) + notify('foldtext returning a table with highlights is not supported, HTML may be incorrect') end end -- cgit From eb37241d38ad35b9e6bfac6379dd10e60aa0350c Mon Sep 17 00:00:00 2001 From: Riley Bruins Date: Sun, 26 May 2024 10:27:12 -0700 Subject: fix(tohtml): properly handle multiple hl groups #29012 Problem: :TOhtml doesn't properly handle virtual text when it has multiple highlight groups. It also improperly calculates position offset for multi-byte virt_text characters. Solution: Apply the `vim.api.nvim_strwidth` broadly to properly calculate character offset, and handle the cases where the `hl` argument can be a table of multiple hl groups. --- runtime/lua/tohtml.lua | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) (limited to 'runtime') diff --git a/runtime/lua/tohtml.lua b/runtime/lua/tohtml.lua index 0fc349e86d..5e145950b7 100644 --- a/runtime/lua/tohtml.lua +++ b/runtime/lua/tohtml.lua @@ -188,6 +188,8 @@ local background_color_cache = nil --- @type string? local foreground_color_cache = nil +local len = vim.api.nvim_strwidth + --- @see https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h3-Operating-System-Commands --- @param color "background"|"foreground"|integer --- @return string? @@ -312,9 +314,12 @@ local function style_line_insert_virt_text(style_line, col, val) end --- @param state vim.tohtml.state ---- @param hl string|integer|nil +--- @param hl string|integer|string[]|integer[]? --- @return nil|integer local function register_hl(state, hl) + if type(hl) == 'table' then + hl = hl[#hl] + end if type(hl) == 'nil' then return elseif type(hl) == 'string' then @@ -537,7 +542,7 @@ local function _styletable_extmarks_virt_text(state, extmark, namespaces) else style_line_insert_virt_text(styletable[row + 1], col + 1, { i[1], hlid }) end - virt_text_len = virt_text_len + #i[1] + virt_text_len = virt_text_len + len(i[1]) end if extmark[4].virt_text_pos == 'overlay' then styletable_insert_range(state, row + 1, col + 1, row + 1, col + virt_text_len + 1, HIDE_ID) @@ -782,7 +787,7 @@ local function styletable_statuscolumn(state) statuscolumn, { winid = state.winid, use_statuscol_lnum = row, highlights = true } ) - local width = vim.api.nvim_strwidth(status.str) + local width = len(status.str) if width > minwidth then minwidth = width end @@ -797,7 +802,7 @@ local function styletable_statuscolumn(state) for k, v in ipairs(hls) do local text = str:sub(v.start + 1, hls[k + 1] and hls[k + 1].start or nil) if k == #hls then - text = text .. (' '):rep(minwidth - vim.api.nvim_strwidth(str)) + text = text .. (' '):rep(minwidth - len(str)) end if text ~= '' then local hlid = register_hl(state, v.group) @@ -817,7 +822,6 @@ local function styletable_listchars(state) local function utf8_sub(str, i, j) return vim.fn.strcharpart(str, i - 1, j and j - i + 1 or nil) end - local len = vim.api.nvim_strwidth --- @type table local listchars = vim.opt_local.listchars:get() local ids = setmetatable({}, { -- cgit From 14a7644181fb3244d548e5d3a0fa23d67580def2 Mon Sep 17 00:00:00 2001 From: Christian Clason Date: Sun, 26 May 2024 20:07:46 +0200 Subject: vim-patch:76174e7: runtime(asm): remove the indent plugin since it has too many issues fixes: vim/vim#14791 https://github.com/vim/vim/commit/76174e71101503900d54d38e00b3a869af1fdd85 Co-authored-by: Christian Brabandt --- runtime/indent/asm.vim | 29 ----------------------------- 1 file changed, 29 deletions(-) delete mode 100644 runtime/indent/asm.vim (limited to 'runtime') diff --git a/runtime/indent/asm.vim b/runtime/indent/asm.vim deleted file mode 100644 index 054612b9d6..0000000000 --- a/runtime/indent/asm.vim +++ /dev/null @@ -1,29 +0,0 @@ -" Vim indent file -" Language: asm -" Maintainer: Philip Jones -" Upstream: https://github.com/philj56/vim-asm-indent -" Last Change: 2017-Jul-01 -" 2024 Apr 25 by Vim Project (undo_indent) - -if exists("b:did_indent") - finish -endif -let b:did_indent = 1 - -setlocal indentexpr=s:getAsmIndent() -setlocal indentkeys=<:>,!^F,o,O - -let b:undo_indent = "setlocal indentexpr< indentkeys<" - -function! s:getAsmIndent() - let line = getline(v:lnum) - let ind = shiftwidth() - - " If the line is a label (starts with ':' terminated keyword), - " then don't indent - if line =~ '^\s*\k\+:' - let ind = 0 - endif - - return ind -endfunction -- cgit From ffbd09ef6acfbfac897be19d5ae847af6e6bd03d Mon Sep 17 00:00:00 2001 From: Christian Clason Date: Sun, 26 May 2024 20:08:13 +0200 Subject: vim-patch:8607192: runtime(typescriptreact): fix highlighting nested and escaped quotes in string props (vim/vim#14852) https://github.com/vim/vim/commit/86071925ede1030d86e764054e36ef8ab56fc666 Co-authored-by: Linda_pp --- runtime/syntax/typescriptreact.vim | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'runtime') diff --git a/runtime/syntax/typescriptreact.vim b/runtime/syntax/typescriptreact.vim index 9dc9a2b797..061ec4d81e 100644 --- a/runtime/syntax/typescriptreact.vim +++ b/runtime/syntax/typescriptreact.vim @@ -1,7 +1,7 @@ " Vim syntax file " Language: TypeScript with React (JSX) " Maintainer: The Vim Project -" Last Change: 2024 May 24 +" Last Change: 2024 May 26 " Based On: Herrington Darkholme's yats.vim " Changes: See https://github.com/HerringtonDarkholme/yats.vim " Credits: See yats.vim on github @@ -118,7 +118,8 @@ syntax match tsxEqual +=+ display contained " " s~~~~~~e -syntax region tsxString contained start=+["']+ end=+["']+ contains=tsxEntity,@Spell display +syntax region tsxString contained start=+"+ skip=+\\"+ end=+"+ contains=tsxEntity,@Spell display +syntax region tsxString contained start=+'+ skip=+\\'+ end=+'+ contains=tsxEntity,@Spell display " " s~~~~~~~~~~~~~~e -- cgit From c4eb0b64bd4923a72fe737837cfe234c80fb539c Mon Sep 17 00:00:00 2001 From: Guilherme Soares <48023091+guilhas07@users.noreply.github.com> Date: Mon, 27 May 2024 13:20:03 +0200 Subject: fix(treesitter): find buffer in multiple windows #28922 Problem: 1. When interacting with multiple :InspectTree and the source buffer windows there is a high chance of errors due to the window ids not being updated and validated. 2. Not all InspectTree windows were closed when the source buffer was closed. Solution: 1. Update InspectTree window id on `CursorMoved` event and validate source buffer window id before trying to navigate to it. 2. Close all InspectTree windows --- runtime/lua/vim/treesitter/dev.lua | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) (limited to 'runtime') diff --git a/runtime/lua/vim/treesitter/dev.lua b/runtime/lua/vim/treesitter/dev.lua index 5c91f101c0..ca8cf85eda 100644 --- a/runtime/lua/vim/treesitter/dev.lua +++ b/runtime/lua/vim/treesitter/dev.lua @@ -325,7 +325,10 @@ function M.inspect_tree(opts) opts = opts or {} + -- source buffer local buf = api.nvim_get_current_buf() + + -- window id for source buffer local win = api.nvim_get_current_win() local treeview = assert(TSTreeView:new(buf, opts.lang)) @@ -334,12 +337,14 @@ function M.inspect_tree(opts) close_win(vim.b[buf].dev_inspect) end + -- window id for tree buffer local w = opts.winid if not w then vim.cmd(opts.command or '60vnew') w = api.nvim_get_current_win() end + -- tree buffer local b = opts.bufnr if b then api.nvim_win_set_buf(w, b) @@ -375,6 +380,12 @@ function M.inspect_tree(opts) callback = function() local row = api.nvim_win_get_cursor(w)[1] local lnum, col = treeview:get(row).node:start() + + -- update source window if original was closed + if not api.nvim_win_is_valid(win) then + win = vim.fn.win_findbuf(buf)[1] + end + api.nvim_set_current_win(win) api.nvim_win_set_cursor(win, { lnum + 1, col }) end, @@ -432,6 +443,7 @@ function M.inspect_tree(opts) return true end + w = api.nvim_get_current_win() api.nvim_buf_clear_namespace(buf, treeview.ns, 0, -1) local row = api.nvim_win_get_cursor(w)[1] local lnum, col, end_lnum, end_col = treeview:get(row).node:range() @@ -441,6 +453,11 @@ function M.inspect_tree(opts) hl_group = 'Visual', }) + -- update source window if original was closed + if not api.nvim_win_is_valid(win) then + win = vim.fn.win_findbuf(buf)[1] + end + local topline, botline = vim.fn.line('w0', win), vim.fn.line('w$', win) -- Move the cursor if highlighted range is completely out of view @@ -506,7 +523,10 @@ function M.inspect_tree(opts) buffer = buf, once = true, callback = function() - close_win(w) + -- close all tree windows + for _, window in pairs(vim.fn.win_findbuf(b)) do + close_win(window) + end end, }) end -- cgit From 48251134ee59a3e2f0aeb89608fa820c21b25d4f Mon Sep 17 00:00:00 2001 From: Gregory Anders <8965202+gpanders@users.noreply.github.com> Date: Mon, 27 May 2024 08:08:23 -0500 Subject: perf: add fast path to vim.validate (#28977) For many small/simple functions (like those found in shared.lua), the runtime of vim.validate can far exceed the runtime of the function itself. Add an "overload" to vim.validate that uses a simple assertion pattern, rather than parsing a full "validation spec". --- runtime/doc/lua.txt | 21 ++++++++++++- runtime/lua/vim/shared.lua | 76 +++++++++++++++++++++++++++++++++++++--------- 2 files changed, 82 insertions(+), 15 deletions(-) (limited to 'runtime') diff --git a/runtime/doc/lua.txt b/runtime/doc/lua.txt index 64a3014388..fd0cd3252f 100644 --- a/runtime/doc/lua.txt +++ b/runtime/doc/lua.txt @@ -2366,7 +2366,26 @@ vim.trim({s}) *vim.trim()* • https://www.lua.org/pil/20.2.html vim.validate({opt}) *vim.validate()* - Validates a parameter specification (types and values). Specs are + Validate function arguments. + + This function has two valid forms: + 1. vim.validate(name: str, value: any, type: string, optional?: bool) + 2. vim.validate(spec: table) + + Form 1 validates that argument {name} with value {value} has the type + {type}. {type} must be a value returned by |lua-type()|. If {optional} is + true, then {value} may be null. This form is significantly faster and + should be preferred for simple cases. + + Example: >lua + function vim.startswith(s, prefix) + vim.validate('s', s, 'string') + vim.validate('prefix', prefix, 'string') + ... + end +< + + Form 2 validates a parameter specification (types and values). Specs are evaluated in alphanumeric order, until the first failure. Usage example: >lua diff --git a/runtime/lua/vim/shared.lua b/runtime/lua/vim/shared.lua index e9e4326057..2641d1feb0 100644 --- a/runtime/lua/vim/shared.lua +++ b/runtime/lua/vim/shared.lua @@ -214,7 +214,7 @@ end ---@param t table (table) Table ---@return T[] : List of keys function vim.tbl_keys(t) - vim.validate({ t = { t, 't' } }) + vim.validate('t', t, 'table') --- @cast t table local keys = {} @@ -231,7 +231,7 @@ end ---@param t table (table) Table ---@return T[] : List of values function vim.tbl_values(t) - vim.validate({ t = { t, 't' } }) + vim.validate('t', t, 'table') local values = {} for _, v in @@ -332,7 +332,7 @@ end ---@param value any Value to compare ---@return boolean `true` if `t` contains `value` function vim.list_contains(t, value) - vim.validate({ t = { t, 't' } }) + vim.validate('t', t, 'table') --- @cast t table for _, v in ipairs(t) do @@ -350,7 +350,7 @@ end ---@param t table Table to check ---@return boolean `true` if `t` is empty function vim.tbl_isempty(t) - vim.validate({ t = { t, 't' } }) + vim.validate('t', t, 'table') return next(t) == nil end @@ -580,7 +580,7 @@ end ---@return fun(table: table, index?: K):K, V # |for-in| iterator over sorted keys and their values ---@return T function vim.spairs(t) - assert(type(t) == 'table', ('expected table, got %s'):format(type(t))) + vim.validate('t', t, 'table') --- @cast t table -- collect the keys @@ -691,7 +691,7 @@ end ---@param t table Table ---@return integer : Number of non-nil values in table function vim.tbl_count(t) - vim.validate({ t = { t, 't' } }) + vim.validate('t', t, 'table') --- @cast t table local count = 0 @@ -723,7 +723,7 @@ end ---@param s string String to trim ---@return string String with whitespace removed from its beginning and end function vim.trim(s) - vim.validate({ s = { s, 's' } }) + vim.validate('s', s, 'string') return s:match('^%s*(.*%S)') or '' end @@ -733,7 +733,7 @@ end ---@param s string String to escape ---@return string %-escaped pattern string function vim.pesc(s) - vim.validate({ s = { s, 's' } }) + vim.validate('s', s, 'string') return (s:gsub('[%(%)%.%%%+%-%*%?%[%]%^%$]', '%%%1')) end @@ -743,7 +743,8 @@ end ---@param prefix string Prefix to match ---@return boolean `true` if `prefix` is a prefix of `s` function vim.startswith(s, prefix) - vim.validate({ s = { s, 's' }, prefix = { prefix, 's' } }) + vim.validate('s', s, 'string') + vim.validate('prefix', prefix, 'string') return s:sub(1, #prefix) == prefix end @@ -753,7 +754,8 @@ end ---@param suffix string Suffix to match ---@return boolean `true` if `suffix` is a suffix of `s` function vim.endswith(s, suffix) - vim.validate({ s = { s, 's' }, suffix = { suffix, 's' } }) + vim.validate('s', s, 'string') + vim.validate('suffix', suffix, 'string') return #suffix == 0 or s:sub(-#suffix) == suffix end @@ -877,8 +879,30 @@ do return true end - --- Validates a parameter specification (types and values). Specs are evaluated in alphanumeric - --- order, until the first failure. + --- Validate function arguments. + --- + --- This function has two valid forms: + --- + --- 1. vim.validate(name: str, value: any, type: string, optional?: bool) + --- 2. vim.validate(spec: table) + --- + --- Form 1 validates that argument {name} with value {value} has the type + --- {type}. {type} must be a value returned by |lua-type()|. If {optional} is + --- true, then {value} may be null. This form is significantly faster and + --- should be preferred for simple cases. + --- + --- Example: + --- + --- ```lua + --- function vim.startswith(s, prefix) + --- vim.validate('s', s, 'string') + --- vim.validate('prefix', prefix, 'string') + --- ... + --- end + --- ``` + --- + --- Form 2 validates a parameter specification (types and values). Specs are + --- evaluated in alphanumeric order, until the first failure. --- --- Usage example: --- @@ -930,8 +954,32 @@ do --- only if the argument is valid. Can optionally return an additional --- informative error message as the second returned value. --- - msg: (optional) error string if validation fails - function vim.validate(opt) - local ok, err_msg = is_valid(opt) + --- @overload fun(name: string, val: any, expected: string, optional?: boolean) + function vim.validate(opt, ...) + local ok = false + local err_msg ---@type string? + local narg = select('#', ...) + if narg == 0 then + ok, err_msg = is_valid(opt) + elseif narg >= 2 then + -- Overloaded signature for fast/simple cases + local name = opt --[[@as string]] + local v, expected, optional = ... ---@type string, string, boolean? + local actual = type(v) + + ok = (actual == expected) or (v == nil and optional == true) + if not ok then + err_msg = ('%s: expected %s, got %s%s'):format( + name, + expected, + actual, + v and (' (%s)'):format(v) or '' + ) + end + else + error('invalid arguments') + end + if not ok then error(err_msg, 2) end -- cgit From 8893b7b340e012b714cc42f0562f37405be32d51 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Mon, 27 May 2024 22:38:10 +0800 Subject: vim-patch:393708c: runtime(vim): re-generate vim syntax from generator (#29041) related: vim/vim#14861 https://github.com/vim/vim/commit/393708cff6f92ee34b450b054dfdb73a65f5bcf7 Co-authored-by: Christian Brabandt --- runtime/syntax/vim.vim | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'runtime') diff --git a/runtime/syntax/vim.vim b/runtime/syntax/vim.vim index 4fc640bab1..22c1e16a30 100644 --- a/runtime/syntax/vim.vim +++ b/runtime/syntax/vim.vim @@ -60,7 +60,8 @@ syn case ignore syn keyword vimGroup contained Comment Constant String Character Number Boolean Float Identifier Function Statement Conditional Repeat Label Operator Keyword Exception PreProc Include Define Macro PreCondit Type StorageClass Structure Typedef Special SpecialChar Tag Delimiter SpecialComment Debug Underlined Ignore Error Todo " Default highlighting groups {{{2 -syn keyword vimHLGroup contained ErrorMsg IncSearch ModeMsg NonText StatusLine StatusLineNC EndOfBuffer VertSplit DiffText PmenuSbar TabLineSel TabLineFill Cursor lCursor QuickFixLine CursorLineSign CursorLineFold CurSearch PmenuKind PmenuKindSel PmenuExtra PmenuExtraSel Normal Directory LineNr CursorLineNr MoreMsg Question Search SpellBad SpellCap SpellRare SpellLocal PmenuThumb Pmenu PmenuSel SpecialKey Title WarningMsg WildMenu Folded FoldColumn SignColumn Visual DiffAdd DiffChange DiffDelete TabLine CursorColumn CursorLine ColorColumn Conceal MatchParen CursorIM LineNrAbove LineNrBelow +syn keyword vimHLGroup contained ErrorMsg IncSearch ModeMsg NonText StatusLine StatusLineNC EndOfBuffer VertSplit DiffText PmenuSbar TabLineSel TabLineFill Cursor lCursor QuickFixLine CursorLineSign CursorLineFold CurSearch PmenuKind PmenuKindSel PmenuExtra PmenuExtraSel Normal Directory LineNr CursorLineNr MoreMsg Question Search SpellBad SpellCap SpellRare SpellLocal PmenuThumb Pmenu PmenuSel SpecialKey Title WarningMsg WildMenu Folded FoldColumn SignColumn Visual DiffAdd DiffChange DiffDelete TabLine CursorColumn CursorLine ColorColumn MatchParen CursorIM LineNrAbove LineNrBelow +syn match vimHLGroup contained "\" syn keyword vimOnlyHLGroup contained Menu Scrollbar StatusLineTerm StatusLineTermNC ToolbarButton ToolbarLine Tooltip VisualNOS syn keyword nvimHLGroup contained FloatBorder FloatFooter FloatTitle MsgSeparator NormalFloat NormalNC Substitute TermCursor TermCursorNC VisualNC Whitespace WinBar WinBarNC WinSeparator "}}}2 -- cgit From 292365fa1b8f543ffa2240bb30af34051ad2d7c8 Mon Sep 17 00:00:00 2001 From: Ilia Choly Date: Mon, 27 May 2024 11:06:03 -0400 Subject: fix(lsp): do not detach from buffer if there are uninitialized clients (#29029) Problem: if on_lines is called before the LSP is initialized, the buffer is detached. Solution: check for uninitialized clients before detaching. --- runtime/lua/vim/lsp.lua | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'runtime') diff --git a/runtime/lua/vim/lsp.lua b/runtime/lua/vim/lsp.lua index 1592fd3151..60b3f3e502 100644 --- a/runtime/lua/vim/lsp.lua +++ b/runtime/lua/vim/lsp.lua @@ -577,7 +577,8 @@ local function buf_attach(bufnr) api.nvim_buf_attach(bufnr, false, { on_lines = function(_, _, changedtick, firstline, lastline, new_lastline) if #lsp.get_clients({ bufnr = bufnr }) == 0 then - return true -- detach + -- detach if there are no clients + return #lsp.get_clients({ bufnr = bufnr, _uninitialized = true }) == 0 end util.buf_versions[bufnr] = changedtick changetracking.send_changes(bufnr, firstline, lastline, new_lastline) -- cgit From 608543f8a90b08cbe84cea878a14f053789f45a4 Mon Sep 17 00:00:00 2001 From: Maria José Solano Date: Mon, 27 May 2024 08:18:10 -0700 Subject: fix(snippet): cancel snippet session when leaving the buffer (#29031) --- runtime/lua/vim/snippet.lua | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'runtime') diff --git a/runtime/lua/vim/snippet.lua b/runtime/lua/vim/snippet.lua index 3fd2555046..8e384e0f97 100644 --- a/runtime/lua/vim/snippet.lua +++ b/runtime/lua/vim/snippet.lua @@ -395,6 +395,15 @@ local function setup_autocmds(bufnr) end end, }) + + vim.api.nvim_create_autocmd('BufLeave', { + group = snippet_group, + desc = 'Stop the snippet session when leaving the buffer', + buffer = bufnr, + callback = function() + M.stop() + end, + }) end --- Expands the given snippet text. -- cgit From 6e8a728e3dad747d0c46dc47a530b76e8997bc08 Mon Sep 17 00:00:00 2001 From: dundargoc Date: Sat, 25 May 2024 20:35:37 +0200 Subject: refactor: fix luals type warnings --- runtime/lua/tohtml.lua | 4 +- runtime/lua/vim/_meta.lua | 2 + runtime/lua/vim/_meta/vimfn.lua | 2 +- runtime/lua/vim/deprecated/health.lua | 2 +- runtime/lua/vim/health.lua | 12 ++--- runtime/lua/vim/health/health.lua | 3 +- runtime/lua/vim/lsp/util.lua | 4 +- runtime/lua/vim/provider/health.lua | 82 +++++++++++++++++------------------ 8 files changed, 56 insertions(+), 55 deletions(-) (limited to 'runtime') diff --git a/runtime/lua/tohtml.lua b/runtime/lua/tohtml.lua index 5e145950b7..120247ed4e 100644 --- a/runtime/lua/tohtml.lua +++ b/runtime/lua/tohtml.lua @@ -65,9 +65,7 @@ local function notify(msg) if #notifications == 0 then vim.schedule(function() if #notifications > 1 then - vim.notify( - ('TOhtml: %s (+ %d more warnings)'):format(notifications[1], tostring(#notifications - 1)) - ) + vim.notify(('TOhtml: %s (+ %d more warnings)'):format(notifications[1], #notifications - 1)) elseif #notifications == 1 then vim.notify('TOhtml: ' .. notifications[1]) end diff --git a/runtime/lua/vim/_meta.lua b/runtime/lua/vim/_meta.lua index 731dd5b923..c9f207cb20 100644 --- a/runtime/lua/vim/_meta.lua +++ b/runtime/lua/vim/_meta.lua @@ -34,3 +34,5 @@ vim.uri_from_fname = uri.uri_from_fname vim.uri_from_bufnr = uri.uri_from_bufnr vim.uri_to_fname = uri.uri_to_fname vim.uri_to_bufnr = uri.uri_to_bufnr + +vim.provider = require('vim.provider') diff --git a/runtime/lua/vim/_meta/vimfn.lua b/runtime/lua/vim/_meta/vimfn.lua index f256f63768..84bb26a135 100644 --- a/runtime/lua/vim/_meta/vimfn.lua +++ b/runtime/lua/vim/_meta/vimfn.lua @@ -1642,7 +1642,7 @@ function vim.fn.execute(command, silent) end --- If {expr} starts with "./" the |current-directory| is used. --- --- @param expr any ---- @return any +--- @return string function vim.fn.exepath(expr) end --- The result is a Number, which is |TRUE| if {expr} is diff --git a/runtime/lua/vim/deprecated/health.lua b/runtime/lua/vim/deprecated/health.lua index 0f6b1f578c..64a755b248 100644 --- a/runtime/lua/vim/deprecated/health.lua +++ b/runtime/lua/vim/deprecated/health.lua @@ -1,7 +1,7 @@ local M = {} local health = vim.health -local deprecated = {} +local deprecated = {} ---@type {[1]: string, [2]: table, [3]: string}[] function M.check() if next(deprecated) == nil then diff --git a/runtime/lua/vim/health.lua b/runtime/lua/vim/health.lua index afeba2ee9d..236f9da752 100644 --- a/runtime/lua/vim/health.lua +++ b/runtime/lua/vim/health.lua @@ -104,10 +104,10 @@ local function filepath_to_healthcheck(path) local subpath = path:gsub('.*lua/', '') if vim.fs.basename(subpath) == 'health.lua' then -- */health.lua - name = assert(vim.fs.dirname(subpath)) + name = vim.fs.dirname(subpath) else -- */health/init.lua - name = assert(vim.fs.dirname(assert(vim.fs.dirname(subpath)))) + name = vim.fs.dirname(vim.fs.dirname(subpath)) end name = name:gsub('/', '.') @@ -301,11 +301,13 @@ end local PATTERNS = { '/autoload/health/*.vim', '/lua/**/**/health.lua', '/lua/**/**/health/init.lua' } --- :checkhealth completion function used by cmdexpand.c get_healthcheck_names() M._complete = function() - local unique = vim + local unique = vim ---@type table + ---@param pattern string .iter(vim.tbl_map(function(pattern) return vim.tbl_map(path2name, vim.api.nvim_get_runtime_file(pattern, true)) end, PATTERNS)) :flatten() + ---@param t table :fold({}, function(t, name) t[name] = true -- Remove duplicates return t @@ -364,7 +366,7 @@ function M._check(mods, plugin_names) vim.fn.call(func, {}) else local f = assert(loadstring(func)) - local ok, output = pcall(f) + local ok, output = pcall(f) ---@type boolean, string if not ok then M.error( string.format('Failed to run healthcheck for "%s" plugin. Exception:\n%s\n', name, output) @@ -391,7 +393,7 @@ function M._check(mods, plugin_names) end s_output[#s_output + 1] = '' s_output = vim.list_extend(header, s_output) - vim.fn.append('$', s_output) + vim.fn.append(vim.fn.line('$'), s_output) vim.cmd.redraw() end diff --git a/runtime/lua/vim/health/health.lua b/runtime/lua/vim/health/health.lua index 5bc03199ee..235dacb82a 100644 --- a/runtime/lua/vim/health/health.lua +++ b/runtime/lua/vim/health/health.lua @@ -239,6 +239,7 @@ local function check_tmux() return end + ---@param option string local get_tmux_option = function(option) local cmd = 'tmux show-option -qvg ' .. option -- try global scope local out = vim.fn.system(vim.fn.split(cmd)) @@ -378,7 +379,7 @@ local function check_terminal() 'SSH_TTY', }) do if vim.env[env_var] then - health.info(vim.fn.printf('$%s="%s"', env_var, vim.env[env_var])) + health.info(string.format('$%s="%s"', env_var, vim.env[env_var])) end end end diff --git a/runtime/lua/vim/lsp/util.lua b/runtime/lua/vim/lsp/util.lua index 5a229a1169..0099e82f52 100644 --- a/runtime/lua/vim/lsp/util.lua +++ b/runtime/lua/vim/lsp/util.lua @@ -616,7 +616,7 @@ function M.rename(old_fname, new_fname, opts) buf_rename[b] = { from = old_bname, to = new_bname } end - local newdir = assert(vim.fs.dirname(new_fname)) + local newdir = vim.fs.dirname(new_fname) vim.fn.mkdir(newdir, 'p') local ok, err = os.rename(old_fname_full, new_fname) @@ -625,7 +625,7 @@ function M.rename(old_fname, new_fname, opts) local old_undofile = vim.fn.undofile(old_fname_full) if uv.fs_stat(old_undofile) ~= nil then local new_undofile = vim.fn.undofile(new_fname) - vim.fn.mkdir(assert(vim.fs.dirname(new_undofile)), 'p') + vim.fn.mkdir(vim.fs.dirname(new_undofile), 'p') os.rename(old_undofile, new_undofile) end diff --git a/runtime/lua/vim/provider/health.lua b/runtime/lua/vim/provider/health.lua index d6932f651e..fa2c452268 100644 --- a/runtime/lua/vim/provider/health.lua +++ b/runtime/lua/vim/provider/health.lua @@ -95,10 +95,10 @@ local function system(cmd, args) error(emsg) end - -- return opts.output return vim.trim(vim.fn.system(cmd)), shell_error_code end +---@param provider string local function provider_disabled(provider) local loaded_var = 'loaded_' .. provider .. '_provider' local v = vim.g[loaded_var] @@ -126,9 +126,9 @@ local function clipboard() health.error('pbcopy does not work with tmux version: ' .. tmux_version, advice) end - local clipboard_tool = vim.fn['provider#clipboard#Executable']() + local clipboard_tool = vim.fn['provider#clipboard#Executable']() ---@type string if vim.g.clipboard ~= nil and clipboard_tool == '' then - local error_message = vim.fn['provider#clipboard#Error']() + local error_message = vim.fn['provider#clipboard#Error']() ---@type string health.error( error_message, "Use the example in :help g:clipboard as a template, or don't set g:clipboard at all." @@ -179,7 +179,7 @@ local function node() ) end - local node_detect_table = vim.fn['provider#node#Detect']() + local node_detect_table = vim.fn['provider#node#Detect']() ---@type string[] local host = node_detect_table[1] if host:find('^%s*$') then health.warn('Missing "neovim" npm (or yarn, pnpm) package.', { @@ -290,7 +290,7 @@ local function perl() elseif latest_cpan[1] == '!' then local cpanm_errs = vim.split(latest_cpan, '!') if cpanm_errs[1]:find("Can't write to ") then - local advice = {} + local advice = {} ---@type string[] for i = 2, #cpanm_errs do advice[#advice + 1] = cpanm_errs[i] end @@ -303,7 +303,7 @@ local function perl() return end end - latest_cpan = vim.fn.matchstr(latest_cpan, [[\(\.\?\d\)\+]]) + latest_cpan = tostring(vim.fn.matchstr(latest_cpan, [[\(\.\?\d\)\+]])) if latest_cpan:find('^%s*$') then health.error('Cannot parse version number from cpanm output: ' .. latest_cpan) return @@ -349,9 +349,11 @@ local function python_exepath(invocation) return vim.fs.normalize(vim.trim(p.stdout)) end --- Check if pyenv is available and a valid pyenv root can be found, then return --- their respective paths. If either of those is invalid, return two empty --- strings, effectively ignoring pyenv. +--- Check if pyenv is available and a valid pyenv root can be found, then return +--- their respective paths. If either of those is invalid, return two empty +--- strings, effectively ignoring pyenv. +--- +--- @return {[1]: string, [2]: string} local function check_for_pyenv() local pyenv_path = vim.fn.resolve(vim.fn.exepath('pyenv')) @@ -394,7 +396,9 @@ local function check_bin(bin) return true end --- Fetch the contents of a URL. +--- Fetch the contents of a URL. +--- +--- @param url string local function download(url) local has_curl = vim.fn.executable('curl') == 1 if has_curl and vim.fn.system({ 'curl', '-V' }):find('Protocols:.*https') then @@ -429,25 +433,24 @@ local function download(url) return message end --- Get the latest Nvim Python client (pynvim) version from PyPI. +--- Get the latest Nvim Python client (pynvim) version from PyPI. local function latest_pypi_version() local pypi_version = 'unable to get pypi response' local pypi_response = download('https://pypi.python.org/pypi/pynvim/json') if pypi_response ~= '' then local pcall_ok, output = pcall(vim.fn.json_decode, pypi_response) - local pypi_data - if pcall_ok then - pypi_data = output - else + if not pcall_ok then return 'error: ' .. pypi_response end + local pypi_data = output local pypi_element = pypi_data['info'] or {} pypi_version = pypi_element['version'] or 'unable to parse' end return pypi_version end +--- @param s string local function is_bad_response(s) local lower = s:lower() return vim.startswith(lower, 'unable') @@ -455,16 +458,18 @@ local function is_bad_response(s) or vim.startswith(lower, 'outdated') end --- Get version information using the specified interpreter. The interpreter is --- used directly in case breaking changes were introduced since the last time --- Nvim's Python client was updated. --- --- Returns: { --- {python executable version}, --- {current nvim version}, --- {current pypi nvim status}, --- {installed version status} --- } +--- Get version information using the specified interpreter. The interpreter is +--- used directly in case breaking changes were introduced since the last time +--- Nvim's Python client was updated. +--- +--- @param python string +--- +--- Returns: { +--- {python executable version}, +--- {current nvim version}, +--- {current pypi nvim status}, +--- {installed version status} +--- } local function version_info(python) local pypi_version = latest_pypi_version() @@ -512,9 +517,9 @@ local function version_info(python) if rc ~= 0 or nvim_version == '' then nvim_version = 'unable to find pynvim module version' local base = vim.fs.basename(nvim_path) - local metas = vim.fn.glob(base .. '-*/METADATA', 1, 1) - vim.list_extend(metas, vim.fn.glob(base .. '-*/PKG-INFO', 1, 1)) - vim.list_extend(metas, vim.fn.glob(base .. '.egg-info/PKG-INFO', 1, 1)) + local metas = vim.fn.glob(base .. '-*/METADATA', true, 1) + vim.list_extend(metas, vim.fn.glob(base .. '-*/PKG-INFO', true, 1)) + vim.list_extend(metas, vim.fn.glob(base .. '.egg-info/PKG-INFO', true, 1)) metas = table.sort(metas, compare) if metas and next(metas) ~= nil then @@ -544,14 +549,13 @@ end local function python() health.start('Python 3 provider (optional)') - local pyname = 'python3' ---@type string? local python_exe = '' local virtual_env = os.getenv('VIRTUAL_ENV') local venv = virtual_env and vim.fn.resolve(virtual_env) or '' - local host_prog_var = pyname .. '_host_prog' - local python_multiple = {} + local host_prog_var = 'python3_host_prog' + local python_multiple = {} ---@type string[] - if provider_disabled(pyname) then + if provider_disabled('python3') then return end @@ -564,8 +568,7 @@ local function python() health.info(message) end - local pythonx_warnings - pyname, pythonx_warnings = vim.provider.python.detect_by_module('neovim') + local pyname, pythonx_warnings = vim.provider.python.detect_by_module('neovim') if not pyname then health.warn( @@ -653,12 +656,7 @@ local function python() ) health.warn('pyenv is not set up optimally.', advice) elseif venv ~= '' then - local venv_root - if pyenv_root ~= '' then - venv_root = pyenv_root - else - venv_root = vim.fs.dirname(venv) - end + local venv_root = pyenv_root ~= '' and pyenv_root or vim.fs.dirname(venv) if vim.startswith(vim.fn.resolve(python_exe), venv_root .. '/') then local advice = string.format( @@ -743,9 +741,9 @@ local function python() health.ok('no $VIRTUAL_ENV') return end - local errors = {} + local errors = {} ---@type string[] -- Keep hints as dict keys in order to discard duplicates. - local hints = {} + local hints = {} ---@type table -- The virtualenv should contain some Python executables, and those -- executables should be first both on Nvim's $PATH and the $PATH of -- subshells launched from Nvim. -- cgit From ff097f2091e7a970e5b12960683b4dade5563040 Mon Sep 17 00:00:00 2001 From: Maria José Solano Date: Sun, 4 Feb 2024 14:13:23 -0800 Subject: feat(lsp): completion side effects --- runtime/doc/lsp.txt | 26 ++ runtime/doc/news.txt | 3 +- runtime/lua/vim/lsp.lua | 5 +- runtime/lua/vim/lsp/_completion.lua | 276 -------------- runtime/lua/vim/lsp/client.lua | 23 +- runtime/lua/vim/lsp/completion.lua | 734 ++++++++++++++++++++++++++++++++++++ runtime/lua/vim/lsp/handlers.lua | 2 +- runtime/lua/vim/lsp/protocol.lua | 10 +- 8 files changed, 785 insertions(+), 294 deletions(-) delete mode 100644 runtime/lua/vim/lsp/_completion.lua create mode 100644 runtime/lua/vim/lsp/completion.lua (limited to 'runtime') diff --git a/runtime/doc/lsp.txt b/runtime/doc/lsp.txt index 50fffca497..0e165e6f54 100644 --- a/runtime/doc/lsp.txt +++ b/runtime/doc/lsp.txt @@ -1604,6 +1604,32 @@ save({lenses}, {bufnr}, {client_id}) *vim.lsp.codelens.save()* • {client_id} (`integer`) +============================================================================== +Lua module: vim.lsp.completion *lsp-completion* + +*vim.lsp.completion.BufferOpts* + + Fields: ~ + • {autotrigger}? (`boolean`) Whether to trigger completion + automatically. Default: false + + + *vim.lsp.completion.enable()* +enable({enable}, {client_id}, {bufnr}, {opts}) + Enables or disables completions from the given language client in the + given buffer. + + Parameters: ~ + • {enable} (`boolean`) True to enable, false to disable + • {client_id} (`integer`) Client ID + • {bufnr} (`integer`) Buffer handle, or 0 for the current buffer + • {opts} (`vim.lsp.completion.BufferOpts?`) See + |vim.lsp.completion.BufferOpts|. + +trigger() *vim.lsp.completion.trigger()* + Trigger LSP completion in the current buffer. + + ============================================================================== Lua module: vim.lsp.inlay_hint *lsp-inlay_hint* diff --git a/runtime/doc/news.txt b/runtime/doc/news.txt index 708e127136..439316f62e 100644 --- a/runtime/doc/news.txt +++ b/runtime/doc/news.txt @@ -95,7 +95,8 @@ EVENTS LSP -• TODO +• Completion side effects (including snippet expansion, execution of commands + and application of additional text edits) is now built-in. LUA diff --git a/runtime/lua/vim/lsp.lua b/runtime/lua/vim/lsp.lua index 1592fd3151..da3d4d91f2 100644 --- a/runtime/lua/vim/lsp.lua +++ b/runtime/lua/vim/lsp.lua @@ -3,7 +3,6 @@ local validate = vim.validate local lsp = vim._defer_require('vim.lsp', { _changetracking = ..., --- @module 'vim.lsp._changetracking' - _completion = ..., --- @module 'vim.lsp._completion' _dynamic = ..., --- @module 'vim.lsp._dynamic' _snippet_grammar = ..., --- @module 'vim.lsp._snippet_grammar' _tagfunc = ..., --- @module 'vim.lsp._tagfunc' @@ -11,6 +10,7 @@ local lsp = vim._defer_require('vim.lsp', { buf = ..., --- @module 'vim.lsp.buf' client = ..., --- @module 'vim.lsp.client' codelens = ..., --- @module 'vim.lsp.codelens' + completion = ..., --- @module 'vim.lsp.completion' diagnostic = ..., --- @module 'vim.lsp.diagnostic' handlers = ..., --- @module 'vim.lsp.handlers' inlay_hint = ..., --- @module 'vim.lsp.inlay_hint' @@ -1002,8 +1002,7 @@ end --- - findstart=0: column where the completion starts, or -2 or -3 --- - findstart=1: list of matches (actually just calls |complete()|) function lsp.omnifunc(findstart, base) - log.debug('omnifunc.findstart', { findstart = findstart, base = base }) - return vim.lsp._completion.omnifunc(findstart, base) + return vim.lsp.completion._omnifunc(findstart, base) end --- @class vim.lsp.formatexpr.Opts diff --git a/runtime/lua/vim/lsp/_completion.lua b/runtime/lua/vim/lsp/_completion.lua deleted file mode 100644 index a169f96565..0000000000 --- a/runtime/lua/vim/lsp/_completion.lua +++ /dev/null @@ -1,276 +0,0 @@ -local M = {} -local api = vim.api -local lsp = vim.lsp -local protocol = lsp.protocol -local ms = protocol.Methods - ---- @alias vim.lsp.CompletionResult lsp.CompletionList | lsp.CompletionItem[] - --- TODO(mariasolos): Remove this declaration once we figure out a better way to handle --- literal/anonymous types (see https://github.com/neovim/neovim/pull/27542/files#r1495259331). ---- @class lsp.ItemDefaults ---- @field editRange lsp.Range | { insert: lsp.Range, replace: lsp.Range } | nil ---- @field insertTextFormat lsp.InsertTextFormat? ---- @field insertTextMode lsp.InsertTextMode? ---- @field data any - ----@param input string unparsed snippet ----@return string parsed snippet -local function parse_snippet(input) - local ok, parsed = pcall(function() - return vim.lsp._snippet_grammar.parse(input) - end) - return ok and tostring(parsed) or input -end - ---- Returns text that should be inserted when selecting completion item. The ---- precedence is as follows: textEdit.newText > insertText > label ---- ---- See https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_completion ---- ----@param item lsp.CompletionItem ----@return string -local function get_completion_word(item) - if item.textEdit ~= nil and item.textEdit.newText ~= nil and item.textEdit.newText ~= '' then - if item.insertTextFormat == protocol.InsertTextFormat.PlainText then - return item.textEdit.newText - else - return parse_snippet(item.textEdit.newText) - end - elseif item.insertText ~= nil and item.insertText ~= '' then - if item.insertTextFormat == protocol.InsertTextFormat.PlainText then - return item.insertText - else - return parse_snippet(item.insertText) - end - end - return item.label -end - ---- Applies the given defaults to the completion item, modifying it in place. ---- ---- @param item lsp.CompletionItem ---- @param defaults lsp.ItemDefaults? -local function apply_defaults(item, defaults) - if not defaults then - return - end - - item.insertTextFormat = item.insertTextFormat or defaults.insertTextFormat - item.insertTextMode = item.insertTextMode or defaults.insertTextMode - item.data = item.data or defaults.data - if defaults.editRange then - local textEdit = item.textEdit or {} - item.textEdit = textEdit - textEdit.newText = textEdit.newText or item.textEditText or item.insertText - if defaults.editRange.start then - textEdit.range = textEdit.range or defaults.editRange - elseif defaults.editRange.insert then - textEdit.insert = defaults.editRange.insert - textEdit.replace = defaults.editRange.replace - end - end -end - ----@param result vim.lsp.CompletionResult ----@return lsp.CompletionItem[] -local function get_items(result) - if result.items then - for _, item in ipairs(result.items) do - ---@diagnostic disable-next-line: param-type-mismatch - apply_defaults(item, result.itemDefaults) - end - return result.items - else - return result - end -end - ---- Turns the result of a `textDocument/completion` request into vim-compatible ---- |complete-items|. ---- ----@param result vim.lsp.CompletionResult Result of `textDocument/completion` ----@param prefix string prefix to filter the completion items ----@return table[] ----@see complete-items -function M._lsp_to_complete_items(result, prefix) - local items = get_items(result) - if vim.tbl_isempty(items) then - return {} - end - - local function matches_prefix(item) - return vim.startswith(get_completion_word(item), prefix) - end - - items = vim.tbl_filter(matches_prefix, items) --[[@as lsp.CompletionItem[]|]] - table.sort(items, function(a, b) - return (a.sortText or a.label) < (b.sortText or b.label) - end) - - local matches = {} - for _, item in ipairs(items) do - local info = '' - local documentation = item.documentation - if documentation then - if type(documentation) == 'string' and documentation ~= '' then - info = documentation - elseif type(documentation) == 'table' and type(documentation.value) == 'string' then - info = documentation.value - else - vim.notify( - ('invalid documentation value %s'):format(vim.inspect(documentation)), - vim.log.levels.WARN - ) - end - end - local word = get_completion_word(item) - table.insert(matches, { - word = word, - abbr = item.label, - kind = protocol.CompletionItemKind[item.kind] or 'Unknown', - menu = item.detail or '', - info = #info > 0 and info or nil, - icase = 1, - dup = 1, - empty = 1, - user_data = { - nvim = { - lsp = { - completion_item = item, - }, - }, - }, - }) - end - return matches -end - ----@param lnum integer 0-indexed ----@param items lsp.CompletionItem[] -local function adjust_start_col(lnum, line, items, encoding) - local min_start_char = nil - for _, item in pairs(items) do - if item.textEdit and item.textEdit.range.start.line == lnum then - if min_start_char and min_start_char ~= item.textEdit.range.start.character then - return nil - end - min_start_char = item.textEdit.range.start.character - end - end - if min_start_char then - return vim.lsp.util._str_byteindex_enc(line, min_start_char, encoding) - else - return nil - end -end - ----@private ----@param line string line content ----@param lnum integer 0-indexed line number ----@param client_start_boundary integer 0-indexed word boundary ----@param server_start_boundary? integer 0-indexed word boundary, based on textEdit.range.start.character ----@param result vim.lsp.CompletionResult ----@param encoding string ----@return table[] matches ----@return integer? server_start_boundary -function M._convert_results( - line, - lnum, - cursor_col, - client_start_boundary, - server_start_boundary, - result, - encoding -) - -- Completion response items may be relative to a position different than `client_start_boundary`. - -- Concrete example, with lua-language-server: - -- - -- require('plenary.asy| - -- ▲ ▲ ▲ - -- │ │ └── cursor_pos: 20 - -- │ └────── client_start_boundary: 17 - -- └────────────── textEdit.range.start.character: 9 - -- .newText = 'plenary.async' - -- ^^^ - -- prefix (We'd remove everything not starting with `asy`, - -- so we'd eliminate the `plenary.async` result - -- - -- `adjust_start_col` is used to prefer the language server boundary. - -- - local candidates = get_items(result) - local curstartbyte = adjust_start_col(lnum, line, candidates, encoding) - if server_start_boundary == nil then - server_start_boundary = curstartbyte - elseif curstartbyte ~= nil and curstartbyte ~= server_start_boundary then - server_start_boundary = client_start_boundary - end - local prefix = line:sub((server_start_boundary or client_start_boundary) + 1, cursor_col) - local matches = M._lsp_to_complete_items(result, prefix) - return matches, server_start_boundary -end - ----@param findstart integer 0 or 1, decides behavior ----@param base integer findstart=0, text to match against ----@return integer|table Decided by {findstart}: ---- - findstart=0: column where the completion starts, or -2 or -3 ---- - findstart=1: list of matches (actually just calls |complete()|) -function M.omnifunc(findstart, base) - assert(base) -- silence luals - local bufnr = api.nvim_get_current_buf() - local clients = lsp.get_clients({ bufnr = bufnr, method = ms.textDocument_completion }) - local remaining = #clients - if remaining == 0 then - return findstart == 1 and -1 or {} - end - - local win = api.nvim_get_current_win() - local cursor = api.nvim_win_get_cursor(win) - local lnum = cursor[1] - 1 - local cursor_col = cursor[2] - local line = api.nvim_get_current_line() - local line_to_cursor = line:sub(1, cursor_col) - local client_start_boundary = vim.fn.match(line_to_cursor, '\\k*$') --[[@as integer]] - local server_start_boundary = nil - local items = {} - - local function on_done() - local mode = api.nvim_get_mode()['mode'] - if mode == 'i' or mode == 'ic' then - vim.fn.complete((server_start_boundary or client_start_boundary) + 1, items) - end - end - - local util = vim.lsp.util - for _, client in ipairs(clients) do - local params = util.make_position_params(win, client.offset_encoding) - client.request(ms.textDocument_completion, params, function(err, result) - if err then - vim.lsp.log.warn(err.message) - end - if result and vim.fn.mode() == 'i' then - local matches - matches, server_start_boundary = M._convert_results( - line, - lnum, - cursor_col, - client_start_boundary, - server_start_boundary, - result, - client.offset_encoding - ) - vim.list_extend(items, matches) - end - remaining = remaining - 1 - if remaining == 0 then - vim.schedule(on_done) - end - end, bufnr) - end - - -- Return -2 to signal that we should continue completion so that we can - -- async complete. - return -2 -end - -return M diff --git a/runtime/lua/vim/lsp/client.lua b/runtime/lua/vim/lsp/client.lua index 4beb7fefda..c8616bf728 100644 --- a/runtime/lua/vim/lsp/client.lua +++ b/runtime/lua/vim/lsp/client.lua @@ -869,7 +869,8 @@ end --- @param command lsp.Command --- @param context? {bufnr: integer} --- @param handler? lsp.Handler only called if a server command -function Client:_exec_cmd(command, context, handler) +--- @param on_unsupported? function handler invoked when the command is not supported by the client. +function Client:_exec_cmd(command, context, handler, on_unsupported) context = vim.deepcopy(context or {}, true) --[[@as lsp.HandlerContext]] context.bufnr = context.bufnr or api.nvim_get_current_buf() context.client_id = self.id @@ -883,14 +884,18 @@ function Client:_exec_cmd(command, context, handler) local command_provider = self.server_capabilities.executeCommandProvider local commands = type(command_provider) == 'table' and command_provider.commands or {} if not vim.list_contains(commands, cmdname) then - vim.notify_once( - string.format( - 'Language server `%s` does not support command `%s`. This command may require a client extension.', - self.name, - cmdname - ), - vim.log.levels.WARN - ) + if on_unsupported then + on_unsupported() + else + vim.notify_once( + string.format( + 'Language server `%s` does not support command `%s`. This command may require a client extension.', + self.name, + cmdname + ), + vim.log.levels.WARN + ) + end return end -- Not using command directly to exclude extra properties, diff --git a/runtime/lua/vim/lsp/completion.lua b/runtime/lua/vim/lsp/completion.lua new file mode 100644 index 0000000000..25b3d53c8c --- /dev/null +++ b/runtime/lua/vim/lsp/completion.lua @@ -0,0 +1,734 @@ +local M = {} + +local api = vim.api +local lsp = vim.lsp +local protocol = lsp.protocol +local ms = protocol.Methods + +local rtt_ms = 50 +local ns_to_ms = 0.000001 + +--- @alias vim.lsp.CompletionResult lsp.CompletionList | lsp.CompletionItem[] + +-- TODO(mariasolos): Remove this declaration once we figure out a better way to handle +-- literal/anonymous types (see https://github.com/neovim/neovim/pull/27542/files#r1495259331). +--- @nodoc +--- @class lsp.ItemDefaults +--- @field editRange lsp.Range | { insert: lsp.Range, replace: lsp.Range } | nil +--- @field insertTextFormat lsp.InsertTextFormat? +--- @field insertTextMode lsp.InsertTextMode? +--- @field data any + +--- @nodoc +--- @class vim.lsp.completion.BufHandle +--- @field clients table +--- @field triggers table + +--- @type table +local buf_handles = {} + +--- @nodoc +--- @class vim.lsp.completion.Context +local Context = { + cursor = nil, --- @type { [1]: integer, [2]: integer }? + last_request_time = nil, --- @type integer? + pending_requests = {}, --- @type function[] + isIncomplete = false, +} + +--- @nodoc +function Context:cancel_pending() + for _, cancel in ipairs(self.pending_requests) do + cancel() + end + + self.pending_requests = {} +end + +--- @nodoc +function Context:reset() + -- Note that the cursor isn't reset here, it needs to survive a `CompleteDone` event. + self.isIncomplete = false + self.last_request_time = nil + self:cancel_pending() +end + +--- @type uv.uv_timer_t? +local completion_timer = nil + +--- @return uv.uv_timer_t +local function new_timer() + return assert(vim.uv.new_timer()) +end + +local function reset_timer() + if completion_timer then + completion_timer:stop() + completion_timer:close() + end + + completion_timer = nil +end + +--- @param window integer +--- @param warmup integer +--- @return fun(sample: number): number +local function exp_avg(window, warmup) + local count = 0 + local sum = 0 + local value = 0 + + return function(sample) + if count < warmup then + count = count + 1 + sum = sum + sample + value = sum / count + else + local factor = 2.0 / (window + 1) + value = value * (1 - factor) + sample * factor + end + return value + end +end +local compute_new_average = exp_avg(10, 10) + +--- @return number +local function next_debounce() + if not Context.last_request_time then + return rtt_ms + end + + local ms_since_request = (vim.uv.hrtime() - Context.last_request_time) * ns_to_ms + return math.max((ms_since_request - rtt_ms) * -1, 0) +end + +--- @param input string Unparsed snippet +--- @return string # Parsed snippet if successful, else returns its input +local function parse_snippet(input) + local ok, parsed = pcall(function() + return lsp._snippet_grammar.parse(input) + end) + return ok and tostring(parsed) or input +end + +--- @param item lsp.CompletionItem +--- @param suffix? string +local function apply_snippet(item, suffix) + if item.textEdit then + vim.snippet.expand(item.textEdit.newText .. suffix) + elseif item.insertText then + vim.snippet.expand(item.insertText .. suffix) + end +end + +--- Returns text that should be inserted when a selecting completion item. The +--- precedence is as follows: textEdit.newText > insertText > label +--- +--- See https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_completion +--- +--- @param item lsp.CompletionItem +--- @return string +local function get_completion_word(item) + if item.textEdit ~= nil and item.textEdit.newText ~= nil and item.textEdit.newText ~= '' then + if item.insertTextFormat == protocol.InsertTextFormat.PlainText then + return item.textEdit.newText + else + return parse_snippet(item.textEdit.newText) + end + elseif item.insertText ~= nil and item.insertText ~= '' then + if item.insertTextFormat == protocol.InsertTextFormat.PlainText then + return item.insertText + else + return parse_snippet(item.insertText) + end + end + return item.label +end + +--- Applies the given defaults to the completion item, modifying it in place. +--- +--- @param item lsp.CompletionItem +--- @param defaults lsp.ItemDefaults? +local function apply_defaults(item, defaults) + if not defaults then + return + end + + item.insertTextFormat = item.insertTextFormat or defaults.insertTextFormat + item.insertTextMode = item.insertTextMode or defaults.insertTextMode + item.data = item.data or defaults.data + if defaults.editRange then + local textEdit = item.textEdit or {} + item.textEdit = textEdit + textEdit.newText = textEdit.newText or item.textEditText or item.insertText + if defaults.editRange.start then + textEdit.range = textEdit.range or defaults.editRange + elseif defaults.editRange.insert then + textEdit.insert = defaults.editRange.insert + textEdit.replace = defaults.editRange.replace + end + end +end + +--- @param result vim.lsp.CompletionResult +--- @return lsp.CompletionItem[] +local function get_items(result) + if result.items then + -- When we have a list, apply the defaults and return an array of items. + for _, item in ipairs(result.items) do + ---@diagnostic disable-next-line: param-type-mismatch + apply_defaults(item, result.itemDefaults) + end + return result.items + else + -- Else just return the items as they are. + return result + end +end + +--- Turns the result of a `textDocument/completion` request into vim-compatible +--- |complete-items|. +--- +--- @private +--- @param result vim.lsp.CompletionResult Result of `textDocument/completion` +--- @param prefix string prefix to filter the completion items +--- @param client_id integer? Client ID +--- @return table[] +--- @see complete-items +function M._lsp_to_complete_items(result, prefix, client_id) + local items = get_items(result) + if vim.tbl_isempty(items) then + return {} + end + + local function matches_prefix(item) + return vim.startswith(get_completion_word(item), prefix) + end + + items = vim.tbl_filter(matches_prefix, items) --[[@as lsp.CompletionItem[]|]] + table.sort(items, function(a, b) + return (a.sortText or a.label) < (b.sortText or b.label) + end) + + local matches = {} + for _, item in ipairs(items) do + local info = '' + local documentation = item.documentation + if documentation then + if type(documentation) == 'string' and documentation ~= '' then + info = documentation + elseif type(documentation) == 'table' and type(documentation.value) == 'string' then + info = documentation.value + else + vim.notify( + ('invalid documentation value %s'):format(vim.inspect(documentation)), + vim.log.levels.WARN + ) + end + end + local word = get_completion_word(item) + table.insert(matches, { + word = word, + abbr = item.label, + kind = protocol.CompletionItemKind[item.kind] or 'Unknown', + menu = item.detail or '', + info = #info > 0 and info or '', + icase = 1, + dup = 1, + empty = 1, + user_data = { + nvim = { + lsp = { + completion_item = item, + client_id = client_id, + }, + }, + }, + }) + end + return matches +end + +--- @param lnum integer 0-indexed +--- @param line string +--- @param items lsp.CompletionItem[] +--- @param encoding string +--- @return integer? +local function adjust_start_col(lnum, line, items, encoding) + local min_start_char = nil + for _, item in pairs(items) do + if item.textEdit and item.textEdit.range.start.line == lnum then + if min_start_char and min_start_char ~= item.textEdit.range.start.character then + return nil + end + min_start_char = item.textEdit.range.start.character + end + end + if min_start_char then + return lsp.util._str_byteindex_enc(line, min_start_char, encoding) + else + return nil + end +end + +--- @private +--- @param line string line content +--- @param lnum integer 0-indexed line number +--- @param cursor_col integer +--- @param client_id integer client ID +--- @param client_start_boundary integer 0-indexed word boundary +--- @param server_start_boundary? integer 0-indexed word boundary, based on textEdit.range.start.character +--- @param result vim.lsp.CompletionResult +--- @param encoding string +--- @return table[] matches +--- @return integer? server_start_boundary +function M._convert_results( + line, + lnum, + cursor_col, + client_id, + client_start_boundary, + server_start_boundary, + result, + encoding +) + -- Completion response items may be relative to a position different than `client_start_boundary`. + -- Concrete example, with lua-language-server: + -- + -- require('plenary.asy| + -- ▲ ▲ ▲ + -- │ │ └── cursor_pos: 20 + -- │ └────── client_start_boundary: 17 + -- └────────────── textEdit.range.start.character: 9 + -- .newText = 'plenary.async' + -- ^^^ + -- prefix (We'd remove everything not starting with `asy`, + -- so we'd eliminate the `plenary.async` result + -- + -- `adjust_start_col` is used to prefer the language server boundary. + -- + local candidates = get_items(result) + local curstartbyte = adjust_start_col(lnum, line, candidates, encoding) + if server_start_boundary == nil then + server_start_boundary = curstartbyte + elseif curstartbyte ~= nil and curstartbyte ~= server_start_boundary then + server_start_boundary = client_start_boundary + end + local prefix = line:sub((server_start_boundary or client_start_boundary) + 1, cursor_col) + local matches = M._lsp_to_complete_items(result, prefix, client_id) + return matches, server_start_boundary +end + +--- Implements 'omnifunc' compatible LSP completion. +--- +--- @see |complete-functions| +--- @see |complete-items| +--- @see |CompleteDone| +--- +--- @param findstart integer 0 or 1, decides behavior +--- @param base integer findstart=0, text to match against +--- +--- @return integer|table Decided by {findstart}: +--- - findstart=0: column where the completion starts, or -2 or -3 +--- - findstart=1: list of matches (actually just calls |complete()|) +function M._omnifunc(findstart, base) + vim.lsp.log.debug('omnifunc.findstart', { findstart = findstart, base = base }) + assert(base) -- silence luals + local bufnr = api.nvim_get_current_buf() + local clients = lsp.get_clients({ bufnr = bufnr, method = ms.textDocument_completion }) + local remaining = #clients + if remaining == 0 then + return findstart == 1 and -1 or {} + end + + local win = api.nvim_get_current_win() + local cursor = api.nvim_win_get_cursor(win) + local lnum = cursor[1] - 1 + local cursor_col = cursor[2] + local line = api.nvim_get_current_line() + local line_to_cursor = line:sub(1, cursor_col) + local client_start_boundary = vim.fn.match(line_to_cursor, '\\k*$') --[[@as integer]] + local server_start_boundary = nil + local items = {} + + local function on_done() + local mode = api.nvim_get_mode()['mode'] + if mode == 'i' or mode == 'ic' then + vim.fn.complete((server_start_boundary or client_start_boundary) + 1, items) + end + end + + local util = vim.lsp.util + for _, client in ipairs(clients) do + local params = util.make_position_params(win, client.offset_encoding) + client.request(ms.textDocument_completion, params, function(err, result) + if err then + lsp.log.warn(err.message) + end + if result and vim.fn.mode() == 'i' then + local matches + matches, server_start_boundary = M._convert_results( + line, + lnum, + cursor_col, + client.id, + client_start_boundary, + server_start_boundary, + result, + client.offset_encoding + ) + vim.list_extend(items, matches) + end + remaining = remaining - 1 + if remaining == 0 then + vim.schedule(on_done) + end + end, bufnr) + end + + -- Return -2 to signal that we should continue completion so that we can + -- async complete. + return -2 +end + +--- @param clients table +--- @param bufnr integer +--- @param win integer +--- @param callback fun(responses: table) +--- @return function # Cancellation function +local function request(clients, bufnr, win, callback) + local responses = {} --- @type table + local request_ids = {} --- @type table + local remaining_requests = vim.tbl_count(clients) + + for client_id, client in pairs(clients) do + local params = lsp.util.make_position_params(win, client.offset_encoding) + local ok, request_id = client.request(ms.textDocument_completion, params, function(err, result) + responses[client_id] = { err = err, result = result } + remaining_requests = remaining_requests - 1 + if remaining_requests == 0 then + callback(responses) + end + end, bufnr) + + if ok then + request_ids[client_id] = request_id + end + end + + return function() + for client_id, request_id in pairs(request_ids) do + local client = lsp.get_client_by_id(client_id) + if client then + client.cancel_request(request_id) + end + end + end +end + +--- @param handle vim.lsp.completion.BufHandle +local function on_insert_char_pre(handle) + if tonumber(vim.fn.pumvisible()) == 1 then + if Context.isIncomplete then + reset_timer() + + local debounce_ms = next_debounce() + if debounce_ms == 0 then + vim.schedule(M.trigger) + else + completion_timer = new_timer() + completion_timer:start(debounce_ms, 0, vim.schedule_wrap(M.trigger)) + end + end + + return + end + + local char = api.nvim_get_vvar('char') + if not completion_timer and handle.triggers[char] then + completion_timer = assert(vim.uv.new_timer()) + completion_timer:start(25, 0, function() + reset_timer() + vim.schedule(M.trigger) + end) + end +end + +local function on_insert_leave() + reset_timer() + Context.cursor = nil + Context:reset() +end + +local function on_complete_done() + local completed_item = api.nvim_get_vvar('completed_item') + if not completed_item or not completed_item.user_data or not completed_item.user_data.nvim then + Context:reset() + return + end + + local cursor_row, cursor_col = unpack(api.nvim_win_get_cursor(0)) --- @type integer, integer + cursor_row = cursor_row - 1 + local completion_item = completed_item.user_data.nvim.lsp.completion_item --- @type lsp.CompletionItem + local client_id = completed_item.user_data.nvim.lsp.client_id --- @type integer + if not completion_item or not client_id then + Context:reset() + return + end + + local bufnr = api.nvim_get_current_buf() + local expand_snippet = completion_item.insertTextFormat == protocol.InsertTextFormat.Snippet + and (completion_item.textEdit ~= nil or completion_item.insertText ~= nil) + + Context:reset() + + local client = lsp.get_client_by_id(client_id) + if not client then + return + end + + local offset_encoding = client.offset_encoding or 'utf-16' + local resolve_provider = (client.server_capabilities.completionProvider or {}).resolveProvider + + local function clear_word() + if not expand_snippet then + return nil + end + + -- Remove the already inserted word. + local start_char = cursor_col - #completed_item.word + local line = api.nvim_buf_get_lines(bufnr, cursor_row, cursor_row + 1, true)[1] + api.nvim_buf_set_text(bufnr, cursor_row, start_char, cursor_row, #line, { '' }) + return line:sub(cursor_col + 1) + end + + --- @param suffix? string + local function apply_snippet_and_command(suffix) + if expand_snippet then + apply_snippet(completion_item, suffix) + end + + local command = completion_item.command + if command then + client:_exec_cmd(command, { bufnr = bufnr }, nil, function() + vim.lsp.log.warn( + string.format( + 'Language server `%s` does not support command `%s`. This command may require a client extension.', + client.name, + command.command + ) + ) + end) + end + end + + if completion_item.additionalTextEdits and next(completion_item.additionalTextEdits) then + local suffix = clear_word() + lsp.util.apply_text_edits(completion_item.additionalTextEdits, bufnr, offset_encoding) + apply_snippet_and_command(suffix) + elseif resolve_provider and type(completion_item) == 'table' then + local changedtick = vim.b[bufnr].changedtick + + --- @param result lsp.CompletionItem + client.request(ms.completionItem_resolve, completion_item, function(err, result) + if changedtick ~= vim.b[bufnr].changedtick then + return + end + + local suffix = clear_word() + if err then + vim.notify_once(err.message, vim.log.levels.WARN) + elseif result and result.additionalTextEdits then + lsp.util.apply_text_edits(result.additionalTextEdits, bufnr, offset_encoding) + if result.command then + completion_item.command = result.command + end + end + + apply_snippet_and_command(suffix) + end, bufnr) + else + local suffix = clear_word() + apply_snippet_and_command(suffix) + end +end + +--- @class vim.lsp.completion.BufferOpts +--- @field autotrigger? boolean Whether to trigger completion automatically. Default: false + +--- @param client_id integer +---@param bufnr integer +---@param opts vim.lsp.completion.BufferOpts +local function enable_completions(client_id, bufnr, opts) + if not buf_handles[bufnr] then + buf_handles[bufnr] = { clients = {}, triggers = {} } + + -- Attach to buffer events. + api.nvim_buf_attach(bufnr, false, { + on_detach = function(_, buf) + buf_handles[buf] = nil + end, + on_reload = function(_, buf) + M.enable(true, client_id, buf, opts) + end, + }) + + -- Set up autocommands. + local group = + api.nvim_create_augroup(string.format('vim/lsp/completion-%d', bufnr), { clear = true }) + api.nvim_create_autocmd('CompleteDone', { + group = group, + buffer = bufnr, + callback = function() + local reason = api.nvim_get_vvar('event').reason --- @type string + if reason == 'accept' then + on_complete_done() + end + end, + }) + if opts.autotrigger then + api.nvim_create_autocmd('InsertCharPre', { + group = group, + buffer = bufnr, + callback = function() + on_insert_char_pre(buf_handles[bufnr]) + end, + }) + api.nvim_create_autocmd('InsertLeave', { + group = group, + buffer = bufnr, + callback = on_insert_leave, + }) + end + end + + if not buf_handles[bufnr].clients[client_id] then + local client = lsp.get_client_by_id(client_id) + assert(client, 'invalid client ID') + + -- Add the new client to the buffer's clients. + buf_handles[bufnr].clients[client_id] = client + + -- Add the new client to the clients that should be triggered by its trigger characters. + --- @type string[] + local triggers = vim.tbl_get( + client.server_capabilities, + 'completionProvider', + 'triggerCharacters' + ) or {} + for _, char in ipairs(triggers) do + local clients_for_trigger = buf_handles[bufnr].triggers[char] + if not clients_for_trigger then + clients_for_trigger = {} + buf_handles[bufnr].triggers[char] = clients_for_trigger + end + local client_exists = vim.iter(clients_for_trigger):any(function(c) + return c.id == client_id + end) + if not client_exists then + table.insert(clients_for_trigger, client) + end + end + end +end + +--- @param client_id integer +--- @param bufnr integer +local function disable_completions(client_id, bufnr) + local handle = buf_handles[bufnr] + if not handle then + return + end + + handle.clients[client_id] = nil + if not next(handle.clients) then + buf_handles[bufnr] = nil + api.nvim_del_augroup_by_name(string.format('vim/lsp/completion-%d', bufnr)) + else + for char, clients in pairs(handle.triggers) do + --- @param c vim.lsp.Client + handle.triggers[char] = vim.tbl_filter(function(c) + return c.id ~= client_id + end, clients) + end + end +end + +--- Enables or disables completions from the given language client in the given buffer. +--- +--- @param enable boolean True to enable, false to disable +--- @param client_id integer Client ID +--- @param bufnr integer Buffer handle, or 0 for the current buffer +--- @param opts? vim.lsp.completion.BufferOpts +function M.enable(enable, client_id, bufnr, opts) + bufnr = (bufnr == 0 and api.nvim_get_current_buf()) or bufnr + + if enable then + enable_completions(client_id, bufnr, opts or {}) + else + disable_completions(client_id, bufnr) + end +end + +--- Trigger LSP completion in the current buffer. +function M.trigger() + reset_timer() + Context:cancel_pending() + + local win = api.nvim_get_current_win() + local bufnr = api.nvim_get_current_buf() + local cursor_row, cursor_col = unpack(api.nvim_win_get_cursor(win)) --- @type integer, integer + local line = api.nvim_get_current_line() + local line_to_cursor = line:sub(1, cursor_col) + local clients = (buf_handles[bufnr] or {}).clients or {} + local word_boundary = vim.fn.match(line_to_cursor, '\\k*$') + local start_time = vim.uv.hrtime() + Context.last_request_time = start_time + + local cancel_request = request(clients, bufnr, win, function(responses) + local end_time = vim.uv.hrtime() + rtt_ms = compute_new_average((end_time - start_time) * ns_to_ms) + + Context.pending_requests = {} + Context.isIncomplete = false + + local row_changed = api.nvim_win_get_cursor(win)[1] ~= cursor_row + local mode = api.nvim_get_mode().mode + if row_changed or not (mode == 'i' or mode == 'ic') then + return + end + + local matches = {} + local server_start_boundary --- @type integer? + for client_id, response in pairs(responses) do + if response.err then + vim.notify_once(response.err.message, vim.log.levels.warn) + end + + local result = response.result + if result then + Context.isIncomplete = Context.isIncomplete or result.isIncomplete + local client = lsp.get_client_by_id(client_id) + local encoding = client and client.offset_encoding or 'utf-16' + local client_matches + client_matches, server_start_boundary = M._convert_results( + line, + cursor_row - 1, + cursor_col, + client_id, + word_boundary, + nil, + result, + encoding + ) + vim.list_extend(matches, client_matches) + end + end + local start_col = (server_start_boundary or word_boundary) + 1 + vim.fn.complete(start_col, matches) + end) + + table.insert(Context.pending_requests, cancel_request) +end + +return M diff --git a/runtime/lua/vim/lsp/handlers.lua b/runtime/lua/vim/lsp/handlers.lua index f9d394642c..38c43893eb 100644 --- a/runtime/lua/vim/lsp/handlers.lua +++ b/runtime/lua/vim/lsp/handlers.lua @@ -3,7 +3,7 @@ local protocol = require('vim.lsp.protocol') local ms = protocol.Methods local util = require('vim.lsp.util') local api = vim.api -local completion = require('vim.lsp._completion') +local completion = require('vim.lsp.completion') --- @type table local M = {} diff --git a/runtime/lua/vim/lsp/protocol.lua b/runtime/lua/vim/lsp/protocol.lua index 419c2ff644..8ac4cc794b 100644 --- a/runtime/lua/vim/lsp/protocol.lua +++ b/runtime/lua/vim/lsp/protocol.lua @@ -738,14 +738,16 @@ function protocol.make_client_capabilities() completion = { dynamicRegistration = false, completionItem = { - -- Until we can actually expand snippet, move cursor and allow for true snippet experience, - -- this should be disabled out of the box. - -- However, users can turn this back on if they have a snippet plugin. - snippetSupport = false, + snippetSupport = true, commitCharactersSupport = false, preselectSupport = false, deprecatedSupport = false, documentationFormat = { constants.MarkupKind.Markdown, constants.MarkupKind.PlainText }, + resolveSupport = { + properties = { + 'additionalTextEdits', + }, + }, }, completionItemKind = { valueSet = get_value_set(constants.CompletionItemKind), -- cgit From 7b16c1fa8451880c72769f6d3c311f24c74f4fc7 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Tue, 28 May 2024 06:39:07 +0800 Subject: fix(runtime): source c ftplugin properly for cpp on Windows (#29053) On Windows, '{' is currently not treated as a wildcard char, so another wildcard char is needed for the pattern to be treated as a wildcard. It may be worth trying to make '{' always a wildcard char in the future, but that'll be a bit harder as it'll be necessary to make sure '{' is escaped at various places. --- runtime/ftplugin/cpp.vim | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'runtime') diff --git a/runtime/ftplugin/cpp.vim b/runtime/ftplugin/cpp.vim index d4931a2533..5cdad8fdc8 100644 --- a/runtime/ftplugin/cpp.vim +++ b/runtime/ftplugin/cpp.vim @@ -10,7 +10,8 @@ if exists("b:did_ftplugin") endif " Behaves mostly just like C -runtime! ftplugin/c.{vim,lua} ftplugin/c_*.{vim,lua} ftplugin/c/*.{vim,lua} +" XXX: "[.]" in the first pattern makes it a wildcard on Windows +runtime! ftplugin/c[.]{vim,lua} ftplugin/c_*.{vim,lua} ftplugin/c/*.{vim,lua} " C++ uses templates with " Disabled, because it gives an error for typing an unmatched ">". -- cgit From 4e2c8dc37468fc06897ba26498c8b5dae7dc5a94 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Tue, 28 May 2024 14:40:09 +0800 Subject: vim-patch:0b74eec: runtime(stylus): remove remaining css code (vim/vim#14866) This seems to be a forgotten fixup in https://github.com/vim/vim/commit/2d919d2744a99c9bb9e79984e85b8e8f5ec14c07#r141568461 https://github.com/vim/vim/commit/0b74eeceb856e7a4c2823f5b6c2c2ee95a72331c --- runtime/syntax/stylus.vim | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) (limited to 'runtime') diff --git a/runtime/syntax/stylus.vim b/runtime/syntax/stylus.vim index fd0f33b65a..d8bf641e60 100644 --- a/runtime/syntax/stylus.vim +++ b/runtime/syntax/stylus.vim @@ -4,17 +4,7 @@ " Filenames: *.styl, *.stylus " Based On: Tim Pope (sass.vim) " Created: Dec 14, 2011 -" Modified: Apr 29, 2024 - -if main_syntax == "css" - syn sync minlines=10 -endif - -" let b:current_syntax = "css" -" -if main_syntax == 'css' - unlet main_syntax -endif +" Modified: May 28, 2024 syn case ignore -- cgit From 90a4b1a59cf0c204cb39ec7789ab8783626e449d Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Tue, 28 May 2024 03:07:13 -0700 Subject: refactor: deprecate vim.region() #28416 Problem: `vim.region()` is redundant with `getregionpos()`. Solution: Deprecate `vim.region()`. --- runtime/doc/deprecated.txt | 2 ++ runtime/doc/lua.txt | 24 ------------------------ runtime/doc/news-0.10.txt | 2 +- runtime/lua/vim/_editor.lua | 3 +++ runtime/lua/vim/lsp/buf.lua | 2 +- 5 files changed, 7 insertions(+), 26 deletions(-) (limited to 'runtime') diff --git a/runtime/doc/deprecated.txt b/runtime/doc/deprecated.txt index 646ba72bd8..be220fc307 100644 --- a/runtime/doc/deprecated.txt +++ b/runtime/doc/deprecated.txt @@ -19,6 +19,8 @@ API - nvim_subscribe() Plugins must maintain their own "multicast" channels list. - nvim_unsubscribe() Plugins must maintain their own "multicast" channels list. +LUA +- vim.region() Use |getregionpos()| instead. ------------------------------------------------------------------------------ DEPRECATED IN 0.10 *deprecated-0.10* diff --git a/runtime/doc/lua.txt b/runtime/doc/lua.txt index fd0cd3252f..36d6e0d41e 100644 --- a/runtime/doc/lua.txt +++ b/runtime/doc/lua.txt @@ -1708,30 +1708,6 @@ vim.print({...}) *vim.print()* • |vim.inspect()| • |:=| - *vim.region()* -vim.region({bufnr}, {pos1}, {pos2}, {regtype}, {inclusive}) - Gets a dict of line segment ("chunk") positions for the region from `pos1` - to `pos2`. - - Input and output positions are byte positions, (0,0)-indexed. "End of - line" column position (for example, |linewise| visual selection) is - returned as |v:maxcol| (big number). - - Parameters: ~ - • {bufnr} (`integer`) Buffer number, or 0 for current buffer - • {pos1} (`integer[]|string`) Start of region as a (line, column) - tuple or |getpos()|-compatible string - • {pos2} (`integer[]|string`) End of region as a (line, column) - tuple or |getpos()|-compatible string - • {regtype} (`string`) |setreg()|-style selection type - • {inclusive} (`boolean`) Controls whether the ending column is - inclusive (see also 'selection'). - - Return: ~ - (`table`) region Dict of the form `{linenr = {startcol,endcol}}`. - `endcol` is exclusive, and whole lines are returned as - `{startcol,endcol} = {0,-1}`. - vim.schedule_wrap({fn}) *vim.schedule_wrap()* Returns a function which calls {fn} via |vim.schedule()|. diff --git a/runtime/doc/news-0.10.txt b/runtime/doc/news-0.10.txt index 8a0e7e92e7..d611eee242 100644 --- a/runtime/doc/news-0.10.txt +++ b/runtime/doc/news-0.10.txt @@ -307,7 +307,7 @@ The following new features were added. a predicate function that is checked for each value. (Use |vim.list_contains()| for checking list-like tables (integer keys without gaps) for literal values.) - • |vim.region()| can use a string accepted by |getpos()| as position. + • vim.region() can use a string accepted by |getpos()| as position. • Options: • 'winfixbuf' keeps a window focused onto a specific buffer diff --git a/runtime/lua/vim/_editor.lua b/runtime/lua/vim/_editor.lua index 5e9be509c8..9f952db4fc 100644 --- a/runtime/lua/vim/_editor.lua +++ b/runtime/lua/vim/_editor.lua @@ -494,6 +494,7 @@ do vim.t = make_dict_accessor('t') end +--- @deprecated --- Gets a dict of line segment ("chunk") positions for the region from `pos1` to `pos2`. --- --- Input and output positions are byte positions, (0,0)-indexed. "End of line" column @@ -507,6 +508,8 @@ end ---@return table region Dict of the form `{linenr = {startcol,endcol}}`. `endcol` is exclusive, and ---whole lines are returned as `{startcol,endcol} = {0,-1}`. function vim.region(bufnr, pos1, pos2, regtype, inclusive) + vim.deprecate('vim.region', 'vim.fn.getregionpos()', '0.13') + if not vim.api.nvim_buf_is_loaded(bufnr) then vim.fn.bufload(bufnr) end diff --git a/runtime/lua/vim/lsp/buf.lua b/runtime/lua/vim/lsp/buf.lua index 49833eaeec..299b68e134 100644 --- a/runtime/lua/vim/lsp/buf.lua +++ b/runtime/lua/vim/lsp/buf.lua @@ -135,7 +135,7 @@ end ---@param mode "v"|"V" ---@return table {start={row,col}, end={row,col}} using (1, 0) indexing local function range_from_selection(bufnr, mode) - -- TODO: Use `vim.region()` instead https://github.com/neovim/neovim/pull/13896 + -- TODO: Use `vim.fn.getregionpos()` instead. -- [bufnum, lnum, col, off]; both row and column 1-indexed local start = vim.fn.getpos('v') -- cgit From 8ba73f0e4cc6c82032a348a1d6c8d794ed150fd7 Mon Sep 17 00:00:00 2001 From: Gregory Anders <8965202+gpanders@users.noreply.github.com> Date: Tue, 28 May 2024 08:51:44 -0500 Subject: feat(diagnostic): add vim.diagnostic.jump() (#26745) Deprecate vim.diagnostic.goto_prev() and vim.diagnostic.goto_next() in favor of a unified vim.diagnostic.jump() interface. We cannot name the function "goto()" because some of our tooling (luacheck and stylua) fail to parse it, presumably because "goto" is a keyword in newer versions of Lua. vim.diagnostic.jump() also allows moving to a specific diagnostic and moving by multiple diagnostics at a time (useful for creating mappings that use v:count). --- runtime/doc/deprecated.txt | 17 +++- runtime/doc/diagnostic.txt | 91 +++++++++---------- runtime/lua/vim/diagnostic.lua | 193 ++++++++++++++++++++++++++++++----------- 3 files changed, 195 insertions(+), 106 deletions(-) (limited to 'runtime') diff --git a/runtime/doc/deprecated.txt b/runtime/doc/deprecated.txt index be220fc307..6c6585d76e 100644 --- a/runtime/doc/deprecated.txt +++ b/runtime/doc/deprecated.txt @@ -22,6 +22,20 @@ API LUA - vim.region() Use |getregionpos()| instead. +DIAGNOSTICS +- *vim.diagnostic.goto_next()* Use |vim.diagnostic.jump()| with `{count = 1}` instead. +- *vim.diagnostic.goto_prev()* Use |vim.diagnostic.jump()| with `{count = -1}` instead. +- *vim.diagnostic.get_next_pos()* + Use the "lnum" and "col" fields from the return value of + |vim.diagnostic.get_next()| instead. +- *vim.diagnostic.get_prev_pos()* + Use the "lnum" and "col" fields from the return value of + |vim.diagnostic.get_prev()| instead. +- The "win_id" parameter used by various functions is deprecated in favor of + "winid" |winid| +- The "cursor_position" parameter of |vim.diagnostic.JumpOpts| is renamed to + "pos" + ------------------------------------------------------------------------------ DEPRECATED IN 0.10 *deprecated-0.10* @@ -204,9 +218,6 @@ internally and are no longer exposed as part of the API. Instead, use - *vim.lsp.diagnostic.set_underline()* - *vim.lsp.diagnostic.set_virtual_text()* -Configuring |diagnostic-signs| with |:sign-define| or |sign_define()| is no -longer supported. Use the "signs" key of |vim.diagnostic.config()| instead. - LSP FUNCTIONS - *vim.lsp.buf.server_ready()* Use |LspAttach| instead, depending on your use-case. "Server ready" is not diff --git a/runtime/doc/diagnostic.txt b/runtime/doc/diagnostic.txt index 36616b9a0d..be9e54d6cd 100644 --- a/runtime/doc/diagnostic.txt +++ b/runtime/doc/diagnostic.txt @@ -378,28 +378,37 @@ Lua module: vim.diagnostic *diagnostic-api* • {severity}? (`vim.diagnostic.SeverityFilter`) See |diagnostic-severity|. -*vim.diagnostic.GotoOpts* +*vim.diagnostic.JumpOpts* Extends: |vim.diagnostic.GetOpts| Configuration table with the following keys: Fields: ~ - • {cursor_position}? (`{[1]:integer,[2]:integer}`, default: current cursor position) - Cursor position as a `(row, col)` tuple. See - |nvim_win_get_cursor()|. - • {wrap}? (`boolean`, default: `true`) Whether to loop - around file or not. Similar to 'wrapscan'. - • {severity}? (`vim.diagnostic.SeverityFilter`) See - |diagnostic-severity|. - • {float}? (`boolean|vim.diagnostic.Opts.Float`, default: - `true`) If `true`, call - |vim.diagnostic.open_float()| after moving. If a - table, pass the table as the {opts} parameter to - |vim.diagnostic.open_float()|. Unless overridden, - the float will show diagnostics at the new cursor - position (as if "cursor" were passed to the - "scope" option). - • {win_id}? (`integer`, default: `0`) Window ID + • {diagnostic}? (`vim.Diagnostic`) The diagnostic to jump to. Mutually + exclusive with {count}, {namespace}, and {severity}. + See |vim.Diagnostic|. + • {count}? (`integer`) The number of diagnostics to move by, + starting from {pos}. A positive integer moves forward + by {count} diagnostics, while a negative integer moves + backward by {count} diagnostics. Mutually exclusive + with {diagnostic}. + • {pos}? (`{[1]:integer,[2]:integer}`) Cursor position as a + `(row, col)` tuple. See |nvim_win_get_cursor()|. Used + to find the nearest diagnostic when {count} is used. + Only used when {count} is non-nil. Default is the + current cursor position. + • {wrap}? (`boolean`, default: `true`) Whether to loop around + file or not. Similar to 'wrapscan'. + • {severity}? (`vim.diagnostic.SeverityFilter`) See + |diagnostic-severity|. + • {float}? (`boolean|vim.diagnostic.Opts.Float`, default: `true`) + If `true`, call |vim.diagnostic.open_float()| after + moving. If a table, pass the table as the {opts} + parameter to |vim.diagnostic.open_float()|. Unless + overridden, the float will show diagnostics at the new + cursor position (as if "cursor" were passed to the + "scope" option). + • {winid}? (`integer`, default: `0`) Window ID *vim.diagnostic.NS* @@ -678,52 +687,20 @@ get_next({opts}) *vim.diagnostic.get_next()* Get the next diagnostic closest to the cursor position. Parameters: ~ - • {opts} (`vim.diagnostic.GotoOpts?`) See |vim.diagnostic.GotoOpts|. + • {opts} (`vim.diagnostic.JumpOpts?`) See |vim.diagnostic.JumpOpts|. Return: ~ (`vim.Diagnostic?`) Next diagnostic. See |vim.Diagnostic|. -get_next_pos({opts}) *vim.diagnostic.get_next_pos()* - Return the position of the next diagnostic in the current buffer. - - Parameters: ~ - • {opts} (`vim.diagnostic.GotoOpts?`) See |vim.diagnostic.GotoOpts|. - - Return: ~ - (`table|false`) Next diagnostic position as a `(row, col)` tuple or - false if no next diagnostic. - get_prev({opts}) *vim.diagnostic.get_prev()* Get the previous diagnostic closest to the cursor position. Parameters: ~ - • {opts} (`vim.diagnostic.GotoOpts?`) See |vim.diagnostic.GotoOpts|. + • {opts} (`vim.diagnostic.JumpOpts?`) See |vim.diagnostic.JumpOpts|. Return: ~ (`vim.Diagnostic?`) Previous diagnostic. See |vim.Diagnostic|. -get_prev_pos({opts}) *vim.diagnostic.get_prev_pos()* - Return the position of the previous diagnostic in the current buffer. - - Parameters: ~ - • {opts} (`vim.diagnostic.GotoOpts?`) See |vim.diagnostic.GotoOpts|. - - Return: ~ - (`table|false`) Previous diagnostic position as a `(row, col)` tuple - or `false` if there is no prior diagnostic. - -goto_next({opts}) *vim.diagnostic.goto_next()* - Move to the next diagnostic. - - Parameters: ~ - • {opts} (`vim.diagnostic.GotoOpts?`) See |vim.diagnostic.GotoOpts|. - -goto_prev({opts}) *vim.diagnostic.goto_prev()* - Move to the previous diagnostic in the current buffer. - - Parameters: ~ - • {opts} (`vim.diagnostic.GotoOpts?`) See |vim.diagnostic.GotoOpts|. - hide({namespace}, {bufnr}) *vim.diagnostic.hide()* Hide currently displayed diagnostics. @@ -753,6 +730,16 @@ is_enabled({filter}) *vim.diagnostic.is_enabled()* Return: ~ (`boolean`) +jump({opts}) *vim.diagnostic.jump()* + Move to a diagnostic. + + Parameters: ~ + • {opts} (`vim.diagnostic.JumpOpts`) See |vim.diagnostic.JumpOpts|. + + Return: ~ + (`vim.Diagnostic?`) The diagnostic that was moved to. See + |vim.Diagnostic|. + *vim.diagnostic.match()* match({str}, {pat}, {groups}, {severity_map}, {defaults}) Parse a diagnostic from a string. @@ -792,7 +779,7 @@ open_float({opts}) *vim.diagnostic.open_float()* Return (multiple): ~ (`integer?`) float_bufnr - (`integer?`) win_id + (`integer?`) winid reset({namespace}, {bufnr}) *vim.diagnostic.reset()* Remove all diagnostics from the given namespace. diff --git a/runtime/lua/vim/diagnostic.lua b/runtime/lua/vim/diagnostic.lua index 348204abb7..8e68e9608a 100644 --- a/runtime/lua/vim/diagnostic.lua +++ b/runtime/lua/vim/diagnostic.lua @@ -835,21 +835,36 @@ local function filter_highest(diagnostics) end end ---- @param position {[1]: integer, [2]: integer} --- @param search_forward boolean ---- @param bufnr integer ---- @param opts vim.diagnostic.GotoOpts ---- @param namespace integer[]|integer +--- @param opts vim.diagnostic.JumpOpts? --- @return vim.Diagnostic? -local function next_diagnostic(position, search_forward, bufnr, opts, namespace) +local function next_diagnostic(search_forward, opts) + opts = opts or {} + + -- Support deprecated win_id alias + if opts.win_id then + vim.deprecate('opts.win_id', 'opts.winid', '0.13') + opts.winid = opts.win_id + opts.win_id = nil + end + + -- Support deprecated cursor_position alias + if opts.cursor_position then + vim.deprecate('opts.cursor_position', 'opts.pos', '0.13') + opts.pos = opts.cursor_position + opts.cursor_position = nil + end + + local winid = opts.winid or api.nvim_get_current_win() + local bufnr = api.nvim_win_get_buf(winid) + local position = opts.pos or api.nvim_win_get_cursor(winid) + + -- Adjust row to be 0-indexed position[1] = position[1] - 1 - bufnr = get_bufnr(bufnr) - local wrap = if_nil(opts.wrap, true) - local get_opts = vim.deepcopy(opts) - get_opts.namespace = get_opts.namespace or namespace + local wrap = if_nil(opts.wrap, true) - local diagnostics = get_diagnostics(bufnr, get_opts, true) + local diagnostics = get_diagnostics(bufnr, opts, true) if opts._highest then filter_highest(diagnostics) @@ -902,32 +917,41 @@ local function next_diagnostic(position, search_forward, bufnr, opts, namespace) end end ---- @param opts vim.diagnostic.GotoOpts? ---- @param pos {[1]:integer,[2]:integer}|false -local function diagnostic_move_pos(opts, pos) - opts = opts or {} - - local float = if_nil(opts.float, true) - local win_id = opts.win_id or api.nvim_get_current_win() - - if not pos then +--- Move the cursor to the given diagnostic. +--- +--- @param diagnostic vim.Diagnostic? +--- @param opts vim.diagnostic.JumpOpts? +local function goto_diagnostic(diagnostic, opts) + if not diagnostic then api.nvim_echo({ { 'No more valid diagnostics to move to', 'WarningMsg' } }, true, {}) return end - api.nvim_win_call(win_id, function() + opts = opts or {} + + -- Support deprecated win_id alias + if opts.win_id then + vim.deprecate('opts.win_id', 'opts.winid', '0.13') + opts.winid = opts.win_id + opts.win_id = nil + end + + local winid = opts.winid or api.nvim_get_current_win() + + api.nvim_win_call(winid, function() -- Save position in the window's jumplist vim.cmd("normal! m'") - api.nvim_win_set_cursor(win_id, { pos[1] + 1, pos[2] }) + api.nvim_win_set_cursor(winid, { diagnostic.lnum + 1, diagnostic.col }) -- Open folds under the cursor vim.cmd('normal! zv') end) + local float = if_nil(opts.float, true) if float then local float_opts = type(float) == 'table' and float or {} vim.schedule(function() M.open_float(vim.tbl_extend('keep', float_opts, { - bufnr = api.nvim_win_get_buf(win_id), + bufnr = api.nvim_win_get_buf(winid), scope = 'cursor', focus = false, })) @@ -1114,24 +1138,24 @@ end --- Get the previous diagnostic closest to the cursor position. --- ----@param opts? vim.diagnostic.GotoOpts +---@param opts? vim.diagnostic.JumpOpts ---@return vim.Diagnostic? : Previous diagnostic function M.get_prev(opts) - opts = opts or {} - - local win_id = opts.win_id or api.nvim_get_current_win() - local bufnr = api.nvim_win_get_buf(win_id) - local cursor_position = opts.cursor_position or api.nvim_win_get_cursor(win_id) - - return next_diagnostic(cursor_position, false, bufnr, opts, opts.namespace) + return next_diagnostic(false, opts) end --- Return the position of the previous diagnostic in the current buffer. --- ----@param opts? vim.diagnostic.GotoOpts +---@param opts? vim.diagnostic.JumpOpts ---@return table|false: Previous diagnostic position as a `(row, col)` tuple --- or `false` if there is no prior diagnostic. +---@deprecated function M.get_prev_pos(opts) + vim.deprecate( + 'vim.diagnostic.get_prev_pos()', + 'access the lnum and col fields from get_prev() instead', + '0.13' + ) local prev = M.get_prev(opts) if not prev then return false @@ -1141,31 +1165,33 @@ function M.get_prev_pos(opts) end --- Move to the previous diagnostic in the current buffer. ----@param opts? vim.diagnostic.GotoOpts +---@param opts? vim.diagnostic.JumpOpts +---@deprecated function M.goto_prev(opts) - return diagnostic_move_pos(opts, M.get_prev_pos(opts)) + vim.deprecate('vim.diagnostic.goto_prev()', 'vim.diagnostic.jump()', '0.13') + goto_diagnostic(M.get_prev(opts), opts) end --- Get the next diagnostic closest to the cursor position. --- ----@param opts? vim.diagnostic.GotoOpts +---@param opts? vim.diagnostic.JumpOpts ---@return vim.Diagnostic? : Next diagnostic function M.get_next(opts) - opts = opts or {} - - local win_id = opts.win_id or api.nvim_get_current_win() - local bufnr = api.nvim_win_get_buf(win_id) - local cursor_position = opts.cursor_position or api.nvim_win_get_cursor(win_id) - - return next_diagnostic(cursor_position, true, bufnr, opts, opts.namespace) + return next_diagnostic(true, opts) end --- Return the position of the next diagnostic in the current buffer. --- ----@param opts? vim.diagnostic.GotoOpts +---@param opts? vim.diagnostic.JumpOpts ---@return table|false : Next diagnostic position as a `(row, col)` tuple or false if no next --- diagnostic. +---@deprecated function M.get_next_pos(opts) + vim.deprecate( + 'vim.diagnostic.get_next_pos()', + 'access the lnum and col fields from get_next() instead', + '0.13' + ) local next = M.get_next(opts) if not next then return false @@ -1187,12 +1213,21 @@ end --- @field severity? vim.diagnostic.SeverityFilter --- Configuration table with the following keys: ---- @class vim.diagnostic.GotoOpts : vim.diagnostic.GetOpts +--- @class vim.diagnostic.JumpOpts : vim.diagnostic.GetOpts +--- +--- The diagnostic to jump to. Mutually exclusive with {count}, {namespace}, +--- and {severity}. +--- @field diagnostic? vim.Diagnostic +--- +--- The number of diagnostics to move by, starting from {pos}. A positive +--- integer moves forward by {count} diagnostics, while a negative integer moves +--- backward by {count} diagnostics. Mutually exclusive with {diagnostic}. +--- @field count? integer --- ---- Cursor position as a `(row, col)` tuple. ---- See |nvim_win_get_cursor()|. ---- (default: current cursor position) ---- @field cursor_position? {[1]:integer,[2]:integer} +--- Cursor position as a `(row, col)` tuple. See |nvim_win_get_cursor()|. Used +--- to find the nearest diagnostic when {count} is used. Only used when {count} +--- is non-nil. Default is the current cursor position. +--- @field pos? {[1]:integer,[2]:integer} --- --- Whether to loop around file or not. Similar to 'wrapscan'. --- (default: `true`) @@ -1214,13 +1249,69 @@ end --- --- Window ID --- (default: `0`) ---- @field win_id? integer +--- @field winid? integer + +--- Move to a diagnostic. +--- +--- @param opts vim.diagnostic.JumpOpts +--- @return vim.Diagnostic? # The diagnostic that was moved to. +function M.jump(opts) + -- One of "diagnostic" or "count" must be provided + assert( + opts.diagnostic or opts.count, + 'One of "diagnostic" or "count" must be specified in the options to vim.diagnostic.jump()' + ) + + if opts.diagnostic then + goto_diagnostic(opts.diagnostic, opts) + return opts.diagnostic + end + + local count = opts.count + if count == 0 then + return nil + end + + -- Support deprecated cursor_position alias + if opts.cursor_position then + vim.deprecate('opts.cursor_position', 'opts.pos', '0.13') + opts.pos = opts.cursor_position + opts.cursor_position = nil + end + + -- Copy the opts table so that we can modify it + local opts_ = vim.deepcopy(opts, true) + + local diag = nil + while count ~= 0 do + local next = next_diagnostic(count > 0, opts_) + if not next then + break + end + + -- Update cursor position + opts_.pos = { next.lnum + 1, next.col } + + if count > 0 then + count = count - 1 + else + count = count + 1 + end + diag = next + end + + goto_diagnostic(diag, opts) + + return diag +end --- Move to the next diagnostic. --- ----@param opts? vim.diagnostic.GotoOpts +---@param opts? vim.diagnostic.JumpOpts +---@deprecated function M.goto_next(opts) - diagnostic_move_pos(opts, M.get_next_pos(opts)) + vim.deprecate('vim.diagnostic.goto_next()', 'vim.diagnostic.jump()', '0.13') + goto_diagnostic(M.get_next(opts), opts) end M.handlers.signs = { @@ -1688,7 +1779,7 @@ end --- ---@param opts vim.diagnostic.Opts.Float? ---@return integer? float_bufnr ----@return integer? win_id +---@return integer? winid function M.open_float(opts, ...) -- Support old (bufnr, opts) signature local bufnr --- @type integer? -- cgit From e6cfcaed184d4ecdc8a8638429e1bd9e1b3251dc Mon Sep 17 00:00:00 2001 From: Maria José Solano Date: Sat, 25 May 2024 10:23:05 -0700 Subject: feat(snippet): add default keymaps during snippet session --- runtime/doc/news.txt | 6 +++++ runtime/lua/vim/snippet.lua | 63 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 69 insertions(+) (limited to 'runtime') diff --git a/runtime/doc/news.txt b/runtime/doc/news.txt index 439316f62e..f1b402c92e 100644 --- a/runtime/doc/news.txt +++ b/runtime/doc/news.txt @@ -85,6 +85,12 @@ DEFAULTS - |gra| in Normal and Visual mode maps to |vim.lsp.buf.code_action()| - CTRL-S in Insert mode maps to |vim.lsp.buf.signature_help()| +• Snippet: + - `` in Insert and Select mode maps to |vim.snippet.jump({ direction = 1 })| + when a snippet is active and jumpable forwards. + - `` in Insert and Select mode maps to |vim.snippet.jump({ direction = -1 })| + when a snippet is active and jumpable backwards. + EDITOR • TODO diff --git a/runtime/lua/vim/snippet.lua b/runtime/lua/vim/snippet.lua index 3d8f73f362..1ec5235d7b 100644 --- a/runtime/lua/vim/snippet.lua +++ b/runtime/lua/vim/snippet.lua @@ -2,6 +2,8 @@ local G = vim.lsp._snippet_grammar local snippet_group = vim.api.nvim_create_augroup('vim/snippet', {}) local snippet_ns = vim.api.nvim_create_namespace('vim/snippet') local hl_group = 'SnippetTabstop' +local jump_forward_key = '' +local jump_backward_key = '' --- Returns the 0-based cursor position. --- @@ -182,6 +184,8 @@ end --- @field extmark_id integer --- @field tabstops table --- @field current_tabstop vim.snippet.Tabstop +--- @field tab_keymaps { i: table?, s: table? } +--- @field shift_tab_keymaps { i: table?, s: table? } local Session = {} --- Creates a new snippet session in the current buffer. @@ -197,6 +201,8 @@ function Session.new(bufnr, snippet_extmark, tabstop_data) extmark_id = snippet_extmark, tabstops = {}, current_tabstop = Tabstop.new(0, bufnr, { 0, 0, 0, 0 }), + tab_keymaps = { i = nil, s = nil }, + shift_tab_keymaps = { i = nil, s = nil }, }, { __index = Session }) -- Create the tabstops. @@ -207,9 +213,64 @@ function Session.new(bufnr, snippet_extmark, tabstop_data) end end + self:set_keymaps() + return self end +--- Sets the snippet navigation keymaps. +--- +--- @package +function Session:set_keymaps() + local function maparg(key, mode) + local map = vim.fn.maparg(key, mode, false, true) --[[ @as table ]] + if not vim.tbl_isempty(map) and map.buffer == 1 then + return map + else + return nil + end + end + + local function set(jump_key, direction) + vim.keymap.set({ 'i', 's' }, jump_key, function() + return vim.snippet.active({ direction = direction }) + and 'lua vim.snippet.jump(' .. direction .. ')' + or jump_key + end, { expr = true, silent = true, buffer = self.bufnr }) + end + + self.tab_keymaps = { + i = maparg(jump_forward_key, 'i'), + s = maparg(jump_forward_key, 's'), + } + self.shift_tab_keymaps = { + i = maparg(jump_backward_key, 'i'), + s = maparg(jump_backward_key, 's'), + } + set(jump_forward_key, 1) + set(jump_backward_key, -1) +end + +--- Restores/deletes the keymaps used for snippet navigation. +--- +--- @package +function Session:restore_keymaps() + local function restore(keymap, lhs, mode) + if keymap then + vim.api.nvim_buf_call(self.bufnr, function() + vim.fn.mapset(keymap) + end) + else + vim.api.nvim_buf_del_keymap(self.bufnr, mode, lhs) + end + end + + restore(self.tab_keymaps.i, jump_forward_key, 'i') + restore(self.tab_keymaps.s, jump_forward_key, 's') + restore(self.shift_tab_keymaps.i, jump_backward_key, 'i') + restore(self.shift_tab_keymaps.s, jump_backward_key, 's') +end + --- Returns the destination tabstop index when jumping in the given direction. --- --- @package @@ -619,6 +680,8 @@ function M.stop() return end + M._session:restore_keymaps() + vim.api.nvim_clear_autocmds({ group = snippet_group, buffer = M._session.bufnr }) vim.api.nvim_buf_clear_namespace(M._session.bufnr, snippet_ns, 0, -1) -- cgit From 1c6d9200521acb2329be55ab8bec3056deade66a Mon Sep 17 00:00:00 2001 From: Gregory Anders <8965202+gpanders@users.noreply.github.com> Date: Tue, 28 May 2024 13:24:16 -0500 Subject: feat(defaults): use vim.diagnostic.jump() for default mappings (#29066) This allows the mappings to work with a count and also enables new ]D and [D mappings to go to the last/first diagnostic in the buffer. --- runtime/doc/news.txt | 7 +++++-- runtime/doc/tagsrch.txt | 16 ++++++++++++---- runtime/doc/vim_diff.txt | 2 ++ runtime/lua/vim/_defaults.lua | 16 ++++++++++++---- 4 files changed, 31 insertions(+), 10 deletions(-) (limited to 'runtime') diff --git a/runtime/doc/news.txt b/runtime/doc/news.txt index b5ba2921e6..ceb638a459 100644 --- a/runtime/doc/news.txt +++ b/runtime/doc/news.txt @@ -34,11 +34,14 @@ API DEFAULTS -• TODO +• |]d-default| and |[d-default| accept a count. +• |[D-default| and |]D-default| jump to the first and last diagnostic in the + current buffer, respectively. EDITOR -• The order in which signs are placed was changed. Higher priority signs will now appear left of lower priority signs. +• The order in which signs are placed was changed. Higher priority signs will + now appear left of lower priority signs. EVENTS diff --git a/runtime/doc/tagsrch.txt b/runtime/doc/tagsrch.txt index ef1654d365..8b2813785f 100644 --- a/runtime/doc/tagsrch.txt +++ b/runtime/doc/tagsrch.txt @@ -781,15 +781,15 @@ CTRL-W i Open a new window, with the cursor on the first line count'th matching line is displayed. *[d-default* - Mapped to |vim.diagnostic.goto_prev()| by default. - |default-mappings| + Jumps to the previous diagnostic in the current buffer + by default. |vim.diagnostic.jump()| |default-mappings| *]d* ]d like "[d", but start at the current cursor position. *]d-default* - Mapped to |vim.diagnostic.goto_next()| by default. - |default-mappings| + Jumps to the next diagnostic in the current buffer by + default. |vim.diagnostic.jump()| |default-mappings| *:ds* *:dsearch* :[range]ds[earch][!] [count] [/]string[/] @@ -803,9 +803,17 @@ CTRL-W i Open a new window, with the cursor on the first line displayed for the found lines. The search starts from the beginning of the file. + *[D-default* + Jumps to the first diagnostic in the current buffer by + default. |vim.diagnostic.jump()| |default-mappings| + *]D* ]D like "[D", but start at the current cursor position. + *]D-default* + Jumps to the last diagnostic in the current buffer by + default. |vim.diagnostic.jump()| |default-mappings| + *:dli* *:dlist* :[range]dli[st][!] [/]string[/] Like `[D` and `]D`, but search in [range] lines diff --git a/runtime/doc/vim_diff.txt b/runtime/doc/vim_diff.txt index 5d894bb5e1..ac20948f14 100644 --- a/runtime/doc/vim_diff.txt +++ b/runtime/doc/vim_diff.txt @@ -145,6 +145,8 @@ of these in your config by simply removing the mapping, e.g. ":unmap Y". - |i_CTRL-S| - ]d |]d-default| - [d |[d-default| +- [D |[D-default| +- ]D |]D-default| - d |CTRL-W_d-default| - Nvim LSP client defaults |lsp-defaults| - K |K-lsp-default| diff --git a/runtime/lua/vim/_defaults.lua b/runtime/lua/vim/_defaults.lua index 5b964b84a0..26d8729029 100644 --- a/runtime/lua/vim/_defaults.lua +++ b/runtime/lua/vim/_defaults.lua @@ -180,12 +180,20 @@ do --- See |[d-default|, |]d-default|, and |CTRL-W_d-default|. do vim.keymap.set('n', ']d', function() - vim.diagnostic.goto_next({ float = false }) - end, { desc = 'Jump to the next diagnostic' }) + vim.diagnostic.jump({ count = vim.v.count1, float = false }) + end, { desc = 'Jump to the next diagnostic in the current buffer' }) vim.keymap.set('n', '[d', function() - vim.diagnostic.goto_prev({ float = false }) - end, { desc = 'Jump to the previous diagnostic' }) + vim.diagnostic.jump({ count = -vim.v.count1, float = false }) + end, { desc = 'Jump to the previous diagnostic in the current buffer' }) + + vim.keymap.set('n', ']D', function() + vim.diagnostic.jump({ count = math.huge, wrap = false, float = false }) + end, { desc = 'Jump to the last diagnostic in the current buffer' }) + + vim.keymap.set('n', '[D', function() + vim.diagnostic.jump({ count = -math.huge, wrap = false, float = false }) + end, { desc = 'Jump to the first diagnostic in the current buffer' }) vim.keymap.set('n', 'd', function() vim.diagnostic.open_float() -- cgit From efa45832ea02e777ce3f5556ef3cd959c164ec24 Mon Sep 17 00:00:00 2001 From: Gregory Anders <8965202+gpanders@users.noreply.github.com> Date: Tue, 28 May 2024 14:54:50 -0500 Subject: feat: add "jump" options to vim.diagnostic.config() (#29067) Problem: There is no easy way to configure the behavior of the default diagnostic "jump" mappings. For example, some users way want to show the floating window, and some may not (likewise, some way want to only move between warnings/errors, or disable the "wrap" parameter). Solution: Add a "jump" table to vim.diagnostic.config() that sets default values for vim.diagnostic.jump(). Alternatives: Users can override the default mappings to use the exact options to vim.diagnostic.jump() that they want, but this has a couple issues: - While the default mappings are not complicated, they are also not trivial, so overriding them requires users to understand implementation details (specifically things like setting "count" properly). - If plugins want to change the default mappings, or configure the behavior in any way (e.g. floating window display), it becomes even harder for users to tweak specific behavior. vim.diagnostic.config() already works quite well as the "entry point" for tuning knobs with diagnostic UI elements, so this fits in nicely and composes well with existing mental models and idioms. --- runtime/doc/diagnostic.txt | 18 ++++++++++++++++-- runtime/doc/news.txt | 5 +++++ runtime/lua/vim/_defaults.lua | 8 ++++---- runtime/lua/vim/diagnostic.lua | 41 ++++++++++++++++++++++++++++++++++------- runtime/lua/vim/shared.lua | 2 +- 5 files changed, 60 insertions(+), 14 deletions(-) (limited to 'runtime') diff --git a/runtime/doc/diagnostic.txt b/runtime/doc/diagnostic.txt index be9e54d6cd..2438c48154 100644 --- a/runtime/doc/diagnostic.txt +++ b/runtime/doc/diagnostic.txt @@ -381,7 +381,8 @@ Lua module: vim.diagnostic *diagnostic-api* *vim.diagnostic.JumpOpts* Extends: |vim.diagnostic.GetOpts| - Configuration table with the following keys: + Configuration table with the keys listed below. Some parameters can have + their default values changed with |vim.diagnostic.config()|. Fields: ~ • {diagnostic}? (`vim.Diagnostic`) The diagnostic to jump to. Mutually @@ -419,7 +420,7 @@ Lua module: vim.diagnostic *diagnostic-api* • {disabled}? (`boolean`) *vim.diagnostic.Opts* - Each of the configuration options below accepts one of the following: + Many of the configuration options below accept one of the following: • `false`: Disable this feature • `true`: Enable this feature, use default settings. • `table`: Enable this feature with overrides. Use an empty table to use @@ -450,6 +451,9 @@ Lua module: vim.diagnostic *diagnostic-api* displayed before lower severities (e.g. ERROR is displayed before WARN). Options: • {reverse}? (boolean) Reverse sort order + • {jump}? (`vim.diagnostic.Opts.Jump`) Default values for + |vim.diagnostic.jump()|. See + |vim.diagnostic.Opts.Jump|. *vim.diagnostic.Opts.Float* @@ -509,6 +513,16 @@ Lua module: vim.diagnostic *diagnostic-api* • {focus_id}? (`string`) • {border}? (`string`) see |nvim_open_win()|. +*vim.diagnostic.Opts.Jump* + + Fields: ~ + • {float}? (`boolean|vim.diagnostic.Opts.Float`) Default value of + the {float} parameter of |vim.diagnostic.jump()|. + • {wrap}? (`boolean`) Default value of the {wrap} parameter of + |vim.diagnostic.jump()|. + • {severity}? (`vim.diagnostic.SeverityFilter`) Default value of the + {severity} parameter of |vim.diagnostic.jump()|. + *vim.diagnostic.Opts.Signs* Fields: ~ diff --git a/runtime/doc/news.txt b/runtime/doc/news.txt index ceb638a459..13e4b23ea1 100644 --- a/runtime/doc/news.txt +++ b/runtime/doc/news.txt @@ -38,6 +38,11 @@ DEFAULTS • |[D-default| and |]D-default| jump to the first and last diagnostic in the current buffer, respectively. +DIAGNOSTICS + +• |vim.diagnostic.config()| accepts a "jump" table to specify defaults for + |vim.diagnostic.jump()|. + EDITOR • The order in which signs are placed was changed. Higher priority signs will diff --git a/runtime/lua/vim/_defaults.lua b/runtime/lua/vim/_defaults.lua index 26d8729029..79fe5a8513 100644 --- a/runtime/lua/vim/_defaults.lua +++ b/runtime/lua/vim/_defaults.lua @@ -180,19 +180,19 @@ do --- See |[d-default|, |]d-default|, and |CTRL-W_d-default|. do vim.keymap.set('n', ']d', function() - vim.diagnostic.jump({ count = vim.v.count1, float = false }) + vim.diagnostic.jump({ count = vim.v.count1 }) end, { desc = 'Jump to the next diagnostic in the current buffer' }) vim.keymap.set('n', '[d', function() - vim.diagnostic.jump({ count = -vim.v.count1, float = false }) + vim.diagnostic.jump({ count = -vim.v.count1 }) end, { desc = 'Jump to the previous diagnostic in the current buffer' }) vim.keymap.set('n', ']D', function() - vim.diagnostic.jump({ count = math.huge, wrap = false, float = false }) + vim.diagnostic.jump({ count = math.huge, wrap = false }) end, { desc = 'Jump to the last diagnostic in the current buffer' }) vim.keymap.set('n', '[D', function() - vim.diagnostic.jump({ count = -math.huge, wrap = false, float = false }) + vim.diagnostic.jump({ count = -math.huge, wrap = false }) end, { desc = 'Jump to the first diagnostic in the current buffer' }) vim.keymap.set('n', 'd', function() diff --git a/runtime/lua/vim/diagnostic.lua b/runtime/lua/vim/diagnostic.lua index 8e68e9608a..dca7698356 100644 --- a/runtime/lua/vim/diagnostic.lua +++ b/runtime/lua/vim/diagnostic.lua @@ -42,7 +42,7 @@ local M = {} --- --- @field namespace? integer ---- Each of the configuration options below accepts one of the following: +--- Many of the configuration options below accept one of the following: --- - `false`: Disable this feature --- - `true`: Enable this feature, use default settings. --- - `table`: Enable this feature with overrides. Use an empty table to use default values. @@ -78,6 +78,9 @@ local M = {} --- - {reverse}? (boolean) Reverse sort order --- (default: `false`) --- @field severity_sort? boolean|{reverse?:boolean} +--- +--- Default values for |vim.diagnostic.jump()|. See |vim.diagnostic.Opts.Jump|. +--- @field jump? vim.diagnostic.Opts.Jump --- @class (private) vim.diagnostic.OptsResolved --- @field float vim.diagnostic.Opts.Float @@ -241,6 +244,20 @@ local M = {} --- whole line the sign is placed in. --- @field linehl? table +--- @class vim.diagnostic.Opts.Jump +--- +--- Default value of the {float} parameter of |vim.diagnostic.jump()|. +--- @field float? boolean|vim.diagnostic.Opts.Float +--- +--- Default value of the {wrap} parameter of |vim.diagnostic.jump()|. +--- @field wrap? boolean +--- +--- Default value of the {severity} parameter of |vim.diagnostic.jump()|. +--- @field severity? vim.diagnostic.SeverityFilter +--- +--- Default value of the {_highest} parameter of |vim.diagnostic.jump()|. +--- @field package _highest? boolean + -- TODO: inherit from `vim.diagnostic.Opts`, implement its fields. --- Optional filters |kwargs|, or `nil` for all. --- @class vim.diagnostic.Filter @@ -284,6 +301,13 @@ local global_diagnostic_options = { float = true, update_in_insert = false, severity_sort = false, + jump = { + -- Do not show floating window + float = false, + + -- Wrap around buffer + wrap = true, + }, } --- @class (private) vim.diagnostic.Handler @@ -1212,7 +1236,8 @@ end --- See |diagnostic-severity|. --- @field severity? vim.diagnostic.SeverityFilter ---- Configuration table with the following keys: +--- Configuration table with the keys listed below. Some parameters can have their default values +--- changed with |vim.diagnostic.config()|. --- @class vim.diagnostic.JumpOpts : vim.diagnostic.GetOpts --- --- The diagnostic to jump to. Mutually exclusive with {count}, {namespace}, @@ -1256,12 +1281,17 @@ end --- @param opts vim.diagnostic.JumpOpts --- @return vim.Diagnostic? # The diagnostic that was moved to. function M.jump(opts) + vim.validate('opts', opts, 'table') + -- One of "diagnostic" or "count" must be provided assert( opts.diagnostic or opts.count, 'One of "diagnostic" or "count" must be specified in the options to vim.diagnostic.jump()' ) + -- Apply configuration options from vim.diagnostic.config() + opts = vim.tbl_deep_extend('keep', opts, global_diagnostic_options.jump) + if opts.diagnostic then goto_diagnostic(opts.diagnostic, opts) return opts.diagnostic @@ -1279,18 +1309,15 @@ function M.jump(opts) opts.cursor_position = nil end - -- Copy the opts table so that we can modify it - local opts_ = vim.deepcopy(opts, true) - local diag = nil while count ~= 0 do - local next = next_diagnostic(count > 0, opts_) + local next = next_diagnostic(count > 0, opts) if not next then break end -- Update cursor position - opts_.pos = { next.lnum + 1, next.col } + opts.pos = { next.lnum + 1, next.col } if count > 0 then count = count - 1 diff --git a/runtime/lua/vim/shared.lua b/runtime/lua/vim/shared.lua index 2641d1feb0..0ec79e1dc7 100644 --- a/runtime/lua/vim/shared.lua +++ b/runtime/lua/vim/shared.lua @@ -379,7 +379,7 @@ local function tbl_extend(behavior, deep_extend, ...) for i = 1, select('#', ...) do local tbl = select(i, ...) - vim.validate({ ['after the second argument'] = { tbl, 't' } }) + vim.validate('after the second argument', tbl, 'table') --- @cast tbl table if tbl then for k, v in pairs(tbl) do -- cgit From 025c87441502cf570bad7b71f40bc6fe88989297 Mon Sep 17 00:00:00 2001 From: crwebb85 <51029315+crwebb85@users.noreply.github.com> Date: Thu, 30 May 2024 02:59:23 -0400 Subject: fix(lsp): clear lsp client diagnostics (#29050) Problem: When an lsp client is stopped, the client will only clear the diagnostics for the attached buffers but not the unattached buffers. Solution: Reset the diagnostics for the whole namespace rather than for only the attached buffers. --- runtime/lua/vim/lsp.lua | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'runtime') diff --git a/runtime/lua/vim/lsp.lua b/runtime/lua/vim/lsp.lua index 94c31359da..96dbf97146 100644 --- a/runtime/lua/vim/lsp.lua +++ b/runtime/lua/vim/lsp.lua @@ -391,8 +391,8 @@ end local function on_client_exit(code, signal, client_id) local client = all_clients[client_id] - for bufnr in pairs(client.attached_buffers) do - vim.schedule(function() + vim.schedule(function() + for bufnr in pairs(client.attached_buffers) do if client and client.attached_buffers[bufnr] then api.nvim_exec_autocmds('LspDetach', { buffer = bufnr, @@ -401,15 +401,16 @@ local function on_client_exit(code, signal, client_id) }) end - local namespace = vim.lsp.diagnostic.get_namespace(client_id) - vim.diagnostic.reset(namespace, bufnr) client.attached_buffers[bufnr] = nil if #lsp.get_clients({ bufnr = bufnr, _uninitialized = true }) == 0 then reset_defaults(bufnr) end - end) - end + end + + local namespace = vim.lsp.diagnostic.get_namespace(client_id) + vim.diagnostic.reset(namespace) + end) local name = client.name or 'unknown' -- cgit From 0df2c6b5d09fab392dd1a14e4b2e6a3b03203aaa Mon Sep 17 00:00:00 2001 From: Mathias Fussenegger Date: Tue, 28 May 2024 21:37:46 +0200 Subject: feat(lsp): use fuzzy match on filterText instead of prefix match The `complete()` mechanism matches completion candidates against the typed text, so strict pre-filtering isn't necessary. This is a first step towards supporting postfix snippets (like `items@insert` in luals) --- runtime/lua/vim/lsp/completion.lua | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) (limited to 'runtime') diff --git a/runtime/lua/vim/lsp/completion.lua b/runtime/lua/vim/lsp/completion.lua index 25b3d53c8c..f9b0563b86 100644 --- a/runtime/lua/vim/lsp/completion.lua +++ b/runtime/lua/vim/lsp/completion.lua @@ -201,11 +201,17 @@ function M._lsp_to_complete_items(result, prefix, client_id) return {} end - local function matches_prefix(item) - return vim.startswith(get_completion_word(item), prefix) - end + if prefix ~= '' then + ---@param item lsp.CompletionItem + local function match_prefix(item) + if item.filterText then + return next(vim.fn.matchfuzzy({ item.filterText }, prefix)) + end + return true + end - items = vim.tbl_filter(matches_prefix, items) --[[@as lsp.CompletionItem[]|]] + items = vim.tbl_filter(match_prefix, items) --[[@as lsp.CompletionItem[]|]] + end table.sort(items, function(a, b) return (a.sortText or a.label) < (b.sortText or b.label) end) -- cgit From b2bad0ac91ddb9b33c3547b6fd4f7278794818d9 Mon Sep 17 00:00:00 2001 From: Mathias Fussenegger Date: Tue, 28 May 2024 23:20:25 +0200 Subject: feat(lsp): support postfix snippets in completion --- runtime/lua/vim/lsp/completion.lua | 35 +++++++++++++++++++++++++---------- 1 file changed, 25 insertions(+), 10 deletions(-) (limited to 'runtime') diff --git a/runtime/lua/vim/lsp/completion.lua b/runtime/lua/vim/lsp/completion.lua index f9b0563b86..39c0c5fa29 100644 --- a/runtime/lua/vim/lsp/completion.lua +++ b/runtime/lua/vim/lsp/completion.lua @@ -129,18 +129,33 @@ end --- @param item lsp.CompletionItem --- @return string local function get_completion_word(item) - if item.textEdit ~= nil and item.textEdit.newText ~= nil and item.textEdit.newText ~= '' then - if item.insertTextFormat == protocol.InsertTextFormat.PlainText then - return item.textEdit.newText - else - return parse_snippet(item.textEdit.newText) - end - elseif item.insertText ~= nil and item.insertText ~= '' then - if item.insertTextFormat == protocol.InsertTextFormat.PlainText then - return item.insertText - else + if item.insertTextFormat == protocol.InsertTextFormat.Snippet then + if item.textEdit then + -- Use label instead of text if text has different starting characters. + -- label is used as abbr (=displayed), but word is used for filtering + -- This is required for things like postfix completion. + -- E.g. in lua: + -- + -- local f = {} + -- f@| + -- ▲ + -- └─ cursor + -- + -- item.textEdit.newText: table.insert(f, $0) + -- label: insert + -- + -- Typing `i` would remove the candidate because newText starts with `t`. + local text = item.insertText or item.textEdit.newText + return #text < #item.label and text or item.label + elseif item.insertText and item.insertText ~= '' then return parse_snippet(item.insertText) + else + return item.label end + elseif item.textEdit then + return item.textEdit.newText + elseif item.insertText and item.insertText ~= '' then + return item.insertText end return item.label end -- cgit From 5c33815448e11b514678f39cecc74e68131d4628 Mon Sep 17 00:00:00 2001 From: Mathias Fußenegger Date: Thu, 30 May 2024 10:46:26 +0200 Subject: refactor(lsp): replace util.buf_versions with changedtick (#28943) `lsp.util.buf_versions` was already derived from changedtick (`on_lines` from `buf_attach` synced the version) As far as I can tell there is no need to keep track of the state in a separate table. --- runtime/doc/deprecated.txt | 3 +++ runtime/lua/vim/lsp.lua | 5 +---- runtime/lua/vim/lsp/_changetracking.lua | 3 +-- runtime/lua/vim/lsp/client.lua | 5 ++--- runtime/lua/vim/lsp/inlay_hint.lua | 4 ++-- runtime/lua/vim/lsp/semantic_tokens.lua | 6 +++--- runtime/lua/vim/lsp/util.lua | 16 +++++++++++----- 7 files changed, 23 insertions(+), 19 deletions(-) (limited to 'runtime') diff --git a/runtime/doc/deprecated.txt b/runtime/doc/deprecated.txt index 6c6585d76e..3b3e6afa9e 100644 --- a/runtime/doc/deprecated.txt +++ b/runtime/doc/deprecated.txt @@ -22,6 +22,9 @@ API LUA - vim.region() Use |getregionpos()| instead. +LSP +- *vim.lsp.util.buf_versions* Use |b:changedtick| instead. + DIAGNOSTICS - *vim.diagnostic.goto_next()* Use |vim.diagnostic.jump()| with `{count = 1}` instead. - *vim.diagnostic.goto_prev()* Use |vim.diagnostic.jump()| with `{count = -1}` instead. diff --git a/runtime/lua/vim/lsp.lua b/runtime/lua/vim/lsp.lua index 96dbf97146..c2deac0113 100644 --- a/runtime/lua/vim/lsp.lua +++ b/runtime/lua/vim/lsp.lua @@ -484,7 +484,6 @@ local function text_document_did_save_handler(bufnr) text = lsp._buf_get_full_text(bufnr), }, }) - util.buf_versions[bufnr] = 0 end local save_capability = vim.tbl_get(client.server_capabilities, 'textDocumentSync', 'save') if save_capability then @@ -520,7 +519,6 @@ local function buf_detach_client(bufnr, client) end client.attached_buffers[bufnr] = nil - util.buf_versions[bufnr] = nil local namespace = lsp.diagnostic.get_namespace(client.id) vim.diagnostic.reset(namespace, bufnr) @@ -576,12 +574,11 @@ local function buf_attach(bufnr) }) -- First time, so attach and set up stuff. api.nvim_buf_attach(bufnr, false, { - on_lines = function(_, _, changedtick, firstline, lastline, new_lastline) + on_lines = function(_, _, _, firstline, lastline, new_lastline) if #lsp.get_clients({ bufnr = bufnr }) == 0 then -- detach if there are no clients return #lsp.get_clients({ bufnr = bufnr, _uninitialized = true }) == 0 end - util.buf_versions[bufnr] = changedtick changetracking.send_changes(bufnr, firstline, lastline, new_lastline) end, diff --git a/runtime/lua/vim/lsp/_changetracking.lua b/runtime/lua/vim/lsp/_changetracking.lua index b2be53269f..ce701f0772 100644 --- a/runtime/lua/vim/lsp/_changetracking.lua +++ b/runtime/lua/vim/lsp/_changetracking.lua @@ -1,6 +1,5 @@ local protocol = require('vim.lsp.protocol') local sync = require('vim.lsp.sync') -local util = require('vim.lsp.util') local api = vim.api local uv = vim.uv @@ -277,7 +276,7 @@ local function send_changes(bufnr, sync_kind, state, buf_state) client.notify(protocol.Methods.textDocument_didChange, { textDocument = { uri = uri, - version = util.buf_versions[bufnr], + version = vim.b[bufnr].changedtick, }, contentChanges = changes, }) diff --git a/runtime/lua/vim/lsp/client.lua b/runtime/lua/vim/lsp/client.lua index 327cd19125..b28fe2f797 100644 --- a/runtime/lua/vim/lsp/client.lua +++ b/runtime/lua/vim/lsp/client.lua @@ -673,8 +673,8 @@ function Client:_request(method, params, handler, bufnr) end -- Ensure pending didChange notifications are sent so that the server doesn't operate on a stale state changetracking.flush(self, bufnr) - local version = lsp.util.buf_versions[bufnr] bufnr = resolve_bufnr(bufnr) + local version = vim.b[bufnr].changedtick log.debug(self._log_prefix, 'client.request', self.id, method, params, handler, bufnr) local success, request_id = self.rpc.request(method, params, function(err, result) local context = { @@ -922,14 +922,13 @@ function Client:_text_document_did_open_handler(bufnr) local params = { textDocument = { - version = 0, + version = vim.b[bufnr].changedtick, uri = vim.uri_from_bufnr(bufnr), languageId = self.get_language_id(bufnr, filetype), text = lsp._buf_get_full_text(bufnr), }, } self.notify(ms.textDocument_didOpen, params) - lsp.util.buf_versions[bufnr] = params.textDocument.version -- Next chance we get, we should re-do the diagnostics vim.schedule(function() diff --git a/runtime/lua/vim/lsp/inlay_hint.lua b/runtime/lua/vim/lsp/inlay_hint.lua index f98496456b..78f309abf7 100644 --- a/runtime/lua/vim/lsp/inlay_hint.lua +++ b/runtime/lua/vim/lsp/inlay_hint.lua @@ -43,7 +43,7 @@ function M.on_inlayhint(err, result, ctx, _) return end local bufnr = assert(ctx.bufnr) - if util.buf_versions[bufnr] ~= ctx.version then + if vim.b[bufnr].changedtick ~= ctx.version then return end local client_id = ctx.client_id @@ -324,7 +324,7 @@ api.nvim_set_decoration_provider(namespace, { return end - if bufstate.version ~= util.buf_versions[bufnr] then + if bufstate.version ~= vim.b[bufnr].changedtick then return end diff --git a/runtime/lua/vim/lsp/semantic_tokens.lua b/runtime/lua/vim/lsp/semantic_tokens.lua index ef2502b12e..278014a4ea 100644 --- a/runtime/lua/vim/lsp/semantic_tokens.lua +++ b/runtime/lua/vim/lsp/semantic_tokens.lua @@ -116,7 +116,7 @@ local function tokens_to_ranges(data, bufnr, client, request) if elapsed_ns > yield_interval_ns then vim.schedule(function() - coroutine.resume(co, util.buf_versions[bufnr]) + coroutine.resume(co, vim.b[bufnr].changedtick) end) if request.version ~= coroutine.yield() then -- request became stale since the last time the coroutine ran. @@ -275,7 +275,7 @@ end --- ---@package function STHighlighter:send_request() - local version = util.buf_versions[self.bufnr] + local version = vim.b[self.bufnr].changedtick self:reset_timer() @@ -418,7 +418,7 @@ end function STHighlighter:on_win(topline, botline) for client_id, state in pairs(self.client_state) do local current_result = state.current_result - if current_result.version and current_result.version == util.buf_versions[self.bufnr] then + if current_result.version and current_result.version == vim.b[self.bufnr].changedtick then if not current_result.namespace_cleared then api.nvim_buf_clear_namespace(self.bufnr, state.namespace, 0, -1) current_result.namespace_cleared = true diff --git a/runtime/lua/vim/lsp/util.lua b/runtime/lua/vim/lsp/util.lua index 0099e82f52..d1f0e97065 100644 --- a/runtime/lua/vim/lsp/util.lua +++ b/runtime/lua/vim/lsp/util.lua @@ -509,8 +509,7 @@ function M.apply_text_document_edit(text_document_edit, index, offset_encoding) and ( text_document.version and text_document.version > 0 - and M.buf_versions[bufnr] - and M.buf_versions[bufnr] > text_document.version + and vim.b[bufnr].changedtick > text_document.version ) then print('Buffer ', text_document.uri, ' newer than edits.') @@ -2200,9 +2199,16 @@ function M._refresh(method, opts) end end -M._get_line_byte_from_position = get_line_byte_from_position - ---@nodoc -M.buf_versions = {} ---@type table +---@deprecated +---@type table +M.buf_versions = setmetatable({}, { + __index = function(_, bufnr) + vim.deprecate('vim.lsp.util.buf_versions', 'vim.b.changedtick', '0.13') + return vim.b[bufnr].changedtick + end, +}) + +M._get_line_byte_from_position = get_line_byte_from_position return M -- cgit From 7c48cedf3078648e2a1ab9a4002e8795e8d07f53 Mon Sep 17 00:00:00 2001 From: Christian Clason Date: Fri, 31 May 2024 11:24:06 +0200 Subject: vim-patch:7129f2a: runtime(java): Improve the matching of lambda expressions (vim/vim#14880) - Distinguish some formal parameters. - Support multi-line definitions. https://github.com/vim/vim/commit/7129f2ad2fd9de3e3812a569ba3ad6bf162fd238 Co-authored-by: Aliaksei Budavei <32549825+zzzyxwvut@users.noreply.github.com> --- runtime/syntax/java.vim | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) (limited to 'runtime') diff --git a/runtime/syntax/java.vim b/runtime/syntax/java.vim index 9867b147c2..5ba724d24e 100644 --- a/runtime/syntax/java.vim +++ b/runtime/syntax/java.vim @@ -3,7 +3,7 @@ " Maintainer: Aliaksei Budavei <0x000c70 AT gmail DOT com> " Former Maintainer: Claudio Fleiner " Repository: https://github.com/zzzyxwvut/java-vim.git -" Last Change: 2024 May 10 +" Last Change: 2024 May 30 " Please check :help java.vim for comments on some of the options available. @@ -348,7 +348,6 @@ if exists("java_highlight_functions") exec 'syn region javaFuncDef start=/' . s:ff.Engine('\%#=2', '') . '^\s\+\%(\%(@\%(\K\k*\.\)*\K\k*\>\)\s\+\)*\%(p\%(ublic\|rotected\|rivate\)\s\+\)\=\%(\%(abstract\|default\)\s\+\|\%(\%(final\|\%(native\|strictfp\)\|s\%(tatic\|ynchronized\)\)\s\+\)*\)\=\%(<.*[[:space:]-]\@' . s:ff.Peek('1', '') . '\s\+\)\=\%(void\|\%(b\%(oolean\|yte\)\|char\|short\|int\|long\|float\|double\|\%(\<\K\k*\>\.\)*\<' . s:ff.UpperCase('[$_[:upper:]]', '[^a-z0-9]') . '\k*\>\%(<[^(){}]*[[:space:]-]\@' . s:ff.Peek('1', '') . '\)\=\)\%(\[\]\)*\)\s\+\<' . s:ff.LowerCase('[$_[:lower:]]', '[^A-Z0-9]') . '\k*\>\s*(/ end=/)/ skip=/\/\*.\{-}\*\/\|\/\/.*$/ contains=@javaFuncParams' endif - exec 'syn match javaLambdaDef "\<\K\k*\>\%(\\)\@' . s:ff.Peek('7', '') . '"' syn match javaBraces "[{}]" endif @@ -421,9 +420,26 @@ syn match javaParenError "\]" hi def link javaParenError javaError +" Lambda expressions (JLS-17, §15.27). if exists("java_highlight_functions") " Make ()-matching definitions after the parenthesis error catcher. - exec 'syn match javaLambdaDef "\k\@' . s:ff.Peek('4', '') . '?\[\]@,.]\)*)\s*->"' + " + " Match: ([@A [@B ...] final] var a[, var b, ...]) -> + " | ([@A [@B ...] final] T[<α>][[][]] a[, T b, ...]) -> + " There is no recognition of expressions interspersed with comments + " or of expressions whose parameterised parameter types are written + " across multiple lines. + exec 'syn match javaLambdaDef "\k\@' . s:ff.Peek('4', '') . '\%((\_.\{-1,})\)\{-,1}[[:space:]\n]\+\)*\%(final[[:space:]\n]\+\)\=\%(\<\K\k*\>\.\)*\<\K\k*\>\%(<[^(){}]*[[:space:]-]\@' . s:ff.Peek('1', '') . '\)\=\%(\%(\%(\[\]\)\+\|\.\.\.\)\)\=[[:space:]\n]\+\<\K\k*\>\%(\[\]\)*\%(,[[:space:]\n]*\)\=\)\+)[[:space:]\n]*->" contains=javaAnnotation,javaParamModifier,javaLambdaVarType,javaType,@javaClasses,javaVarArg' + " Match: () -> + " | (a[, b, ...]) -> + exec 'syn match javaLambdaDef "\k\@' . s:ff.Peek('4', '') . '\%(,[[:space:]\n]*\)\=\)*)[[:space:]\n]*->"' + " Match: a -> + exec 'syn match javaLambdaDef "\<\K\k*\>\%(\\)\@' . s:ff.Peek('7', '') . '"' + + syn keyword javaParamModifier contained final + hi def link javaParamModifier javaConceptKind + syn keyword javaLambdaVarType contained var + hi def link javaLambdaVarType javaOperator endif " The @javaTop cluster comprises non-contained Java syntax groups. -- cgit From 07af492f635c51d44d02d8012611cc5e11a4af19 Mon Sep 17 00:00:00 2001 From: Christian Clason Date: Fri, 31 May 2024 12:07:31 +0200 Subject: vim-patch:9.1.0453: filetype: rasi files are not recognized Problem: filetype: rasi files are not recognized Solution: regonize '*.rasi' files as rasi filetype, include a filetype and syntax plugin (Pierrick Guillaume) ported from: https://github.com/Fymyte/rasi.vim closes: vim/vim#14821 https://github.com/vim/vim/commit/280e5b13ca568ed592a894140bf1ac74356f4b33 Co-authored-by: Pierrick Guillaume --- runtime/doc/syntax.txt | 7 + runtime/ftplugin/rasi.vim | 25 ++++ runtime/lua/vim/filetype.lua | 1 + runtime/syntax/rasi.vim | 298 +++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 331 insertions(+) create mode 100644 runtime/ftplugin/rasi.vim create mode 100644 runtime/syntax/rasi.vim (limited to 'runtime') diff --git a/runtime/doc/syntax.txt b/runtime/doc/syntax.txt index 06d7ad8f7e..fc55569a1c 100644 --- a/runtime/doc/syntax.txt +++ b/runtime/doc/syntax.txt @@ -2575,6 +2575,13 @@ To highlight R code in knitr chunk headers, add to your |vimrc|: > let rrst_syn_hl_chunk = 1 +RASI *rasi.vim* *ft-rasi-syntax* + +Rasi stands for Rofi Advanced Style Information. It is used by the program +`rofi` to style the rendering of the search window. The language is heavily +inspired by CSS stylesheet. Files with the following extensions are recognized +as rasi files: .rasi. + READLINE *readline.vim* *ft-readline-syntax* The readline library is primarily used by the BASH shell, which adds quite a diff --git a/runtime/ftplugin/rasi.vim b/runtime/ftplugin/rasi.vim new file mode 100644 index 0000000000..5f8ce862df --- /dev/null +++ b/runtime/ftplugin/rasi.vim @@ -0,0 +1,25 @@ +" Vim filetype plugin file +" Language: RASI +" Maintainer: Pierrick Guillaume +" Last Change: 2024 May 21 + +if exists("b:did_ftplugin") + finish +endif +let b:did_ftplugin = 1 + +let s:cpo_save = &cpo +set cpo&vim + +let b:undo_ftplugin = "setl com< cms< isk< inc<" + +setlocal comments=s1:/*,mb:*,ex:*/ +setlocal commentstring=//\ %s +setlocal iskeyword+=- + +let &l:include = '^\s*@import\s\+\%(url(\)\=' + +let &cpo = s:cpo_save +unlet s:cpo_save + +" vim: ts=8 diff --git a/runtime/lua/vim/filetype.lua b/runtime/lua/vim/filetype.lua index 2ab6cc6059..500632a2b2 100644 --- a/runtime/lua/vim/filetype.lua +++ b/runtime/lua/vim/filetype.lua @@ -873,6 +873,7 @@ local extension = { t6 = 'raku', p6 = 'raku', raml = 'raml', + rasi = 'rasi', rbs = 'rbs', rego = 'rego', rem = 'remind', diff --git a/runtime/syntax/rasi.vim b/runtime/syntax/rasi.vim new file mode 100644 index 0000000000..40c3393fc5 --- /dev/null +++ b/runtime/syntax/rasi.vim @@ -0,0 +1,298 @@ +" Vim syntax file +" Language: rasi (Rofi Advanced Style Information) +" Maintainer: Pierrick Guillaume +" Last Change: 2024 May 21 +" +" Syntax support for rasi config file + +" This file is based on syntax defined in rofi-theme man page +" https://man.archlinux.org/man/community/rofi/rofi-theme.5.en + +if exists('b:current_syntax') + finish +endif +let b:current_syntax = 'rasi' + +" String {{{ +syn region rasiString start=+"+ skip=+\\"+ end=+"+ oneline contained +syn match rasiCharacter +L\='[^\\]'+ contained + +syn cluster rasiPropertyVals add=rasiString,rasiCharacter +" }}} + +" Integer/Real {{{ +syn match rasiNumber display contained '[+-]\?\d\+\(\.\d\+\)\?' + +syn cluster rasiPropertyVals add=rasiNumber +" }}} + +" Boolean {{{ +syn keyword rasiBool contained true false + +syn cluster rasiPropertyVals add=rasiBool +" }}} + +" Image {{{ +syn match rasiInvImage display contained 'url([^)]*)' +syn keyword rasiImageK contained url linear-gradient + +syn match rasiImage display contained transparent 'url(\s*"\([^"]\|\\"\)\+"\(\s*,\s*\(none\|both\|width\|height\)\)\?\s*)' contains=rasiImageScale,rasiString,rasiImageK +syn keyword rasiImageScale contained none both width height + +syn match rasiImage display contained transparent 'linear-gradient(\s*\(\(top\|left\|right\|bottom\)\s*,\s*\)\?[^,)]\+\s*\(,\s*[^,)]\+\s*\)\+)' contains=rasiImageDirection,@rasiColors,rasiImageK +syn keyword rasiImageDirection contained top left right bottom + +syn match rasiImage display contained transparent 'linear-gradient(\s*\d\+\(rad\|grad\|deg\)\s*,\s*[^,)]\+\s*\(,\s*[^,)]\+\s*\)\+)' contains=rasiImageUnit,@rasiColor,@rasiInvColor,rasiNumber,rasiImageK +syn match rasiImageUnit display contained '\(rad\|grad\|deg\)\>' + +syn cluster rasiPropertyVals add=rasiInvImage,rasiImage +" }}} + +" Reference {{{ +syn match rasiReference display contained '@[a-zA-Z0-9-]\+' + +syn keyword rasiVarReferenceK contained var + +syn match rasiInvVarReference display contained 'var([^)]*)' +syn match rasiVarReference display contained transparent 'var(\s*[a-zA-Z0-9-]\+\s*,\s*\(\a\+\s*([^)]*)\)\?[^),]*)' contains=rasiVarReferenceK,rasiPropertyIdRef,@rasiPropertyVals +syn match rasiPropertyIdRef display contained '\a[a-zA-Z0-9-]*' + +syn cluster rasiPropertyVals add=rasiReference,rasiInvVarReference,rasiVarReference +" }}} + +" Env variable {{{ +syn match rasiInvEnv display contained '${[^}]*}' +syn match rasiEnv display contained '${\w\+}'hs=s+2,he=e-1 + +syn keyword rasiEnvVarK contained env + +syn match rasiInvEnvVar display contained 'env([^)]*)' +syn match rasiEnvVar display contained transparent 'env(\s*\w\+\s*,\s*\(\a\+([^)]*)\)\?[^),]*)' contains=rasiEnvVarK,rasiEnvRef,@rasiPropertyVals +syn match rasiEnvRef display contained '\a\w*' + +syn cluster rasiPropertyVals add=rasiEnv,rasiInvEnv,rasiInvEnvVar,rasiEnvVar +" }}} + +" Color {{{ +syn keyword rasiColorK contained rgb[a] hsl[a] hwb[a] cmyk + +syn match rasiHexColor display contained '#\x\{3,4}' +syn match rasiHexColor display contained '#\x\{6}' +syn match rasiHexColor display contained '#\x\{8}' +syn match rasiInvHexColor display contained '#\x\{5}\X'he=e-1,me=e-1 +syn match rasiInvHexColor display contained '#\x\{7}\X'he=e-1,me=e-1 + +syn match rasiInvRGBColor display contained 'rgb\(a\)\?([^)]*)' +syn match rasiRGBColor display contained transparent 'rgb\(a\)\?(\s*\d\+\s*\(%\)\?\s*,\(\s*\d\+\s*\(%\)\?\s*\){2}\(,\s*\(\d\(\.\d*\)\?\|\d\{,3}%\)\s*\)\?)' contains=rasiColorK,rasiNumber,rasiDistance + +syn match rasiInvHSLColor display contained 'h\(sl\|wb\)\(a\)\?([^)]*)' +syn match rasiHSLColor display contained transparent 'h\(sl\|wb\)\(a\)\?(\s*\d\+\(\.\d*\)\?\(deg\|rad\|grad\|turn\)\?\s*\(,\s*\(\d\(\.\d*\)\?\|\d\{,3}%\)\s*\)\{2,3})' contains=rasiColorK,rasiNumber,rasiDistance + + +"this matches doesn't works properly (too long ?) +syn match rasiInvCMYKColor display contained 'cmyk([^)]*)' +syn match rasiCMYKColor display contained transparent 'cmyk(\s*\(\d\(\.\d*\)\?\|\d\{,3}%\)\s*\(,\s*\(\d\(\.\d*\)\?\|\d\{,3}%\)\s*\)\{3,4})' contains=rasiColorK,rasiNumber,rasiDistance + +syn case ignore +syn keyword rasiNamedColor contained + \ AliceBlue AntiqueWhite Aqua Aquamarine Azure Beige Bisque Black BlanchedAlmond Blue + \ BlueViolet Brown BurlyWood CadetBlue Chartreuse Chocolate Coral CornflowerBlue Cornsilk + \ Crimson Cyan DarkBlue DarkCyan DarkGoldenRod DarkGray DarkGrey DarkGreen DarkKhaki DarkMagenta + \ DarkOliveGreen DarkOrange DarkOrchid DarkRed DarkSalmon DarkSeaGreen Dark SlateBlue + \ DarkSlateGray DarkSlateGrey DarkTurquoise DarkViolet DeepPink DeepSkyBlue DimGray DimGrey + \ DodgerBlue FireBrick FloralWhite ForestGreen Fuchsia Gainsboro GhostWhite Gold GoldenRod + \ Gray Grey Green GreenYellow HoneyDew HotPink IndianRed Indigo Ivory Khaki Lavender + \ LavenderBlush LawnGreen LemonChiffon LightBlue LightCoral LightCyan LightGoldenRodYellow + \ LightGray LightGrey LightGreen LightPink LightSalmon LightSeaGreen LightSkyBlue LightSlateGray + \ LightSlateGrey LightSteelBlue LightYellow Lime LimeGreen Linen Magenta Maroon MediumAquaMarine + \ MediumBlue MediumOrchid MediumPurple MediumSeaGreen MediumSlateBlue MediumSpringGreen + \ MediumTurquoise MediumVioletRed MidnightBlue MintCream MistyRose Moccasin NavajoWhite Navy + \ OldLace Olive OliveDrab Orange OrangeRed Orchid PaleGoldenRod PaleGreen PaleTurquoise + \ PaleVioletRed PapayaWhip PeachPuff Peru Pink Plum PowderBlue Purple RebeccaPurple Red + \ RosyBrown RoyalBlue SaddleBrown Salmon SandyBrown SeaGreen SeaShell Sienna Silver SkyBlue + \ SlateBlue SlateGray SlateGrey Snow SpringGreen SteelBlue Tan Teal Thistle Tomato Turquoise + \ Violet Wheat White WhiteSmoke Yellow YellowGreen transparent[] "uses `[]` to escape keyword + +syn cluster rasiColors add=rasiHexColor,rasiRGBColor,rasiHSLColor,rasiCMYKColor,rasiNamedColor +syn cluster rasiColors add=rasiInvHexColor,rasiInvRGBColor,rasiInvHSLColor,rasiInvCMYKColor + +syn cluster rasiPropertyVals add=@rasiColors +" }}} + +" Text-Style {{{ +syn keyword rasiTextStyle contained bold italic underline strikethrough none + +syn cluster rasiPropertyVals add=rasiTextStyle +" }}} + +" Line-Style {{{ +syn keyword rasiLineStyle contained dash solid + +syn cluster rasiPropertyVals add=rasiLineStyle +" }}} + +" Distance {{{ +syn match rasiDistanceUnit display contained '\(px\|em\|ch\|%\|mm\)' + +syn match rasiInvDistance display contained '[+-]\?\d\+\.\d\+\(px\|mm\)' +syn match rasiDistance display contained transparent '[-+]\?\d\+\(px\|mm\)' contains=rasiDistanceUnit,rasiNumber +syn match rasiDistance display contained transparent '[+-]\?\d\+\(\.\d\+\)\?\(em\|ch\|%\)' contains=rasiDistanceUnit,rasiNumber + +syn keyword rasiDistanceCalc contained calc nextgroup=rasiDistanceCalcBody +syn region rasiDistanceCalcBody display contained start=+(+ end=+)+ contains=rasiDistanceCalcOp,rasiDistance,rasiInvDistance +syn match rasiDistanceCalcOp display contained '\(+\|-\|/\|\*\|%\|min\|max\)' + +syn cluster rasiPropertyVals add=rasiInvDistance,rasiDistance,rasiDistanceCalc +" }}} + +" Position {{{ +syn keyword rasiPosition contained center east north west south + +syn cluster rasiPropertyVals add=rasiPosition +" }}} + +" Orientation {{{ +syn keyword rasiOrientation contained horizontal vertical + +syn cluster rasiPropertyVals add=rasiOrientation +" }}} + +" Cursor {{{ +syn keyword rasiCursor contained default pointer text + +syn cluster rasiPropertyVals add=rasiCursor +" }}} + +" Keyword List {{{ +syn region rasiKeywordList contained start=+\[+ end=+\]+ contains=rasiPropertyIdRef + +syn cluster rasiPropertyVals add=rasiKeywordList +" }}} + +" Inherit {{{ +syn keyword rasiInherit contained inherit children + +syn cluster rasiPropertyVals add=rasiInherit +" }}} + +syn match rasiGlobalImport display '^\s*@\(import\|theme\)' nextgroup=rasiString skipwhite + +" Section {{{ +" syn region rasiSection transparent start='^[^{]\+{'me=e-1 end='}' contains=rasiSectionOpenning,rasiSectionContent +syn match rasiSectionOpenning transparent '^[^{]\+{'me=e-1 contains=rasiGlobalSection,rasiWidgetName,rasiGlobalMedia nextgroup=rasiThemeSectionContent +" syn match rasiThemeInnerSectionOpenning transparent '^[^:${]\+{'me=e-1 contains=rasiWidgetName nextgroup=rasiThemeInnerSectionContent contained + +syn match rasiGlobalMedia display contained '^\s*@media' nextgroup=rasiInvMediaBody,rasiMediaBody skipwhite +syn match rasiInvMediaBody display contained '([^)]*)' +syn match rasiMediaBody display contained '(\s*[a-z-]\+\s*:\s*\d\+\(px\|mm\)\?\s*)' contains=rasiMediaK,rasiNumber,rasiDistance +syn keyword rasiMediaK contained min-width max-width min-height max-height min-aspect-ratio max-aspect-ratio monitor-id + +syn match rasiGlobalSection display contained '^*' +syn match rasiWidgetName display contained '[a-zA-Z0-9-]\+' nextgroup=rasiVisibleMod skipwhite + +syn keyword rasiVisibleMod contained normal selected alternate nextgroup=rasiVisibleMod,rasiStateWrapper skipwhite +syn match rasiStateWrapper display contained transparent '\.\(normal\|active\|urgent\)' contains=rasiState +syn keyword rasiState contained normal active urgent + + +syn region rasiThemeSectionContent transparent start="{" end="}" contains=rasiProperty,rasiComment,rasiCommentL,rasiSectionOpenning contained +" syn region rasiThemeInnerSectionContent transparent start="{" end="}" contains=rasiProperty,rasiComment,rasiCommentL,rasiThemeInnerSectionOpenning contained + +syn match rasiProperty transparent '^\s*\S\+\s*:.*;\s*$' keepend contained contains=rasiPropertyId,rasiInvPropertyId,rasiPropertyVal,rasiComment,rasiCommentL +syn match rasiInvPropertyId '^\([^:]\&[^/]\{2}\)*:'me=e-1 contained +syn match rasiPropertyId '^\s*[0-9a-zA-Z-]\+\s*:'me=e-1 contained +syn match rasiInvPropertyVal ':[^;];\s*\S\+\s*$'ms=s+1,hs=s+1 +syn match rasiPropertyVal ':\s*[^;]\+;\s*$'ms=s+1,hs=s+1 contained contains=@rasiPropertyVals +" }}} + +" Comment {{{ +syn cluster rasiCommentGroup contains=rasiTodo,rasiBadContinuation + +syn region rasiCommentL start="//" skip="\\$" end="$" keepend contains=@rasiCommentGroup,@Spell +syn region rasiComment start="/\*" end="\*/" contains=@rasiCommentGroup,rasiCommentStartError,@Spell fold extend + +syn match rasiCommentError display '\*/' + +syn keyword rasiTodo contained TODO FIXME XXX NOTE + +if exists("rasi_minlines") + let b:rasi_minlines = rasi_minlines +else + let b:rasi_minlines = 50 +endif +exec "syn sync ccomment rasiComment minlines=" . b:rasi_minlines +" }}} + + + +" Highlighting: {{{ +hi def link rasiError Error + +hi def link rasiTodo Todo +hi def link rasiComment Comment +hi def link rasiCommentStart rasiComment +hi def link rasiCommentL rasiComment +hi def link rasiCommentError rasiError + +hi def link rasiString String +hi def link rasiNumber Number +hi def link rasiBool Boolean + +hi def link rasiImageK Function +hi def link rasiImageScale Keyword +hi def link rasiImageDirection Keyword +hi def link rasiImageUnit Type +hi def link rasiInvImage rasiError + +hi def link rasiHexColor Number +hi def link rasiColorK Function +hi def link rasiNamedColor Number +hi def link rasiInvColor rasiError +hi def link rasiInvHexColor rasiInvColor +hi def link rasiInvRGBColor rasiInvColor +hi def link rasiInvHSLColor rasiInvColor +hi def link rasiInvCMYKColor rasiInvColor + +hi def link rasiTextStyle Keyword +hi def link rasiLineStyle Keyword + +hi def link rasiDistanceUnit Type +hi def link rasiDistanceCalc Function +hi def link rasiDistanceCalcOp Operator +hi def link rasiInvDistance rasiError + +hi def link rasiPosition Keyword +hi def link rasiOrientation Keyword +hi def link rasiCursor Keyword + +hi def link rasiReference Identifier +hi def link rasiPropertyIdRef Identifier +hi def link rasiVarReferenceK Function +hi def link rasiInvVarReference rasiError + +hi def link rasiEnv Identifier +hi def link rasiEnvRef Identifier +hi def link rasiEnvVarK Function +hi def link rasiInvEnv rasiError +hi def link rasiInvEnvVar rasiError + +hi def link rasiWidgetName StorageClass +hi def link rasiGlobalSection StorageClass +hi def link rasiVisibleMod Type +hi def link rasiState Tag + +hi def link rasiInherit Identifier + +hi def link rasiGlobalImport Include + +hi def link rasiGlobalMedia Preproc +hi def link rasiMediaK Keyword +hi def link rasiInvMediaBody rasiError + +hi def link rasiPropertyId Identifier +hi def link rasiInvProperty rasiError +hi def link rasiInvPropertyId rasiError +hi def link rasiInvPropertyVal rasiError +" }}} + +" vim:ts=8 -- cgit From 9b3dfa3ac0dbc823c00a23ed7bd57dc0f0782a3f Mon Sep 17 00:00:00 2001 From: Christian Clason Date: Fri, 31 May 2024 12:33:00 +0200 Subject: vim-patch:9.1.0454: minor issues in test_filetype with rasi test Problem: minor issues in test_filetype with rasi test (after 9.1.0453) Solution: re-sort test_filetype, fix wrong syntax.txt help tags https://github.com/vim/vim/commit/f3dd6f617c65a9b939697362efe6833eb2778612 Co-authored-by: Christian Brabandt --- runtime/doc/syntax.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'runtime') diff --git a/runtime/doc/syntax.txt b/runtime/doc/syntax.txt index fc55569a1c..cf553d6707 100644 --- a/runtime/doc/syntax.txt +++ b/runtime/doc/syntax.txt @@ -2578,7 +2578,7 @@ To highlight R code in knitr chunk headers, add to your |vimrc|: > RASI *rasi.vim* *ft-rasi-syntax* Rasi stands for Rofi Advanced Style Information. It is used by the program -`rofi` to style the rendering of the search window. The language is heavily +rofi to style the rendering of the search window. The language is heavily inspired by CSS stylesheet. Files with the following extensions are recognized as rasi files: .rasi. -- cgit From 6566a59b3a6c8dabfa40f8debd0de96d875825e9 Mon Sep 17 00:00:00 2001 From: Ilia Choly Date: Fri, 31 May 2024 08:41:10 -0400 Subject: refactor(lsp): use predefined types in util function signatures (#29095) --- runtime/doc/lsp.txt | 44 +++++++++++++++++--------------- runtime/lua/vim/lsp/util.lua | 60 +++++++++++++++++++++++--------------------- 2 files changed, 55 insertions(+), 49 deletions(-) (limited to 'runtime') diff --git a/runtime/doc/lsp.txt b/runtime/doc/lsp.txt index a78a16968f..c4856c6818 100644 --- a/runtime/doc/lsp.txt +++ b/runtime/doc/lsp.txt @@ -1832,8 +1832,8 @@ apply_text_document_edit({text_document_edit}, {index}, {offset_encoding}) document. Parameters: ~ - • {text_document_edit} (`table`) a `TextDocumentEdit` object - • {index} (`integer`) Optional index of the edit, if from + • {text_document_edit} (`lsp.TextDocumentEdit`) + • {index} (`integer?`) Optional index of the edit, if from a list of edits (or nil, if not from a list) • {offset_encoding} (`string?`) @@ -1845,7 +1845,7 @@ apply_text_edits({text_edits}, {bufnr}, {offset_encoding}) Applies a list of text edits to a buffer. Parameters: ~ - • {text_edits} (`table`) list of `TextEdit` objects + • {text_edits} (`lsp.TextEdit[]`) • {bufnr} (`integer`) Buffer id • {offset_encoding} (`string`) utf-8|utf-16|utf-32 @@ -1857,7 +1857,7 @@ apply_workspace_edit({workspace_edit}, {offset_encoding}) Applies a `WorkspaceEdit`. Parameters: ~ - • {workspace_edit} (`table`) `WorkspaceEdit` + • {workspace_edit} (`lsp.WorkspaceEdit`) • {offset_encoding} (`string`) utf-8|utf-16|utf-32 (required) See also: ~ @@ -1875,8 +1875,7 @@ buf_highlight_references({bufnr}, {references}, {offset_encoding}) Parameters: ~ • {bufnr} (`integer`) Buffer id - • {references} (`table`) List of `DocumentHighlight` objects to - highlight + • {references} (`lsp.DocumentHighlight[]`) objects to highlight • {offset_encoding} (`string`) One of "utf-8", "utf-16", "utf-32". See also: ~ @@ -1910,8 +1909,8 @@ convert_input_to_markdown_lines({input}, {contents}) Parameters: ~ • {input} (`lsp.MarkedString|lsp.MarkedString[]|lsp.MarkupContent`) - • {contents} (`table?`) List of strings to extend with converted lines. - Defaults to {}. + • {contents} (`string[]?`) List of strings to extend with converted + lines. Defaults to {}. Return: ~ (`string[]`) extended with lines of converted markdown. @@ -1924,15 +1923,16 @@ convert_signature_help_to_markdown_lines({signature_help}, {ft}, {triggers}) Converts `textDocument/signatureHelp` response to markdown lines. Parameters: ~ - • {signature_help} (`table`) Response of `textDocument/SignatureHelp` + • {signature_help} (`lsp.SignatureHelp`) Response of + `textDocument/SignatureHelp` • {ft} (`string?`) filetype that will be use as the `lang` for the label markdown code block • {triggers} (`table?`) list of trigger characters from the lsp server. used to better determine parameter offsets Return (multiple): ~ - (`table?`) table list of lines of converted markdown. - (`table?`) table of active hl + (`string[]?`) table list of lines of converted markdown. + (`number[]?`) table of active hl See also: ~ • https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_signatureHelp @@ -1954,7 +1954,7 @@ jump_to_location({location}, {offset_encoding}, {reuse_win}) Jumps to a location. Parameters: ~ - • {location} (`table`) (`Location`|`LocationLink`) + • {location} (`lsp.Location|lsp.LocationLink`) • {offset_encoding} (`string?`) utf-8|utf-16|utf-32 • {reuse_win} (`boolean?`) Jump to existing window if buffer is already open. @@ -2019,7 +2019,8 @@ make_formatting_params({options}) cursor position. Parameters: ~ - • {options} (`table?`) with valid `FormattingOptions` entries + • {options} (`lsp.FormattingOptions?`) with valid `FormattingOptions` + entries Return: ~ (`lsp.DocumentFormattingParams`) object @@ -2059,7 +2060,7 @@ make_position_params({window}, {offset_encoding}) `window` Return: ~ - (`table`) `TextDocumentPositionParams` object + (`lsp.TextDocumentPositionParams`) See also: ~ • https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocumentPositionParams @@ -2090,7 +2091,7 @@ make_text_document_params({bufnr}) • {bufnr} (`integer?`) Buffer handle, defaults to current Return: ~ - (`table`) `TextDocumentIdentifier` + (`lsp.TextDocumentIdentifier`) See also: ~ • https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocumentIdentifier @@ -2100,8 +2101,11 @@ make_workspace_params({added}, {removed}) Create the workspace params Parameters: ~ - • {added} (`table`) - • {removed} (`table`) + • {added} (`lsp.WorkspaceFolder[]`) + • {removed} (`lsp.WorkspaceFolder[]`) + + Return: ~ + (`lsp.WorkspaceFoldersChangeEvent`) *vim.lsp.util.open_floating_preview()* open_floating_preview({contents}, {syntax}, {opts}) @@ -2145,7 +2149,7 @@ preview_location({location}, {opts}) *vim.lsp.util.preview_location()* definition) Parameters: ~ - • {location} (`table`) a single `Location` or `LocationLink` + • {location} (`lsp.Location|lsp.LocationLink`) • {opts} (`table`) Return (multiple): ~ @@ -2175,7 +2179,7 @@ show_document({location}, {offset_encoding}, {opts}) Shows document and optionally jumps to the location. Parameters: ~ - • {location} (`table`) (`Location`|`LocationLink`) + • {location} (`lsp.Location|lsp.LocationLink`) • {offset_encoding} (`string?`) utf-8|utf-16|utf-32 • {opts} (`table?`) options • reuse_win (boolean) Jump to existing window if @@ -2200,7 +2204,7 @@ stylize_markdown({bufnr}, {contents}, {opts}) Parameters: ~ • {bufnr} (`integer`) - • {contents} (`table`) of lines to show in window + • {contents} (`string[]`) of lines to show in window • {opts} (`table`) with optional fields • height of floating window • width of floating window diff --git a/runtime/lua/vim/lsp/util.lua b/runtime/lua/vim/lsp/util.lua index d1f0e97065..b33f6ccf69 100644 --- a/runtime/lua/vim/lsp/util.lua +++ b/runtime/lua/vim/lsp/util.lua @@ -173,11 +173,11 @@ local _str_byteindex_enc = M._str_byteindex_enc --- CAUTION: Changes in-place! --- ---@deprecated ----@param lines (table) Original list of strings ----@param A (table) Start position; a 2-tuple of {line,col} numbers ----@param B (table) End position; a 2-tuple of {line,col} numbers ----@param new_lines (table) list of strings to replace the original ----@return table The modified {lines} object +---@param lines string[] Original list of strings +---@param A [integer, integer] Start position; a 2-tuple of {line,col} numbers +---@param B [integer, integer] End position; a 2-tuple {line,col} numbers +---@param new_lines string[] list of strings to replace the original +---@return string[] The modified {lines} object function M.set_lines(lines, A, B, new_lines) vim.deprecate('vim.lsp.util.set_lines()', 'nil', '0.12') -- 0-indexing to 1-indexing @@ -343,7 +343,7 @@ local function get_line_byte_from_position(bufnr, position, offset_encoding) end --- Applies a list of text edits to a buffer. ----@param text_edits table list of `TextEdit` objects +---@param text_edits lsp.TextEdit[] ---@param bufnr integer Buffer id ---@param offset_encoding string utf-8|utf-16|utf-32 ---@see https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textEdit @@ -481,8 +481,8 @@ end --- Applies a `TextDocumentEdit`, which is a list of changes to a single --- document. --- ----@param text_document_edit table: a `TextDocumentEdit` object ----@param index integer: Optional index of the edit, if from a list of edits (or nil, if not from a list) +---@param text_document_edit lsp.TextDocumentEdit +---@param index? integer: Optional index of the edit, if from a list of edits (or nil, if not from a list) ---@param offset_encoding? string ---@see https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocumentEdit function M.apply_text_document_edit(text_document_edit, index, offset_encoding) @@ -533,6 +533,7 @@ local function path_under_prefix(path, prefix) end --- Get list of buffers whose filename matches the given path prefix (normalized full path) +---@param prefix string ---@return integer[] local function get_bufs_with_prefix(prefix) prefix = path_components(prefix) @@ -677,7 +678,7 @@ end --- Applies a `WorkspaceEdit`. --- ----@param workspace_edit table `WorkspaceEdit` +---@param workspace_edit lsp.WorkspaceEdit ---@param offset_encoding string utf-8|utf-16|utf-32 (required) ---@see https://microsoft.github.io/language-server-protocol/specifications/specification-current/#workspace_applyEdit function M.apply_workspace_edit(workspace_edit, offset_encoding) @@ -723,8 +724,8 @@ end --- Note that if the input is of type `MarkupContent` and its kind is `plaintext`, --- then the corresponding value is returned without further modifications. --- ----@param input (lsp.MarkedString | lsp.MarkedString[] | lsp.MarkupContent) ----@param contents (table|nil) List of strings to extend with converted lines. Defaults to {}. +---@param input lsp.MarkedString|lsp.MarkedString[]|lsp.MarkupContent +---@param contents string[]|nil List of strings to extend with converted lines. Defaults to {}. ---@return string[] extended with lines of converted markdown. ---@see https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_hover function M.convert_input_to_markdown_lines(input, contents) @@ -759,11 +760,11 @@ end --- Converts `textDocument/signatureHelp` response to markdown lines. --- ----@param signature_help table Response of `textDocument/SignatureHelp` +---@param signature_help lsp.SignatureHelp Response of `textDocument/SignatureHelp` ---@param ft string|nil filetype that will be use as the `lang` for the label markdown code block ---@param triggers table|nil list of trigger characters from the lsp server. used to better determine parameter offsets ----@return table|nil table list of lines of converted markdown. ----@return table|nil table of active hl +---@return string[]|nil table list of lines of converted markdown. +---@return number[]|nil table of active hl ---@see https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_signatureHelp function M.convert_signature_help_to_markdown_lines(signature_help, ft, triggers) if not signature_help.signatures then @@ -960,7 +961,7 @@ end --- Shows document and optionally jumps to the location. --- ----@param location table (`Location`|`LocationLink`) +---@param location lsp.Location|lsp.LocationLink ---@param offset_encoding string|nil utf-8|utf-16|utf-32 ---@param opts table|nil options --- - reuse_win (boolean) Jump to existing window if buffer is already open. @@ -1017,7 +1018,7 @@ end --- Jumps to a location. --- ----@param location table (`Location`|`LocationLink`) +---@param location lsp.Location|lsp.LocationLink ---@param offset_encoding string|nil utf-8|utf-16|utf-32 ---@param reuse_win boolean|nil Jump to existing window if buffer is already open. ---@return boolean `true` if the jump succeeded @@ -1038,7 +1039,7 @@ end --- - for Location, range is shown (e.g., function definition) --- - for LocationLink, targetRange is shown (e.g., body of function definition) --- ----@param location table a single `Location` or `LocationLink` +---@param location lsp.Location|lsp.LocationLink ---@param opts table ---@return integer|nil buffer id of float window ---@return integer|nil window id of float window @@ -1154,7 +1155,7 @@ end --- If you want to open a popup with fancy markdown, use `open_floating_preview` instead --- ---@param bufnr integer ----@param contents table of lines to show in window +---@param contents string[] of lines to show in window ---@param opts table with optional fields --- - height of floating window --- - width of floating window @@ -1669,7 +1670,7 @@ do --[[ References ]] --- Shows a list of document highlights for a certain buffer. --- ---@param bufnr integer Buffer id - ---@param references table List of `DocumentHighlight` objects to highlight + ---@param references lsp.DocumentHighlight[] objects to highlight ---@param offset_encoding string One of "utf-8", "utf-16", "utf-32". ---@see https://microsoft.github.io/language-server-protocol/specification/#textDocumentContentChangeEvent function M.buf_highlight_references(bufnr, references, offset_encoding) @@ -1873,7 +1874,7 @@ end --- CAUTION: Modifies the input in-place! --- ---@deprecated ----@param lines table list of lines +---@param lines string[] list of lines ---@return string filetype or "markdown" if it was unchanged. function M.try_trim_markdown_code_blocks(lines) vim.deprecate('vim.lsp.util.try_trim_markdown_code_blocks()', 'nil', '0.12') @@ -1898,7 +1899,7 @@ function M.try_trim_markdown_code_blocks(lines) end ---@param window integer|nil: window handle or 0 for current, defaults to current ----@param offset_encoding string utf-8|utf-16|utf-32|nil defaults to `offset_encoding` of first client of buffer of `window` +---@param offset_encoding? string utf-8|utf-16|utf-32|nil defaults to `offset_encoding` of first client of buffer of `window` local function make_position_param(window, offset_encoding) window = window or 0 local buf = api.nvim_win_get_buf(window) @@ -1919,7 +1920,7 @@ end --- ---@param window integer|nil: window handle or 0 for current, defaults to current ---@param offset_encoding string|nil utf-8|utf-16|utf-32|nil defaults to `offset_encoding` of first client of buffer of `window` ----@return table `TextDocumentPositionParams` object +---@return lsp.TextDocumentPositionParams ---@see https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocumentPositionParams function M.make_position_params(window, offset_encoding) window = window or 0 @@ -1932,7 +1933,7 @@ function M.make_position_params(window, offset_encoding) end --- Utility function for getting the encoding of the first LSP client on the given buffer. ----@param bufnr (integer) buffer handle or 0 for current, defaults to current +---@param bufnr integer buffer handle or 0 for current, defaults to current ---@return string encoding first client if there is one, nil otherwise function M._get_offset_encoding(bufnr) validate({ @@ -2033,15 +2034,16 @@ end --- Creates a `TextDocumentIdentifier` object for the current buffer. --- ---@param bufnr integer|nil: Buffer handle, defaults to current ----@return table `TextDocumentIdentifier` +---@return lsp.TextDocumentIdentifier ---@see https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocumentIdentifier function M.make_text_document_params(bufnr) return { uri = vim.uri_from_bufnr(bufnr or 0) } end --- Create the workspace params ----@param added table ----@param removed table +---@param added lsp.WorkspaceFolder[] +---@param removed lsp.WorkspaceFolder[] +---@return lsp.WorkspaceFoldersChangeEvent function M.make_workspace_params(added, removed) return { event = { added = added, removed = removed } } end @@ -2049,8 +2051,8 @@ end --- Returns indentation size. --- ---@see 'shiftwidth' ----@param bufnr (integer|nil): Buffer handle, defaults to current ----@return (integer) indentation size +---@param bufnr integer|nil: Buffer handle, defaults to current +---@return integer indentation size function M.get_effective_tabstop(bufnr) validate({ bufnr = { bufnr, 'n', true } }) local bo = bufnr and vim.bo[bufnr] or vim.bo @@ -2060,7 +2062,7 @@ end --- Creates a `DocumentFormattingParams` object for the current buffer and cursor position. --- ----@param options table|nil with valid `FormattingOptions` entries +---@param options lsp.FormattingOptions|nil with valid `FormattingOptions` entries ---@return lsp.DocumentFormattingParams object ---@see https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_formatting function M.make_formatting_params(options) -- cgit From 4cff4185647c17b1a397c4c26ff7d8b0738f6396 Mon Sep 17 00:00:00 2001 From: Gregory Anders Date: Thu, 30 May 2024 19:57:47 -0500 Subject: fix(vim.text): remove assert from vim.text.hexdecode Instead, return nil plus an error message if the input is invalid. --- runtime/doc/lua.txt | 5 +++-- runtime/lua/vim/text.lua | 10 +++++++--- 2 files changed, 10 insertions(+), 5 deletions(-) (limited to 'runtime') diff --git a/runtime/doc/lua.txt b/runtime/doc/lua.txt index 36d6e0d41e..8e600adeb9 100644 --- a/runtime/doc/lua.txt +++ b/runtime/doc/lua.txt @@ -4385,8 +4385,9 @@ vim.text.hexdecode({enc}) *vim.text.hexdecode()* Parameters: ~ • {enc} (`string`) String to decode - Return: ~ - (`string`) Decoded string + Return (multiple): ~ + (`string?`) Decoded string + (`string?`) Error message, if any vim.text.hexencode({str}) *vim.text.hexencode()* Hex encode a string. diff --git a/runtime/lua/vim/text.lua b/runtime/lua/vim/text.lua index bc90d490aa..0be3396464 100644 --- a/runtime/lua/vim/text.lua +++ b/runtime/lua/vim/text.lua @@ -18,15 +18,19 @@ end --- Hex decode a string. --- --- @param enc string String to decode ---- @return string : Decoded string +--- @return string? : Decoded string +--- @return string? : Error message, if any function M.hexdecode(enc) - assert(#enc % 2 == 0, 'string must have an even number of hex characters') + if #enc % 2 ~= 0 then + return nil, 'string must have an even number of hex characters' + end + local str = {} ---@type string[] for i = 1, #enc, 2 do local n = assert(tonumber(enc:sub(i, i + 1), 16)) str[#str + 1] = string.char(n) end - return table.concat(str) + return table.concat(str), nil end return M -- cgit From d62d181ce065556be51d5eda0425aa42f427cc27 Mon Sep 17 00:00:00 2001 From: Ilia Choly Date: Fri, 31 May 2024 10:48:05 -0400 Subject: refactor(lsp): use tuple syntax in generated protocol types (#29110) --- runtime/lua/vim/lsp/_meta/protocol.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'runtime') diff --git a/runtime/lua/vim/lsp/_meta/protocol.lua b/runtime/lua/vim/lsp/_meta/protocol.lua index 9a11972007..cbddd24630 100644 --- a/runtime/lua/vim/lsp/_meta/protocol.lua +++ b/runtime/lua/vim/lsp/_meta/protocol.lua @@ -3235,7 +3235,7 @@ error('Cannot require a meta file') --- ---*Note*: a label of type string should be a substring of its containing signature label. ---Its intended use case is to highlight the parameter label part in the `SignatureInformation.label`. ----@field label string|{ [1]: uinteger, [2]: uinteger } +---@field label string|[uinteger, uinteger] --- ---The human-readable doc-comment of this parameter. Will be shown ---in the UI but can be omitted. -- cgit From 50f6d364c661b88a1edc5ffc8e284d1c0ff70810 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Sat, 1 Jun 2024 14:47:18 +0800 Subject: vim-patch:0bdc5d8: runtime(doc): Add ft_hare.txt to Reference Manual TOC (#29120) while at it, also re-align ft_context.txt with the rest of the list. closes: vim/vim#14863 https://github.com/vim/vim/commit/0bdc5d8241335c3451f629eed7a3734021d41679 Co-authored-by: h-east --- runtime/doc/help.txt | 1 + 1 file changed, 1 insertion(+) (limited to 'runtime') diff --git a/runtime/doc/help.txt b/runtime/doc/help.txt index 43f80101ed..685bce2553 100644 --- a/runtime/doc/help.txt +++ b/runtime/doc/help.txt @@ -127,6 +127,7 @@ PROGRAMMING LANGUAGE SUPPORT |filetype| Settings for specific types of files |quickfix| Commands for a quick edit-compile-fix cycle |ft_ada.txt| Ada filetype plugin +|ft_hare.txt| Filetype plugin for Hare |ft_ps1.txt| PowerShell filetype plugin |ft_raku.txt| Raku filetype plugin |ft_rust.txt| Rust filetype plugin -- cgit From cc1f2d2ca6caa3da4cb7910f74fed4375202e888 Mon Sep 17 00:00:00 2001 From: Mathias Fussenegger Date: Thu, 30 May 2024 10:24:54 +0200 Subject: perf(lsp): don't copy completion items in filter pass --- runtime/lua/vim/lsp/completion.lua | 100 ++++++++++++++++++++----------------- 1 file changed, 54 insertions(+), 46 deletions(-) (limited to 'runtime') diff --git a/runtime/lua/vim/lsp/completion.lua b/runtime/lua/vim/lsp/completion.lua index 39c0c5fa29..8777947acf 100644 --- a/runtime/lua/vim/lsp/completion.lua +++ b/runtime/lua/vim/lsp/completion.lua @@ -201,6 +201,24 @@ local function get_items(result) end end +---@param item lsp.CompletionItem +---@return string +local function get_doc(item) + local doc = item.documentation + if not doc then + return '' + end + if type(doc) == 'string' then + return doc + end + if type(doc) == 'table' and type(doc.value) == 'string' then + return doc.value + end + + vim.notify('invalid documentation value: ' .. vim.inspect(doc), vim.log.levels.WARN) + return '' +end + --- Turns the result of a `textDocument/completion` request into vim-compatible --- |complete-items|. --- @@ -216,58 +234,48 @@ function M._lsp_to_complete_items(result, prefix, client_id) return {} end - if prefix ~= '' then - ---@param item lsp.CompletionItem - local function match_prefix(item) - if item.filterText then - return next(vim.fn.matchfuzzy({ item.filterText }, prefix)) - end - return true + local matches = prefix == '' and function() + return true + end or function(item) + if item.filterText then + return next(vim.fn.matchfuzzy({ item.filterText }, prefix)) end - - items = vim.tbl_filter(match_prefix, items) --[[@as lsp.CompletionItem[]|]] + return true end - table.sort(items, function(a, b) - return (a.sortText or a.label) < (b.sortText or b.label) - end) - - local matches = {} + local candidates = {} for _, item in ipairs(items) do - local info = '' - local documentation = item.documentation - if documentation then - if type(documentation) == 'string' and documentation ~= '' then - info = documentation - elseif type(documentation) == 'table' and type(documentation.value) == 'string' then - info = documentation.value - else - vim.notify( - ('invalid documentation value %s'):format(vim.inspect(documentation)), - vim.log.levels.WARN - ) - end - end - local word = get_completion_word(item) - table.insert(matches, { - word = word, - abbr = item.label, - kind = protocol.CompletionItemKind[item.kind] or 'Unknown', - menu = item.detail or '', - info = #info > 0 and info or '', - icase = 1, - dup = 1, - empty = 1, - user_data = { - nvim = { - lsp = { - completion_item = item, - client_id = client_id, + if matches(item) then + local word = get_completion_word(item) + table.insert(candidates, { + word = word, + abbr = item.label, + kind = protocol.CompletionItemKind[item.kind] or 'Unknown', + menu = item.detail or '', + info = get_doc(item), + icase = 1, + dup = 1, + empty = 1, + user_data = { + nvim = { + lsp = { + completion_item = item, + client_id = client_id, + }, }, }, - }, - }) + }) + end end - return matches + ---@diagnostic disable-next-line: no-unknown + table.sort(candidates, function(a, b) + ---@type lsp.CompletionItem + local itema = a.user_data.nvim.lsp.completion_item + ---@type lsp.CompletionItem + local itemb = b.user_data.nvim.lsp.completion_item + return (itema.sortText or itema.label) < (itemb.sortText or itemb.label) + end) + + return candidates end --- @param lnum integer 0-indexed -- cgit From 4c938f6d72710507db22074951eee23869ed49e0 Mon Sep 17 00:00:00 2001 From: Mathias Fussenegger Date: Thu, 30 May 2024 10:46:47 +0200 Subject: refactor(lsp): share completion request logic between omnifunc & trigger --- runtime/lua/vim/lsp/completion.lua | 209 +++++++++++++++---------------------- 1 file changed, 85 insertions(+), 124 deletions(-) (limited to 'runtime') diff --git a/runtime/lua/vim/lsp/completion.lua b/runtime/lua/vim/lsp/completion.lua index 8777947acf..c514c5ef4d 100644 --- a/runtime/lua/vim/lsp/completion.lua +++ b/runtime/lua/vim/lsp/completion.lua @@ -348,78 +348,6 @@ function M._convert_results( return matches, server_start_boundary end ---- Implements 'omnifunc' compatible LSP completion. ---- ---- @see |complete-functions| ---- @see |complete-items| ---- @see |CompleteDone| ---- ---- @param findstart integer 0 or 1, decides behavior ---- @param base integer findstart=0, text to match against ---- ---- @return integer|table Decided by {findstart}: ---- - findstart=0: column where the completion starts, or -2 or -3 ---- - findstart=1: list of matches (actually just calls |complete()|) -function M._omnifunc(findstart, base) - vim.lsp.log.debug('omnifunc.findstart', { findstart = findstart, base = base }) - assert(base) -- silence luals - local bufnr = api.nvim_get_current_buf() - local clients = lsp.get_clients({ bufnr = bufnr, method = ms.textDocument_completion }) - local remaining = #clients - if remaining == 0 then - return findstart == 1 and -1 or {} - end - - local win = api.nvim_get_current_win() - local cursor = api.nvim_win_get_cursor(win) - local lnum = cursor[1] - 1 - local cursor_col = cursor[2] - local line = api.nvim_get_current_line() - local line_to_cursor = line:sub(1, cursor_col) - local client_start_boundary = vim.fn.match(line_to_cursor, '\\k*$') --[[@as integer]] - local server_start_boundary = nil - local items = {} - - local function on_done() - local mode = api.nvim_get_mode()['mode'] - if mode == 'i' or mode == 'ic' then - vim.fn.complete((server_start_boundary or client_start_boundary) + 1, items) - end - end - - local util = vim.lsp.util - for _, client in ipairs(clients) do - local params = util.make_position_params(win, client.offset_encoding) - client.request(ms.textDocument_completion, params, function(err, result) - if err then - lsp.log.warn(err.message) - end - if result and vim.fn.mode() == 'i' then - local matches - matches, server_start_boundary = M._convert_results( - line, - lnum, - cursor_col, - client.id, - client_start_boundary, - server_start_boundary, - result, - client.offset_encoding - ) - vim.list_extend(items, matches) - end - remaining = remaining - 1 - if remaining == 0 then - vim.schedule(on_done) - end - end, bufnr) - end - - -- Return -2 to signal that we should continue completion so that we can - -- async complete. - return -2 -end - --- @param clients table --- @param bufnr integer --- @param win integer @@ -455,6 +383,64 @@ local function request(clients, bufnr, win, callback) end end +local function trigger(bufnr, clients) + reset_timer() + Context:cancel_pending() + + local win = api.nvim_get_current_win() + local cursor_row, cursor_col = unpack(api.nvim_win_get_cursor(win)) --- @type integer, integer + local line = api.nvim_get_current_line() + local line_to_cursor = line:sub(1, cursor_col) + local word_boundary = vim.fn.match(line_to_cursor, '\\k*$') + local start_time = vim.uv.hrtime() + Context.last_request_time = start_time + + local cancel_request = request(clients, bufnr, win, function(responses) + local end_time = vim.uv.hrtime() + rtt_ms = compute_new_average((end_time - start_time) * ns_to_ms) + + Context.pending_requests = {} + Context.isIncomplete = false + + local row_changed = api.nvim_win_get_cursor(win)[1] ~= cursor_row + local mode = api.nvim_get_mode().mode + if row_changed or not (mode == 'i' or mode == 'ic') then + return + end + + local matches = {} + local server_start_boundary --- @type integer? + for client_id, response in pairs(responses) do + if response.err then + vim.notify_once(response.err.message, vim.log.levels.warn) + end + + local result = response.result + if result then + Context.isIncomplete = Context.isIncomplete or result.isIncomplete + local client = lsp.get_client_by_id(client_id) + local encoding = client and client.offset_encoding or 'utf-16' + local client_matches + client_matches, server_start_boundary = M._convert_results( + line, + cursor_row - 1, + cursor_col, + client_id, + word_boundary, + nil, + result, + encoding + ) + vim.list_extend(matches, client_matches) + end + end + local start_col = (server_start_boundary or word_boundary) + 1 + vim.fn.complete(start_col, matches) + end) + + table.insert(Context.pending_requests, cancel_request) +end + --- @param handle vim.lsp.completion.BufHandle local function on_insert_char_pre(handle) if tonumber(vim.fn.pumvisible()) == 1 then @@ -701,63 +687,38 @@ end --- Trigger LSP completion in the current buffer. function M.trigger() - reset_timer() - Context:cancel_pending() - - local win = api.nvim_get_current_win() local bufnr = api.nvim_get_current_buf() - local cursor_row, cursor_col = unpack(api.nvim_win_get_cursor(win)) --- @type integer, integer - local line = api.nvim_get_current_line() - local line_to_cursor = line:sub(1, cursor_col) local clients = (buf_handles[bufnr] or {}).clients or {} - local word_boundary = vim.fn.match(line_to_cursor, '\\k*$') - local start_time = vim.uv.hrtime() - Context.last_request_time = start_time - - local cancel_request = request(clients, bufnr, win, function(responses) - local end_time = vim.uv.hrtime() - rtt_ms = compute_new_average((end_time - start_time) * ns_to_ms) - - Context.pending_requests = {} - Context.isIncomplete = false - - local row_changed = api.nvim_win_get_cursor(win)[1] ~= cursor_row - local mode = api.nvim_get_mode().mode - if row_changed or not (mode == 'i' or mode == 'ic') then - return - end + trigger(bufnr, clients) +end - local matches = {} - local server_start_boundary --- @type integer? - for client_id, response in pairs(responses) do - if response.err then - vim.notify_once(response.err.message, vim.log.levels.warn) - end +--- Implements 'omnifunc' compatible LSP completion. +--- +--- @see |complete-functions| +--- @see |complete-items| +--- @see |CompleteDone| +--- +--- @param findstart integer 0 or 1, decides behavior +--- @param base integer findstart=0, text to match against +--- +--- @return integer|table Decided by {findstart}: +--- - findstart=0: column where the completion starts, or -2 or -3 +--- - findstart=1: list of matches (actually just calls |complete()|) +function M._omnifunc(findstart, base) + vim.lsp.log.debug('omnifunc.findstart', { findstart = findstart, base = base }) + assert(base) -- silence luals + local bufnr = api.nvim_get_current_buf() + local clients = lsp.get_clients({ bufnr = bufnr, method = ms.textDocument_completion }) + local remaining = #clients + if remaining == 0 then + return findstart == 1 and -1 or {} + end - local result = response.result - if result then - Context.isIncomplete = Context.isIncomplete or result.isIncomplete - local client = lsp.get_client_by_id(client_id) - local encoding = client and client.offset_encoding or 'utf-16' - local client_matches - client_matches, server_start_boundary = M._convert_results( - line, - cursor_row - 1, - cursor_col, - client_id, - word_boundary, - nil, - result, - encoding - ) - vim.list_extend(matches, client_matches) - end - end - local start_col = (server_start_boundary or word_boundary) + 1 - vim.fn.complete(start_col, matches) - end) + trigger(bufnr, clients) - table.insert(Context.pending_requests, cancel_request) + -- Return -2 to signal that we should continue completion so that we can + -- async complete. + return -2 end return M -- cgit From 138a93a057dabd70673b7466bf5af41bd66f1385 Mon Sep 17 00:00:00 2001 From: Mathias Fussenegger Date: Thu, 30 May 2024 10:51:52 +0200 Subject: perf(lsp): avoid repeated table lookup in completion.enable --- runtime/lua/vim/lsp/completion.lua | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) (limited to 'runtime') diff --git a/runtime/lua/vim/lsp/completion.lua b/runtime/lua/vim/lsp/completion.lua index c514c5ef4d..b77bf3e3c2 100644 --- a/runtime/lua/vim/lsp/completion.lua +++ b/runtime/lua/vim/lsp/completion.lua @@ -575,8 +575,10 @@ end ---@param bufnr integer ---@param opts vim.lsp.completion.BufferOpts local function enable_completions(client_id, bufnr, opts) - if not buf_handles[bufnr] then - buf_handles[bufnr] = { clients = {}, triggers = {} } + local buf_handle = buf_handles[bufnr] + if not buf_handle then + buf_handle = { clients = {}, triggers = {} } + buf_handles[bufnr] = buf_handle -- Attach to buffer events. api.nvim_buf_attach(bufnr, false, { @@ -617,12 +619,12 @@ local function enable_completions(client_id, bufnr, opts) end end - if not buf_handles[bufnr].clients[client_id] then + if not buf_handle.clients[client_id] then local client = lsp.get_client_by_id(client_id) assert(client, 'invalid client ID') -- Add the new client to the buffer's clients. - buf_handles[bufnr].clients[client_id] = client + buf_handle.clients[client_id] = client -- Add the new client to the clients that should be triggered by its trigger characters. --- @type string[] @@ -632,10 +634,10 @@ local function enable_completions(client_id, bufnr, opts) 'triggerCharacters' ) or {} for _, char in ipairs(triggers) do - local clients_for_trigger = buf_handles[bufnr].triggers[char] + local clients_for_trigger = buf_handle.triggers[char] if not clients_for_trigger then clients_for_trigger = {} - buf_handles[bufnr].triggers[char] = clients_for_trigger + buf_handle.triggers[char] = clients_for_trigger end local client_exists = vim.iter(clients_for_trigger):any(function(c) return c.id == client_id -- cgit From 7a8f42dc036f3bc6e8b106c580e0cd50dbed465e Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Sun, 2 Jun 2024 06:06:12 +0800 Subject: vim-patch:e299591: runtime(doc): clarify 'shortmess' flag "S" (#29131) fixes: vim/vim#14893 https://github.com/vim/vim/commit/e299591498a20c5c587364e4df57f947dfc02897 Co-authored-by: Christian Brabandt --- runtime/doc/options.txt | 10 +++++++--- runtime/lua/vim/_meta/options.lua | 10 +++++++--- 2 files changed, 14 insertions(+), 6 deletions(-) (limited to 'runtime') diff --git a/runtime/doc/options.txt b/runtime/doc/options.txt index edda46e197..a48ebd7199 100644 --- a/runtime/doc/options.txt +++ b/runtime/doc/options.txt @@ -5459,8 +5459,8 @@ A jump table for the options with a short description can be found at |Q_op|. message; also for quickfix message (e.g., ":cn") s don't give "search hit BOTTOM, continuing at TOP" or *shm-s* "search hit TOP, continuing at BOTTOM" messages; when using - the search count do not show "W" after the count message (see - S below) + the search count do not show "W" before the count message + (see |shm-S| below) t truncate file message at the start if it is too long *shm-t* to fit on the command-line, "<" will appear in the left most column; ignored in Ex mode @@ -5482,7 +5482,11 @@ A jump table for the options with a short description can be found at |Q_op|. `:silent` was used for the command; note that this also affects messages from 'autoread' reloading S do not show search count message when searching, e.g. *shm-S* - "[1/5]" + "[1/5]". When the "S" flag is not present (e.g. search count + is shown), the "search hit BOTTOM, continuing at TOP" and + "search hit TOP, continuing at BOTTOM" messages are only + indicated by a "W" (Mnemonic: Wrapped) letter before the + search count statistics. This gives you the opportunity to avoid that a change between buffers requires you to hit , but still gives as useful a message as diff --git a/runtime/lua/vim/_meta/options.lua b/runtime/lua/vim/_meta/options.lua index 428b7c4d4f..2eae0d27a7 100644 --- a/runtime/lua/vim/_meta/options.lua +++ b/runtime/lua/vim/_meta/options.lua @@ -5781,8 +5781,8 @@ vim.bo.sw = vim.bo.shiftwidth --- message; also for quickfix message (e.g., ":cn") --- s don't give "search hit BOTTOM, continuing at TOP" or *shm-s* --- "search hit TOP, continuing at BOTTOM" messages; when using ---- the search count do not show "W" after the count message (see ---- S below) +--- the search count do not show "W" before the count message +--- (see `shm-S` below) --- t truncate file message at the start if it is too long *shm-t* --- to fit on the command-line, "<" will appear in the left most --- column; ignored in Ex mode @@ -5804,7 +5804,11 @@ vim.bo.sw = vim.bo.shiftwidth --- `:silent` was used for the command; note that this also --- affects messages from 'autoread' reloading --- S do not show search count message when searching, e.g. *shm-S* ---- "[1/5]" +--- "[1/5]". When the "S" flag is not present (e.g. search count +--- is shown), the "search hit BOTTOM, continuing at TOP" and +--- "search hit TOP, continuing at BOTTOM" messages are only +--- indicated by a "W" (Mnemonic: Wrapped) letter before the +--- search count statistics. --- --- This gives you the opportunity to avoid that a change between buffers --- requires you to hit , but still gives as useful a message as -- cgit From 19be3d26830ced203631045f2f622e75e6d857a7 Mon Sep 17 00:00:00 2001 From: Mathias Fußenegger Date: Sun, 2 Jun 2024 09:54:15 +0200 Subject: fix(lsp): trim trailing whitespace from completion words (#29122) the `complete()` mechanism doesn't play nicely with trailing newlines or tabs. A newline causes it to insert a null character, showing up as `^@`. --- runtime/lua/vim/lsp/completion.lua | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'runtime') diff --git a/runtime/lua/vim/lsp/completion.lua b/runtime/lua/vim/lsp/completion.lua index b77bf3e3c2..f8e17ae2f0 100644 --- a/runtime/lua/vim/lsp/completion.lua +++ b/runtime/lua/vim/lsp/completion.lua @@ -153,7 +153,8 @@ local function get_completion_word(item) return item.label end elseif item.textEdit then - return item.textEdit.newText + local word = item.textEdit.newText + return word:match('^(%S*)') or word elseif item.insertText and item.insertText ~= '' then return item.insertText end -- cgit From 659d3dcd2edf1b178a20015cab399390ffda1a32 Mon Sep 17 00:00:00 2001 From: Christian Clason Date: Sun, 2 Jun 2024 17:31:37 +0200 Subject: vim-patch:9.1.0460: filetype: lintstagedrc files are not recognized MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Problem: filetype: lintstagedrc files are not recognized Solution: recognize '.lintstagedrc' files as json filetype (İlyas Akın) see: https://github.com/lint-staged/lint-staged closes: vim/vim#14897 https://github.com/vim/vim/commit/7577afd5efd0f7ebf0dbbca09713185024263ed7 Co-authored-by: İlyas Akın --- runtime/lua/vim/filetype.lua | 1 + 1 file changed, 1 insertion(+) (limited to 'runtime') diff --git a/runtime/lua/vim/filetype.lua b/runtime/lua/vim/filetype.lua index 500632a2b2..c8f9bcfd84 100644 --- a/runtime/lua/vim/filetype.lua +++ b/runtime/lua/vim/filetype.lua @@ -1451,6 +1451,7 @@ local filename = { ['.firebaserc'] = 'json', ['.prettierrc'] = 'json', ['.stylelintrc'] = 'json', + ['.lintstagedrc'] = 'json', ['flake.lock'] = 'json', ['.babelrc'] = 'jsonc', ['.eslintrc'] = 'jsonc', -- cgit From 054a287dbe6fe4308d26ec593da2057641f2bb9b Mon Sep 17 00:00:00 2001 From: Soham Shanbhag Date: Mon, 3 Jun 2024 16:48:43 +0900 Subject: feat(ftplugin): change 'commentstring' to `// %s` for C/C++ (#29085) Problem: The default commentstring for C/C++ can lead to invalid code when commenting and does not match the Nvim codebase. Solution: Change commentstring to `// %s` as used by Neovim. Also set all commentstrings that derive from the default C string explicitly (and correctly). --- runtime/ftplugin/arduino.lua | 1 + runtime/ftplugin/c.lua | 2 +- runtime/ftplugin/calender.lua | 2 +- runtime/ftplugin/ch.lua | 1 + runtime/ftplugin/cs.lua | 2 +- runtime/ftplugin/css.lua | 2 +- runtime/ftplugin/d.lua | 2 +- runtime/ftplugin/indent.lua | 2 +- runtime/ftplugin/objc.lua | 1 + runtime/ftplugin/xdefaults.lua | 2 +- runtime/ftplugin/xs.lua | 1 + 11 files changed, 11 insertions(+), 7 deletions(-) create mode 100644 runtime/ftplugin/arduino.lua create mode 100644 runtime/ftplugin/ch.lua create mode 100644 runtime/ftplugin/objc.lua create mode 100644 runtime/ftplugin/xs.lua (limited to 'runtime') diff --git a/runtime/ftplugin/arduino.lua b/runtime/ftplugin/arduino.lua new file mode 100644 index 0000000000..f398d66a63 --- /dev/null +++ b/runtime/ftplugin/arduino.lua @@ -0,0 +1 @@ +vim.bo.commentstring = '// %s' diff --git a/runtime/ftplugin/c.lua b/runtime/ftplugin/c.lua index 0ddbf09470..2695b642aa 100644 --- a/runtime/ftplugin/c.lua +++ b/runtime/ftplugin/c.lua @@ -1,5 +1,5 @@ -- These are the default option values in Vim, but not in Nvim, so must be set explicitly. -vim.bo.commentstring = '/*%s*/' +vim.bo.commentstring = '// %s' vim.bo.define = '^\\s*#\\s*define' vim.bo.include = '^\\s*#\\s*include' diff --git a/runtime/ftplugin/calender.lua b/runtime/ftplugin/calender.lua index b4e68148f5..984111a08b 100644 --- a/runtime/ftplugin/calender.lua +++ b/runtime/ftplugin/calender.lua @@ -1 +1 @@ -vim.bo.commentstring = '/*%s*/' +vim.bo.commentstring = '/* %s */' diff --git a/runtime/ftplugin/ch.lua b/runtime/ftplugin/ch.lua new file mode 100644 index 0000000000..f398d66a63 --- /dev/null +++ b/runtime/ftplugin/ch.lua @@ -0,0 +1 @@ +vim.bo.commentstring = '// %s' diff --git a/runtime/ftplugin/cs.lua b/runtime/ftplugin/cs.lua index b4e68148f5..f398d66a63 100644 --- a/runtime/ftplugin/cs.lua +++ b/runtime/ftplugin/cs.lua @@ -1 +1 @@ -vim.bo.commentstring = '/*%s*/' +vim.bo.commentstring = '// %s' diff --git a/runtime/ftplugin/css.lua b/runtime/ftplugin/css.lua index b4e68148f5..984111a08b 100644 --- a/runtime/ftplugin/css.lua +++ b/runtime/ftplugin/css.lua @@ -1 +1 @@ -vim.bo.commentstring = '/*%s*/' +vim.bo.commentstring = '/* %s */' diff --git a/runtime/ftplugin/d.lua b/runtime/ftplugin/d.lua index b4e68148f5..f398d66a63 100644 --- a/runtime/ftplugin/d.lua +++ b/runtime/ftplugin/d.lua @@ -1 +1 @@ -vim.bo.commentstring = '/*%s*/' +vim.bo.commentstring = '// %s' diff --git a/runtime/ftplugin/indent.lua b/runtime/ftplugin/indent.lua index b4e68148f5..f398d66a63 100644 --- a/runtime/ftplugin/indent.lua +++ b/runtime/ftplugin/indent.lua @@ -1 +1 @@ -vim.bo.commentstring = '/*%s*/' +vim.bo.commentstring = '// %s' diff --git a/runtime/ftplugin/objc.lua b/runtime/ftplugin/objc.lua new file mode 100644 index 0000000000..f398d66a63 --- /dev/null +++ b/runtime/ftplugin/objc.lua @@ -0,0 +1 @@ +vim.bo.commentstring = '// %s' diff --git a/runtime/ftplugin/xdefaults.lua b/runtime/ftplugin/xdefaults.lua index b4e68148f5..e54bf808b0 100644 --- a/runtime/ftplugin/xdefaults.lua +++ b/runtime/ftplugin/xdefaults.lua @@ -1 +1 @@ -vim.bo.commentstring = '/*%s*/' +vim.bo.commentstring = '! %s' diff --git a/runtime/ftplugin/xs.lua b/runtime/ftplugin/xs.lua new file mode 100644 index 0000000000..f398d66a63 --- /dev/null +++ b/runtime/ftplugin/xs.lua @@ -0,0 +1 @@ +vim.bo.commentstring = '// %s' -- cgit From a9c89bcbf69a3d0ef47f324a47ff6eb482467e70 Mon Sep 17 00:00:00 2001 From: dundargoc Date: Mon, 3 Jun 2024 11:55:20 +0200 Subject: fix(gx): allow `@` in url This will make `gx` work for links for the form https://hachyderm.io/@neovim. --- runtime/lua/vim/ui.lua | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'runtime') diff --git a/runtime/lua/vim/ui.lua b/runtime/lua/vim/ui.lua index 99b9b78e2a..f168da4955 100644 --- a/runtime/lua/vim/ui.lua +++ b/runtime/lua/vim/ui.lua @@ -179,7 +179,13 @@ function M._get_url() current_node = current_node:parent() end end - return vim.fn.expand('') + + local old_isfname = vim.o.isfname + vim.cmd [[set isfname+=@-@]] + local url = vim.fn.expand('') + vim.o.isfname = old_isfname + + return url end return M -- cgit From 5aa9906676f3ad040b0ccb75eb5fd560def1e0ec Mon Sep 17 00:00:00 2001 From: ippachi Date: Tue, 4 Jun 2024 01:07:09 +0900 Subject: fix(lsp): use client.id instead of pairs index (#29143) Problem: Completion side effects not working randomly. Solution: When creating the table of LSP responses, the table index was used, but this is not the same as the actual client_id, so it was changed to use the client_id directly. --- runtime/lua/vim/lsp/completion.lua | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'runtime') diff --git a/runtime/lua/vim/lsp/completion.lua b/runtime/lua/vim/lsp/completion.lua index f8e17ae2f0..c9326a0681 100644 --- a/runtime/lua/vim/lsp/completion.lua +++ b/runtime/lua/vim/lsp/completion.lua @@ -349,7 +349,7 @@ function M._convert_results( return matches, server_start_boundary end ---- @param clients table +--- @param clients table # keys != client_id --- @param bufnr integer --- @param win integer --- @param callback fun(responses: table) @@ -359,7 +359,8 @@ local function request(clients, bufnr, win, callback) local request_ids = {} --- @type table local remaining_requests = vim.tbl_count(clients) - for client_id, client in pairs(clients) do + for _, client in pairs(clients) do + local client_id = client.id local params = lsp.util.make_position_params(win, client.offset_encoding) local ok, request_id = client.request(ms.textDocument_completion, params, function(err, result) responses[client_id] = { err = err, result = result } -- cgit From 2f5b8a009280eba995aecf67d1e8d99b7c72c51c Mon Sep 17 00:00:00 2001 From: Christian Clason Date: Tue, 4 Jun 2024 09:39:28 +0200 Subject: vim-patch:9.1.0464: no whitespace padding in commentstring option in ftplugins Problem: no whitespace padding in commentstring option in ftplugins Solution: Change default to include whitespace padding, update existing filetype plugins with the new default value (Riley Bruins) closes: vim/vim#14843 https://github.com/vim/vim/commit/0a0830624a260660c7fa692ecb7e6e5de09114ba Co-authored-by: Riley Bruins --- runtime/doc/options.txt | 4 ++-- runtime/ftplugin/abaqus.vim | 3 ++- runtime/ftplugin/arduino.vim | 3 ++- runtime/ftplugin/asm.vim | 3 ++- runtime/ftplugin/astro.vim | 7 ++++--- runtime/ftplugin/bitbake.vim | 3 ++- runtime/ftplugin/c.vim | 3 ++- runtime/ftplugin/calendar.vim | 3 ++- runtime/ftplugin/cgdbrc.vim | 3 ++- runtime/ftplugin/csh.vim | 3 ++- runtime/ftplugin/css.lua | 1 - runtime/ftplugin/css.vim | 3 ++- runtime/ftplugin/desktop.vim | 3 ++- runtime/ftplugin/dtd.vim | 3 ++- runtime/ftplugin/dtrace.vim | 5 +++-- runtime/ftplugin/dts.vim | 3 ++- runtime/ftplugin/erlang.vim | 5 +++-- runtime/ftplugin/eruby.vim | 3 ++- runtime/ftplugin/fennel.vim | 3 ++- runtime/ftplugin/fish.vim | 3 ++- runtime/ftplugin/fortran.vim | 3 ++- runtime/ftplugin/fstab.vim | 3 ++- runtime/ftplugin/gdb.vim | 3 ++- runtime/ftplugin/groovy.vim | 3 ++- runtime/ftplugin/hamster.vim | 3 ++- runtime/ftplugin/html.vim | 3 ++- runtime/ftplugin/indent.vim | 3 ++- runtime/ftplugin/initex.vim | 3 ++- runtime/ftplugin/java.vim | 3 ++- runtime/ftplugin/javascript.vim | 3 ++- runtime/ftplugin/jq.vim | 3 ++- runtime/ftplugin/jsonc.vim | 3 ++- runtime/ftplugin/lc.vim | 13 +++++++++++++ runtime/ftplugin/ld.vim | 5 +++-- runtime/ftplugin/liquid.vim | 3 ++- runtime/ftplugin/lisp.vim | 3 ++- runtime/ftplugin/markdown.vim | 3 ++- runtime/ftplugin/mma.vim | 5 +++-- runtime/ftplugin/modula2.vim | 3 ++- runtime/ftplugin/modula3.vim | 3 ++- runtime/ftplugin/nroff.vim | 6 +++--- runtime/ftplugin/obse.vim | 7 ++++--- runtime/ftplugin/ocaml.vim | 4 +++- runtime/ftplugin/odin.vim | 5 +++-- runtime/ftplugin/openvpn.vim | 3 ++- runtime/ftplugin/pascal.vim | 3 ++- runtime/ftplugin/pdf.vim | 3 ++- runtime/ftplugin/perl.vim | 3 ++- runtime/ftplugin/php.vim | 3 ++- runtime/ftplugin/ps1.vim | 3 ++- runtime/ftplugin/ps1xml.vim | 3 ++- runtime/ftplugin/qml.vim | 3 ++- runtime/ftplugin/racket.vim | 5 ++--- runtime/ftplugin/raku.vim | 13 +++++++------ runtime/ftplugin/rust.vim | 11 ++++++----- runtime/ftplugin/scdoc.vim | 9 +++++---- runtime/ftplugin/scheme.vim | 15 ++++++++------- runtime/ftplugin/tcl.vim | 3 ++- runtime/ftplugin/typescript.vim | 3 ++- runtime/ftplugin/vim.vim | 3 ++- runtime/ftplugin/wat.vim | 3 ++- runtime/ftplugin/xdefaults.lua | 1 - runtime/ftplugin/xdefaults.vim | 9 +++++---- runtime/ftplugin/xml.vim | 3 ++- runtime/lua/vim/_meta/options.lua | 4 ++-- runtime/syntax/lc.vim | 2 +- runtime/syntax/mma.vim | 2 +- 67 files changed, 171 insertions(+), 102 deletions(-) delete mode 100644 runtime/ftplugin/css.lua create mode 100644 runtime/ftplugin/lc.vim delete mode 100644 runtime/ftplugin/xdefaults.lua (limited to 'runtime') diff --git a/runtime/doc/options.txt b/runtime/doc/options.txt index a48ebd7199..20e825329a 100644 --- a/runtime/doc/options.txt +++ b/runtime/doc/options.txt @@ -1442,8 +1442,8 @@ A jump table for the options with a short description can be found at |Q_op|. 'commentstring' 'cms' string (default "") local to buffer A template for a comment. The "%s" in the value is replaced with the - comment text. For example, C uses "/*%s*/". Used for |commenting| and to - add markers for folding, see |fold-marker|. + comment text, and should be padded with a space when possible. + Used for |commenting| and to add markers for folding, see |fold-marker|. *'complete'* *'cpt'* *E535* 'complete' 'cpt' string (default ".,w,b,u,t") diff --git a/runtime/ftplugin/abaqus.vim b/runtime/ftplugin/abaqus.vim index c16e7b032e..d4bb6fe777 100644 --- a/runtime/ftplugin/abaqus.vim +++ b/runtime/ftplugin/abaqus.vim @@ -3,6 +3,7 @@ " Maintainer: Carl Osterwisch " Last Change: 2022 Oct 08 " 2024 Jan 14 by Vim Project (browsefilter) +" 2024 May 23 by Riley Bruins ('commentstring') " Only do this when not done yet for this buffer if exists("b:did_ftplugin") | finish | endif @@ -27,7 +28,7 @@ setlocal isfname-=, " Define format of comment lines (see 'formatoptions' for uses) setlocal comments=:** -setlocal commentstring=**%s +setlocal commentstring=**\ %s " Definitions start with a * and assign a NAME, NSET, or ELSET " Used in [d ^wd and other commands diff --git a/runtime/ftplugin/arduino.vim b/runtime/ftplugin/arduino.vim index dae3dd83d3..60b11dab1a 100644 --- a/runtime/ftplugin/arduino.vim +++ b/runtime/ftplugin/arduino.vim @@ -3,6 +3,7 @@ " Maintainer: The Vim Project " Ken Takata " Last Change: 2024 Apr 12 +" 2024 Jun 02 by Riley Bruins ('commentstring') " " Most of the part was copied from c.vim. @@ -32,7 +33,7 @@ setlocal fo-=t fo+=croql " These options have the right value as default, but the user may have " overruled that. -setlocal commentstring& define& include& +setlocal commentstring=/*\ %s\ */ define& include& " Set completion with CTRL-X CTRL-O to autoloaded function. if exists('&ofu') diff --git a/runtime/ftplugin/asm.vim b/runtime/ftplugin/asm.vim index 0ae1610394..4482b90d0b 100644 --- a/runtime/ftplugin/asm.vim +++ b/runtime/ftplugin/asm.vim @@ -4,13 +4,14 @@ " Last Change: 2020 May 23 " 2023 Aug 28 by Vim Project (undo_ftplugin) " 2024 Apr 09 by Vim Project (add Matchit support) +" 2024 May 23 by Riley Bruins ('commentstring') if exists("b:did_ftplugin") | finish | endif let b:did_ftplugin = 1 setl include=^\\s*%\\s*include setl comments=:;,s1:/*,mb:*,ex:*/,:// -setl commentstring=;%s +setl commentstring=;\ %s let b:undo_ftplugin = "setl commentstring< comments< include<" diff --git a/runtime/ftplugin/astro.vim b/runtime/ftplugin/astro.vim index 0b0e03447b..5d35ba9624 100644 --- a/runtime/ftplugin/astro.vim +++ b/runtime/ftplugin/astro.vim @@ -2,6 +2,7 @@ " Language: Astro " Maintainer: Romain Lafourcade " Last Change: 2024 Apr 21 +" 2024 May 24 by Riley Bruins ('commentstring') if exists("b:did_ftplugin") finish @@ -25,17 +26,17 @@ function! s:AstroComments() abort \ || s:IdentifyScope('^\s*') " ECMAScript comments setlocal comments=sO:*\ -,mO:*\ \ ,exO:*/,s1:/*,mb:*,ex:*/,:// - setlocal commentstring=//%s + setlocal commentstring=//\ %s elseif s:IdentifyScope('^\s*') " CSS comments setlocal comments=s1:/*,mb:*,ex:*/ - setlocal commentstring=/*%s*/ + setlocal commentstring=/*\ %s\ */ else " HTML comments setlocal comments=s: - setlocal commentstring= + setlocal commentstring= endif endfunction diff --git a/runtime/ftplugin/bitbake.vim b/runtime/ftplugin/bitbake.vim index 99fe334627..4d50a7feb7 100644 --- a/runtime/ftplugin/bitbake.vim +++ b/runtime/ftplugin/bitbake.vim @@ -3,13 +3,14 @@ " Maintainer: Gregory Anders " Repository: https://github.com/openembedded/bitbake " Latest Revision: 2022-07-23 +" 2024-05-23 by Riley Bruins ('commentstring') if exists("b:did_ftplugin") finish endif let b:did_ftplugin = 1 -setlocal commentstring=#%s +setlocal commentstring=#\ %s setlocal comments=:# setlocal suffixesadd=.bb,.bbclass diff --git a/runtime/ftplugin/c.vim b/runtime/ftplugin/c.vim index 716b454675..8b2b784eb4 100644 --- a/runtime/ftplugin/c.vim +++ b/runtime/ftplugin/c.vim @@ -2,6 +2,7 @@ " Language: C " Maintainer: The Vim Project " Last Change: 2023 Aug 22 +" 2024 Jun 02 by Riley Bruins ('commentstring') " Former Maintainer: Bram Moolenaar " Only do this when not done yet for this buffer @@ -24,7 +25,7 @@ setlocal fo-=t fo+=croql " These options have the right value as default, but the user may have " overruled that. -setlocal commentstring& define& include& +setlocal commentstring=/*\ %s\ */ define& include& " Set completion with CTRL-X CTRL-O to autoloaded function. if exists('&ofu') diff --git a/runtime/ftplugin/calendar.vim b/runtime/ftplugin/calendar.vim index f454ba1dc8..c4e683acf6 100644 --- a/runtime/ftplugin/calendar.vim +++ b/runtime/ftplugin/calendar.vim @@ -2,6 +2,7 @@ " Language: calendar(1) input file " Previous Maintainer: Nikolai Weibull " Latest Revision: 2008-07-09 +" 2024-06-02 by Riley Bruins ('commentstring') if exists("b:did_ftplugin") finish @@ -13,7 +14,7 @@ set cpo&vim let b:undo_ftplugin = "setl com< cms< inc< fo<" -setlocal comments=s1:/*,mb:*,ex:*/ commentstring& include& +setlocal comments=s1:/*,mb:*,ex:*/ commentstring=/*\ %s\ */ include& setlocal formatoptions-=t formatoptions+=croql let &cpo = s:cpo_save diff --git a/runtime/ftplugin/cgdbrc.vim b/runtime/ftplugin/cgdbrc.vim index 46cf135c5c..99f9702d26 100644 --- a/runtime/ftplugin/cgdbrc.vim +++ b/runtime/ftplugin/cgdbrc.vim @@ -3,6 +3,7 @@ " Maintainer: Wu, Zhenyu " Documentation: https://cgdb.github.io/docs/Configuring-CGDB.html " Latest Revision: 2024-04-09 +" 2024-05-23 by Riley Bruins ('commentstring') if exists('b:did_ftplugin') finish @@ -14,7 +15,7 @@ set cpoptions&vim let b:undo_ftplugin = 'setl com< cms<' -setlocal commentstring=#%s +setlocal commentstring=#\ %s setlocal comments=:# let &cpoptions = s:save_cpoptions diff --git a/runtime/ftplugin/csh.vim b/runtime/ftplugin/csh.vim index a22bee3279..74666b9680 100644 --- a/runtime/ftplugin/csh.vim +++ b/runtime/ftplugin/csh.vim @@ -4,6 +4,7 @@ " Previous Maintainer: Dan Sharp " Contributor: Johannes Zellner " Last Change: 2024 Jan 14 +" 2024 May 23 by Riley Bruins ('commentstring') if exists("b:did_ftplugin") finish @@ -14,7 +15,7 @@ let s:save_cpo = &cpo set cpo-=C setlocal comments=:# -setlocal commentstring=#%s +setlocal commentstring=#\ %s setlocal formatoptions-=t setlocal formatoptions+=crql diff --git a/runtime/ftplugin/css.lua b/runtime/ftplugin/css.lua deleted file mode 100644 index 984111a08b..0000000000 --- a/runtime/ftplugin/css.lua +++ /dev/null @@ -1 +0,0 @@ -vim.bo.commentstring = '/* %s */' diff --git a/runtime/ftplugin/css.vim b/runtime/ftplugin/css.vim index ece2def4ee..778a9e12d6 100644 --- a/runtime/ftplugin/css.vim +++ b/runtime/ftplugin/css.vim @@ -3,6 +3,7 @@ " Maintainer: Doug Kearns " Previous Maintainer: Nikolai Weibull " Last Change: 2020 Dec 21 +" 2024 Jun 02 by Riley Bruins ('commentstring') if exists("b:did_ftplugin") finish @@ -14,7 +15,7 @@ set cpo&vim let b:undo_ftplugin = "setl com< cms< inc< fo< ofu< isk<" -setlocal comments=s1:/*,mb:*,ex:*/ commentstring& +setlocal comments=s1:/*,mb:*,ex:*/ commentstring=/*\ %s\ */ setlocal formatoptions-=t formatoptions+=croql setlocal omnifunc=csscomplete#CompleteCSS setlocal iskeyword+=- diff --git a/runtime/ftplugin/desktop.vim b/runtime/ftplugin/desktop.vim index bd6fd7097c..d15afd24b9 100644 --- a/runtime/ftplugin/desktop.vim +++ b/runtime/ftplugin/desktop.vim @@ -2,6 +2,7 @@ " Language: XDG desktop entry " Maintainer: Eisuke Kawashima ( e.kawaschima+vim AT gmail.com ) " Last Change: 2022-07-26 +" 2024-05-24 by Riley Bruins ('commentstring') if exists('b:did_ftplugin') finish @@ -9,5 +10,5 @@ endif let b:did_ftplugin = v:true setl comments=:# -setl commentstring=#%s +setl commentstring=#\ %s let b:undo_ftplugin = 'setl com< cms<' diff --git a/runtime/ftplugin/dtd.vim b/runtime/ftplugin/dtd.vim index bea8c5c18a..f97014814b 100644 --- a/runtime/ftplugin/dtd.vim +++ b/runtime/ftplugin/dtd.vim @@ -6,6 +6,7 @@ " Former maintainer: Dan Sharp " Last Change: 2009 Jan 20 " 2024 Jan 14 by Vim Project (browsefilter) +" 2024 May 23 by Riley Bruins ('commentstring') if exists("b:did_ftplugin") | finish | endif let b:did_ftplugin = 1 @@ -15,7 +16,7 @@ let b:did_ftplugin = 1 let s:save_cpo = &cpo set cpo-=C -setlocal commentstring= +setlocal commentstring= setlocal comments=s: setlocal formatoptions-=t diff --git a/runtime/ftplugin/dtrace.vim b/runtime/ftplugin/dtrace.vim index 9288097f7f..a276b310a3 100644 --- a/runtime/ftplugin/dtrace.vim +++ b/runtime/ftplugin/dtrace.vim @@ -1,6 +1,7 @@ " Language: D script as described in "Solaris Dynamic Tracing Guide", " http://docs.sun.com/app/docs/doc/817-6223 " Last Change: 2008/03/20 +" 2024/05/23 by Riley Bruins @@ -26,8 +27,8 @@ setlocal fo-=t fo+=croql setlocal comments=sO:*\ -,mO:*\ \ ,exO:*/,s1:/*,mb:*,ex:*/ " dtrace uses /* */ comments. Set this explicitly, just in case the user -" changed this (/*%s*/ is the default) -setlocal commentstring=/*%s*/ +" changed this (/*\ %s\ */ is the default) +setlocal commentstring=/*\ %s\ */ setlocal iskeyword+=@,$ diff --git a/runtime/ftplugin/dts.vim b/runtime/ftplugin/dts.vim index 42e38338b7..346ff94704 100644 --- a/runtime/ftplugin/dts.vim +++ b/runtime/ftplugin/dts.vim @@ -2,6 +2,7 @@ " Language: dts/dtsi (device tree files) " Maintainer: Wu, Zhenyu " Latest Revision: 2024 Apr 12 +" 2024 Jun 02 by Riley Bruins ('commentstring') if exists('b:did_ftplugin') finish @@ -12,5 +13,5 @@ let b:undo_ftplugin = 'setl inc< cms< com<' setlocal include=^\\%(#include\\\|/include/\\) " same as C -setlocal commentstring& +setlocal commentstring=/*\ %s\ */ setlocal comments=sO:*\ -,mO:*\ \ ,exO:*/,s1:/*,mb:*,ex:*/,:///,:// diff --git a/runtime/ftplugin/erlang.vim b/runtime/ftplugin/erlang.vim index 1cb57f4c85..5a3ab717d9 100644 --- a/runtime/ftplugin/erlang.vim +++ b/runtime/ftplugin/erlang.vim @@ -6,7 +6,8 @@ " Eduardo Lopez (http://github.com/tapichu) " Arvid Bjurklint (http://github.com/slarwise) " Paweł Zacharek (http://github.com/subc2) -" Last Update: 2023-Dec-20 +" Riley Bruins (http://github.com/ribru17) ('commentstring') +" Last Update: 2024 May 23 " License: Vim license " URL: https://github.com/vim-erlang/vim-erlang-runtime @@ -27,7 +28,7 @@ if get(g:, 'erlang_folding', 0) endif setlocal comments=:%%%,:%%,:% -setlocal commentstring=%%s +setlocal commentstring=%\ %s setlocal formatoptions+=ro diff --git a/runtime/ftplugin/eruby.vim b/runtime/ftplugin/eruby.vim index b5c4665d24..b3e074aa20 100644 --- a/runtime/ftplugin/eruby.vim +++ b/runtime/ftplugin/eruby.vim @@ -5,6 +5,7 @@ " Release Coordinator: Doug Kearns " Last Change: 2022 May 15 " 2024 Jan 14 by Vim Project (browsefilter) +" 2024 May 23 by Riley Bruins ('commentstring') " Only do this when not done yet for this buffer if exists("b:did_ftplugin") @@ -125,7 +126,7 @@ if exists("loaded_matchit") endif " TODO: comments= -setlocal commentstring=<%#%s%> +setlocal commentstring=<%#\ %s\ %> let b:undo_ftplugin = "setl cms< " . \ " | unlet! b:browsefilter b:match_words | " . b:undo_ftplugin diff --git a/runtime/ftplugin/fennel.vim b/runtime/ftplugin/fennel.vim index 93cf366726..2a9623faff 100644 --- a/runtime/ftplugin/fennel.vim +++ b/runtime/ftplugin/fennel.vim @@ -2,13 +2,14 @@ " Language: Fennel " Maintainer: Gregory Anders " Last Update: 2023 Jun 9 +" 2024 May 24 by Riley Bruins ('commentstring') if exists('b:did_ftplugin') finish endif let b:did_ftplugin = 1 -setlocal commentstring=;%s +setlocal commentstring=;\ %s setlocal comments=:;;,:; setlocal formatoptions-=t setlocal suffixesadd=.fnl diff --git a/runtime/ftplugin/fish.vim b/runtime/ftplugin/fish.vim index f06ad3a0bf..55d7ea8dd9 100644 --- a/runtime/ftplugin/fish.vim +++ b/runtime/ftplugin/fish.vim @@ -4,6 +4,7 @@ " Repository: https://github.com/nickeb96/fish.vim " Last Change: February 1, 2023 " 2023 Aug 28 by Vim Project (undo_ftplugin) +" 2024 May 23 by Riley Bruins ('commentstring') if exists("b:did_ftplugin") finish @@ -12,7 +13,7 @@ let b:did_ftplugin = 1 setlocal iskeyword=@,48-57,_,192-255,-,. setlocal comments=:# -setlocal commentstring=#%s +setlocal commentstring=#\ %s setlocal formatoptions+=crjq let b:undo_ftplugin = "setl cms< com< fo< isk<" diff --git a/runtime/ftplugin/fortran.vim b/runtime/ftplugin/fortran.vim index 3c325818d3..19a4c1e62b 100644 --- a/runtime/ftplugin/fortran.vim +++ b/runtime/ftplugin/fortran.vim @@ -11,6 +11,7 @@ " Doug Kearns, and Fritz Reese. " Last Change: 2023 Dec 22 " 2024 Jan 14 by Vim Project (browsefilter) +" 2024 May 23 by Riley Bruins ('commentstring') " Only do these settings when not done yet for this buffer if exists("b:did_ftplugin") @@ -89,7 +90,7 @@ else endif " Set commentstring for foldmethod=marker -setlocal cms=!%s +setlocal cms=!\ %s " Tabs are not a good idea in Fortran so the default is to expand tabs if !exists("fortran_have_tabs") diff --git a/runtime/ftplugin/fstab.vim b/runtime/ftplugin/fstab.vim index 99805322cd..0e7ffda498 100644 --- a/runtime/ftplugin/fstab.vim +++ b/runtime/ftplugin/fstab.vim @@ -3,6 +3,7 @@ " Maintainer: Radu Dineiu " URL: https://raw.github.com/rid9/vim-fstab/master/ftplugin/fstab.vim " Last Change: 2021 Jan 02 +" 2024 May 23 by Riley Bruins ('commentstring') " Version: 1.0 " " Credits: @@ -13,7 +14,7 @@ if exists("b:did_ftplugin") endif let b:did_ftplugin = 1 -setlocal commentstring=#%s +setlocal commentstring=#\ %s let b:undo_ftplugin = "setlocal commentstring<" " vim: ts=8 ft=vim diff --git a/runtime/ftplugin/gdb.vim b/runtime/ftplugin/gdb.vim index 7c10633be4..af88a04d54 100644 --- a/runtime/ftplugin/gdb.vim +++ b/runtime/ftplugin/gdb.vim @@ -3,11 +3,12 @@ " Maintainer: Michaël Peeters " Last Changed: 2017-10-26 " 2024-04-10: - add Matchit support (by Vim Project) +" 2024-04-23: - add space to commentstring (by Riley Bruins) ('commentstring') if exists("b:did_ftplugin") | finish | endif let b:did_ftplugin = 1 -setlocal commentstring=#%s +setlocal commentstring=#\ %s setlocal include=^\\s*source " Undo the stuff we changed. diff --git a/runtime/ftplugin/groovy.vim b/runtime/ftplugin/groovy.vim index cc7d6e35eb..a2e2b2f93e 100644 --- a/runtime/ftplugin/groovy.vim +++ b/runtime/ftplugin/groovy.vim @@ -2,6 +2,7 @@ " Language: groovy " Maintainer: Justin M. Keyes " Last Change: 2016 May 22 +" 2024 May 24 by Riley Bruins ('commentstring') if exists('b:did_ftplugin') finish @@ -13,7 +14,7 @@ set cpo-=C let b:undo_ftplugin = 'setlocal commentstring<' -setlocal commentstring=//%s +setlocal commentstring=//\ %s let &cpo = s:cpo_save unlet s:cpo_save diff --git a/runtime/ftplugin/hamster.vim b/runtime/ftplugin/hamster.vim index 5446e72286..904f267fdc 100644 --- a/runtime/ftplugin/hamster.vim +++ b/runtime/ftplugin/hamster.vim @@ -3,6 +3,7 @@ " Version: 2.0.6.0 " Maintainer: David Fishburn " Last Change: 2021 Jan 19 +" 2024 May 23 by Riley Bruins ('commentstring') " Only do this when not done yet for this buffer if exists("b:did_ftplugin") @@ -31,7 +32,7 @@ if &tw == 0 endif " Comments start with a double quote -setlocal commentstring=#%s +setlocal commentstring=#\ %s " Move around functions. noremap [[ :call search('^\s*sub\>', "bW") diff --git a/runtime/ftplugin/html.vim b/runtime/ftplugin/html.vim index 3aa60a873e..5495f859de 100644 --- a/runtime/ftplugin/html.vim +++ b/runtime/ftplugin/html.vim @@ -3,6 +3,7 @@ " Maintainer: Doug Kearns " Previous Maintainer: Dan Sharp " Last Change: 2024 Jan 14 +" 2024 May 24 by Riley Bruins ('commentstring') if exists("b:did_ftplugin") finish @@ -13,7 +14,7 @@ let s:save_cpo = &cpo set cpo-=C setlocal matchpairs+=<:> -setlocal commentstring= +setlocal commentstring= setlocal comments=s: let b:undo_ftplugin = "setlocal comments< commentstring< matchpairs<" diff --git a/runtime/ftplugin/indent.vim b/runtime/ftplugin/indent.vim index 64a650ad7b..32208d38d8 100644 --- a/runtime/ftplugin/indent.vim +++ b/runtime/ftplugin/indent.vim @@ -3,6 +3,7 @@ " Maintainer: Doug Kearns " Previous Maintainer: Nikolai Weibull " Latest Revision: 2008-07-09 +" 2024-06-02 by Riley Bruins ('commentstring') if exists("b:did_ftplugin") finish @@ -14,7 +15,7 @@ set cpo&vim let b:undo_ftplugin = "setl com< cms< fo<" -setlocal comments=s1:/*,mb:*,ex:*/ commentstring& +setlocal comments=s1:/*,mb:*,ex:*/ commentstring=/*\ %s\ */ setlocal formatoptions-=t formatoptions+=croql let &cpo = s:cpo_save diff --git a/runtime/ftplugin/initex.vim b/runtime/ftplugin/initex.vim index 0ee3e8d899..71049df6bd 100644 --- a/runtime/ftplugin/initex.vim +++ b/runtime/ftplugin/initex.vim @@ -3,6 +3,7 @@ " Maintainer: Benji Fisher, Ph.D. " Version: 1.0 " Last Change: Wed 19 Apr 2006 +" Last Change: Thu 23 May 2024 by Riley Bruins ('commentstring') " Only do this when not done yet for this buffer. if exists("b:did_ftplugin") @@ -23,7 +24,7 @@ setlocal com=sO:%\ -,mO:%\ \ ,eO:%%,:% " Set 'commentstring' to recognize the % comment character: " (Thanks to Ajit Thakkar.) -setlocal cms=%%s +setlocal cms=%\ %s " Allow "[d" to be used to find a macro definition: let &l:define='\\\([egx]\|char\|mathchar\|count\|dimen\|muskip\|skip\|toks\)\=' diff --git a/runtime/ftplugin/java.vim b/runtime/ftplugin/java.vim index fa2b61075f..eee7ef0153 100644 --- a/runtime/ftplugin/java.vim +++ b/runtime/ftplugin/java.vim @@ -5,6 +5,7 @@ " Repository: https://github.com/zzzyxwvut/java-vim.git " Last Change: 2024 Apr 18 " 2024 Jan 14 by Vim Project (browsefilter) +" 2024 May 23 by Riley Bruins ('commentstring') if exists("b:did_ftplugin") | finish | endif let b:did_ftplugin = 1 @@ -61,7 +62,7 @@ setlocal formatoptions-=t formatoptions+=croql " Set 'comments' to format dashed lists in comments. Behaves just like C. setlocal comments& comments^=sO:*\ -,mO:*\ \ ,exO:*/ -setlocal commentstring=//%s +setlocal commentstring=//\ %s " Change the :browse e filter to primarily show Java-related files. if (has("gui_win32") || has("gui_gtk")) && !exists("b:browsefilter") diff --git a/runtime/ftplugin/javascript.vim b/runtime/ftplugin/javascript.vim index 2633954903..455b794cf0 100644 --- a/runtime/ftplugin/javascript.vim +++ b/runtime/ftplugin/javascript.vim @@ -3,6 +3,7 @@ " Maintainer: Doug Kearns " Contributor: Romain Lafourcade " Last Change: 2024 Jan 14 +" 2024 May 23 by Riley Bruins ('commentstring') if exists("b:did_ftplugin") finish @@ -24,7 +25,7 @@ endif " Set 'comments' to format dashed lists in comments. setlocal comments=sO:*\ -,mO:*\ \ ,exO:*/,s1:/*,mb:*,ex:*/,:// -setlocal commentstring=//%s +setlocal commentstring=//\ %s " Change the :browse e filter to primarily show JavaScript-related files. if (has("gui_win32") || has("gui_gtk")) && !exists("b:browsefilter") diff --git a/runtime/ftplugin/jq.vim b/runtime/ftplugin/jq.vim index 88958e80dd..d25883640b 100644 --- a/runtime/ftplugin/jq.vim +++ b/runtime/ftplugin/jq.vim @@ -2,6 +2,7 @@ " Language: jq " Maintainer: Vito " Last Change: 2024 Apr 29 +" 2024 May 23 by Riley Bruins ('commentstring') " Upstream: https://github.com/vito-c/jq.vim if exists('b:did_ftplugin') @@ -10,7 +11,7 @@ endif let b:did_ftplugin = 1 setlocal include=^\\s*\\%(import\\\|include\\) -setlocal commentstring=#%s +setlocal commentstring=#\ %s compiler jq let b:undo_ftplugin = 'setl commentstring< include<' diff --git a/runtime/ftplugin/jsonc.vim b/runtime/ftplugin/jsonc.vim index e47a75f574..ec3268492c 100644 --- a/runtime/ftplugin/jsonc.vim +++ b/runtime/ftplugin/jsonc.vim @@ -5,6 +5,7 @@ " https://github.com/kevinoid/vim-jsonc " License: MIT " Last Change: 2021 Nov 22 +" 2024 May 23 by Riley Bruins ('commentstring') runtime! ftplugin/json.vim @@ -15,7 +16,7 @@ else endif " Set comment (formatting) related options. {{{1 -setlocal commentstring=//%s comments=sO:*\ -,mO:*\ \ ,exO:*/,s1:/*,mb:*,ex:*/,:// +setlocal commentstring=//\ %s comments=sO:*\ -,mO:*\ \ ,exO:*/,s1:/*,mb:*,ex:*/,:// " Let Vim know how to disable the plug-in. let b:undo_ftplugin = 'setlocal commentstring< comments<' diff --git a/runtime/ftplugin/lc.vim b/runtime/ftplugin/lc.vim new file mode 100644 index 0000000000..e818f1aecb --- /dev/null +++ b/runtime/ftplugin/lc.vim @@ -0,0 +1,13 @@ +" Vim filetype plugin +" Language: Elsa +" Maintainer: Riley Bruins +" Last Change: 2024 May 25 + +if exists('b:did_ftplugin') + finish +endif +let b:did_ftplugin = 1 + +setl comments=:-- commentstring=--\ %s + +let b:undo_ftplugin = 'setl com< cms<' diff --git a/runtime/ftplugin/ld.vim b/runtime/ftplugin/ld.vim index 1ab80d533c..9cc70bd94d 100644 --- a/runtime/ftplugin/ld.vim +++ b/runtime/ftplugin/ld.vim @@ -1,7 +1,8 @@ " Vim filetype plugin file " Language: ld(1) script " Previous Maintainer: Nikolai Weibull -" Latest Revision: 2008-07-09 +" Latest Revision: 2008 Jul 09 +" 2024 May 23 by Riley Bruins ('commentstring') if exists("b:did_ftplugin") finish @@ -13,7 +14,7 @@ set cpo&vim let b:undo_ftplugin = "setl com< cms< inc< fo<" -setlocal comments=s1:/*,mb:*,ex:*/ commentstring=/*%s*/ include=^\\s*INCLUDE +setlocal comments=s1:/*,mb:*,ex:*/ commentstring=/*\ %s\ */ include=^\\s*INCLUDE setlocal formatoptions-=t formatoptions+=croql let &cpo = s:cpo_save diff --git a/runtime/ftplugin/liquid.vim b/runtime/ftplugin/liquid.vim index f24ec4cbb2..dbd8abe457 100644 --- a/runtime/ftplugin/liquid.vim +++ b/runtime/ftplugin/liquid.vim @@ -2,6 +2,7 @@ " Language: Liquid " Maintainer: Tim Pope " Last Change: 2022 Mar 15 +" 2024 May 23 by Riley Bruins ('commentstring') if exists('b:did_ftplugin') finish @@ -56,6 +57,6 @@ if exists('loaded_matchit') let b:match_words .= '\<\%(if\w*\|unless\|case\)\>:\<\%(elsif\|else\|when\)\>:\,\<\%(for\|tablerow\)\>:\%({%\s*\)\@<=empty\>:\,\<\(capture\|comment\|highlight\)\>:\' endif -setlocal commentstring={%\ comment\ %}%s{%\ endcomment\ %} +setlocal commentstring={%\ comment\ %}\ %s\ {%\ endcomment\ %} let b:undo_ftplugin .= 'setl cms< | unlet! b:browsefilter b:match_words' diff --git a/runtime/ftplugin/lisp.vim b/runtime/ftplugin/lisp.vim index db3ac96631..fe3c6fe996 100644 --- a/runtime/ftplugin/lisp.vim +++ b/runtime/ftplugin/lisp.vim @@ -5,6 +5,7 @@ " Original author: Dorai Sitaram " Original URL: http://www.ccs.neu.edu/~dorai/vimplugins/vimplugins.html " Last Change: Mar 10, 2021 +" May 23, 2024 by Riley Bruins ('commentstring') " Only do this when not done yet for this buffer if exists("b:did_ftplugin") @@ -19,6 +20,6 @@ setl define=^\\s*(def\\k* setl formatoptions-=t setl iskeyword+=+,-,*,/,%,<,=,>,:,$,?,!,@-@,94 setl lisp -setl commentstring=;%s +setl commentstring=;\ %s let b:undo_ftplugin = "setlocal comments< define< formatoptions< iskeyword< lisp< commentstring<" diff --git a/runtime/ftplugin/markdown.vim b/runtime/ftplugin/markdown.vim index 022dd0d601..d4ee5ac242 100644 --- a/runtime/ftplugin/markdown.vim +++ b/runtime/ftplugin/markdown.vim @@ -2,6 +2,7 @@ " Language: Markdown " Maintainer: Tim Pope " Last Change: 2023 Dec 28 +" 2024 May 24 by Riley Bruins ('commentstring') if exists("b:did_ftplugin") finish @@ -12,7 +13,7 @@ runtime! ftplugin/html.vim ftplugin/html_*.vim ftplugin/html/*.vim let s:keepcpo= &cpo set cpo&vim -setlocal comments=fb:*,fb:-,fb:+,n:> commentstring= +setlocal comments=fb:*,fb:-,fb:+,n:> commentstring= setlocal formatoptions+=tcqln formatoptions-=r formatoptions-=o setlocal formatlistpat=^\\s*\\d\\+\\.\\s\\+\\\|^\\s*[-*+]\\s\\+\\\|^\\[^\\ze[^\\]]\\+\\]:\\&^.\\{4\\} diff --git a/runtime/ftplugin/mma.vim b/runtime/ftplugin/mma.vim index ce4cee18ae..91a8111bcb 100644 --- a/runtime/ftplugin/mma.vim +++ b/runtime/ftplugin/mma.vim @@ -1,7 +1,8 @@ " Vim filetype plugin file " Language: Mathematica " Maintainer: Ian Ford -" Last Change: 22 January 2019 +" Last Change: 2019 Jan 22 +" 2024 May 23 by Riley Bruins ('commentstring') " Only do this when not done yet for this buffer if exists("b:did_ftplugin") @@ -13,4 +14,4 @@ let b:did_ftplugin = 1 let b:undo_ftplugin = "setlocal commentstring<" -setlocal commentstring=\(*%s*\) +setlocal commentstring=\(*\ %s\ *\) diff --git a/runtime/ftplugin/modula2.vim b/runtime/ftplugin/modula2.vim index 9c1acc276a..306688da05 100644 --- a/runtime/ftplugin/modula2.vim +++ b/runtime/ftplugin/modula2.vim @@ -2,6 +2,7 @@ " Language: Modula-2 " Maintainer: Doug Kearns " Last Change: 2024 Jan 14 +" 2024 May 23 by Riley Bruins ('commentstring') if exists("b:did_ftplugin") finish @@ -17,7 +18,7 @@ if s:dialect ==# "r10" setlocal comments=s:(*,m:\ ,e:*),:! setlocal commentstring=!\ %s else - setlocal commentstring=(*%s*) + setlocal commentstring=(*\ %s\ *) setlocal comments=s:(*,m:\ ,e:*) endif setlocal formatoptions-=t formatoptions+=croql diff --git a/runtime/ftplugin/modula3.vim b/runtime/ftplugin/modula3.vim index 45dd7ca01c..f899d1d103 100644 --- a/runtime/ftplugin/modula3.vim +++ b/runtime/ftplugin/modula3.vim @@ -2,6 +2,7 @@ " Language: Modula-3 " Maintainer: Doug Kearns " Last Change: 2024 Jan 14 +" 2024 May 24 by Riley Bruins ('commentstring') if exists("b:did_ftplugin") finish @@ -12,7 +13,7 @@ let s:cpo_save = &cpo set cpo&vim setlocal comments=s0:(*,mb:\ ,ex:*) -setlocal commentstring=(*%s*) +setlocal commentstring=(*\ %s\ *) setlocal formatoptions-=t formatoptions+=croql setlocal suffixesadd+=.m3 setlocal formatprg=m3pp diff --git a/runtime/ftplugin/nroff.vim b/runtime/ftplugin/nroff.vim index cf62d02daa..ed0b32f5f3 100644 --- a/runtime/ftplugin/nroff.vim +++ b/runtime/ftplugin/nroff.vim @@ -2,15 +2,15 @@ " Language: roff(7) " Maintainer: Aman Verma " Homepage: https://github.com/a-vrma/vim-nroff-ftplugin -" Previous Maintainer: Chris Spiegel -" Last Change: 2020 Nov 21 +" Previous Maintainer: Chris Spiegel +" 2024 May 24 by Riley Bruins ('commentstring') if exists("b:did_ftplugin") finish endif let b:did_ftplugin = 1 -setlocal commentstring=.\\\"%s +setlocal commentstring=.\\\"\ %s setlocal comments=:.\\\" setlocal sections+=Sh diff --git a/runtime/ftplugin/obse.vim b/runtime/ftplugin/obse.vim index 6d865f05ee..bf5076f41f 100644 --- a/runtime/ftplugin/obse.vim +++ b/runtime/ftplugin/obse.vim @@ -2,8 +2,9 @@ " Language: Oblivion Language (obl) " Original Creator: Kat " Maintainer: Kat -" Created: August 08, 2021 -" Last Change: 13 November 2022 +" Created: 2021 Aug 08 +" Last Change: 2022 Nov 13 +" 2024 May 23 by Riley Bruins ('commentstring') if exists("b:did_ftplugin") finish @@ -20,7 +21,7 @@ noremap