aboutsummaryrefslogtreecommitdiff
path: root/runtime
diff options
context:
space:
mode:
Diffstat (limited to 'runtime')
-rw-r--r--runtime/autoload/spellfile.vim10
-rw-r--r--runtime/doc/lsp.txt14
-rw-r--r--runtime/doc/lua.txt326
-rw-r--r--runtime/doc/options.txt29
-rw-r--r--runtime/doc/quickfix.txt39
-rw-r--r--runtime/doc/spell.txt14
-rw-r--r--runtime/doc/treesitter.txt295
-rw-r--r--runtime/doc/vim_diff.txt1
-rw-r--r--runtime/filetype.vim8
-rw-r--r--runtime/lua/vim/lsp/buf.lua46
-rw-r--r--runtime/lua/vim/lsp/callbacks.lua21
-rw-r--r--runtime/lua/vim/lsp/rpc.lua11
-rw-r--r--runtime/lua/vim/lsp/util.lua49
-rw-r--r--runtime/lua/vim/treesitter/highlighter.lua84
-rw-r--r--runtime/lua/vim/uri.lua20
-rw-r--r--runtime/pack/dist/opt/cfilter/plugin/cfilter.vim39
16 files changed, 599 insertions, 407 deletions
diff --git a/runtime/autoload/spellfile.vim b/runtime/autoload/spellfile.vim
index d098902305..e36e2f936b 100644
--- a/runtime/autoload/spellfile.vim
+++ b/runtime/autoload/spellfile.vim
@@ -1,13 +1,9 @@
" Vim script to download a missing spell file
if !exists('g:spellfile_URL')
- " Prefer using http:// when netrw should be able to use it, since
- " more firewalls let this through.
- if executable("curl") || executable("wget") || executable("fetch")
- let g:spellfile_URL = 'http://ftp.vim.org/pub/vim/runtime/spell'
- else
- let g:spellfile_URL = 'ftp://ftp.vim.org/pub/vim/runtime/spell'
- endif
+ " Always use https:// because it's secure. The certificate is for nluug.nl,
+ " thus we can't use the alias ftp.vim.org here.
+ let g:spellfile_URL = 'https://ftp.nluug.nl/pub/vim/runtime/spell'
endif
let s:spellfile_URL = '' " Start with nothing so that s:donedict is reset.
diff --git a/runtime/doc/lsp.txt b/runtime/doc/lsp.txt
index 0300ba55b3..44b611c2cf 100644
--- a/runtime/doc/lsp.txt
+++ b/runtime/doc/lsp.txt
@@ -23,14 +23,14 @@ QUICKSTART *lsp-quickstart*
Nvim provides a LSP client, but the servers are provided by third parties.
Follow these steps to get LSP features:
- 1. Install the nvim-lsp plugin. It provides common configuration for
+ 1. Install the nvim-lspconfig plugin. It provides common configuration for
various servers so you can get started quickly.
- https://github.com/neovim/nvim-lsp
+ https://github.com/neovim/nvim-lspconfig
2. Install a language server. Try ":LspInstall <tab>" or use your system
package manager to install the relevant language server:
https://microsoft.github.io/language-server-protocol/implementors/servers/
3. Add `nvim_lsp.xx.setup{…}` to your vimrc, where "xx" is the name of the
- relevant config. See the nvim-lsp README for details.
+ relevant config. See the nvim-lspconfig README for details.
To check LSP clients attached to the current buffer: >
@@ -39,9 +39,10 @@ To check LSP clients attached to the current buffer: >
*lsp-config*
Inline diagnostics are enabled automatically, e.g. syntax errors will be
annotated in the buffer. But you probably want to use other features like
-go-to-definition, hover, etc. Example config: >
+go-to-definition, hover, etc. Full list of features in |vim.lsp.buf|.
+
+Example config: >
- nnoremap <silent> gd <cmd>lua vim.lsp.buf.declaration()<CR>
nnoremap <silent> <c-]> <cmd>lua vim.lsp.buf.definition()<CR>
nnoremap <silent> K <cmd>lua vim.lsp.buf.hover()<CR>
nnoremap <silent> gD <cmd>lua vim.lsp.buf.implementation()<CR>
@@ -50,6 +51,9 @@ go-to-definition, hover, etc. Example config: >
nnoremap <silent> gr <cmd>lua vim.lsp.buf.references()<CR>
nnoremap <silent> g0 <cmd>lua vim.lsp.buf.document_symbol()<CR>
nnoremap <silent> gW <cmd>lua vim.lsp.buf.workspace_symbol()<CR>
+ nnoremap <silent> gd <cmd>lua vim.lsp.buf.declaration()<CR>
+
+Note: Language servers may have limited support for these features.
Nvim provides the |vim.lsp.omnifunc| 'omnifunc' handler which allows
|i_CTRL-X_CTRL-O| to consume LSP completion. Example config (note the use of
diff --git a/runtime/doc/lua.txt b/runtime/doc/lua.txt
index 509ed7bf2c..2b638a8539 100644
--- a/runtime/doc/lua.txt
+++ b/runtime/doc/lua.txt
@@ -551,290 +551,6 @@ Example: TCP echo-server *tcp-server*
print('TCP echo-server listening on port: '..server:getsockname().port)
------------------------------------------------------------------------------
-VIM.TREESITTER *lua-treesitter*
-
-Nvim integrates the tree-sitter library for incremental parsing of buffers.
-
-Currently Nvim does not provide the tree-sitter parsers, instead these must
-be built separately, for instance using the tree-sitter utility. The only
-exception is a C parser being included in official builds for testing
-purposes. Parsers are searched for as `parser/{lang}.*` in any 'runtimepath'
-directory. A parser can also be loaded manually using a full path: >
-
- vim.treesitter.require_language("python", "/path/to/python.so")
-
-<Create a parser for a buffer and a given language (if another plugin uses the
-same buffer/language combination, it will be safely reused). Use >
-
- parser = vim.treesitter.get_parser(bufnr, lang)
-
-<`bufnr=0` can be used for current buffer. `lang` will default to 'filetype' (this
-doesn't work yet for some filetypes like "cpp") Currently, the parser will be
-retained for the lifetime of a buffer but this is subject to change. A plugin
-should keep a reference to the parser object as long as it wants incremental
-updates.
-
-Parser files *treesitter-parsers*
-
-Parsers are the heart of tree-sitter. They are libraries that tree-sitter will
-search for in the `parsers` runtime directory.
-
-For a parser to be available for a given language, there must be a file named
-`{lang}.so` within the parser directory.
-
-Parser methods *lua-treesitter-parser*
-
-tsparser:parse() *tsparser:parse()*
-Whenever you need to access the current syntax tree, parse the buffer: >
-
- tstree = parser:parse()
-
-<This will return an immutable tree that represents the current state of the
-buffer. When the plugin wants to access the state after a (possible) edit
-it should call `parse()` again. If the buffer wasn't edited, the same tree will
-be returned again without extra work. If the buffer was parsed before,
-incremental parsing will be done of the changed parts.
-
-NB: to use the parser directly inside a |nvim_buf_attach| Lua callback, you must
-call `get_parser()` before you register your callback. But preferably parsing
-shouldn't be done directly in the change callback anyway as they will be very
-frequent. Rather a plugin that does any kind of analysis on a tree should use
-a timer to throttle too frequent updates.
-
-tsparser:set_included_ranges({ranges}) *tsparser:set_included_ranges()*
- Changes the ranges the parser should consider. This is used for
- language injection. {ranges} should be of the form (all zero-based): >
- {
- {start_node, end_node},
- ...
- }
-<
- NOTE: `start_node` and `end_node` are both inclusive.
-
-Tree methods *lua-treesitter-tree*
-
-tstree:root() *tstree:root()*
- Return the root node of this tree.
-
-
-Node methods *lua-treesitter-node*
-
-tsnode:parent() *tsnode:parent()*
- Get the node's immediate parent.
-
-tsnode:iter_children() *tsnode:iter_children()*
- Iterates over all the direct children of {tsnode}, regardless of
- wether they are named or not.
- Returns the child node plus the eventual field name corresponding to
- this child node.
-
-tsnode:field({name}) *tsnode:field()*
- Returns a table of the nodes corresponding to the {name} field.
-
-tsnode:child_count() *tsnode:child_count()*
- Get the node's number of children.
-
-tsnode:child({index}) *tsnode:child()*
- Get the node's child at the given {index}, where zero represents the
- first child.
-
-tsnode:named_child_count() *tsnode:named_child_count()*
- Get the node's number of named children.
-
-tsnode:named_child({index}) *tsnode:named_child()*
- Get the node's named child at the given {index}, where zero represents
- the first named child.
-
-tsnode:start() *tsnode:start()*
- Get the node's start position. Return three values: the row, column
- and total byte count (all zero-based).
-
-tsnode:end_() *tsnode:end_()*
- Get the node's end position. Return three values: the row, column
- and total byte count (all zero-based).
-
-tsnode:range() *tsnode:range()*
- Get the range of the node. Return four values: the row, column
- of the start position, then the row, column of the end position.
-
-tsnode:type() *tsnode:type()*
- Get the node's type as a string.
-
-tsnode:symbol() *tsnode:symbol()*
- Get the node's type as a numerical id.
-
-tsnode:named() *tsnode:named()*
- Check if the node is named. Named nodes correspond to named rules in
- the grammar, whereas anonymous nodes correspond to string literals
- in the grammar.
-
-tsnode:missing() *tsnode:missing()*
- Check if the node is missing. Missing nodes are inserted by the
- parser in order to recover from certain kinds of syntax errors.
-
-tsnode:has_error() *tsnode:has_error()*
- Check if the node is a syntax error or contains any syntax errors.
-
-tsnode:sexpr() *tsnode:sexpr()*
- Get an S-expression representing the node as a string.
-
-tsnode:descendant_for_range({start_row}, {start_col}, {end_row}, {end_col})
- *tsnode:descendant_for_range()*
- Get the smallest node within this node that spans the given range of
- (row, column) positions
-
-tsnode:named_descendant_for_range({start_row}, {start_col}, {end_row}, {end_col})
- *tsnode:named_descendant_for_range()*
- Get the smallest named node within this node that spans the given
- range of (row, column) positions
-
-Query methods *lua-treesitter-query*
-
-Tree-sitter queries are supported, with some limitations. Currently, the only
-supported match predicate is `eq?` (both comparing a capture against a string
-and two captures against each other).
-
-vim.treesitter.parse_query({lang}, {query})
- *vim.treesitter.parse_query()*
- Parse {query} as a string. (If the query is in a file, the caller
- should read the contents into a string before calling).
-
-query:iter_captures({node}, {bufnr}, {start_row}, {end_row})
- *query:iter_captures()*
- Iterate over all captures from all matches inside {node}.
- {bufnr} is needed if the query contains predicates, then the caller
- must ensure to use a freshly parsed tree consistent with the current
- text of the buffer. {start_row} and {end_row} can be used to limit
- matches inside a row range (this is typically used with root node
- as the node, i e to get syntax highlight matches in the current
- viewport)
-
- The iterator returns two values, a numeric id identifying the capture
- and the captured node. The following example shows how to get captures
- by name:
->
- for id, node in query:iter_captures(tree:root(), bufnr, first, last) do
- local name = query.captures[id] -- name of the capture in the query
- -- typically useful info about the node:
- local type = node:type() -- type of the captured node
- local row1, col1, row2, col2 = node:range() -- range of the capture
- ... use the info here ...
- end
-<
-query:iter_matches({node}, {bufnr}, {start_row}, {end_row})
- *query:iter_matches()*
- Iterate over all matches within a node. The arguments are the same as
- for |query:iter_captures()| but the iterated values are different:
- an (1-based) index of the pattern in the query, and a table mapping
- capture indices to nodes. If the query has more than one pattern
- the capture table might be sparse, and e.g. `pairs` should be used and not
- `ipairs`. Here an example iterating over all captures in
- every match:
->
- for pattern, match in cquery:iter_matches(tree:root(), bufnr, first, last) do
- for id,node in pairs(match) do
- local name = query.captures[id]
- -- `node` was captured by the `name` capture in the match
- ... use the info here ...
- end
- end
-
-Treesitter Query Predicates *lua-treesitter-predicates*
-
-When writing queries for treesitter, one might use `predicates`, that is,
-special scheme nodes that are evaluted to verify things on a captured node for
-example, the |eq?| predicate : >
- ((identifier) @foo (#eq? @foo "foo"))
-
-This will only match identifier corresponding to the `"foo"` text.
-Here is a list of built-in predicates :
-
- `eq?` *ts-predicate-eq?*
- This predicate will check text correspondance between nodes or
- strings : >
- ((identifier) @foo (#eq? @foo "foo"))
- ((node1) @left (node2) @right (#eq? @left @right))
-<
- `match?` *ts-predicate-match?*
- `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.
-
- `lua-match?` *ts-predicate-lua-match?*
- This will match the same way than |match?| but using lua
- regexes.
-
- `contains?` *ts-predicate-contains?*
- Will check if any of the following arguments appears in the
- text corresponding to the node : >
- ((identifier) @foo (#contains? @foo "foo"))
- ((identifier) @foo-bar (#contains @foo-bar "foo" "bar"))
-<
- *lua-treesitter-not-predicate*
-Each predicate has a `not-` prefixed predicate that is just the negation of
-the predicate.
-
- *vim.treesitter.query.add_predicate()*
-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*
-
-NOTE: This is a partially implemented feature, and not usable as a default
-solution yet. What is documented here is a temporary interface indented
-for those who want to experiment with this feature and contribute to
-its development.
-
-Highlights are defined in the same query format as in the tree-sitter highlight
-crate, which some limitations and additions. Set a highlight query for a
-buffer with this code: >
-
- local query = [[
- "for" @keyword
- "if" @keyword
- "return" @keyword
-
- (string_literal) @string
- (number_literal) @number
- (comment) @comment
-
- (preproc_function_def name: (identifier) @function)
-
- ; ... more definitions
- ]]
-
- highlighter = vim.treesitter.TSHighlighter.new(query, bufnr, lang)
- -- alternatively, to use the current buffer and its filetype:
- -- highlighter = vim.treesitter.TSHighlighter.new(query)
-
- -- Don't recreate the highlighter for the same buffer, instead
- -- modify the query like this:
- local query2 = [[ ... ]]
- highlighter:set_query(query2)
-
-As mentioned above the supported predicate is currently only `eq?`. `match?`
-predicates behave like matching always fails. As an addition a capture which
-begin with an upper-case letter like `@WarningMsg` will map directly to this
-highlight group, if defined. Also if the predicate begins with upper-case and
-contains a dot only the part before the first will be interpreted as the
-highlight group. As an example, this warns of a binary expression with two
-identical identifiers, highlighting both as |hl-WarningMsg|: >
-
- ((binary_expression left: (identifier) @WarningMsg.left right: (identifier) @WarningMsg.right)
- (eq? @WarningMsg.left @WarningMsg.right))
-
-------------------------------------------------------------------------------
VIM.HIGHLIGHT *lua-highlight*
Nvim includes a function for highlighting a selection on yank (see for example
@@ -1567,4 +1283,46 @@ validate({opt}) *vim.validate()*
• msg: (optional) error string if validation
fails
+
+==============================================================================
+Lua module: uri *lua-uri*
+
+uri_from_bufnr({bufnr}) *vim.uri_from_bufnr()*
+ Get a URI from a bufnr
+
+ Parameters: ~
+ {bufnr} (number): Buffer number
+
+ Return: ~
+ URI
+
+uri_from_fname({path}) *vim.uri_from_fname()*
+ Get a URI from a file path.
+
+ Parameters: ~
+ {path} (string): Path to file
+
+ Return: ~
+ URI
+
+uri_to_bufnr({uri}) *vim.uri_to_bufnr()*
+ Return or create a buffer for a uri.
+
+ Parameters: ~
+ {uri} (string): The URI
+
+ Return: ~
+ bufnr.
+ Note:
+ Creates buffer but does not load it
+
+uri_to_fname({uri}) *vim.uri_to_fname()*
+ Get a filename from a URI
+
+ Parameters: ~
+ {uri} (string): The URI
+
+ Return: ~
+ Filename
+
vim:tw=78:ts=8:ft=help:norl:
diff --git a/runtime/doc/options.txt b/runtime/doc/options.txt
index 190d6f9229..bd61d113fb 100644
--- a/runtime/doc/options.txt
+++ b/runtime/doc/options.txt
@@ -2738,21 +2738,26 @@ A jump table for the options with a short description can be found at |Q_op|.
hor{N} horizontal bar, {N} percent of the character height
ver{N} vertical bar, {N} percent of the character width
block block cursor, fills the whole character
- [only one of the above three should be present]
+ - Only one of the above three should be present.
+ - Default is "block" for each mode.
blinkwait{N} *cursor-blinking*
blinkon{N}
blinkoff{N}
blink times for cursor: blinkwait is the delay before
the cursor starts blinking, blinkon is the time that
the cursor is shown and blinkoff is the time that the
- cursor is not shown. The times are in msec. When one
- of the numbers is zero, there is no blinking. E.g.: >
+ cursor is not shown. Times are in msec. When one of
+ the numbers is zero, there is no blinking. E.g.: >
:set guicursor=n:blinkon0
-< {group-name}
- Highlight group name that sets the color and font for
- the cursor. |inverse|/reverse and no group-name are
- interpreted as "the host terminal default cursor
- colors" which usually invert bg and fg colors.
+< - Default is "blinkon0" for each mode.
+ {group-name}
+ Highlight group that decides the color and font of the
+ cursor.
+ In the |TUI|:
+ - |inverse|/reverse and no group-name are interpreted
+ as "host-terminal default cursor colors" which
+ typically means "inverted bg and fg colors".
+ - |ctermfg| and |guifg| are ignored.
{group-name}/{group-name}
Two highlight group names, the first is used when
no language mappings are used, the other when they
@@ -5667,6 +5672,14 @@ A jump table for the options with a short description can be found at |Q_op|.
up to the first character that is not an ASCII letter or number and
not a dash. Also see |set-spc-auto|.
+ *'spelloptions'* *'spo'*
+'spelloptions' 'spo' string (default "")
+ local to buffer
+ A comma separated list of options for spell checking:
+ camel When a word is CamelCased, assume "Cased" is a
+ separate word: every upper-case character in a word
+ that comes after a lower case character indicates the
+ start of a new word.
*'spellsuggest'* *'sps'*
'spellsuggest' 'sps' string (default "best")
diff --git a/runtime/doc/quickfix.txt b/runtime/doc/quickfix.txt
index 61e090cc78..188cfc91b6 100644
--- a/runtime/doc/quickfix.txt
+++ b/runtime/doc/quickfix.txt
@@ -501,6 +501,29 @@ EXECUTE A COMMAND IN ALL THE BUFFERS IN QUICKFIX OR LOCATION LIST:
< Otherwise it works the same as `:ldo`.
{not in Vi}
+FILTERING A QUICKFIX OR LOCATION LIST:
+ *cfilter-plugin* *:Cfilter* *:Lfilter*
+If you have too many entries in a quickfix list, you can use the cfilter
+plugin to reduce the number of entries. Load the plugin with: >
+
+ packadd cfilter
+
+Then you can use the following commands to filter a quickfix/location list: >
+
+ :Cfilter[!] /{pat}/
+ :Lfilter[!] /{pat}/
+
+The |:Cfilter| command creates a new quickfix list from the entries matching
+{pat} in the current quickfix list. {pat} is a Vim |regular-expression|
+pattern. Both the file name and the text of the entries are matched against
+{pat}. If the optional ! is supplied, then the entries not matching {pat} are
+used. The pattern can be optionally enclosed using one of the following
+characters: ', ", /. If the pattern is empty, then the last used search
+pattern is used.
+
+The |:Lfilter| command does the same as |:Cfilter| but operates on the current
+location list.
+
=============================================================================
2. The error window *quickfix-window*
@@ -1563,22 +1586,6 @@ The backslashes before the pipe character are required to avoid it to be
recognized as a command separator. The backslash before each space is
required for the set command.
- *cfilter-plugin* *:Cfilter* *:Lfilter*
-If you have too many matching messages, you can use the cfilter plugin to
-reduce the number of entries. Load the plugin with: >
- packadd cfilter
-
-Then you can use these command: >
- :Cfilter[!] /{pat}/
- :Lfilter[!] /{pat}/
-
-:Cfilter creates a new quickfix list from entries matching {pat} in the
-current quickfix list. Both the file name and the text of the entries are
-matched against {pat}. If ! is supplied, then entries not matching {pat} are
-used.
-
-:Lfilter does the same as :Cfilter but operates on the current location list.
-
=============================================================================
8. The directory stack *quickfix-directory-stack*
diff --git a/runtime/doc/spell.txt b/runtime/doc/spell.txt
index b88e26cdff..0eef976819 100644
--- a/runtime/doc/spell.txt
+++ b/runtime/doc/spell.txt
@@ -187,6 +187,9 @@ When there is a line break right after a sentence the highlighting of the next
line may be postponed. Use |CTRL-L| when needed. Also see |set-spc-auto| for
how it can be set automatically when 'spelllang' is set.
+The 'spelloptions' option has a few more flags that influence the way spell
+checking works.
+
Vim counts the number of times a good word is encountered. This is used to
sort the suggestions: words that have been seen before get a small bonus,
words that have been seen often get a bigger bonus. The COMMON item in the
@@ -617,11 +620,12 @@ ask you where to write the file (there must be a writable directory in
'runtimepath' for this).
The plugin has a default place where to look for spell files, on the Vim ftp
-server. If you want to use another location or another protocol, set the
-g:spellfile_URL variable to the directory that holds the spell files. The
-|netrw| plugin is used for getting the file, look there for the specific
-syntax of the URL. Example: >
- let g:spellfile_URL = 'http://ftp.vim.org/vim/runtime/spell'
+server. The protocol used is SSL (https://) for security. If you want to use
+another location or another protocol, set the g:spellfile_URL variable to the
+directory that holds the spell files. You can use http:// or ftp://, but you
+are taking a security risk then. The |netrw| plugin is used for getting the
+file, look there for the specific syntax of the URL. Example: >
+ let g:spellfile_URL = 'https://ftp.nluug.nl/vim/runtime/spell'
You may need to escape special characters.
The plugin will only ask about downloading a language once. If you want to
diff --git a/runtime/doc/treesitter.txt b/runtime/doc/treesitter.txt
new file mode 100644
index 0000000000..7f644486f7
--- /dev/null
+++ b/runtime/doc/treesitter.txt
@@ -0,0 +1,295 @@
+*treesitter.txt* Nvim
+
+
+ NVIM REFERENCE MANUAL
+
+
+Tree-sitter integration *treesitter*
+
+ Type |gO| to see the table of contents.
+
+------------------------------------------------------------------------------
+VIM.TREESITTER *lua-treesitter*
+
+Nvim integrates the tree-sitter library for incremental parsing of buffers.
+
+Currently Nvim does not provide the tree-sitter parsers, instead these must
+be built separately, for instance using the tree-sitter utility. The only
+exception is a C parser being included in official builds for testing
+purposes. Parsers are searched for as `parser/{lang}.*` in any 'runtimepath'
+directory. A parser can also be loaded manually using a full path: >
+
+ vim.treesitter.require_language("python", "/path/to/python.so")
+
+<Create a parser for a buffer and a given language (if another plugin uses the
+same buffer/language combination, it will be safely reused). Use >
+
+ parser = vim.treesitter.get_parser(bufnr, lang)
+
+<`bufnr=0` can be used for current buffer. `lang` will default to 'filetype' (this
+doesn't work yet for some filetypes like "cpp") Currently, the parser will be
+retained for the lifetime of a buffer but this is subject to change. A plugin
+should keep a reference to the parser object as long as it wants incremental
+updates.
+
+Parser files *treesitter-parsers*
+
+Parsers are the heart of tree-sitter. They are libraries that tree-sitter will
+search for in the `parser` runtime directory.
+
+For a parser to be available for a given language, there must be a file named
+`{lang}.so` within the parser directory.
+
+Parser methods *lua-treesitter-parser*
+
+tsparser:parse() *tsparser:parse()*
+Whenever you need to access the current syntax tree, parse the buffer: >
+
+ tstree = parser:parse()
+
+<This will return an immutable tree that represents the current state of the
+buffer. When the plugin wants to access the state after a (possible) edit
+it should call `parse()` again. If the buffer wasn't edited, the same tree will
+be returned again without extra work. If the buffer was parsed before,
+incremental parsing will be done of the changed parts.
+
+NB: to use the parser directly inside a |nvim_buf_attach| Lua callback, you must
+call `get_parser()` before you register your callback. But preferably parsing
+shouldn't be done directly in the change callback anyway as they will be very
+frequent. Rather a plugin that does any kind of analysis on a tree should use
+a timer to throttle too frequent updates.
+
+tsparser:set_included_ranges({ranges}) *tsparser:set_included_ranges()*
+ Changes the ranges the parser should consider. This is used for
+ language injection. {ranges} should be of the form (all zero-based): >
+ {
+ {start_node, end_node},
+ ...
+ }
+<
+ NOTE: `start_node` and `end_node` are both inclusive.
+
+Tree methods *lua-treesitter-tree*
+
+tstree:root() *tstree:root()*
+ Return the root node of this tree.
+
+
+Node methods *lua-treesitter-node*
+
+tsnode:parent() *tsnode:parent()*
+ Get the node's immediate parent.
+
+tsnode:iter_children() *tsnode:iter_children()*
+ Iterates over all the direct children of {tsnode}, regardless of
+ wether they are named or not.
+ Returns the child node plus the eventual field name corresponding to
+ this child node.
+
+tsnode:field({name}) *tsnode:field()*
+ Returns a table of the nodes corresponding to the {name} field.
+
+tsnode:child_count() *tsnode:child_count()*
+ Get the node's number of children.
+
+tsnode:child({index}) *tsnode:child()*
+ Get the node's child at the given {index}, where zero represents the
+ first child.
+
+tsnode:named_child_count() *tsnode:named_child_count()*
+ Get the node's number of named children.
+
+tsnode:named_child({index}) *tsnode:named_child()*
+ Get the node's named child at the given {index}, where zero represents
+ the first named child.
+
+tsnode:start() *tsnode:start()*
+ Get the node's start position. Return three values: the row, column
+ and total byte count (all zero-based).
+
+tsnode:end_() *tsnode:end_()*
+ Get the node's end position. Return three values: the row, column
+ and total byte count (all zero-based).
+
+tsnode:range() *tsnode:range()*
+ Get the range of the node. Return four values: the row, column
+ of the start position, then the row, column of the end position.
+
+tsnode:type() *tsnode:type()*
+ Get the node's type as a string.
+
+tsnode:symbol() *tsnode:symbol()*
+ Get the node's type as a numerical id.
+
+tsnode:named() *tsnode:named()*
+ Check if the node is named. Named nodes correspond to named rules in
+ the grammar, whereas anonymous nodes correspond to string literals
+ in the grammar.
+
+tsnode:missing() *tsnode:missing()*
+ Check if the node is missing. Missing nodes are inserted by the
+ parser in order to recover from certain kinds of syntax errors.
+
+tsnode:has_error() *tsnode:has_error()*
+ Check if the node is a syntax error or contains any syntax errors.
+
+tsnode:sexpr() *tsnode:sexpr()*
+ Get an S-expression representing the node as a string.
+
+tsnode:descendant_for_range({start_row}, {start_col}, {end_row}, {end_col})
+ *tsnode:descendant_for_range()*
+ Get the smallest node within this node that spans the given range of
+ (row, column) positions
+
+tsnode:named_descendant_for_range({start_row}, {start_col}, {end_row}, {end_col})
+ *tsnode:named_descendant_for_range()*
+ Get the smallest named node within this node that spans the given
+ range of (row, column) positions
+
+Query methods *lua-treesitter-query*
+
+Tree-sitter queries are supported, with some limitations. Currently, the only
+supported match predicate is `eq?` (both comparing a capture against a string
+and two captures against each other).
+
+vim.treesitter.parse_query({lang}, {query})
+ *vim.treesitter.parse_query()*
+ Parse {query} as a string. (If the query is in a file, the caller
+ should read the contents into a string before calling).
+
+query:iter_captures({node}, {bufnr}, {start_row}, {end_row})
+ *query:iter_captures()*
+ Iterate over all captures from all matches inside {node}.
+ {bufnr} is needed if the query contains predicates, then the caller
+ must ensure to use a freshly parsed tree consistent with the current
+ text of the buffer. {start_row} and {end_row} can be used to limit
+ matches inside a row range (this is typically used with root node
+ as the node, i e to get syntax highlight matches in the current
+ viewport)
+
+ The iterator returns two values, a numeric id identifying the capture
+ and the captured node. The following example shows how to get captures
+ by name:
+>
+ for id, node in query:iter_captures(tree:root(), bufnr, first, last) do
+ local name = query.captures[id] -- name of the capture in the query
+ -- typically useful info about the node:
+ local type = node:type() -- type of the captured node
+ local row1, col1, row2, col2 = node:range() -- range of the capture
+ ... use the info here ...
+ end
+<
+query:iter_matches({node}, {bufnr}, {start_row}, {end_row})
+ *query:iter_matches()*
+ Iterate over all matches within a node. The arguments are the same as
+ for |query:iter_captures()| but the iterated values are different:
+ an (1-based) index of the pattern in the query, and a table mapping
+ capture indices to nodes. If the query has more than one pattern
+ the capture table might be sparse, and e.g. `pairs` should be used and not
+ `ipairs`. Here an example iterating over all captures in
+ every match:
+>
+ for pattern, match in cquery:iter_matches(tree:root(), bufnr, first, last) do
+ for id,node in pairs(match) do
+ local name = query.captures[id]
+ -- `node` was captured by the `name` capture in the match
+ ... use the info here ...
+ end
+ end
+
+Treesitter Query Predicates *lua-treesitter-predicates*
+
+When writing queries for treesitter, one might use `predicates`, that is,
+special scheme nodes that are evaluted to verify things on a captured node for
+example, the |eq?| predicate : >
+ ((identifier) @foo (#eq? @foo "foo"))
+
+This will only match identifier corresponding to the `"foo"` text.
+Here is a list of built-in predicates :
+
+ `eq?` *ts-predicate-eq?*
+ This predicate will check text correspondance between nodes or
+ strings : >
+ ((identifier) @foo (#eq? @foo "foo"))
+ ((node1) @left (node2) @right (#eq? @left @right))
+<
+ `match?` *ts-predicate-match?*
+ `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.
+
+ `lua-match?` *ts-predicate-lua-match?*
+ This will match the same way than |match?| but using lua
+ regexes.
+
+ `contains?` *ts-predicate-contains?*
+ Will check if any of the following arguments appears in the
+ text corresponding to the node : >
+ ((identifier) @foo (#contains? @foo "foo"))
+ ((identifier) @foo-bar (#contains @foo-bar "foo" "bar"))
+<
+ *lua-treesitter-not-predicate*
+Each predicate has a `not-` prefixed predicate that is just the negation of
+the predicate.
+
+ *vim.treesitter.query.add_predicate()*
+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*
+
+NOTE: This is a partially implemented feature, and not usable as a default
+solution yet. What is documented here is a temporary interface indented
+for those who want to experiment with this feature and contribute to
+its development.
+
+Highlights are defined in the same query format as in the tree-sitter highlight
+crate, which some limitations and additions. Set a highlight query for a
+buffer with this code: >
+
+ local query = [[
+ "for" @keyword
+ "if" @keyword
+ "return" @keyword
+
+ (string_literal) @string
+ (number_literal) @number
+ (comment) @comment
+
+ (preproc_function_def name: (identifier) @function)
+
+ ; ... more definitions
+ ]]
+
+ highlighter = vim.treesitter.TSHighlighter.new(query, bufnr, lang)
+ -- alternatively, to use the current buffer and its filetype:
+ -- highlighter = vim.treesitter.TSHighlighter.new(query)
+
+ -- Don't recreate the highlighter for the same buffer, instead
+ -- modify the query like this:
+ local query2 = [[ ... ]]
+ highlighter:set_query(query2)
+
+As mentioned above the supported predicate is currently only `eq?`. `match?`
+predicates behave like matching always fails. As an addition a capture which
+begin with an upper-case letter like `@WarningMsg` will map directly to this
+highlight group, if defined. Also if the predicate begins with upper-case and
+contains a dot only the part before the first will be interpreted as the
+highlight group. As an example, this warns of a binary expression with two
+identical identifiers, highlighting both as |hl-WarningMsg|: >
+
+ ((binary_expression left: (identifier) @WarningMsg.left right: (identifier) @WarningMsg.right)
+ (eq? @WarningMsg.left @WarningMsg.right))
+
+ vim:tw=78:ts=8:ft=help:norl:
diff --git a/runtime/doc/vim_diff.txt b/runtime/doc/vim_diff.txt
index 4bcea3e3fe..3090be82f2 100644
--- a/runtime/doc/vim_diff.txt
+++ b/runtime/doc/vim_diff.txt
@@ -508,7 +508,6 @@ Test functions:
test_alloc_fail()
test_autochdir()
test_disable_char_avail()
- test_garbagecollect_now()
test_null_channel()
test_null_dict()
test_null_job()
diff --git a/runtime/filetype.vim b/runtime/filetype.vim
index 32bd6daba0..c464e8cebd 100644
--- a/runtime/filetype.vim
+++ b/runtime/filetype.vim
@@ -1158,10 +1158,10 @@ au BufNewFile,BufRead *.papp,*.pxml,*.pxsl setf papp
au BufNewFile,BufRead */etc/passwd,*/etc/passwd-,*/etc/passwd.edit,*/etc/shadow,*/etc/shadow-,*/etc/shadow.edit,*/var/backups/passwd.bak,*/var/backups/shadow.bak setf passwd
" Pascal (also *.p)
-au BufNewFile,BufRead *.pas setf pascal
+au BufNewFile,BufRead *.pas,*.pp setf pascal
-" Delphi project file
-au BufNewFile,BufRead *.dpr setf pascal
+" Delphi or Lazarus program file
+au BufNewFile,BufRead *.dpr,*.lpr setf pascal
" PDF
au BufNewFile,BufRead *.pdf setf pdf
@@ -1732,7 +1732,7 @@ au BufNewFile,BufRead *.texinfo,*.texi,*.txi setf texinfo
au BufNewFile,BufRead texmf.cnf setf texmf
" Tidy config
-au BufNewFile,BufRead .tidyrc,tidyrc setf tidy
+au BufNewFile,BufRead .tidyrc,tidyrc,tidy.conf setf tidy
" TF mud client
au BufNewFile,BufRead *.tf,.tfrc,tfrc setf tf
diff --git a/runtime/lua/vim/lsp/buf.lua b/runtime/lua/vim/lsp/buf.lua
index 208082f241..c015884f5b 100644
--- a/runtime/lua/vim/lsp/buf.lua
+++ b/runtime/lua/vim/lsp/buf.lua
@@ -1,9 +1,7 @@
local vim = vim
local validate = vim.validate
-local api = vim.api
local vfn = vim.fn
local util = require 'vim.lsp.util'
-local list_extend = vim.list_extend
local M = {}
@@ -142,6 +140,7 @@ function M.formatting_sync(options, timeout_ms)
local result = vim.lsp.buf_request_sync(0, "textDocument/formatting", params, timeout_ms)
if not result then return end
result = result[1].result
+ if not result then return end
vim.lsp.util.apply_text_edits(result)
end
@@ -153,36 +152,14 @@ end
--@param start_pos ({number, number}, optional) mark-indexed position.
---Defaults to the end of the last visual selection.
function M.range_formatting(options, start_pos, end_pos)
- validate {
- options = {options, 't', true};
- start_pos = {start_pos, 't', true};
- end_pos = {end_pos, 't', true};
- }
+ validate { options = {options, 't', true} }
local sts = vim.bo.softtabstop;
options = vim.tbl_extend('keep', options or {}, {
tabSize = (sts > 0 and sts) or (sts < 0 and vim.bo.shiftwidth) or vim.bo.tabstop;
insertSpaces = vim.bo.expandtab;
})
- local A = list_extend({}, start_pos or api.nvim_buf_get_mark(0, '<'))
- local B = list_extend({}, end_pos or api.nvim_buf_get_mark(0, '>'))
- -- convert to 0-index
- A[1] = A[1] - 1
- B[1] = B[1] - 1
- -- account for encoding.
- if A[2] > 0 then
- A = {A[1], util.character_offset(0, A[1], A[2])}
- end
- if B[2] > 0 then
- B = {B[1], util.character_offset(0, B[1], B[2])}
- end
- local params = {
- textDocument = { uri = vim.uri_from_bufnr(0) };
- range = {
- start = { line = A[1]; character = A[2]; };
- ["end"] = { line = B[1]; character = B[2]; };
- };
- options = options;
- }
+ local params = util.make_given_range_params(start_pos, end_pos)
+ params.options = options
return request('textDocument/rangeFormatting', params)
end
@@ -307,6 +284,21 @@ function M.code_action(context)
request('textDocument/codeAction', params)
end
+--- Performs |vim.lsp.buf.code_action()| for a given range.
+---
+--@param context: (table, optional) Valid `CodeActionContext` object
+--@param start_pos ({number, number}, optional) mark-indexed position.
+---Defaults to the start of the last visual selection.
+--@param end_pos ({number, number}, optional) mark-indexed position.
+---Defaults to the end of the last visual selection.
+function M.range_code_action(context, start_pos, end_pos)
+ validate { context = { context, 't', true } }
+ context = context or { diagnostics = util.get_line_diagnostics() }
+ local params = util.make_given_range_params(start_pos, end_pos)
+ params.context = context
+ request('textDocument/codeAction', params)
+end
+
--- Executes an LSP server command.
---
--@param command A valid `ExecuteCommandParams` object
diff --git a/runtime/lua/vim/lsp/callbacks.lua b/runtime/lua/vim/lsp/callbacks.lua
index 0ee03e6a2f..4e7a8333a0 100644
--- a/runtime/lua/vim/lsp/callbacks.lua
+++ b/runtime/lua/vim/lsp/callbacks.lua
@@ -229,16 +229,19 @@ M['textDocument/implementation'] = location_callback
--@see https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_signatureHelp
M['textDocument/signatureHelp'] = function(_, method, result)
+ -- When use `autocmd CompleteDone <silent><buffer> lua vim.lsp.buf.signature_help()` to call signatureHelp callback
+ -- If the completion item doesn't have signatures It will make noise. Change to use `print` that can use `<silent>` to ignore
+ if not (result and result.signatures and result.signatures[1]) then
+ print('No signature help available')
+ return
+ end
+ local lines = util.convert_signature_help_to_markdown_lines(result)
+ lines = util.trim_empty_lines(lines)
+ if vim.tbl_isempty(lines) then
+ print('No signature help available')
+ return
+ end
util.focusable_preview(method, function()
- if not (result and result.signatures and result.signatures[1]) then
- return { 'No signature available' }
- end
- -- TODO show popup when signatures is empty?
- local lines = util.convert_signature_help_to_markdown_lines(result)
- lines = util.trim_empty_lines(lines)
- if vim.tbl_isempty(lines) then
- return { 'No signature available' }
- end
return lines, util.try_trim_markdown_code_blocks(lines)
end)
end
diff --git a/runtime/lua/vim/lsp/rpc.lua b/runtime/lua/vim/lsp/rpc.lua
index 64080cf4f2..749a51fecc 100644
--- a/runtime/lua/vim/lsp/rpc.lua
+++ b/runtime/lua/vim/lsp/rpc.lua
@@ -494,10 +494,13 @@ local function start(cmd, cmd_args, handlers, extra_spawn_params)
decoded.error = convert_NIL(decoded.error)
decoded.result = convert_NIL(decoded.result)
- -- Do not surface RequestCancelled to users, it is RPC-internal.
- if decoded.error
- and decoded.error.code == protocol.ErrorCodes.RequestCancelled then
- local _ = log.debug() and log.debug("Received cancellation ack", decoded)
+ -- Do not surface RequestCancelled or ContentModified to users, it is RPC-internal.
+ if decoded.error then
+ if decoded.error.code == protocol.ErrorCodes.RequestCancelled then
+ local _ = log.debug() and log.debug("Received cancellation ack", decoded)
+ elseif decoded.error.code == protocol.ErrorCodes.ContentModified then
+ local _ = log.debug() and log.debug("Received content modified ack", decoded)
+ end
local result_id = tonumber(decoded.id)
-- Clear any callback since this is cancelled now.
-- This is safe to do assuming that these conditions hold:
diff --git a/runtime/lua/vim/lsp/util.lua b/runtime/lua/vim/lsp/util.lua
index 24cb454e5b..d94a8bb774 100644
--- a/runtime/lua/vim/lsp/util.lua
+++ b/runtime/lua/vim/lsp/util.lua
@@ -505,13 +505,13 @@ function M.convert_signature_help_to_markdown_lines(signature_help)
if signature.documentation then
M.convert_input_to_markdown_lines(signature.documentation, contents)
end
- if signature_help.parameters then
+ if signature.parameters and #signature.parameters > 0 then
local active_parameter = signature_help.activeParameter or 0
-- If the activeParameter is not inside the valid range, then clip it.
- if active_parameter >= #signature_help.parameters then
+ if active_parameter >= #signature.parameters then
active_parameter = 0
end
- local parameter = signature.parameters and signature.parameters[active_parameter]
+ local parameter = signature.parameters[active_parameter + 1]
if parameter then
--[=[
--Represents a parameter of a callable-signature. A parameter can
@@ -532,8 +532,8 @@ function M.convert_signature_help_to_markdown_lines(signature_help)
}
--]=]
-- TODO highlight parameter
- if parameter.documentation then
- M.convert_input_help_to_markdown_lines(parameter.documentation, contents)
+ if parameter.documentation and parameter.documentation ~= vim.NIL then
+ M.convert_input_to_markdown_lines(parameter.documentation, contents)
end
end
end
@@ -668,7 +668,7 @@ function M.focusable_float(unique_name, fn)
local bufnr = api.nvim_get_current_buf()
do
local win = find_window_by_var(unique_name, bufnr)
- if win then
+ if win and api.nvim_win_is_valid(win) and not vim.fn.pumvisible() then
api.nvim_set_current_win(win)
api.nvim_command("stopinsert")
return
@@ -1465,11 +1465,46 @@ end
function M.make_range_params()
local position = make_position_param()
return {
- textDocument = { uri = vim.uri_from_bufnr(0) },
+ textDocument = M.make_text_document_params(),
range = { start = position; ["end"] = position; }
}
end
+--- Using the given range in the current buffer, creates an object that
+--- is similar to |vim.lsp.util.make_range_params()|.
+---
+--@param start_pos ({number, number}, optional) mark-indexed position.
+---Defaults to the start of the last visual selection.
+--@param end_pos ({number, number}, optional) mark-indexed position.
+---Defaults to the end of the last visual selection.
+--@returns { textDocument = { uri = `current_file_uri` }, range = { start =
+---`start_position`, end = `end_position` } }
+function M.make_given_range_params(start_pos, end_pos)
+ validate {
+ start_pos = {start_pos, 't', true};
+ end_pos = {end_pos, 't', true};
+ }
+ local A = list_extend({}, start_pos or api.nvim_buf_get_mark(0, '<'))
+ local B = list_extend({}, end_pos or api.nvim_buf_get_mark(0, '>'))
+ -- convert to 0-index
+ A[1] = A[1] - 1
+ B[1] = B[1] - 1
+ -- account for encoding.
+ if A[2] > 0 then
+ A = {A[1], M.character_offset(0, A[1], A[2])}
+ end
+ if B[2] > 0 then
+ B = {B[1], M.character_offset(0, B[1], B[2])}
+ end
+ return {
+ textDocument = M.make_text_document_params(),
+ range = {
+ start = {line = A[1], character = A[2]},
+ ['end'] = {line = B[1], character = B[2]}
+ }
+ }
+end
+
--- Creates a `TextDocumentIdentifier` object for the current buffer.
---
--@returns `TextDocumentIdentifier`
diff --git a/runtime/lua/vim/treesitter/highlighter.lua b/runtime/lua/vim/treesitter/highlighter.lua
index 718088e0ad..5b964a6020 100644
--- a/runtime/lua/vim/treesitter/highlighter.lua
+++ b/runtime/lua/vim/treesitter/highlighter.lua
@@ -3,7 +3,8 @@ local a = vim.api
-- support reload for quick experimentation
local TSHighlighter = rawget(vim.treesitter, 'TSHighlighter') or {}
TSHighlighter.__index = TSHighlighter
-local ts_hs_ns = a.nvim_create_namespace("treesitter_hl")
+
+TSHighlighter.active = TSHighlighter.active or {}
-- These are conventions defined by tree-sitter, though it
-- needs to be user extensible also.
@@ -54,13 +55,16 @@ TSHighlighter.hl_map = {
}
function TSHighlighter.new(query, bufnr, ft)
+ if bufnr == nil or bufnr == 0 then
+ bufnr = a.nvim_get_current_buf()
+ end
+
local self = setmetatable({}, TSHighlighter)
self.parser = vim.treesitter.get_parser(
bufnr,
ft,
{
on_changedtree = function(...) self:on_changedtree(...) end,
- on_bytes = function() self.parser:parse() end
}
)
@@ -69,8 +73,12 @@ function TSHighlighter.new(query, bufnr, ft)
self.edit_count = 0
self.redraw_count = 0
self.line_count = {}
+ self.root = self.parser:parse():root()
a.nvim_buf_set_option(self.buf, "syntax", "")
+ -- TODO(bfredl): can has multiple highlighters per buffer????
+ TSHighlighter.active[bufnr] = self
+
-- Tricky: if syntax hasn't been enabled, we need to reload color scheme
-- but use synload.vim rather than syntax.vim to not enable
-- syntax FileType autocmds. Later on we should integrate with the
@@ -100,6 +108,12 @@ function TSHighlighter:get_hl_from_capture(capture)
end
end
+function TSHighlighter:on_changedtree(changes)
+ for _, ch in ipairs(changes or {}) do
+ a.nvim__buf_redraw_range(self.buf, ch[1], ch[3]+1)
+ end
+end
+
function TSHighlighter:set_query(query)
if type(query) == "string" then
query = vim.treesitter.parse_query(self.parser.lang, query)
@@ -123,28 +137,60 @@ function TSHighlighter:set_query(query)
end
})
- self:on_changedtree({{self.parser:parse():root():range()}})
+ a.nvim__buf_redraw_range(self.buf, 0, a.nvim_buf_line_count(self.buf))
end
-function TSHighlighter:on_changedtree(changes)
- -- Get a fresh root
- local root = self.parser:parse():root()
+function TSHighlighter._on_line(_, _win, buf, line)
+ -- on_line is only called when this is non-nil
+ local self = TSHighlighter.active[buf]
+ if self.root == nil then
+ return -- parser bought the farm already
+ end
- for _, ch in ipairs(changes or {}) do
- a.nvim_buf_clear_namespace(self.buf, ts_hs_ns, ch[1], ch[3]+1)
-
- for capture, node in self.query:iter_captures(root, self.buf, ch[1], ch[3] + 1) do
- local start_row, start_col, end_row, end_col = node:range()
- local hl = self.hl_cache[capture]
- if hl then
- a.nvim_buf_set_extmark(self.buf, ts_hs_ns, start_row, start_col, {
- end_col = end_col,
- end_line = end_row,
- hl_group = hl
- })
- end
+ if self.iter == nil then
+ self.iter = self.query:iter_captures(self.root,buf,line,self.botline)
+ end
+ while line >= self.nextrow do
+ local capture, node = self.iter()
+ if capture == nil then
+ break
+ end
+ local start_row, start_col, end_row, end_col = node:range()
+ local hl = self.hl_cache[capture]
+ if hl and end_row >= line then
+ a.nvim__put_attr(start_row, start_col, { end_line = end_row, end_col = end_col, hl_group = hl })
+ end
+ if start_row > line then
+ self.nextrow = start_row
end
end
end
+function TSHighlighter._on_start(_, buf, _tick)
+ local self = TSHighlighter.active[buf]
+ if self then
+ local tree = self.parser:parse()
+ self.root = (tree and tree:root()) or nil
+ end
+end
+
+function TSHighlighter._on_win(_, _win, buf, _topline, botline)
+ local self = TSHighlighter.active[buf]
+ if not self then
+ return false
+ end
+
+ self.iter = nil
+ self.nextrow = 0
+ self.botline = botline
+ self.redraw_count = self.redraw_count + 1
+ return true
+end
+
+a.nvim__set_luahl {
+ on_start = TSHighlighter._on_start;
+ on_win = TSHighlighter._on_win;
+ on_line = TSHighlighter._on_line;
+}
+
return TSHighlighter
diff --git a/runtime/lua/vim/uri.lua b/runtime/lua/vim/uri.lua
index 9c3535c676..f1a12c72ec 100644
--- a/runtime/lua/vim/uri.lua
+++ b/runtime/lua/vim/uri.lua
@@ -7,6 +7,9 @@
local uri_decode
do
local schar = string.char
+
+ --- Convert hex to char
+ --@private
local function hex_to_char(hex)
return schar(tonumber(hex, 16))
end
@@ -34,6 +37,8 @@ do
else
tohex = function(b) return string.format("%02x", b) end
end
+
+ --@private
local function percent_encode_char(char)
return "%"..tohex(sbyte(char), 2)
end
@@ -45,10 +50,14 @@ do
end
+--@private
local function is_windows_file_uri(uri)
return uri:match('^file:///[a-zA-Z]:') ~= nil
end
+--- Get a URI from a file path.
+--@param path (string): Path to file
+--@return URI
local function uri_from_fname(path)
local volume_path, fname = path:match("^([a-zA-Z]:)(.*)")
local is_windows = volume_path ~= nil
@@ -67,6 +76,9 @@ end
local URI_SCHEME_PATTERN = '^([a-zA-Z]+[a-zA-Z0-9+-.]*)://.*'
+--- Get a URI from a bufnr
+--@param bufnr (number): Buffer number
+--@return URI
local function uri_from_bufnr(bufnr)
local fname = vim.api.nvim_buf_get_name(bufnr)
local scheme = fname:match(URI_SCHEME_PATTERN)
@@ -77,6 +89,9 @@ local function uri_from_bufnr(bufnr)
end
end
+--- Get a filename from a URI
+--@param uri (string): The URI
+--@return Filename
local function uri_to_fname(uri)
local scheme = assert(uri:match(URI_SCHEME_PATTERN), 'URI must contain a scheme: ' .. uri)
if scheme ~= 'file' then
@@ -93,7 +108,10 @@ local function uri_to_fname(uri)
return uri
end
--- Return or create a buffer for a uri.
+--- Return or create a buffer for a uri.
+--@param uri (string): The URI
+--@return bufnr.
+--@note Creates buffer but does not load it
local function uri_to_bufnr(uri)
local scheme = assert(uri:match(URI_SCHEME_PATTERN), 'URI must contain a scheme: ' .. uri)
if scheme == 'file' then
diff --git a/runtime/pack/dist/opt/cfilter/plugin/cfilter.vim b/runtime/pack/dist/opt/cfilter/plugin/cfilter.vim
index 7a6464fc98..fe4455fe2e 100644
--- a/runtime/pack/dist/opt/cfilter/plugin/cfilter.vim
+++ b/runtime/pack/dist/opt/cfilter/plugin/cfilter.vim
@@ -1,15 +1,17 @@
" cfilter.vim: Plugin to filter entries from a quickfix/location list
-" Last Change: May 12, 2018
-" Maintainer: Yegappan Lakshmanan (yegappan AT yahoo DOT com)
-" Version: 1.0
+" Last Change: Aug 23, 2018
+" Maintainer: Yegappan Lakshmanan (yegappan AT yahoo DOT com)
+" Version: 1.1
"
" Commands to filter the quickfix list:
-" :Cfilter[!] {pat}
+" :Cfilter[!] /{pat}/
" Create a new quickfix list from entries matching {pat} in the current
" quickfix list. Both the file name and the text of the entries are
" matched against {pat}. If ! is supplied, then entries not matching
-" {pat} are used.
-" :Lfilter[!] {pat}
+" {pat} are used. The pattern can be optionally enclosed using one of
+" the following characters: ', ", /. If the pattern is empty, then the
+" last used search pattern is used.
+" :Lfilter[!] /{pat}/
" Same as :Cfilter but operates on the current location list.
"
if exists("loaded_cfilter")
@@ -17,7 +19,7 @@ if exists("loaded_cfilter")
endif
let loaded_cfilter = 1
-func s:Qf_filter(qf, pat, bang)
+func s:Qf_filter(qf, searchpat, bang)
if a:qf
let Xgetlist = function('getqflist')
let Xsetlist = function('setqflist')
@@ -28,14 +30,31 @@ func s:Qf_filter(qf, pat, bang)
let cmd = ':Lfilter' . a:bang
endif
+ let firstchar = a:searchpat[0]
+ let lastchar = a:searchpat[-1:]
+ if firstchar == lastchar &&
+ \ (firstchar == '/' || firstchar == '"' || firstchar == "'")
+ let pat = a:searchpat[1:-2]
+ if pat == ''
+ " Use the last search pattern
+ let pat = @/
+ endif
+ else
+ let pat = a:searchpat
+ endif
+
+ if pat == ''
+ return
+ endif
+
if a:bang == '!'
- let cond = 'v:val.text !~# a:pat && bufname(v:val.bufnr) !~# a:pat'
+ let cond = 'v:val.text !~# pat && bufname(v:val.bufnr) !~# pat'
else
- let cond = 'v:val.text =~# a:pat || bufname(v:val.bufnr) =~# a:pat'
+ let cond = 'v:val.text =~# pat || bufname(v:val.bufnr) =~# pat'
endif
let items = filter(Xgetlist(), cond)
- let title = cmd . ' ' . a:pat
+ let title = cmd . ' /' . pat . '/'
call Xsetlist([], ' ', {'title' : title, 'items' : items})
endfunc