diff options
-rw-r--r-- | .cirrus.yml | 2 | ||||
-rw-r--r-- | runtime/ftplugin/nroff.vim | 19 | ||||
-rw-r--r-- | runtime/lua/vim/lsp/completion.lua | 18 | ||||
-rw-r--r-- | runtime/syntax/vim.vim | 255 | ||||
-rw-r--r-- | src/nvim/memline.c | 10 | ||||
-rw-r--r-- | test/functional/lua/buffer_updates_spec.lua | 18 | ||||
-rw-r--r-- | test/functional/plugin/lsp/completion_spec.lua | 77 |
7 files changed, 318 insertions, 81 deletions
diff --git a/.cirrus.yml b/.cirrus.yml index bb98430763..d2262d44c0 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -6,7 +6,7 @@ freebsd_task: name: FreeBSD only_if: $BRANCH != "master" freebsd_instance: - image_family: freebsd-14-0 + image_family: freebsd-14-2 timeout_in: 30m install_script: - pkg install -y cmake gmake ninja unzip wget gettext python git diff --git a/runtime/ftplugin/nroff.vim b/runtime/ftplugin/nroff.vim index ed0b32f5f3..7d3d2a597f 100644 --- a/runtime/ftplugin/nroff.vim +++ b/runtime/ftplugin/nroff.vim @@ -2,8 +2,11 @@ " Language: roff(7) " Maintainer: Aman Verma " Homepage: https://github.com/a-vrma/vim-nroff-ftplugin +" Document: https://www.gnu.org/software/groff/manual/groff.html " Previous Maintainer: Chris Spiegel <cspiegel@gmail.com> -" 2024 May 24 by Riley Bruins <ribru17@gmail.com> ('commentstring') +" Last Changes: +" 2024 May 24 by Riley Bruins <ribru17@gmail.com> ('commentstring' #14843) +" 2025 Feb 12 by Wu, Zhenyu <wuzhenyu@ustc.edu> (matchit configuration #16619) if exists("b:did_ftplugin") finish @@ -13,5 +16,17 @@ let b:did_ftplugin = 1 setlocal commentstring=.\\\"\ %s setlocal comments=:.\\\" setlocal sections+=Sh +setlocal define=.\s*de -let b:undo_ftplugin = 'setlocal commentstring< comments< sections<' +let b:undo_ftplugin = 'setlocal commentstring< comments< sections< define<' + +if exists('loaded_matchit') + let b:match_words = '^\.\s*ie\>:^\.\s*el\>' + \ . ',^\.\s*LB\>:^\.\s*LI\>:^\.\s*LE\>' + \ . ',^\.\s*TS\>:^\.\s*TE\>' + \ . ',^\.\s*PS\>:^\.\s*P[EF]\>' + \ . ',^\.\s*EQ\>:^\.\s*EN\>' + \ . ',^\.\s*[\>:^\.\s*]\>' + \ . ',^\.\s*FS\>:^\.\s*FE\>' + let b:undo_ftplugin .= "| unlet b:match_words" +endif diff --git a/runtime/lua/vim/lsp/completion.lua b/runtime/lua/vim/lsp/completion.lua index cf6d07745f..f287304508 100644 --- a/runtime/lua/vim/lsp/completion.lua +++ b/runtime/lua/vim/lsp/completion.lua @@ -493,6 +493,7 @@ local function trigger(bufnr, clients) end end local start_col = (server_start_boundary or word_boundary) + 1 + Context.cursor = { cursor_row, start_col } vim.fn.complete(start_col, matches) end) @@ -518,11 +519,14 @@ local function on_insert_char_pre(handle) end local char = api.nvim_get_vvar('char') - if not completion_timer and handle.triggers[char] then + local matched_clients = handle.triggers[char] + if not completion_timer and matched_clients then completion_timer = assert(vim.uv.new_timer()) completion_timer:start(25, 0, function() reset_timer() - vim.schedule(M.trigger) + vim.schedule(function() + trigger(api.nvim_get_current_buf(), matched_clients) + end) end) end end @@ -569,8 +573,14 @@ local function on_complete_done() end -- Remove the already inserted word. - local start_char = cursor_col - #completed_item.word - api.nvim_buf_set_text(bufnr, cursor_row, start_char, cursor_row, cursor_col, { '' }) + api.nvim_buf_set_text( + bufnr, + Context.cursor[1] - 1, + Context.cursor[2] - 1, + cursor_row, + cursor_col, + { '' } + ) end local function apply_snippet_and_command() diff --git a/runtime/syntax/vim.vim b/runtime/syntax/vim.vim index c4e231d145..9b128265de 100644 --- a/runtime/syntax/vim.vim +++ b/runtime/syntax/vim.vim @@ -185,31 +185,51 @@ Vim9 syn keyword vim9Boolean true false " Numbers {{{2 " ======= syn case ignore -syn match vimNumber '\<\d\+\%(\.\d\+\%(e[+-]\=\d\+\)\=\)\=' skipwhite nextgroup=vimGlobal,vimSubst1,@vimComment -syn match vimNumber '\<0b[01]\+' skipwhite nextgroup=vimGlobal,vimSubst1,@vimComment -syn match vimNumber '\<0o\=\o\+' skipwhite nextgroup=vimGlobal,vimSubst1,@vimComment -syn match vimNumber '\<0x\x\+' skipwhite nextgroup=vimGlobal,vimSubst1,@vimComment +syn match vimNumber '\<\d\+' skipwhite nextgroup=vimGlobal,vimSubst1,@vimComment,vimSubscript +syn match vimNumber '\<\d\+\.\d\+\%(e[+-]\=\d\+\)\=' skipwhite nextgroup=vimGlobal,vimSubst1,@vimComment +syn match vimNumber '\<0b[01]\+' skipwhite nextgroup=vimGlobal,vimSubst1,@vimComment,vimSubscript +syn match vimNumber '\<0o\=\o\+' skipwhite nextgroup=vimGlobal,vimSubst1,@vimComment,vimSubscript +syn match vimNumber '\<0x\x\+' skipwhite nextgroup=vimGlobal,vimSubst1,@vimComment,vimSubscript syn match vimNumber '\<0z\>' skipwhite nextgroup=vimGlobal,vimSubst1,@vimComment -syn match vimNumber '\<0z\%(\x\x\)\+\%(\.\%(\x\x\)\+\)*' skipwhite nextgroup=vimGlobal,vimSubst1,@vimComment +syn match vimNumber '\<0z\%(\x\x\)\+\%(\.\%(\x\x\)\+\)*' skipwhite nextgroup=vimGlobal,vimSubst1,@vimComment,vimSubscript syn match vimNumber '\%(^\|\A\)\zs#\x\{6}' skipwhite nextgroup=vimGlobal,vimSubst1,@vimComment syn case match " All vimCommands are contained by vimIsCommand. {{{2 -syn cluster vimCmdList contains=vimAbb,vimAddress,vimAutoCmd,vimAugroup,vimBehave,vimCall,vimCatch,vimConst,vimDef,vimDefFold,vimDelcommand,@vimEcho,vimEnddef,vimEndfunction,vimExecute,vimIsCommand,vimExtCmd,vimFor,vimFunction,vimFuncFold,vimGlobal,vimHighlight,vimLet,vimLoadkeymap,vimMap,vimMark,vimMatch,vimNotFunc,vimNormal,vimSet,vimSleep,vimSyntax,vimThrow,vimUnlet,vimUnmap,vimUserCmd,vimMenu,vimMenutranslate,@vim9CmdList +syn cluster vimCmdList contains=vimAbb,vimAddress,vimAutoCmd,vimAugroup,vimBehave,vimCall,vimCatch,vimConst,vimDebuggreedy,vimDef,vimDefFold,vimDelcommand,@vimEcho,vimEnddef,vimEndfunction,vimExecute,vimIsCommand,vimExtCmd,vimFor,vimFunction,vimFuncFold,vimGlobal,vimHighlight,vimLet,vimLoadkeymap,vimLockvar,vimMap,vimMark,vimMatch,vimNotFunc,vimNormal,vimSet,vimSleep,vimSyntax,vimThrow,vimUnlet,vimUnlockvar,vimUnmap,vimUserCmd,vimMenu,vimMenutranslate,@vim9CmdList syn cluster vim9CmdList contains=vim9Abstract,vim9Class,vim9Const,vim9Enum,vim9Export,vim9Final,vim9For,vim9Interface,vim9Type,vim9Var syn match vimCmdSep "[:|]\+" skipwhite nextgroup=@vimCmdList,vimSubst1 +syn match vimCount contained "\d\+" syn match vimIsCommand "\<\%(\h\w*\|[23]mat\%[ch]\)\>" nextgroup=vimBang contains=vimCommand syn match vimBang contained "!" -syn match vimVar contained "\<\h[a-zA-Z0-9#_]*\>" -syn match vimVar "\<[bwglstav]:\h[a-zA-Z0-9#_]*\>" -syn match vimVar "\s\zs&\%([lg]:\)\=\a\+\>" -syn match vimVar "\s\zs&t_\S[a-zA-Z0-9]\>" -syn match vimVar "\s\zs&t_k;" -syn match vimFBVar contained "\<[bwglstav]:\h[a-zA-Z0-9#_]*\>" -syn keyword vimCommand contained in -syn cluster vimExprList contains=vimEnvvar,vimFunc,vimNumber,vimOper,vimOperParen,vimLetRegister,vimString,vimVar,@vim9ExprList -syn cluster vim9ExprList contains=vim9Boolean,vim9Null +syn region vimSubscript contained matchgroup=vimSubscriptBracket start="\[" end="]" nextgroup=vimSubscript contains=@vimExprList + +syn match vimVar contained "\<\h[a-zA-Z0-9#_]*\>" nextgroup=vimSubscript contains=vim9Super,vim9This +syn match vimVar "\<[bwglstav]:\h[a-zA-Z0-9#_]*\>" nextgroup=vimSubscript +syn match vimVar "\<a:\%(000\|\d\+\)\>" nextgroup=vimSubscript +syn match vimFBVar contained "\<[bwglsta]:\h[a-zA-Z0-9#_]*\>" nextgroup=vimSubscript + +syn match vimVimVar "\<v:\h\w*\>" nextgroup=vimSubscript +syn match vimOptionVar "&\%([lg]:\)\=\a\+\>" nextgroup=vimSubscript +syn match vimOptionVar "&t_\S[a-zA-Z0-9]\>" nextgroup=vimSubscript +syn match vimOptionVar "&t_k;" nextgroup=vimSubscript +syn cluster vimSpecialVar contains=vimEnvvar,vimLetRegister,vimOptionVar,vimVimVar + +Vim9 syn match vim9LhsVariable "\s\=\h[a-zA-Z0-9#_]*\ze\s\+[-+/*%]\==" +Vim9 syn match vim9LhsVariable "\s\=\h[a-zA-Z0-9#_]*\ze\s\+\.\.=" +Vim9 syn match vim9LhsVariable "\s\=\h[a-zA-Z0-9#_]*\ze\s\+=<<" +Vim9 syn match vim9LhsVariable "\s\=\h[a-zA-Z0-9#_]*\ze\s*->" contains=vim9Super,vim9This +Vim9 syn match vim9LhsVariable "\s\=\h[a-zA-Z0-9#_]*\ze\[" nextgroup=vimSubscript +Vim9 syn match vim9LhsVariable "\s\=\h[a-zA-Z0-9#_]*\ze\." nextgroup=vimOper contains=vim9Super,vim9This + +Vim9 syn match vim9LhsVariableList "\[\_[^]]\+]\ze\s\+[-+/*%]\==" contains=vimVar,@vimSpecialVar +Vim9 syn match vim9LhsVariableList "\[\_[^]]\+]\ze\s\+\.\.=" contains=vimVar,@vimSpecialVar + +Vim9 syn match vim9LhsRegister "@["0-9\-a-zA-Z#=*+_/]\ze\s\+\%(\.\.\)\==" + +syn cluster vimExprList contains=@vimSpecialVar,vimFunc,vimNumber,vimOper,vimOperParen,vimLambda,vimString,vimVar,@vim9ExprList +syn cluster vim9ExprList contains=vim9Boolean,vim9LambdaParams,vim9Null " Insertions And Appends: insert append {{{2 " (buftype != nofile test avoids having append, change, insert show up in the command window) @@ -233,6 +253,11 @@ syn keyword vimBehaveModel contained mswin xterm " ==== syn match vimCall "\<call\=\>" skipwhite nextgroup=vimFunc +" Debuggreedy {{{2 +" =========== +" TODO: special-cased until generalised range/count support is implemented +syn match vimDebuggreedy "\<0\=debugg\%[reedy]\>" contains=vimCount + " Exception Handling {{{2 syn keyword vimThrow th[row] skipwhite nextgroup=@vimExprList syn keyword vimCatch cat[ch] skipwhite nextgroup=vimCatchPattern @@ -255,7 +280,7 @@ syn keyword vimFTOption contained detect indent off on plugin " Augroup : vimAugroupError removed because long augroups caused sync'ing problems. {{{2 " ======= : Trade-off: Increasing synclines with slower editing vs augroup END error checking. -syn cluster vimAugroupList contains=@vimCmdList,vimFilter,vimFunc,vimLineComment,vimSpecFile,vimOper,vimNumber,vimOperParen,@vimComment,vimString,vimSubst,vimRegister,vimCmplxRepeat,vimNotation,vimCtrlChar,vimFuncVar,vimContinue +syn cluster vimAugroupList contains=@vimCmdList,vimFilter,vimFunc,vimLineComment,vimSpecFile,vimOper,vimNumber,vimOperParen,@vimComment,vimString,vimSubst,vimRegister,vimCmplxRepeat,vimNotation,vimCtrlChar,vimContinue syn match vimAugroup "\<aug\%[roup]\>" contains=vimAugroupKey,vimAugroupBang skipwhite nextgroup=vimAugroupBang,vimAutoCmdGroup if exists("g:vimsyn_folding") && g:vimsyn_folding =~# 'a' syn region vimAugroup fold start="\<aug\%[roup]\>\ze\s\+\%([eE][nN][dD]\)\@!\S\+" matchgroup=vimAugroupKey end="\<aug\%[roup]\>\ze\s\+[eE][nN][dD]\>" contains=vimAutoCmd,@vimAugroupList,vimAugroupkey skipwhite nextgroup=vimAugroupEnd @@ -273,31 +298,64 @@ syn keyword vimAugroupKey contained aug[roup] skipwhite nextgroup=vimAugroupBan " Operators: {{{2 " ========= -syn cluster vimOperGroup contains=vimEnvvar,vimFunc,vimFuncVar,vimOper,vimOperParen,vimNumber,vimString,vimRegister,@vimContinue,vim9Comment,vimVar,vimBoolean,vimNull -syn match vimOper "\a\@<!!" skipwhite nextgroup=vimString,vimSpecFile -syn match vimOper "||\|&&\|[-+*/%.]" skipwhite nextgroup=vimString,vimSpecFile -syn match vimOper "?" skipwhite nextgroup=@vimExprList +syn cluster vimOperGroup contains=@vimContinue,@vimExprList,vim9Comment +syn match vimOper "\a\@<!!" skipwhite skipnl nextgroup=@vimOperContinue,@vimExprList,vimSpecFile +syn match vimOper "||\|&&\|[-+*/%.]" skipwhite skipnl nextgroup=@vimOperContinue,@vimExprList,vimSpecFile +syn match vimOper "?" skipwhite skipnl nextgroup=@vimOperContinue,@vimExprList " distinguish ternary : from ex-colon -syn match vimOper "\s\@1<=:\ze\s\|\s\@1<=:$" skipwhite nextgroup=@vimExprList -syn match vimOper "??" skipwhite nextgroup=@vimExprList -syn match vimOper "=" skipwhite nextgroup=vimString,vimSpecFile -syn match vimOper "\%#=1\%(==\|!=\|>=\|<=\|=\~\|!\~\|>\|<\)[?#]\=" skipwhite nextgroup=vimString,vimSpecFile -syn match vimOper "\<is\%(not\)\=\>" skipwhite nextgroup=vimString,vimSpecFile -syn match vimOper "\<is\%(not\)\=[?#]" skipwhite nextgroup=vimString,vimSpecFile -syn region vimOperParen matchgroup=vimParenSep start="(" end=")" contains=@vimOperGroup -syn region vimOperParen matchgroup=vimSep start="#\={" end="}" contains=@vimOperGroup nextgroup=vimVar,vimFuncVar +syn match vimOper "\s\@1<=:\ze\s\|\s\@1<=:$" skipwhite skipnl nextgroup=@vimOperContinue,@vimExprList +syn match vimOper "??" skipwhite skipnl nextgroup=@vimOperContinue,@vimExprList +syn match vimOper "=" skipwhite skipnl nextgroup=@vimOperContinue,@vimExprList,vimSpecFile +syn match vimOper "\%#=1\%(==\|!=\|>=\|<=\|=\~\|!\~\|>\|<\)[?#]\=" skipwhite skipnl nextgroup=@vimOperContinue,@vimExprList,vimSpecFile +syn match vimOper "\<is\%(not\)\=\>" skipwhite skipnl nextgroup=@vimOperContinue,@vimExprList,vimSpecFile +syn match vimOper "\<is\%(not\)\=[?#]" skipwhite skipnl nextgroup=@vimOperContinue,@vimExprList,vimSpecFile +syn region vimOperParen matchgroup=vimParenSep start="(" end=")" contains=@vimOperGroup nextgroup=vimSubscript +syn region vimOperParen matchgroup=vimSep start="#\={" end="}" contains=@vimOperGroup nextgroup=vimSubscript,vimVar +syn region vimOperParen contained matchgroup=vimSep start="\[" end="]" contains=@vimOperGroup nextgroup=vimSubscript,vimVar if !exists("g:vimsyn_noerror") && !exists("g:vimsyn_noopererror") syn match vimOperError ")" endif +syn match vimOperContinue contained "^\s*\zs\\" skipwhite skipnl nextgroup=@vimOperContinue,@vimExprList +syn match vimOperContinueComment contained '^\s*\zs["#]\\ .*' skipwhite skipnl nextgroup=@vimOperContinue,@vimExprList +syn cluster vimOperContinue contains=vimOperContinue,vimOperContinueComment + +" Lambda Expressions: {{{2 +" ================== +syn match vimLambdaOperator contained "->" skipwhite nextgroup=@vimExprList +syn region vimLambda contained matchgroup=Delimiter start="{\ze[[:space:][:alnum:]_.,]*->" end="}" end="$" skip=+\s*\n\s*\\\|\s*\n\s*"\\ + contains=@vimContinue,@vimExprList,vimLambdaParams +syn match vimLambdaParams contained "{\@1<=.\{-}\%(->\)\@=" nextgroup=vimLambdaOperator contains=vimFuncParam + +syn match vim9LambdaOperator contained "=>" skipwhite skipempty nextgroup=@vimExprList,vim9LambdaBlock,vim9LambdaOperatorComment +syn match vim9LambdaParamsParen contained "[()]" +syn region vim9LambdaParams contained + \ matchgroup=vim9LambdaParamsParen + \ start="(\ze\s*\(\.\.\.\)\=\h\w*[,:]\%(\s\|$\)" + \ start="(\ze\s*\n + "\ line continuations + \\%(\s*\%(#\\ .*\|\\\s*\)\n\)*\s*\\\s* + "\ parameter names + \\(\.\.\.\)\=\h\w*[,:]\%(\s\|$\)" + \ end=")\ze\%(:\s\|\s\+=>\)" + \ matchgroup=vimContinue + \ end="^\s*\\\ze\s\+=>" + \ skipwhite nextgroup=vim9LambdaReturnType,vim9LambdaOperator + \ contains=@vim9Continue,vimDefParam,vim9LambdaParamsParen +syn match vim9LambdaParams contained "(\s*)\|(\s*\(\.\.\.\)\=\h\w*\s*)\ze\%(:\s\|\s\+=>\)" skipwhite nextgroup=vim9LambdaReturnType,vim9LambdaOperator contains=vimDefParam,vim9LambdaParamsParen + +syn region vim9LambdaReturnType contained start=":\s" end="$" end="\ze#" end="\ze=>" skipwhite skipempty nextgroup=vim9LambdaOperator,vim9LamdaOperatorComment contains=vimTypeSep transparent +syn region vim9LambdaBlock contained matchgroup=vimSep start="{" end="^\s*\zs}" contains=@vimDefBodyList + +syn match vim9LambdaOperatorComment contained "#.*" skipwhite skipempty nextgroup=@vimExprList,vim9LambdaBlock,vim9LambdaOperatorComment + " Functions: Tag is provided for those who wish to highlight tagged functions {{{2 " ========= -syn cluster vimFuncList contains=vimFuncBang,vimFunctionError,vimFuncKey,vimFuncSID,Tag -syn cluster vimDefList contains=vimFuncBang,vimFunctionError,vimDefKey,vimFuncSID,Tag +syn cluster vimFuncList contains=vimFuncBang,vimFunctionError,vimFuncKey,vimFuncScope,vimFuncSID,Tag +syn cluster vimDefList contains=vimFuncBang,vimFunctionError,vimDefKey,vimFuncScope,vimFuncSID,Tag -syn cluster vimFuncBodyCommon contains=@vimCmdList,vimCmplxRepeat,vimContinue,vimCtrlChar,vimDef,vimEnvvar,vimFBVar,vimFunc,vimFunction,vimLetHereDoc,vimNotation,vimNotFunc,vimNumber,vimOper,vimOperParen,vimRegister,vimSpecFile,vimString,vimSubst,vimFuncFold,vimDefFold -syn cluster vimFuncBodyList contains=@vimFuncBodyCommon,vimComment,vimLineComment,vimFuncVar,vimInsert,vimConst,vimLet,vimSearch -syn cluster vimDefBodyList contains=@vimFuncBodyCommon,vim9Comment,vim9LineComment,vim9Const,vim9Final,vim9Var,vim9Null,vim9Boolean,vim9For,vim9Search +syn cluster vimFuncBodyCommon contains=@vimCmdList,vimCmplxRepeat,vimContinue,vimCtrlChar,vimDef,vimFBVar,vimFunc,vimFunction,vimLetHereDoc,vimNotation,vimNotFunc,vimNumber,vimOper,vimOperParen,vimRegister,vimSpecFile,vimString,vimSubst,vimFuncFold,vimDefFold +syn cluster vimFuncBodyList contains=@vimFuncBodyCommon,vimComment,vimLineComment,vimInsert,vimConst,vimLet,vimSearch +syn cluster vimDefBodyList contains=@vimFuncBodyCommon,vim9Comment,vim9LineComment,vim9Block,vim9Const,vim9Final,vim9Var,vim9Null,vim9Boolean,vim9For,vim9LhsVariable,vim9LhsVariableList,vim9LhsRegister,vim9Search,@vimSpecialVar syn region vimFuncPattern contained matchgroup=vimOper start="/" end="$" contains=@vimSubstList syn match vimFunction "\<fu\%[nction]\>" skipwhite nextgroup=vimCmdSep,vimComment,vimFuncPattern contains=vimFuncKey @@ -311,7 +369,7 @@ syn match vimDefComment contained "#.*" skipwhite skipempty nextgroup=vimDefBody syn match vimFuncBang contained "!" syn match vimFuncSID contained "\c<sid>" -syn match vimFuncSID contained "\<[sg]:" +syn match vimFuncScope contained "\<[sg]:" syn keyword vimFuncKey contained fu[nction] syn keyword vimDefKey contained def @@ -334,7 +392,6 @@ if exists("g:vimsyn_folding") && g:vimsyn_folding =~# 'f' syn region vimDefFold start="\<def\>!\=\s*\%(<[sS][iI][dD]>\|[sg]:\)\=\%(\i\|[#.]\)\+(" end="\<enddef\>" contains=vimDef fold keepend extend transparent endif -syn match vimFuncVar contained "a:\%(\K\k*\|\d\+\)\>" syn match vimFuncBlank contained "\s\+" " Types: {{{2 @@ -357,12 +414,24 @@ syn cluster vimType contains=vimType,vimCompoundType,vimUserType if s:vim9script " Methods {{{3 - syn match vim9MethodDef contained "\<def\>" skipwhite nextgroup=vim9MethodDefName + syn match vim9MethodDef contained "\<def\>" skipwhite nextgroup=vim9MethodDefName,vim9ConstructorDefName syn match vim9MethodDefName contained "\<\h\w*\>" nextgroup=vim9MethodDefParams contains=@vim9MethodName syn region vim9MethodDefParams contained \ matchgroup=Delimiter start="(" end=")" \ skipwhite skipnl nextgroup=vim9MethodDefBody,vimDefComment,vimEnddef,vim9MethodDefReturnType,vimCommentError \ contains=vimDefParam,vim9Comment,vimFuncParamEquals + + syn match vim9ConstructorDefName contained "\<new\w*\>" + \ nextgroup=vim9ConstructorDefParams + \ contains=@vim9MethodName + syn match vim9ConstructorDefParam contained "\<\%(this\.\)\=\h\w*\>" + \ skipwhite nextgroup=vimParamType,vimFuncParamEquals + \ contains=vim9This,vimOper + syn region vim9ConstructorDefParams contained + \ matchgroup=Delimiter start="(" end=")" + \ skipwhite skipnl nextgroup=vim9MethodDefBody,vimDefComment,vimEnddef,vimCommentError + \ contains=vim9ConstructorDefParam,vim9Comment,vimFuncParamEquals + syn region vim9MethodDefReturnType contained \ start=":\s" end="$" matchgroup=vim9Comment end="\ze[#"]" \ skipwhite skipnl nextgroup=vim9MethodDefBody,vimDefComment,vimCommentError @@ -378,7 +447,7 @@ if s:vim9script if !exists("g:vimsyn_noerror") && !exists("g:vimsyn_novimfunctionerror") syn match vim9MethodNameError contained "\<[a-z0-9]\i\>" endif - syn match vim9MethodName contained "\<new\i*\>" + syn match vim9MethodName contained "\<new\w*\>" syn keyword vim9MethodName contained empty len string syn cluster vim9MethodName contains=vim9MethodName,vim9MethodNameError @@ -403,8 +472,11 @@ if s:vim9script syn keyword vim9Implements contained implements skipwhite skipnl nextgroup=vim9ImplementedInterface syn keyword vim9Public contained public syn keyword vim9Static contained static - syn keyword vim9This contained this - syn keyword vim9Super contained super + " FIXME: don't match as dictionary keys, remove when operators are not + " shared between Vim9 and legacy script + syn match vim9This contained "\.\@1<!\<this\>:\@!" + " super must be folowed by '.' + syn match vim9Super contained "\.\@1<!\<super\.\@=" VimFoldc syn region vim9ClassBody start="\<class\>" matchgroup=vimCommand end="\<endclass\>" contains=@vim9ClassBodyList transparent @@ -437,15 +509,19 @@ if s:vim9script VimFoldi syn region vim9InterfaceBody start="\<interface\>" matchgroup=vimCommand end="\<endinterface\>" contains=@vim9InterfaceBodyList transparent - " type {{{3 + " Type Aliases {{{3 syn match vim9Type "\<ty\%[pe]\>" skipwhite nextgroup=vim9TypeAlias,vim9TypeAliasError syn match vim9TypeAlias contained "\<\u\w*\>" skipwhite nextgroup=vim9TypeEquals syn match vim9TypeEquals contained "=" skipwhite nextgroup=@vimType if !exists("g:vimsyn_noerror") && !exists("g:vimsyn_notypealiaserror") - syn match vim9TypeAliasError contained "\<\U\w*" + syn match vim9TypeAliasError contained "\<\l\w*\>" skipwhite nextgroup=vim9TypeEquals endif endif +" Blocks: {{{2 +" ====== +Vim9 syn region vim9Block matchgroup=vimSep start="{" end="^\s*\zs}" contains=@vimDefBodyList + " Keymaps: {{{2 " ======= @@ -512,7 +588,7 @@ syn keyword vimUserCmdAttrAddr contained arguments arg buffers buf lines line lo syn match vimUserCmdAttrAddr contained "?" syn case match -syn region vimUserCmdBlock contained matchgroup=vimSep start="{" end="}" contains=@vimDefBodyList +syn region vimUserCmdBlock contained matchgroup=vimSep start="{" end="^\s*\zs}" contains=@vimDefBodyList syn match vimDelcommand "\<delc\%[ommand]\>" skipwhite nextgroup=vimDelcommandAttr syn match vimDelcommandAttr contained "-buffer\>" @@ -559,8 +635,8 @@ syn region vimPatSepZone oneline contained matchgroup=vimPatSepZ start="\\%\ syn region vimPatRegion contained transparent matchgroup=vimPatSepR start="\\[z%]\=(" end="\\)" contains=@vimSubstList oneline syn match vimNotPatSep contained "\\\\" syn cluster vimStringGroup contains=vimEscape,vimEscapeBrace,vimPatSep,vimNotPatSep,vimPatSepErr,vimPatSepZone,@Spell -syn region vimString oneline keepend matchgroup=vimString start=+[^a-zA-Z>\\@]"+lc=1 skip=+\\\\\|\\"+ matchgroup=vimStringEnd end=+"+ contains=@vimStringGroup extend -syn region vimString oneline matchgroup=vimString start=+[^a-zA-Z>\\@]'+lc=1 end=+'+ contains=vimQuoteEscape extend +syn region vimString oneline keepend matchgroup=vimString start=+[^a-zA-Z>\\@]"+lc=1 skip=+\\\\\|\\"+ matchgroup=vimStringEnd end=+"+ nextgroup=vimSubscript contains=@vimStringGroup extend +syn region vimString oneline matchgroup=vimString start=+[^a-zA-Z>\\@]'+lc=1 end=+'+ nextgroup=vimSubscript contains=vimQuoteEscape extend "syn region vimString oneline start="\s/\s*\A"lc=1 skip="\\\\\|\\+" end="/" contains=@vimStringGroup " see tst45.vim syn match vimString contained +"[^"]*\\$+ skipnl nextgroup=vimStringCont syn match vimStringCont contained +\(\\\\\|.\)\{-}[^\\]"+ @@ -572,8 +648,8 @@ syn match vimEscape contained "\\<" contains=vimNotation syn match vimEscape contained "\\<\*[^>]*>\=>" syn match vimQuoteEscape contained "''" -syn region vimString oneline matchgroup=vimString start=+$'+ skip=+''+ end=+'+ contains=vimQuoteEscape,@vimStringInterpolation extend -syn region vimString oneline matchgroup=vimString start=+$"+ end=+"+ contains=@vimStringGroup,@vimStringInterpolation extend +syn region vimString oneline matchgroup=vimString start=+$'+ skip=+''+ end=+'+ nextgroup=vimSubscript contains=vimQuoteEscape,@vimStringInterpolation extend +syn region vimString oneline matchgroup=vimString start=+$"+ end=+"+ nextgroup=vimSubscript contains=@vimStringGroup,@vimStringInterpolation extend syn region vimStringInterpolationExpr oneline contained matchgroup=vimSep start=+{+ end=+}+ contains=@vimExprList syn match vimStringInterpolationBrace contained "{{" syn match vimStringInterpolationBrace contained "}}" @@ -622,7 +698,7 @@ syn match vimRegister '\<norm\s\+\zs"[a-zA-Z0-9]' syn match vimRegister '\<normal\s\+\zs"[a-zA-Z0-9]' syn match vimRegister '@"' syn match vimPlainRegister contained '"[a-zA-Z0-9\-:.%#*+=]' -syn match vimLetRegister contained '@["0-9\-a-zA-Z#=*+_/]' +syn match vimLetRegister contained '@["0-9\-a-zA-Z:.%#=*+~_/]' syn match vimAddress ",\zs[.$]" skipwhite nextgroup=vimSubst1 syn match vimAddress "%\ze\a" skipwhite nextgroup=vimString,vimSubst1 @@ -649,13 +725,18 @@ syn match vimSetMod contained "\a\@1<=\%(&vim\=\|[!&?<]\)" " Variable Declarations: {{{2 " ===================== -VimL syn keyword vimLet let skipwhite nextgroup=vimVar,vimFuncVar,vimLetRegister,vimVarList -VimL syn keyword vimConst cons[t] skipwhite nextgroup=vimVar,vimVarList -syn region vimVarList contained start="\[" end="]" contains=vimVar,@vimContinue - -VimL syn keyword vimUnlet unl[et] skipwhite nextgroup=vimUnletBang,vimUnletVars -syn match vimUnletBang contained "!" skipwhite nextgroup=vimUnletVars -syn region vimUnletVars contained start="$\I\|\h" skip="\n\s*\\" end="$" end="|" contains=vimVar,vimEnvvar,vimContinue,vimString,vimNumber +VimL syn keyword vimLet let skipwhite nextgroup=@vimSpecialVar,vimVar,vimVarList +VimL syn keyword vimConst cons[t] skipwhite nextgroup=@vimSpecialVar,vimVar,vimVarList +syn region vimVarList contained + \ start="\[" end="]" + \ contains=@vimContinue,@vimSpecialVar,vimVar + +VimL syn keyword vimUnlet unl[et] skipwhite nextgroup=vimUnletBang,vimUnletVars +syn match vimUnletBang contained "\a\@1<=!" skipwhite nextgroup=vimUnletVars +syn region vimUnletVars contained + \ start="$\I\|\h" skip=+\n\s*\\\|\n\s*"\\ \|^\s*"\\ + end="$" end="\ze[|"]" + \ nextgroup=vimCmdSep,vimComment + \ contains=@vimContinue,vimEnvvar,vimVar VimFoldh syn region vimLetHereDoc matchgroup=vimLetHereDocStart start='\%(^\z(\s*\)\S.*\)\@<==<<\s*trim\%(\s\+\)\@>\z(\L\S*\)' matchgroup=vimLetHereDocStop end='^\z1\=\z2$' extend VimFoldh syn region vimLetHereDoc matchgroup=vimLetHereDocStart start='=<<\%(\s*\)\@>\z(\L\S*\)' matchgroup=vimLetHereDocStop end='^\z1$' extend @@ -667,15 +748,39 @@ Vim9 syn keyword vim9Final final skipwhite nextgroup=vim9Variable,vim9VariableLi Vim9 syn keyword vim9Var var skipwhite nextgroup=vim9Variable,vim9VariableList syn match vim9Variable contained "\<\h\w*\>" skipwhite nextgroup=vimTypeSep,vimLetHereDoc,vimOper -syn region vim9VariableList contained start="\[" end="]" contains=vim9Variable,@vimContinue +syn region vim9VariableList contained start="\[" end="]" contains=@vimContinue,@vimSpecialVar,vim9Variable + +" Lockvar and Unlockvar: {{{2 +" ===================== +syn keyword vimLockvar lockv[ar] skipwhite nextgroup=vimLockvarBang,vimLockvarDepth,vimLockvarVars +syn keyword vimUnlockvar unlo[ckvar] skipwhite nextgroup=vimLockvarBang,vimLockvarDepth,vimLockvarVars +syn match vimLockvarBang contained "\a\@1<=!" skipwhite nextgroup=vimLockvarVars +syn match vimLockvarDepth contained "\<[0-3]\>" skipwhite nextgroup=vimLockvarVars +syn region vimLockvarVars contained + \ start="\h" skip=+\n\s*\\\|\n\s*"\\ \|^\s*"\\ + end="$" end="\ze[|"]" + \ nextgroup=vimCmdSep,vimComment + \ contains=@vimContinue,vimVar + +hi def link vimLockvar vimCommand +hi def link vimUnlockvar vimCommand +hi def link vimLockvarBang vimBang +hi def link vimLockvarDepth vimNumber " For: {{{2 " === -if s:vim9script - syn keyword vim9For for skipwhite nextgroup=vim9Variable,vim9VariableList -else - syn keyword vimFor for skipwhite nextgroup=vimVar,vimVarList -endif +" handles Vim9 and legacy for now +syn region vimFor + \ matchgroup=vimCommand + \ start="\<for\>" end="\<in\>" + \ skipwhite skipnl nextgroup=@vimForInContinue,vim9ForInComment,@vimExprList + \ contains=@vimContinue,vimVar,vimVarList,vim9VariableList + \ transparent + +syn match vim9ForInComment contained "#.*" skipwhite skipempty nextgroup=vimForInComment,@vimExprList + +syn match vimForInContinue contained "^\s*\zs\\" skipwhite skipnl nextgroup=@vimForInContinue,@vimExprList +syn match vimForInContinueComment contained '^\s*\zs["#]\\ .*' skipwhite skipnl nextgroup=@vimForInContinue,@vimExprList +syn cluster vimForInContinue contains=vimForInContinue,vimForInContinueComment " Abbreviations: {{{2 " ============= @@ -693,7 +798,7 @@ syn match vimAutoCmdSfxList contained "\S*" skipwhite nextgroup=vimAutoCmdMod,vi syn keyword vimAutoCmd au[tocmd] skipwhite nextgroup=vimAutoCmdBang,vimAutoEventList syn keyword vimAutoCmd do[autocmd] doautoa[ll] skipwhite nextgroup=vimAutoEventList syn match vimAutoCmdMod "\(++\)\=\(once\|nested\)" skipwhite nextgroup=vimAutoCmdBlock -syn region vimAutoCmdBlock contained matchgroup=vimSep start="{" end="}" contains=@vimDefBodyList +syn region vimAutoCmdBlock contained matchgroup=vimSep start="{" end="^\s*\zs}" contains=@vimDefBodyList " Echo And Execute: -- prefer strings! {{{2 " ================ @@ -794,8 +899,8 @@ syn case match " User Function Highlighting: {{{2 " (following Gautam Iyer's suggestion) " ========================== -syn match vimFunc "\%(\%([sSgGbBwWtTlL]:\|<[sS][iI][dD]>\)\=\%(\w\+\.\)*\I[a-zA-Z0-9_.]*\)\ze\s*(" contains=vimFuncEcho,vimFuncName,vimUserFunc,vimExecute -syn match vimUserFunc contained "\%(\%([sSgGbBwWtTlL]:\|<[sS][iI][dD]>\)\=\%(\w\+\.\)*\I[a-zA-Z0-9_.]*\)\|\<\u[a-zA-Z0-9.]*\>\|\<if\>" contains=vimNotation,vim9MethodName +syn match vimFunc "\%(\%([sSgGbBwWtTlL]:\|<[sS][iI][dD]>\)\=\%(\w\+\.\)*\I[a-zA-Z0-9_.]*\)\ze\s*(" skipwhite nextgroup=vimOperParen contains=vimFuncEcho,vimFuncName,vimUserFunc,vimExecute +syn match vimUserFunc contained "\%(\%([sSgGbBwWtTlL]:\|<[sS][iI][dD]>\)\=\%(\w\+\.\)*\I[a-zA-Z0-9_.]*\)\|\<\u[a-zA-Z0-9.]*\>\|\<if\>" contains=vimNotation,vim9MethodName,vim9Super,vim9This syn keyword vimFuncEcho contained ec ech echo syn match vimMap "\<map\%(\s\+(\)\@=" skipwhite nextgroup=vimMapBang,vimMapMod,vimMapLhs @@ -1307,10 +1412,12 @@ if !exists("skip_vim_syntax_inits") hi def link vimConst vimCommand hi def link vimContinue Special hi def link vimContinueComment vimComment + hi def link vimCount Number hi def link vimCtrlChar SpecialChar + hi def link vimDebuggreedy vimCommand hi def link vimDefComment vim9Comment hi def link vimDefKey vimCommand - hi def link vimDefParam vimVar + hi def link vimDefParam vimVar hi def link vimDelcommand vimCommand hi def link vimDelcommandAttr vimUserCmdAttr hi def link vimEcho vimCommand @@ -1326,6 +1433,8 @@ if !exists("skip_vim_syntax_inits") hi def link vimFgBgAttrib vimHiAttrib hi def link vimFuncEcho vimCommand hi def link vimFor vimCommand + hi def link vimForInContinue vimContinue + hi def link vimForInContinueComment vimContinueComment hi def link vimFTCmd vimCommand hi def link vimFTOption vimSynType hi def link vimFuncBang vimBang @@ -1335,8 +1444,8 @@ if !exists("skip_vim_syntax_inits") hi def link vimFuncMod Special hi def link vimFuncParam vimVar hi def link vimFuncParamEquals vimOper - hi def link vimFuncSID Special - hi def link vimFuncVar Identifier + hi def link vimFuncScope vimVar + hi def link vimFuncSID vimNotation hi def link vimGroupAdd vimSynOption hi def link vimGroupName vimGroup hi def link vimGroupRem vimSynOption @@ -1366,6 +1475,7 @@ if !exists("skip_vim_syntax_inits") hi def link vim9KeymapLineComment vimKeymapLineComment hi def link vimKeymapLineComment vimComment hi def link vimKeymapTailComment vimComment + hi def link vimLambdaOperator vimOper hi def link vimLet vimCommand hi def link vimLetHereDoc vimString hi def link vimLetHereDocStart Special @@ -1399,7 +1509,11 @@ if !exists("skip_vim_syntax_inits") hi def link vimNumber Number hi def link vimOperError Error hi def link vimOper Operator + hi def link vimOperContinue vimContinue + hi def link vimOperContinueComment vimContinueComment hi def link vimOption PreProc + hi def link vimOptionVar Identifier + hi def link vimVimVar Identifier hi def link vimParenSep Delimiter hi def link vimPatSepErr vimError hi def link vimPatSepR vimPatSep @@ -1482,7 +1596,7 @@ if !exists("skip_vim_syntax_inits") hi def link vimUserCmdError Error hi def link vimUserCmdKey vimCommand hi def link vimUserFunc Normal - hi def link vimVar Identifier + hi def link vimVar Normal hi def link vimWarn WarningMsg hi def link vim9Abstract vimCommand @@ -1491,6 +1605,7 @@ if !exists("skip_vim_syntax_inits") hi def link vim9Comment Comment hi def link vim9CommentError vimError hi def link vim9CommentTitle PreProc + hi def link vim9ConstructorDefParam vimVar hi def link vim9Const vimCommand hi def link vim9ContinueComment vimContinueComment hi def link vim9Enum vimCommand @@ -1498,9 +1613,15 @@ if !exists("skip_vim_syntax_inits") hi def link vim9Extends Keyword hi def link vim9Final vimCommand hi def link vim9For vimCommand + hi def link vim9ForInComment vim9Comment hi def link vim9Implements Keyword hi def link vim9AbstractDef vimCommand hi def link vim9Interface vimCommand + hi def link vim9LambdaOperator vimOper + hi def link vim9LambdaOperatorComment vim9Comment + hi def link vim9LambdaParamsParen vimParenSep + hi def link vim9LhsRegister vimLetRegister + hi def link vim9LhsVariable vimVar hi def link vim9LineComment vimComment hi def link vim9MethodDef vimCommand hi def link vim9MethodNameError vimFunctionError diff --git a/src/nvim/memline.c b/src/nvim/memline.c index fb7fdfb8b2..047bbbfdaa 100644 --- a/src/nvim/memline.c +++ b/src/nvim/memline.c @@ -1875,6 +1875,11 @@ static char *ml_get_buf_impl(buf_T *buf, linenr_T lnum, bool will_change) static int recursive = 0; static char questions[4]; + if (buf->b_ml.ml_mfp == NULL) { // there are no lines + buf->b_ml.ml_line_len = 1; + return ""; + } + if (lnum > buf->b_ml.ml_line_count) { // invalid line number if (recursive == 0) { // Avoid giving this message for a recursive call, may happen when @@ -1892,11 +1897,6 @@ errorret: } lnum = MAX(lnum, 1); // pretend line 0 is line 1 - if (buf->b_ml.ml_mfp == NULL) { // there are no lines - buf->b_ml.ml_line_len = 1; - return ""; - } - // See if it is the same line as requested last time. // Otherwise may need to flush last used line. // Don't use the last used line when 'swapfile' is reset, need to load all diff --git a/test/functional/lua/buffer_updates_spec.lua b/test/functional/lua/buffer_updates_spec.lua index 7d034222c8..b9c1e9f897 100644 --- a/test/functional/lua/buffer_updates_spec.lua +++ b/test/functional/lua/buffer_updates_spec.lua @@ -305,6 +305,24 @@ describe('lua buffer event callbacks: on_lines', function() n.assert_alive() end) + it('no invalid lnum error for closed memline in on_detach #31251', function() + eq(vim.NIL, exec_lua('return _G.did_detach')) + exec_lua([[ + vim.api.nvim_buf_set_lines(0, 0, -1, false, { '' }) + local bufname = 'buf2' + local buf = vim.api.nvim_create_buf(false, true) + vim.api.nvim_buf_set_name(buf, bufname) + vim.bo[buf].bufhidden = 'wipe' + vim.cmd('vertical diffsplit '..bufname) + vim.api.nvim_buf_attach(0, false, { on_detach = function() + vim.cmd("redraw") + _G.did_detach = true + end}) + vim.cmd.bdelete() + ]]) + eq(true, exec_lua('return _G.did_detach')) + end) + it('#12718 lnume', function() api.nvim_buf_set_lines(0, 0, -1, true, { '1', '2', '3' }) exec_lua(function() diff --git a/test/functional/plugin/lsp/completion_spec.lua b/test/functional/plugin/lsp/completion_spec.lua index 4e90c2fd1b..33c025daba 100644 --- a/test/functional/plugin/lsp/completion_spec.lua +++ b/test/functional/plugin/lsp/completion_spec.lua @@ -770,13 +770,14 @@ end) --- @param name string --- @param completion_result lsp.CompletionList +--- @param trigger_chars? string[] --- @return integer -local function create_server(name, completion_result) +local function create_server(name, completion_result, trigger_chars) return exec_lua(function() local server = _G._create_server({ capabilities = { completionProvider = { - triggerCharacters = { '.' }, + triggerCharacters = trigger_chars or { '.' }, }, }, handlers = { @@ -793,6 +794,7 @@ local function create_server(name, completion_result) cmd = server.cmd, on_attach = function(client, bufnr0) vim.lsp.completion.enable(true, client.id, bufnr0, { + autotrigger = trigger_chars ~= nil, convert = function(item) return { abbr = item.label:gsub('%b()', '') } end, @@ -957,6 +959,39 @@ describe('vim.lsp.completion: protocol', function() end) end) + it('insert char triggers clients matching trigger characters', function() + local results1 = { + isIncomplete = false, + items = { + { + label = 'hello', + }, + }, + } + create_server('dummy1', results1, { 'e' }) + local results2 = { + isIncomplete = false, + items = { + { + label = 'hallo', + }, + }, + } + create_server('dummy2', results2, { 'h' }) + + feed('h') + exec_lua(function() + vim.v.char = 'h' + vim.cmd.startinsert() + vim.api.nvim_exec_autocmds('InsertCharPre', {}) + end) + + assert_matches(function(matches) + eq(1, #matches) + eq('hallo', matches[1].word) + end) + end) + it('executes commands', function() local completion_list = { isIncomplete = false, @@ -1078,4 +1113,42 @@ describe('vim.lsp.completion: integration', function() end) ) end) + + it('#clear multiple-lines word', function() + local completion_list = { + isIncomplete = false, + items = { + { + label = 'then...end', + sortText = '0001', + insertText = 'then\n\t$0\nend', + kind = 15, + insertTextFormat = 2, + }, + }, + } + exec_lua(function() + vim.o.completeopt = 'menuone,noselect' + end) + create_server('dummy', completion_list) + feed('Sif true <C-X><C-O>') + retry(nil, nil, function() + eq( + 1, + exec_lua(function() + return vim.fn.pumvisible() + end) + ) + end) + feed('<C-n><C-y>') + eq( + { true, { 'if true then', '\t', 'end' } }, + exec_lua(function() + return { + vim.snippet.active({ direction = 1 }), + vim.api.nvim_buf_get_lines(0, 0, -1, true), + } + end) + ) + end) end) |