diff options
Diffstat (limited to 'runtime')
-rw-r--r-- | runtime/autoload/health/provider.vim | 44 | ||||
-rw-r--r-- | runtime/autoload/provider/node.vim | 19 | ||||
-rw-r--r-- | runtime/autoload/provider/perl.vim | 28 | ||||
-rw-r--r-- | runtime/autoload/provider/ruby.vim | 3 | ||||
-rw-r--r-- | runtime/doc/api.txt | 29 | ||||
-rw-r--r-- | runtime/doc/cmdline.txt | 1 | ||||
-rw-r--r-- | runtime/doc/eval.txt | 16 | ||||
-rw-r--r-- | runtime/doc/if_perl.txt | 268 | ||||
-rw-r--r-- | runtime/doc/index.txt | 3 | ||||
-rw-r--r-- | runtime/doc/lua.txt | 12 | ||||
-rw-r--r-- | runtime/doc/provider.txt | 6 | ||||
-rw-r--r-- | runtime/doc/vim_diff.txt | 1 | ||||
-rw-r--r-- | runtime/lua/vim/highlight.lua | 2 | ||||
-rw-r--r-- | runtime/lua/vim/treesitter/highlighter.lua | 3 | ||||
-rw-r--r-- | runtime/lua/vim/treesitter/query.lua | 47 |
15 files changed, 410 insertions, 72 deletions
diff --git a/runtime/autoload/health/provider.vim b/runtime/autoload/health/provider.vim index 0482cb7f3c..e8e38f581f 100644 --- a/runtime/autoload/health/provider.vim +++ b/runtime/autoload/health/provider.vim @@ -573,7 +573,7 @@ function! s:check_ruby() abort endif call health#report_info('Ruby: '. s:system('ruby -v')) - let host = provider#ruby#Detect() + let [host, err] = provider#ruby#Detect() if empty(host) call health#report_warn('`neovim-ruby-host` not found.', \ ['Run `gem install neovim` to ensure the neovim RubyGem is installed.', @@ -636,7 +636,7 @@ function! s:check_node() abort call health#report_warn('node.js on this system does not support --inspect-brk so $NVIM_NODE_HOST_DEBUG is ignored.') endif - let host = provider#node#Detect() + let [host, err] = provider#node#Detect() if empty(host) call health#report_warn('Missing "neovim" npm (or yarn) package.', \ ['Run in shell: npm install -g neovim', @@ -689,29 +689,31 @@ function! s:check_perl() abort return endif - if !executable('perl') || !executable('cpanm') - call health#report_warn( - \ '`perl` and `cpanm` must be in $PATH.', - \ ['Install Perl and cpanminus and verify that `perl` and `cpanm` commands work.']) - return + let [perl_exec, perl_errors] = provider#perl#Detect() + if empty(perl_exec) + if !empty(perl_errors) + call health#report_error('perl provider error:', perl_errors) + else + call health#report_warn('No usable perl executable found') + endif + return endif - let perl_v = get(split(s:system(['perl', '-W', '-e', 'print $^V']), "\n"), 0, '') - call health#report_info('Perl: '. perl_v) + + call health#report_info('perl executable: '. perl_exec) + + " we cannot use cpanm that is on the path, as it may not be for the perl + " set with g:perl_host_prog + call s:system([perl_exec, '-W', '-MApp::cpanminus', '-e', '']) if s:shell_error - call health#report_warn('Nvim perl host does not support '.perl_v) - " Skip further checks, they are nonsense if perl is too old. - return + return [perl_exec, '"App::cpanminus" module is not installed'] endif - let host = provider#perl#Detect() - if empty(host) - call health#report_warn('Missing "Neovim::Ext" cpan module.', - \ ['Run in shell: cpanm Neovim::Ext']) - return - endif - call health#report_info('Nvim perl host: '. host) + let latest_cpan_cmd = [perl_exec, + \ '-MApp::cpanminus::fatscript', '-e', + \ 'my $app = App::cpanminus::script->new; + \ $app->parse_options ("--info", "-q", "Neovim::Ext"); + \ exit $app->doit'] - let latest_cpan_cmd = 'cpanm --info -q Neovim::Ext' let latest_cpan = s:system(latest_cpan_cmd) if s:shell_error || empty(latest_cpan) call health#report_error('Failed to run: '. latest_cpan_cmd, @@ -735,7 +737,7 @@ function! s:check_perl() abort return endif - let current_cpan_cmd = [host, '-W', '-MNeovim::Ext', '-e', 'print $Neovim::Ext::VERSION'] + let current_cpan_cmd = [perl_exec, '-W', '-MNeovim::Ext', '-e', 'print $Neovim::Ext::VERSION'] let current_cpan = s:system(current_cpan_cmd) if s:shell_error call health#report_error('Failed to run: '. string(current_cpan_cmd), diff --git a/runtime/autoload/provider/node.vim b/runtime/autoload/provider/node.vim index c5d5e87729..17b6137816 100644 --- a/runtime/autoload/provider/node.vim +++ b/runtime/autoload/provider/node.vim @@ -48,14 +48,15 @@ function! provider#node#can_inspect() abort 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), ''] endif if !executable('node') - return '' + return ['', 'node not found (or not executable)'] endif - if !s:is_minimum_version(v:null, 6, 0) - return '' + if !s:is_minimum_version(v:null, minver[0], minver[1]) + return ['', printf('node version %s.%s not found', minver[0], minver[1])] endif let npm_opts = {} @@ -75,7 +76,7 @@ function! provider#node#Detect() abort if has('unix') let yarn_default_path = $HOME . '/.config/yarn/global/' . yarn_opts.entry_point if filereadable(yarn_default_path) - return yarn_default_path + return [yarn_default_path, ''] endif endif let yarn_opts.job_id = jobstart('yarn global dir', yarn_opts) @@ -85,18 +86,18 @@ function! provider#node#Detect() abort if !empty(npm_opts) let result = jobwait([npm_opts.job_id]) if result[0] == 0 && npm_opts.result != '' - return npm_opts.result + return [npm_opts.result, ''] endif endif if !empty(yarn_opts) let result = jobwait([yarn_opts.job_id]) if result[0] == 0 && yarn_opts.result != '' - return yarn_opts.result + return [yarn_opts.result, ''] endif endif - return '' + return ['', 'failed to detect node'] endfunction function! provider#node#Prog() abort @@ -142,7 +143,7 @@ endfunction let s:err = '' -let s:prog = provider#node#Detect() +let [s:prog, s:_] = provider#node#Detect() let g:loaded_node_provider = empty(s:prog) ? 1 : 2 if g:loaded_node_provider != 2 diff --git a/runtime/autoload/provider/perl.vim b/runtime/autoload/provider/perl.vim index 36ca2bbf14..24f2b018bb 100644 --- a/runtime/autoload/provider/perl.vim +++ b/runtime/autoload/provider/perl.vim @@ -5,15 +5,25 @@ endif let s:loaded_perl_provider = 1 function! provider#perl#Detect() abort - " use g:perl_host_prof if set or check if perl is on the path + " use g:perl_host_prog if set or check if perl is on the path let prog = exepath(get(g:, 'perl_host_prog', 'perl')) if empty(prog) - return '' + return ['', ''] + endif + + " if perl is available, make sure we have 5.22+ + call system([prog, '-e', 'use v5.22']) + if v:shell_error + return ['', 'Perl version is too old, 5.22+ required'] endif " if perl is available, make sure the required module is available call system([prog, '-W', '-MNeovim::Ext', '-e', '']) - return v:shell_error ? '' : prog + if v:shell_error + return ['', '"Neovim::Ext" cpan module is not installed'] + endif + + return [prog, ''] endfunction function! provider#perl#Prog() abort @@ -46,7 +56,7 @@ function! provider#perl#Call(method, args) abort if !exists('s:host') try - let s:host = remote#host#Require('perl') + let s:host = remote#host#Require('legacy-perl-provider') catch let s:err = v:exception echohl WarningMsg @@ -58,12 +68,16 @@ function! provider#perl#Call(method, args) abort return call('rpcrequest', insert(insert(a:args, 'perl_'.a:method), s:host)) endfunction -let s:err = '' -let s:prog = provider#perl#Detect() +let [s:prog, s:err] = provider#perl#Detect() let g:loaded_perl_provider = empty(s:prog) ? 1 : 2 if g:loaded_perl_provider != 2 let s:err = 'Cannot find perl or the required perl module' endif -call remote#host#RegisterPlugin('perl-provider', 'perl', []) + +" The perl provider plugin will run in a separate instance of the perl +" host. +call remote#host#RegisterClone('legacy-perl-provider', 'perl') +call remote#host#RegisterPlugin('legacy-perl-provider', 'ScriptHost.pm', []) + diff --git a/runtime/autoload/provider/ruby.vim b/runtime/autoload/provider/ruby.vim index f843050df9..1f49c623ac 100644 --- a/runtime/autoload/provider/ruby.vim +++ b/runtime/autoload/provider/ruby.vim @@ -5,7 +5,8 @@ endif let g:loaded_ruby_provider = 1 function! provider#ruby#Detect() abort - return s:prog + let e = empty(s:prog) ? 'missing ruby or ruby-host' : '' + return [s:prog, e] endfunction function! provider#ruby#Prog() abort diff --git a/runtime/doc/api.txt b/runtime/doc/api.txt index 851f63ead2..0d896f33f4 100644 --- a/runtime/doc/api.txt +++ b/runtime/doc/api.txt @@ -336,7 +336,7 @@ callbacks. These callbacks are called frequently in various contexts; |textlock| prevents changing buffer contents and window layout (use |vim.schedule| to defer such operations to the main loop instead). -|nvim_buf_attach| will take keyword args for the callbacks. "on_lines" will +|nvim_buf_attach()| will take keyword args for the callbacks. "on_lines" will receive parameters ("lines", {buf}, {changedtick}, {firstline}, {lastline}, {new_lastline}, {old_byte_size}[, {old_utf32_size}, {old_utf16_size}]). Unlike remote channel events the text contents are not passed. The new text can @@ -355,7 +355,7 @@ was changed. The parameters recieved are ("changedtick", {buf}, {changedtick}). *api-lua-detach* In-process Lua callbacks can detach by returning `true`. This will detach all -callbacks attached with the same |nvim_buf_attach| call. +callbacks attached with the same |nvim_buf_attach()| call. ============================================================================== @@ -1603,19 +1603,20 @@ nvim_buf_add_highlight({buffer}, {src_id}, {hl_group}, {line}, marks do. Namespaces are used for batch deletion/updating of a set of - highlights. To create a namespace, use |nvim_create_namespace| - which returns a namespace id. Pass it in to this function as - `ns_id` to add highlights to the namespace. All highlights in - the same namespace can then be cleared with single call to - |nvim_buf_clear_namespace|. If the highlight never will be - deleted by an API call, pass `ns_id = -1` . + highlights. To create a namespace, use + |nvim_create_namespace()| which returns a namespace id. Pass + it in to this function as `ns_id` to add highlights to the + namespace. All highlights in the same namespace can then be + cleared with single call to |nvim_buf_clear_namespace()|. If + the highlight never will be deleted by an API call, pass + `ns_id = -1` . As a shorthand, `ns_id = 0` can be used to create a new namespace for the highlight, the allocated id is then returned. If `hl_group` is the empty string no highlight is added, but a new `ns_id` is still returned. This is supported for backwards compatibility, new code should use - |nvim_create_namespace| to create a new empty namespace. + |nvim_create_namespace()| to create a new empty namespace. Parameters: ~ {buffer} Buffer handle, or 0 for current buffer @@ -2066,12 +2067,12 @@ nvim_buf_set_virtual_text({buffer}, {src_id}, {line}, {chunks}, Namespaces are used to support batch deletion/updating of virtual text. To create a namespace, use - |nvim_create_namespace|. Virtual text is cleared using - |nvim_buf_clear_namespace|. The same `ns_id` can be used for + |nvim_create_namespace()|. Virtual text is cleared using + |nvim_buf_clear_namespace()|. The same `ns_id` can be used for both virtual text and highlights added by - |nvim_buf_add_highlight|, both can then be cleared with a - single call to |nvim_buf_clear_namespace|. If the virtual text - never will be cleared by an API call, pass `ns_id = -1` . + |nvim_buf_add_highlight()|, both can then be cleared with a + single call to |nvim_buf_clear_namespace()|. If the virtual + text never will be cleared by an API call, pass `ns_id = -1` . As a shorthand, `ns_id = 0` can be used to create a new namespace for the virtual text, the allocated id is then diff --git a/runtime/doc/cmdline.txt b/runtime/doc/cmdline.txt index b31177ce0e..163dc81804 100644 --- a/runtime/doc/cmdline.txt +++ b/runtime/doc/cmdline.txt @@ -556,6 +556,7 @@ followed by another Vim command: :lfdo :make :normal + :perlfile :promptfind :promptrepl :pyfile diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt index 48b41ea1b0..5127a9f390 100644 --- a/runtime/doc/eval.txt +++ b/runtime/doc/eval.txt @@ -2288,6 +2288,7 @@ nr2char({expr}[, {utf8}]) String single char with ASCII/UTF8 value {expr} nvim_...({args}...) any call nvim |api| functions or({expr}, {expr}) Number bitwise OR pathshorten({expr}) String shorten directory names in a path +perleval({expr}) any evaluate |perl| expression pow({x}, {y}) Float {x} to the power of {y} prevnonblank({lnum}) Number line nr of non-blank line <= {lnum} printf({fmt}, {expr1}...) String format text @@ -6423,6 +6424,21 @@ pathshorten({expr}) *pathshorten()* < ~/.c/n/a/file1.vim ~ It doesn't matter if the path exists or not. +perleval({expr}) *perleval()* + Evaluate |perl| expression {expr} and return its result + converted to Vim data structures. + Numbers and strings are returned as they are (strings are + copied though). + Lists are represented as Vim |List| type. + Dictionaries are represented as Vim |Dictionary| type, + non-string keys result in error. + + Note: If you want an array or hash, {expr} must return a + reference to it. + Example: > + :echo perleval('[1 .. 4]') +< [1, 2, 3, 4] + pow({x}, {y}) *pow()* Return the power of {x} to the exponent {y} as a |Float|. {x} and {y} must evaluate to a |Float| or a |Number|. diff --git a/runtime/doc/if_perl.txt b/runtime/doc/if_perl.txt new file mode 100644 index 0000000000..f1d07ddb20 --- /dev/null +++ b/runtime/doc/if_perl.txt @@ -0,0 +1,268 @@ +*if_perl.txt* Nvim + + + VIM REFERENCE MANUAL by Jacques Germishuys + +The perl Interface to Vim *if_perl* *perl* + +See |provider-perl| for more information. + + Type |gO| to see the table of contents. + +============================================================================== +1. Commands *perl-commands* + + *:perl* +:[range]perl {stmt} + Execute perl statement {stmt}. The current package is + "main". A simple check if the `:perl` command is + working: > + :perl print "Hello" + +:[range]perl << [endmarker] +{script} +{endmarker} + Execute perl script {script}. Useful for including + perl code in Vim scripts. Requires perl, see + |script-here|. + +The {endmarker} below the {script} must NOT be preceded by any white space. + +If [endmarker] is omitted from after the "<<", a dot '.' must be used after +{script}, like for the |:append| and |:insert| commands. + +Example: > + function! MyVimMethod() + perl << EOF + sub my_vim_method + { + print "Hello World!\n"; + } + EOF + endfunction + +To see what version of perl you have: > + + :perl print $^V +< + *:perldo* +:[range]perldo {cmd} Execute perl command {cmd} for each line in the[range], + with $_ being set to the test of each line in turn, + without a trailing <EOL>. In addition to $_, $line and + $linenr is also set to the line content and line number + respectively. Setting $_ will change the text, but note + that it is not possible to add or delete lines using + this command. + The default for [range] is the whole file: "1,$". + +Examples: +> + :perldo $_ = reverse($_); + :perldo $_ = "".$linenr." => $line"; + +One can use `:perldo` in conjunction with `:perl` to filter a range using +perl. For example: > + + :perl << EOF + sub perl_vim_string_replace + { + my $line = shift; + my $needle = $vim->eval('@a'); + my $replacement = $vim->eval('@b'); + $line =~ s/$needle/$replacement/g; + return $line; + } + EOF + :let @a='somevalue' + :let @b='newvalue' + :'<,'>perldo $_ = perl_vim_string_replace($_) +< + *:perlfile* +:[range]perlfile {file} + Execute the perl script in {file}. The whole + argument is used as a single file name. + +Both of these commands do essentially the same thing - they execute a piece of +perl code, with the "current range" set to the given line range. + +In the case of :perl, the code to execute is in the command-line. +In the case of :perlfile, the code to execute is the contents of the given file. + +perl commands cannot be used in the |sandbox|. + +To pass arguments you need to set @ARGV explicitly. Example: > + + :perl @ARGV = ("foo", "bar"); + :perlfile myscript.pl + +Here are some examples *perl-examples* > + + :perl print "Hello" + :perl $current->line (uc ($current->line)) + :perl my $str = $current->buffer->[42]; print "Set \$str to: $str" + +Note that changes (such as the "use" statements) persist from one command +to the next. + +============================================================================== +2. The VIM module *perl-vim* + +Perl code gets all of its access to Neovim via the "VIM" module. + +Overview > + print "Hello" # displays a message + VIM::Msg("Hello") # displays a message + VIM::SetOption("ai") # sets a vim option + $nbuf = VIM::Buffers() # returns the number of buffers + @buflist = VIM::Buffers() # returns array of all buffers + $mybuf = (VIM::Buffers('a.c'))[0] # returns buffer object for 'a.c' + @winlist = VIM::Windows() # returns array of all windows + $nwin = VIM::Windows() # returns the number of windows + ($success, $v) = VIM::Eval('&path') # $v: option 'path', $success: 1 + ($success, $v) = VIM::Eval('&xyz') # $v: '' and $success: 0 + $v = VIM::Eval('expand("<cfile>")') # expands <cfile> + $curwin->SetHeight(10) # sets the window height + @pos = $curwin->Cursor() # returns (row, col) array + @pos = (10, 10) + $curwin->Cursor(@pos) # sets cursor to @pos + $curwin->Cursor(10,10) # sets cursor to row 10 col 10 + $mybuf = $curwin->Buffer() # returns the buffer object for window + $curbuf->Name() # returns buffer name + $curbuf->Number() # returns buffer number + $curbuf->Count() # returns the number of lines + $l = $curbuf->Get(10) # returns line 10 + @l = $curbuf->Get(1 .. 5) # returns lines 1 through 5 + $curbuf->Delete(10) # deletes line 10 + $curbuf->Delete(10, 20) # delete lines 10 through 20 + $curbuf->Append(10, "Line") # appends a line + $curbuf->Append(10, "L1", "L2", "L3") # appends 3 lines + @l = ("L1", "L2", "L3") + $curbuf->Append(10, @l) # appends L1, L2 and L3 + $curbuf->Set(10, "Line") # replaces line 10 + $curbuf->Set(10, "Line1", "Line2") # replaces lines 10 and 11 + $curbuf->Set(10, @l) # replaces 3 lines + +Module Functions: + + *perl-Msg* +VIM::Msg({msg}) + Displays the message {msg}. + + *perl-SetOption* +VIM::SetOption({arg}) Sets a vim option. {arg} can be any argument that the + ":set" command accepts. Note that this means that no + spaces are allowed in the argument! See |:set|. + + *perl-Buffers* +VIM::Buffers([{bn}...]) With no arguments, returns a list of all the buffers + in an array context or returns the number of buffers + in a scalar context. For a list of buffer names or + numbers {bn}, returns a list of the buffers matching + {bn}, using the same rules as Vim's internal + |bufname()| function. + WARNING: the list becomes invalid when |:bwipe| is + used. + + *perl-Windows* +VIM::Windows([{wn}...]) With no arguments, returns a list of all the windows + in an array context or returns the number of windows + in a scalar context. For a list of window numbers + {wn}, returns a list of the windows with those + numbers. + WARNING: the list becomes invalid when a window is + closed. + + *perl-DoCommand* +VIM::DoCommand({cmd}) Executes Ex command {cmd}. + + *perl-Eval* +VIM::Eval({expr}) Evaluates {expr} and returns (success, value) in list + context or just value in scalar context. + success=1 indicates that val contains the value of + {expr}; success=0 indicates a failure to evaluate + the expression. '@x' returns the contents of register + x, '&x' returns the value of option x, 'x' returns the + value of internal |variables| x, and '$x' is equivalent + to perl's $ENV{x}. All |functions| accessible from + the command-line are valid for {expr}. + A |List| is turned into a string by joining the items + and inserting line breaks. + +============================================================================== +3. VIM::Buffer objects *perl-buffer* + +Methods: + + *perl-Buffer-Name* +Name() Returns the filename for the Buffer. + + *perl-Buffer-Number* +Number() Returns the number of the Buffer. + + *perl-Buffer-Count* +Count() Returns the number of lines in the Buffer. + + *perl-Buffer-Get* +Get({lnum}, {lnum}?, ...) + Returns a text string of line {lnum} in the Buffer + for each {lnum} specified. An array can be passed + with a list of {lnum}'s specified. + + *perl-Buffer-Delete* +Delete({lnum}, {lnum}?) + Deletes line {lnum} in the Buffer. With the second + {lnum}, deletes the range of lines from the first + {lnum} to the second {lnum}. + + *perl-Buffer-Append* +Append({lnum}, {line}, {line}?, ...) + Appends each {line} string after Buffer line {lnum}. + The list of {line}s can be an array. + + *perl-Buffer-Set* +Set({lnum}, {line}, {line}?, ...) + Replaces one or more Buffer lines with specified + {lines}s, starting at Buffer line {lnum}. The list of + {line}s can be an array. If the arguments are + invalid, replacement does not occur. + +============================================================================== +4. VIM::Window objects *perl-window* + +Methods: + *perl-Window-SetHeight* +SetHeight({height}) + Sets the Window height to {height}, within screen + limits. + + *perl-Window-GetCursor* +Cursor({row}?, {col}?) + With no arguments, returns a (row, col) array for the + current cursor position in the Window. With {row} and + {col} arguments, sets the Window's cursor position to + {row} and {col}. Note that {col} is numbered from 0, + Perl-fashion, and thus is one less than the value in + Vim's ruler. + +Buffer() *perl-Window-Buffer* + Returns the Buffer object corresponding to the given + Window. + +============================================================================== +5. Lexical variables *perl-globals* + +There are multiple lexical variables. + +$curwin The current Window object. +$curbuf The current Buffer object. +$vim A Neovim::Ext object. +$nvim The same as $nvim. +$current A Neovim::Ext::Current object. + +These are also available via the "main" package: + +$main::curwin The current Window object. +$main::curbuf The current Buffer object. + +============================================================================== + vim:tw=78:ts=8:noet:ft=help:norl: diff --git a/runtime/doc/index.txt b/runtime/doc/index.txt index bdab10c0e4..afcacad460 100644 --- a/runtime/doc/index.txt +++ b/runtime/doc/index.txt @@ -1441,6 +1441,9 @@ tag command action ~ |:packloadall| :packl[oadall] load all packages under 'packpath' |:pclose| :pc[lose] close preview window |:pedit| :ped[it] edit file in the preview window +|:perl| :perl execute perl command +|:perldo| :perldo execute perl command for each line +|:perfile| :perlfile execute perl script file |:print| :p[rint] print lines |:profdel| :profd[el] stop profiling a function or script |:profile| :prof[ile] profiling functions and scripts diff --git a/runtime/doc/lua.txt b/runtime/doc/lua.txt index e692274383..050483fb5e 100644 --- a/runtime/doc/lua.txt +++ b/runtime/doc/lua.txt @@ -756,14 +756,15 @@ Here is a list of built-in predicates : ((node1) @left (node2) @right (#eq? @left @right)) < `match?` *ts-predicate-match?* - This will match if the provived lua regex matches the text + `vim-match?` *ts-predicate-vim-match?* + This will match if the provived vim regex matches the text corresponding to a node : > ((idenfitier) @constant (#match? @constant "^[A-Z_]+$")) < Note: the `^` and `$` anchors will respectively match the start and end of the node's text. - `vim-match?` *ts-predicate-vim-match?* - This will match the same way than |match?| but using vim + `lua-match?` *ts-predicate-lua-match?* + This will match the same way than |match?| but using lua regexes. `contains?` *ts-predicate-contains?* @@ -782,6 +783,11 @@ vim.treesitter.query.add_predicate({name}, {handler}) This adds a predicate with the name {name} to be used in queries. {handler} should be a function whose signature will be : > handler(match, pattern, bufnr, predicate) +< + *vim.treesitter.query.list_predicates()* +vim.treesitter.query.list_predicates() + +This lists the currently available predicates to use in queries. Treesitter syntax highlighting (WIP) *lua-treesitter-highlight* diff --git a/runtime/doc/provider.txt b/runtime/doc/provider.txt index a92f3ed712..f944689d0b 100644 --- a/runtime/doc/provider.txt +++ b/runtime/doc/provider.txt @@ -129,9 +129,13 @@ To use the RVM "system" Ruby installation: > ============================================================================== Perl integration *provider-perl* -Nvim supports Perl |remote-plugin|s. +Nvim supports Perl |remote-plugin|s on Unix platforms. Support for polling STDIN +on MS-Windows is currently lacking from all known event loop implementations. +The Vim legacy |perl-vim| interface is also supported (which is itself +implemented as a Nvim remote-plugin). https://github.com/jacquesg/p5-Neovim-Ext +Note: Only perl versions from 5.22 onward are supported. PERL QUICKSTART~ diff --git a/runtime/doc/vim_diff.txt b/runtime/doc/vim_diff.txt index 7b121be579..4bcea3e3fe 100644 --- a/runtime/doc/vim_diff.txt +++ b/runtime/doc/vim_diff.txt @@ -408,7 +408,6 @@ Some legacy Vim features are not implemented: - |if_lua|: Nvim Lua API is not compatible with Vim's "if_lua" - *if_mzscheme* -- *if_perl* - |if_py|: *python-bindeval* *python-Function* are not supported - *if_tcl* diff --git a/runtime/lua/vim/highlight.lua b/runtime/lua/vim/highlight.lua index ce0a3de520..705b34dc99 100644 --- a/runtime/lua/vim/highlight.lua +++ b/runtime/lua/vim/highlight.lua @@ -14,7 +14,7 @@ function highlight.range(bufnr, ns, higroup, start, finish, rtype, inclusive) inclusive = inclusive or false -- sanity check - if start[2] < 0 or finish[2] < start[2] then return end + if start[2] < 0 or finish[1] < start[1] then return end local region = vim.region(bufnr, start, finish, rtype, inclusive) for linenr, cols in pairs(region) do diff --git a/runtime/lua/vim/treesitter/highlighter.lua b/runtime/lua/vim/treesitter/highlighter.lua index bb78b5654c..1acf888821 100644 --- a/runtime/lua/vim/treesitter/highlighter.lua +++ b/runtime/lua/vim/treesitter/highlighter.lua @@ -98,7 +98,8 @@ function TSHighlighter:get_hl_from_capture(capture) return vim.split(name, '.', true)[1] else -- Default to false to avoid recomputing - return a.nvim_get_hl_id_by_name(TSHighlighter.hl_map[name]) + local hl = TSHighlighter.hl_map[name] + return hl and a.nvim_get_hl_id_by_name(hl) or 0 end end diff --git a/runtime/lua/vim/treesitter/query.lua b/runtime/lua/vim/treesitter/query.lua index 803b9edbf0..ca27a50c6a 100644 --- a/runtime/lua/vim/treesitter/query.lua +++ b/runtime/lua/vim/treesitter/query.lua @@ -60,7 +60,7 @@ local predicate_handlers = { return true end, - ["match?"] = function(match, _, bufnr, predicate) + ["lua-match?"] = function(match, _, bufnr, predicate) local node = match[predicate[2]] local regex = predicate[3] local start_row, _, end_row, _ = node:range() @@ -71,7 +71,7 @@ local predicate_handlers = { return string.find(M.get_node_text(node, bufnr), regex) end, - ["vim-match?"] = (function() + ["match?"] = (function() local magic_prefixes = {['\\v']=true, ['\\m']=true, ['\\M']=true, ['\\V']=true} local function check_magic(str) if string.len(str) < 2 or magic_prefixes[string.sub(str,1,2)] then @@ -114,6 +114,9 @@ local predicate_handlers = { end } +-- As we provide lua-match? also expose vim-match? +predicate_handlers["vim-match?"] = predicate_handlers["match?"] + --- Adds a new predicates to be used in queries -- -- @param name the name of the predicate, without leading # @@ -127,25 +130,43 @@ function M.add_predicate(name, handler, force) predicate_handlers[name] = handler end +--- Returns the list of currently supported predicates +function M.list_predicates() + return vim.tbl_keys(predicate_handlers) +end + +local function xor(x, y) + return (x or y) and not (x and y) +end + function Query:match_preds(match, pattern, bufnr) local preds = self.info.patterns[pattern] - if not preds then - return true - end - for _, pred in pairs(preds) do + + for _, pred in pairs(preds or {}) do -- Here we only want to return if a predicate DOES NOT match, and -- continue on the other case. This way unknown predicates will not be considered, -- which allows some testing and easier user extensibility (#12173). -- Also, tree-sitter strips the leading # from predicates for us. + local pred_name + local is_not if string.sub(pred[1], 1, 4) == "not-" then - local pred_name = string.sub(pred[1], 5) - if predicate_handlers[pred_name] and - predicate_handlers[pred_name](match, pattern, bufnr, pred) then - return false - end + pred_name = string.sub(pred[1], 5) + is_not = true + else + pred_name = pred[1] + is_not = false + end + + local handler = predicate_handlers[pred_name] + + if not handler then + a.nvim_err_writeln(string.format("No handler for %s", pred[1])) + return false + end + + local pred_matches = handler(match, pattern, bufnr, pred) - elseif predicate_handlers[pred[1]] and - not predicate_handlers[pred[1]](match, pattern, bufnr, pred) then + if not xor(is_not, pred_matches) then return false end end |