diff options
Diffstat (limited to 'runtime')
-rw-r--r-- | runtime/autoload/health/provider.vim | 4 | ||||
-rw-r--r-- | runtime/autoload/provider/node.vim | 2 | ||||
-rw-r--r-- | runtime/autoload/provider/pythonx.vim | 4 | ||||
-rw-r--r-- | runtime/autoload/provider/ruby.vim | 2 | ||||
-rw-r--r-- | runtime/doc/change.txt | 15 | ||||
-rw-r--r-- | runtime/doc/eval.txt | 157 | ||||
-rw-r--r-- | runtime/doc/intro.txt | 1 | ||||
-rw-r--r-- | runtime/doc/mlang.txt | 12 | ||||
-rw-r--r-- | runtime/doc/options.txt | 18 | ||||
-rw-r--r-- | runtime/doc/pi_netrw.txt | 4 | ||||
-rw-r--r-- | runtime/doc/syntax.txt | 12 | ||||
-rw-r--r-- | runtime/doc/treesitter.txt | 5 | ||||
-rw-r--r-- | runtime/doc/usr_41.txt | 12 | ||||
-rw-r--r-- | runtime/doc/usr_42.txt | 4 | ||||
-rw-r--r-- | runtime/doc/vim_diff.txt | 3 | ||||
-rw-r--r-- | runtime/filetype.vim | 1 | ||||
-rw-r--r-- | runtime/lua/vim/lsp/buf.lua | 24 | ||||
-rw-r--r-- | runtime/lua/vim/lsp/util.lua | 51 | ||||
-rw-r--r-- | runtime/lua/vim/treesitter/query.lua | 22 | ||||
-rw-r--r-- | runtime/tutor/tutor.tutor | 2 |
20 files changed, 270 insertions, 85 deletions
diff --git a/runtime/autoload/health/provider.vim b/runtime/autoload/health/provider.vim index de540405e6..001379c85d 100644 --- a/runtime/autoload/health/provider.vim +++ b/runtime/autoload/health/provider.vim @@ -423,10 +423,6 @@ function! s:check_python(version) abort \ ' This could lead to confusing error messages.') endif - if a:version == 3 && str2float(pyversion) < 3.3 - call health#report_warn('Python 3.3+ is recommended.') - endif - call health#report_info('Python version: ' . pyversion) if s:is_bad_response(status) diff --git a/runtime/autoload/provider/node.vim b/runtime/autoload/provider/node.vim index 17b6137816..5079c07d8c 100644 --- a/runtime/autoload/provider/node.vim +++ b/runtime/autoload/provider/node.vim @@ -50,7 +50,7 @@ endfunction function! provider#node#Detect() abort let minver = [6, 0] if exists('g:node_host_prog') - return [expand(g:node_host_prog), ''] + return [expand(g:node_host_prog, v:true), ''] endif if !executable('node') return ['', 'node not found (or not executable)'] diff --git a/runtime/autoload/provider/pythonx.vim b/runtime/autoload/provider/pythonx.vim index 550931d8aa..c292b374b6 100644 --- a/runtime/autoload/provider/pythonx.vim +++ b/runtime/autoload/provider/pythonx.vim @@ -23,7 +23,7 @@ function! provider#pythonx#Require(host) abort endfunction function! s:get_python_executable_from_host_var(major_version) abort - return expand(get(g:, 'python'.(a:major_version == 3 ? '3' : '').'_host_prog', '')) + return expand(get(g:, 'python'.(a:major_version == 3 ? '3' : '').'_host_prog', ''), v:true) endfunction function! s:get_python_candidates(major_version) abort @@ -44,7 +44,7 @@ function! provider#pythonx#DetectByModule(module, major_version) abort let python_exe = s:get_python_executable_from_host_var(a:major_version) if !empty(python_exe) - return [exepath(expand(python_exe)), ''] + return [exepath(expand(python_exe, v:true)), ''] endif let candidates = s:get_python_candidates(a:major_version) diff --git a/runtime/autoload/provider/ruby.vim b/runtime/autoload/provider/ruby.vim index 1f49c623ac..1428fab1cc 100644 --- a/runtime/autoload/provider/ruby.vim +++ b/runtime/autoload/provider/ruby.vim @@ -46,7 +46,7 @@ endfunction function! s:detect() if exists("g:ruby_host_prog") - return expand(g:ruby_host_prog) + return expand(g:ruby_host_prog, v:true) elseif has('win32') return exepath('neovim-ruby-host.bat') else diff --git a/runtime/doc/change.txt b/runtime/doc/change.txt index 19a8be1102..b2e910a834 100644 --- a/runtime/doc/change.txt +++ b/runtime/doc/change.txt @@ -1771,7 +1771,7 @@ Vim has a sorting function and a sorting command. The sorting function can be found here: |sort()|, |uniq()|. *:sor* *:sort* -:[range]sor[t][!] [b][f][i][n][o][r][u][x] [/{pattern}/] +:[range]sor[t][!] [b][f][i][l][n][o][r][u][x] [/{pattern}/] Sort lines in [range]. When no range is given all lines are sorted. @@ -1779,6 +1779,16 @@ found here: |sort()|, |uniq()|. With [i] case is ignored. + With [l] sort uses the current collation locale. + Implementation details: strcoll() is used to compare + strings. See |:language| to check or set the collation + locale. Example: > + :language collate en_US.UTF-8 + :%sort l +< |v:collate| can also used to check the current locale. + Sorting using the locale typically ignores case. + This does not work properly on Mac. + Options [n][f][x][o][b] are mutually exclusive. With [n] sorting is done on the first decimal number @@ -1847,8 +1857,7 @@ found here: |sort()|, |uniq()|. Note that using `:sort` with `:global` doesn't sort the matching lines, it's quite useless. -The details about sorting depend on the library function used. There is no -guarantee that sorting obeys the current locale. You will have to try it out. +`:sort` does not use the current locale unless the l flag is used. Vim does do a "stable" sort. The sorting can be interrupted, but if you interrupt it too late in the diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt index 72c0bec4ff..b19583ed61 100644 --- a/runtime/doc/eval.txt +++ b/runtime/doc/eval.txt @@ -1508,6 +1508,15 @@ v:cmdarg This variable is used for two purposes: the argument for the ":hardcopy" command. This can be used in 'printexpr'. + *v:collate* *collate-variable* +v:collate The current locale setting for collation order of the runtime + environment. This allows Vim scripts to be aware of the + current locale encoding. Technical: it's the value of + LC_COLLATE. When not using a locale the value is "C". + This variable can not be set directly, use the |:language| + command. + See |multi-lang|. + *v:cmdbang* *cmdbang-variable* v:cmdbang Set like v:cmdarg for a file read/write command. When a "!" was used the value is 1, otherwise it is 0. Note that this @@ -2385,6 +2394,7 @@ screenpos({winid}, {lnum}, {col}) Dict screen row and col of a text character screenrow() Number current cursor row search({pattern} [, {flags} [, {stopline} [, {timeout}]]]) Number search for {pattern} +searchcount([{options}]) Dict Get or update the last search count searchdecl({name} [, {global} [, {thisblock}]]) Number search for variable declaration searchpair({start}, {middle}, {end} [, {flags} [, {skip} [...]]]) @@ -2529,6 +2539,8 @@ visualmode([expr]) String last visual mode used wait({timeout}, {condition}[, {interval}]) Number Wait until {condition} is satisfied wildmenumode() Number whether 'wildmenu' mode is active +win_execute({id}, {command} [, {silent}]) + String execute {command} in window {id} win_findbuf({bufnr}) List find windows containing {bufnr} win_getid([{win} [, {tab}]]) Number get |window-ID| for {win} in {tab} win_gettype([{nr}]) String type of window {nr} @@ -3543,6 +3555,8 @@ execute({command} [, {silent}]) *execute()* Note: If nested, an outer execute() will not observe output of the inner calls. Note: Text attributes (highlights) are not captured. + To execute a command in another window than the current one + use `win_execute()`. exepath({expr}) *exepath()* Returns the full path of {expr} if it is an executable and @@ -7280,6 +7294,126 @@ search({pattern} [, {flags} [, {stopline} [, {timeout}]]]) *search()* The 'n' flag tells the function not to move the cursor. +searchcount([{options}]) *searchcount()* + Get or update the last search count, like what is displayed + without the "S" flag in 'shortmess'. This works even if + 'shortmess' does contain the "S" flag. + + This returns a Dictionary. The dictionary is empty if the + previous pattern was not set and "pattern" was not specified. + + key type meaning ~ + current |Number| current position of match; + 0 if the cursor position is + before the first match + exact_match |Boolean| 1 if "current" is matched on + "pos", otherwise 0 + total |Number| total count of matches found + incomplete |Number| 0: search was fully completed + 1: recomputing was timed out + 2: max count exceeded + + For {options} see further down. + + To get the last search count when |n| or |N| was pressed, call + this function with `recompute: 0` . This sometimes returns + wrong information because |n| and |N|'s maximum count is 99. + If it exceeded 99 the result must be max count + 1 (100). If + you want to get correct information, specify `recompute: 1`: > + + " result == maxcount + 1 (100) when many matches + let result = searchcount(#{recompute: 0}) + + " Below returns correct result (recompute defaults + " to 1) + let result = searchcount() +< + The function is useful to add the count to |statusline|: > + function! LastSearchCount() abort + let result = searchcount(#{recompute: 0}) + if empty(result) + return '' + endif + if result.incomplete ==# 1 " timed out + return printf(' /%s [?/??]', @/) + elseif result.incomplete ==# 2 " max count exceeded + if result.total > result.maxcount && + \ result.current > result.maxcount + return printf(' /%s [>%d/>%d]', @/, + \ result.current, result.total) + elseif result.total > result.maxcount + return printf(' /%s [%d/>%d]', @/, + \ result.current, result.total) + endif + endif + return printf(' /%s [%d/%d]', @/, + \ result.current, result.total) + endfunction + let &statusline .= '%{LastSearchCount()}' + + " Or if you want to show the count only when + " 'hlsearch' was on + " let &statusline .= + " \ '%{v:hlsearch ? LastSearchCount() : ""}' +< + You can also update the search count, which can be useful in a + |CursorMoved| or |CursorMovedI| autocommand: > + + autocmd CursorMoved,CursorMovedI * + \ let s:searchcount_timer = timer_start( + \ 200, function('s:update_searchcount')) + function! s:update_searchcount(timer) abort + if a:timer ==# s:searchcount_timer + call searchcount(#{ + \ recompute: 1, maxcount: 0, timeout: 100}) + redrawstatus + endif + endfunction +< + This can also be used to count matched texts with specified + pattern in the current buffer using "pattern": > + + " Count '\<foo\>' in this buffer + " (Note that it also updates search count) + let result = searchcount(#{pattern: '\<foo\>'}) + + " To restore old search count by old pattern, + " search again + call searchcount() +< + {options} must be a Dictionary. It can contain: + key type meaning ~ + recompute |Boolean| if |TRUE|, recompute the count + like |n| or |N| was executed. + otherwise returns the last + result by |n|, |N|, or this + function is returned. + (default: |TRUE|) + pattern |String| recompute if this was given + and different with |@/|. + this works as same as the + below command is executed + before calling this function > + let @/ = pattern +< (default: |@/|) + timeout |Number| 0 or negative number is no + timeout. timeout milliseconds + for recomputing the result + (default: 0) + maxcount |Number| 0 or negative number is no + limit. max count of matched + text while recomputing the + result. if search exceeded + total count, "total" value + becomes `maxcount + 1` + (default: 0) + pos |List| `[lnum, col, off]` value + when recomputing the result. + this changes "current" result + value. see |cursor()|, |getpos() + (default: cursor's position) + + searchdecl({name} [, {global} [, {thisblock}]]) *searchdecl()* Search for the declaration of {name}. @@ -8003,6 +8137,23 @@ sort({list} [, {func} [, {dict}]]) *sort()* *E702* When {func} is given and it is '1' or 'i' then case is ignored. + When {func} is given and it is 'l' then the current collation + locale is used for ordering. Implementation details: strcoll() + is used to compare strings. See |:language| check or set the + collation locale. |v:collate| can also be used to check the + current locale. Sorting using the locale typically ignores + case. Example: > + " ö is sorted similarly to o with English locale. + :language collate en_US.UTF8 + :echo sort(['n', 'o', 'O', 'ö', 'p', 'z'], 'l') +< ['n', 'o', 'O', 'ö', 'p', 'z'] ~ +> + " ö is sorted after z with Swedish locale. + :language collate sv_SE.UTF8 + :echo sort(['n', 'o', 'O', 'ö', 'p', 'z'], 'l') +< ['n', 'o', 'O', 'p', 'z', 'ö'] ~ + This does not work properly on Mac. + When {func} is given and it is 'n' then all items will be sorted numerical (Implementation detail: this uses the strtod() function to parse numbers, Strings, Lists, Dicts and @@ -9123,6 +9274,12 @@ wildmenumode() *wildmenumode()* < (Note, this needs the 'wildcharm' option set appropriately). +win_execute({id}, {command} [, {silent}]) *win_execute()* + Like `execute()` but in the context of window {id}. + The window will temporarily be made the current window, + without triggering autocommands. + Example: > + call win_execute(winid, 'syntax enable') win_findbuf({bufnr}) *win_findbuf()* Returns a |List| with |window-ID|s for windows that contain diff --git a/runtime/doc/intro.txt b/runtime/doc/intro.txt index 925b3e5dbb..f739e2e88b 100644 --- a/runtime/doc/intro.txt +++ b/runtime/doc/intro.txt @@ -169,6 +169,7 @@ Vim would never have become what it is now, without the help of these people! Ken Takata fixes and features Kazunobu Kuriyama GTK 3 Christian Brabandt many fixes, features, user support, etc. + Yegappan Lakshmanan many quickfix features I wish to thank all the people that sent me bug reports and suggestions. The list is too long to mention them all here. Vim would not be the same without diff --git a/runtime/doc/mlang.txt b/runtime/doc/mlang.txt index b57d2b592a..9d3a51302d 100644 --- a/runtime/doc/mlang.txt +++ b/runtime/doc/mlang.txt @@ -31,6 +31,7 @@ use of "-" and "_". :lan[guage] mes[sages] :lan[guage] cty[pe] :lan[guage] tim[e] +:lan[guage] col[late] Print the current language (aka locale). With the "messages" argument the language used for messages is printed. Technical: LC_MESSAGES. @@ -38,15 +39,19 @@ use of "-" and "_". character encoding is printed. Technical: LC_CTYPE. With the "time" argument the language used for strftime() is printed. Technical: LC_TIME. + With the "collate" argument the language used for + collation order is printed. Technical: LC_COLLATE. Without argument all parts of the locale are printed (this is system dependent). The current language can also be obtained with the - |v:lang|, |v:ctype| and |v:lc_time| variables. + |v:lang|, |v:ctype|, |v:collate| and |v:lc_time| + variables. :lan[guage] {name} :lan[guage] mes[sages] {name} :lan[guage] cty[pe] {name} :lan[guage] tim[e] {name} +:lan[guage] col[late] {name} Set the current language (aka locale) to {name}. The locale {name} must be a valid locale on your system. Some systems accept aliases like "en" or @@ -66,7 +71,10 @@ use of "-" and "_". With the "time" argument the language used for time and date messages is set. This affects strftime(). This sets $LC_TIME. - Without an argument both are set, and additionally + With the "collate" argument the language used for the + collation order is set. This affects sorting of + characters. This sets $LC_COLLATE. + Without an argument all are set, and additionally $LANG is set. The LC_NUMERIC value will always be set to "C" so that floating point numbers use '.' as the decimal diff --git a/runtime/doc/options.txt b/runtime/doc/options.txt index 269080e750..4a6ae0245b 100644 --- a/runtime/doc/options.txt +++ b/runtime/doc/options.txt @@ -5267,9 +5267,9 @@ A jump table for the options with a short description can be found at |Q_op|. in a file and echoed to the screen. If the 'shell' option is "csh" or "tcsh" after initializations, the default becomes "|& tee". If the 'shell' option is "sh", "ksh", "mksh", "pdksh", "zsh", "zsh-beta", - "bash" or "fish" the default becomes "2>&1| tee". This means that - stderr is also included. Before using the 'shell' option a path is - removed, thus "/bin/sh" uses "sh". + "bash", "fish", "ash" or "dash" the default becomes "2>&1| tee". This + means that stderr is also included. Before using the 'shell' option a + path is removed, thus "/bin/sh" uses "sh". The initialization of this option is done after reading the vimrc and the other initializations, so that when the 'shell' option is set there, the 'shellpipe' option changes automatically, unless it was @@ -5923,6 +5923,18 @@ A jump table for the options with a short description can be found at |Q_op|. Note that there is no '%' before the closing '}'. The expression cannot contain a '}' character, call a function to work around that. See |stl-%{| below. + {% - This is almost same as { except the result of the expression is + re-evaluated as a statusline format string. Thus if the + return value of expr contains % items they will get expanded. + The expression can contain the } character, the end of + expression is denoted by %}. + The For example: > + func! Stl_filename() abort + return "%t" + endfunc +< `stl=%{Stl_filename()}` results in `"%t"` + `stl=%{%Stl_filename()%}` results in `"Name of current file"` + } - End of `{%` expression ( - Start of item group. Can be used for setting the width and alignment of a section. Must be followed by %) somewhere. ) - End of item group. No width fields allowed. diff --git a/runtime/doc/pi_netrw.txt b/runtime/doc/pi_netrw.txt index 5adafd7877..4b61cd4c25 100644 --- a/runtime/doc/pi_netrw.txt +++ b/runtime/doc/pi_netrw.txt @@ -3181,8 +3181,8 @@ window, then the one window will be horizontally split (by default). If there's more than one window, the previous window will be re-used on the selected file/directory. If the previous window's associated buffer has been modified, and there's only one window with that buffer, then -the user will be asked if s/he wishes to save the buffer first (yes, -no, or cancel). +the user will be asked if they wish to save the buffer first (yes, no, or +cancel). Related Actions |netrw-cr| |netrw-o| |netrw-t| |netrw-v| Associated setting variables: diff --git a/runtime/doc/syntax.txt b/runtime/doc/syntax.txt index 95e00720b1..b159f655fa 100644 --- a/runtime/doc/syntax.txt +++ b/runtime/doc/syntax.txt @@ -1969,7 +1969,7 @@ LEX *lex.vim* *ft-lex-syntax* Lex uses brute-force synchronizing as the "^%%$" section delimiter gives no clue as to what section follows. Consequently, the value for > :syn sync minlines=300 -may be changed by the user if s/he is experiencing synchronization +may be changed by the user if they are experiencing synchronization difficulties (such as may happen with large lex files). @@ -3009,11 +3009,11 @@ variables in your vimrc: < (dash users should use posix) -If there's no "#! ..." line, and the user hasn't availed himself/herself of a -default sh.vim syntax setting as just shown, then syntax/sh.vim will assume -the Bourne shell syntax. No need to quote RFCs or market penetration -statistics in error reports, please -- just select the default version of the -sh your system uses and install the associated "let..." in your <.vimrc>. +If there's no "#! ..." line, and the user hasn't availed themself of a default +sh.vim syntax setting as just shown, then syntax/sh.vim will assume the Bourne +shell syntax. No need to quote RFCs or market penetration statistics in error +reports, please -- just select the default version of the sh your system uses +and install the associated "let..." in your <.vimrc>. The syntax/sh.vim file provides several levels of syntax-based folding: > diff --git a/runtime/doc/treesitter.txt b/runtime/doc/treesitter.txt index 1f4b5d3097..39522898f9 100644 --- a/runtime/doc/treesitter.txt +++ b/runtime/doc/treesitter.txt @@ -212,6 +212,11 @@ Here is a list of built-in predicates : ((identifier) @foo (#contains? @foo "foo")) ((identifier) @foo-bar (#contains @foo-bar "foo" "bar")) < + `any-of?` *ts-predicate-any-of?* + Will check if the text is the same as any of the following + arguments : > + ((identifier) @foo (#any-of? @foo "foo" "bar")) +< *lua-treesitter-not-predicate* Each predicate has a `not-` prefixed predicate that is just the negation of the predicate. diff --git a/runtime/doc/usr_41.txt b/runtime/doc/usr_41.txt index 4cba5a33d0..f92cb3c509 100644 --- a/runtime/doc/usr_41.txt +++ b/runtime/doc/usr_41.txt @@ -1875,7 +1875,7 @@ NOT LOADING It's possible that a user doesn't always want to load this plugin. Or the system administrator has dropped it in the system-wide plugin directory, but a -user has his own plugin he wants to use. Then the user must have a chance to +user has their own plugin they want to use. Then the user must have a chance to disable loading this specific plugin. This will make it possible: > 6 if exists("g:loaded_typecorr") @@ -1908,7 +1908,7 @@ item can be used: > The "<Plug>TypecorrAdd;" thing will do the work, more about that further on. -The user can set the "mapleader" variable to the key sequence that he wants +The user can set the "mapleader" variable to the key sequence that they want this mapping to start with. Thus if the user has done: > let mapleader = "_" @@ -1919,7 +1919,7 @@ will be used, which is a backslash. Then a map for "\a" will be defined. Note that <unique> is used, this will cause an error message if the mapping already happened to exist. |:map-<unique>| -But what if the user wants to define his own key sequence? We can allow that +But what if the user wants to define their own key sequence? We can allow that with this mechanism: > 21 if !hasmapto('<Plug>TypecorrAdd;') @@ -1928,7 +1928,7 @@ with this mechanism: > This checks if a mapping to "<Plug>TypecorrAdd;" already exists, and only defines the mapping from "<Leader>a" if it doesn't. The user then has a -chance of putting this in his vimrc file: > +chance of putting this in their vimrc file: > map ,c <Plug>TypecorrAdd; @@ -2033,7 +2033,7 @@ Now let's add a user command to add a correction: > The user command is defined only if no command with the same name already exists. Otherwise we would get an error here. Overriding the existing user command with ":command!" is not a good idea, this would probably make the user -wonder why the command he defined himself doesn't work. |:command| +wonder why the command they defined themself doesn't work. |:command| SCRIPT VARIABLES @@ -2285,7 +2285,7 @@ An example of how to define functionality in a filetype plugin: > |hasmapto()| is used to check if the user has already defined a map to <Plug>JavaImport;. If not, then the filetype plugin defines the default mapping. This starts with |<LocalLeader>|, which allows the user to select -the key(s) he wants filetype plugin mappings to start with. The default is a +the key(s) they want filetype plugin mappings to start with. The default is a backslash. "<unique>" is used to give an error message if the mapping already exists or overlaps with an existing mapping. diff --git a/runtime/doc/usr_42.txt b/runtime/doc/usr_42.txt index 99da1359c2..ff3ae7057a 100644 --- a/runtime/doc/usr_42.txt +++ b/runtime/doc/usr_42.txt @@ -209,8 +209,8 @@ argument: > :amenu <silent> Mine.Next\ File :call <SID>NextFile()<CR> Don't use "<silent>" too often. It is not needed for short commands. If you -make a menu for someone else, being able to see the executed command will give -him a hint about what he could have typed, instead of using the mouse. +make a menu for someone else, being able to see the executed command will +give them a hint about what they could have typed, instead of using the mouse. LISTING MENUS diff --git a/runtime/doc/vim_diff.txt b/runtime/doc/vim_diff.txt index 2c39fdb53c..bb30495d77 100644 --- a/runtime/doc/vim_diff.txt +++ b/runtime/doc/vim_diff.txt @@ -194,8 +194,7 @@ Options: 'cpoptions' flags: |cpo-_| 'display' flags: "msgsep" minimizes scrolling when showing messages 'guicursor' works in the terminal - 'fillchars' flags: "msgsep" (see 'display'), "foldopen", "foldsep", - "foldclose" + 'fillchars' flags: "msgsep" (see 'display') 'foldcolumn' supports up to 9 dynamic/fixed columns 'inccommand' shows interactive results for |:substitute|-like commands 'pumblend' pseudo-transparent popupmenu diff --git a/runtime/filetype.vim b/runtime/filetype.vim index f0d2b36a84..474a447284 100644 --- a/runtime/filetype.vim +++ b/runtime/filetype.vim @@ -1015,6 +1015,7 @@ au BufNewFile,BufRead *.hgrc,*hgrc setf cfg " Meson Build system config au BufNewFile,BufRead meson.build,meson_options.txt setf meson +au BufNewFile,BufRead *.wrap setf dosini " Messages (logs mostly) au BufNewFile,BufRead */log/{auth,cron,daemon,debug,kern,lpr,mail,messages,news/news,syslog,user}{,.log,.err,.info,.warn,.crit,.notice}{,.[0-9]*,-[0-9]*} setf messages diff --git a/runtime/lua/vim/lsp/buf.lua b/runtime/lua/vim/lsp/buf.lua index 341a3e82fc..5dd7109bb0 100644 --- a/runtime/lua/vim/lsp/buf.lua +++ b/runtime/lua/vim/lsp/buf.lua @@ -297,26 +297,30 @@ local function pick_call_hierarchy_item(call_hierarchy_items) return choice end +local function call_hierarchy(method) + local params = util.make_position_params() + request('textDocument/prepareCallHierarchy', params, function(err, _, result) + if err then + vim.notify(err.message, vim.log.levels.WARN) + return + end + local call_hierarchy_item = pick_call_hierarchy_item(result) + vim.lsp.buf_request(0, method, { item = call_hierarchy_item }) + end) +end + --- Lists all the call sites of the symbol under the cursor in the --- |quickfix| window. If the symbol can resolve to multiple --- items, the user can pick one in the |inputlist|. function M.incoming_calls() - local params = util.make_position_params() - request('textDocument/prepareCallHierarchy', params, function(_, _, result) - local call_hierarchy_item = pick_call_hierarchy_item(result) - vim.lsp.buf_request(0, 'callHierarchy/incomingCalls', { item = call_hierarchy_item }) - end) + call_hierarchy('callHierarchy/incomingCalls') end --- Lists all the items that are called by the symbol under the --- cursor in the |quickfix| window. If the symbol can resolve to --- multiple items, the user can pick one in the |inputlist|. function M.outgoing_calls() - local params = util.make_position_params() - request('textDocument/prepareCallHierarchy', params, function(_, _, result) - local call_hierarchy_item = pick_call_hierarchy_item(result) - vim.lsp.buf_request(0, 'callHierarchy/outgoingCalls', { item = call_hierarchy_item }) - end) + call_hierarchy('callHierarchy/outgoingCalls') end --- List workspace folders. diff --git a/runtime/lua/vim/lsp/util.lua b/runtime/lua/vim/lsp/util.lua index 287624f310..e403a8ee1b 100644 --- a/runtime/lua/vim/lsp/util.lua +++ b/runtime/lua/vim/lsp/util.lua @@ -916,23 +916,6 @@ function M.make_floating_popup_options(width, height, opts) } end -local function _should_add_to_tagstack(new_item) - local stack = vim.fn.gettagstack() - - -- Check if we're at the bottom of the tagstack. - if stack.curidx <= 1 then return true end - - local top_item = stack.items[stack.curidx-1] - - -- Check if the item at the top of the tagstack is exactly the - -- same as the one we want to push. - if top_item.tagname ~= new_item.tagname then return true end - for i, v in ipairs(top_item.from) do - if v ~= new_item.from[i] then return true end - end - return false -end - --- Jumps to a location. --- --@param location (`Location`|`LocationLink`) @@ -941,36 +924,22 @@ function M.jump_to_location(location) -- location may be Location or LocationLink local uri = location.uri or location.targetUri if uri == nil then return end - - local from_bufnr = vim.fn.bufnr('%') - local from = {from_bufnr, vim.fn.line('.'), vim.fn.col('.'), 0} - local item = {tagname=vim.fn.expand('<cword>'), from=from} - + local bufnr = vim.uri_to_bufnr(uri) -- Save position in jumplist - vim.cmd("mark '") + vim.cmd "normal! m'" + + -- Push a new item into tagstack + local from = {vim.fn.bufnr('%'), vim.fn.line('.'), vim.fn.col('.'), 0} + local items = {{tagname=vim.fn.expand('<cword>'), from=from}} + vim.fn.settagstack(vim.fn.win_getid(), {items=items}, 't') --- Jump to new location (adjusting for UTF-16 encoding of characters) - local bufnr = vim.uri_to_bufnr(uri) api.nvim_set_current_buf(bufnr) api.nvim_buf_set_option(0, 'buflisted', true) local range = location.range or location.targetSelectionRange local row = range.start.line local col = get_line_byte_from_position(0, range.start) - -- This prevents the tagstack to be filled with items that provide - -- no motion when CTRL-T is pressed because they're both the source - -- and the destination. - local motionless = - bufnr == from_bufnr and - row+1 == from[2] and col+1 == from[3] - if not motionless and _should_add_to_tagstack(item) then - local winid = vim.fn.win_getid() - local items = {item} - vim.fn.settagstack(winid, {items=items}, 't') - end - - -- Jump to new location api.nvim_win_set_cursor(0, {row + 1, col}) - return true end @@ -1597,6 +1566,12 @@ function M.make_given_range_params(start_pos, end_pos) if B[2] > 0 then B = {B[1], M.character_offset(0, B[1], B[2])} end + -- we need to offset the end character position otherwise we loose the last + -- character of the selection, as LSP end position is exclusive + -- see https://microsoft.github.io/language-server-protocol/specification#range + if vim.o.selection ~= 'exclusive' then + B[2] = B[2] + 1 + end return { textDocument = M.make_text_document_params(), range = { diff --git a/runtime/lua/vim/treesitter/query.lua b/runtime/lua/vim/treesitter/query.lua index 9b4d28e09a..b81eb18945 100644 --- a/runtime/lua/vim/treesitter/query.lua +++ b/runtime/lua/vim/treesitter/query.lua @@ -231,7 +231,7 @@ local predicate_handlers = { local compiled_vim_regexes = setmetatable({}, { __index = function(t, pattern) - local res = vim.regex(check_magic(vim.fn.escape(pattern, '\\'))) + local res = vim.regex(check_magic(pattern)) rawset(t, pattern, res) return res end @@ -260,7 +260,25 @@ local predicate_handlers = { end return false - end + end, + + ["any-of?"] = function(match, _, source, predicate) + local node = match[predicate[2]] + local node_text = M.get_node_text(node, source) + + -- Since 'predicate' will not be used by callers of this function, use it + -- to store a string set built from the list of words to check against. + local string_set = predicate["string_set"] + if not string_set then + string_set = {} + for i=3,#predicate do + string_set[predicate[i]] = true + end + predicate["string_set"] = string_set + end + + return string_set[node_text] + end, } -- As we provide lua-match? also expose vim-match? diff --git a/runtime/tutor/tutor.tutor b/runtime/tutor/tutor.tutor index b46fcc4836..c2d5268e3d 100644 --- a/runtime/tutor/tutor.tutor +++ b/runtime/tutor/tutor.tutor @@ -216,7 +216,7 @@ starting with "$". ## INTERACTIVE ELEMENTS *interactive* As visible in this very document, vim-tutor-mode includes some interactive -elements to provide feedback to the user about his progress. If the text in +elements to provide feedback to the user about their progress. If the text in these elements satisfies some set condition, a ✓ sign will appear in the gutter to the left. Otherwise, a ✗ sign is displayed. |