aboutsummaryrefslogtreecommitdiff
path: root/runtime/lua/vim
diff options
context:
space:
mode:
Diffstat (limited to 'runtime/lua/vim')
-rw-r--r--runtime/lua/vim/highlight.lua2
-rw-r--r--runtime/lua/vim/lsp.lua10
-rw-r--r--runtime/lua/vim/lsp/rpc.lua1
-rw-r--r--runtime/lua/vim/lsp/util.lua10
-rw-r--r--runtime/lua/vim/shared.lua18
-rw-r--r--runtime/lua/vim/treesitter.lua39
-rw-r--r--runtime/lua/vim/treesitter/highlighter.lua28
-rw-r--r--runtime/lua/vim/treesitter/query.lua51
8 files changed, 93 insertions, 66 deletions
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/lsp.lua b/runtime/lua/vim/lsp.lua
index 47dca40208..585528dd5a 100644
--- a/runtime/lua/vim/lsp.lua
+++ b/runtime/lua/vim/lsp.lua
@@ -761,8 +761,12 @@ do
text_document_did_change_handler = function(_, bufnr, changedtick,
firstline, lastline, new_lastline, old_byte_size, old_utf32_size,
old_utf16_size)
- local _ = log.debug() and log.debug("on_lines", bufnr, changedtick, firstline,
- lastline, new_lastline, old_byte_size, old_utf32_size, old_utf16_size, nvim_buf_get_lines(bufnr, firstline, new_lastline, true))
+
+ local _ = log.debug() and log.debug(
+ string.format("on_lines bufnr: %s, changedtick: %s, firstline: %s, lastline: %s, new_lastline: %s, old_byte_size: %s, old_utf32_size: %s, old_utf16_size: %s",
+ bufnr, changedtick, firstline, lastline, new_lastline, old_byte_size, old_utf32_size, old_utf16_size),
+ nvim_buf_get_lines(bufnr, firstline, new_lastline, true)
+ )
-- Don't do anything if there are no clients attached.
if tbl_isempty(all_buffer_active_clients[bufnr] or {}) then
@@ -922,7 +926,7 @@ end
--- To stop all clients:
---
--- <pre>
---- vim.lsp.stop_client(lsp.get_active_clients())
+--- vim.lsp.stop_client(vim.lsp.get_active_clients())
--- </pre>
---
--- By default asks the server to shutdown, unless stop was requested
diff --git a/runtime/lua/vim/lsp/rpc.lua b/runtime/lua/vim/lsp/rpc.lua
index 680e1ba6ae..64080cf4f2 100644
--- a/runtime/lua/vim/lsp/rpc.lua
+++ b/runtime/lua/vim/lsp/rpc.lua
@@ -376,7 +376,6 @@ local function start(cmd, cmd_args, handlers, extra_spawn_params)
--@param params (table): Parameters for the invoked LSP method
--@returns (bool) `true` if notification could be sent, `false` if not
local function notify(method, params)
- local _ = log.debug() and log.debug("rpc.notify", method, params)
return encode_and_send {
jsonrpc = "2.0";
method = method;
diff --git a/runtime/lua/vim/lsp/util.lua b/runtime/lua/vim/lsp/util.lua
index 3ec7311d65..24cb454e5b 100644
--- a/runtime/lua/vim/lsp/util.lua
+++ b/runtime/lua/vim/lsp/util.lua
@@ -299,10 +299,9 @@ end
---
--@see https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_completion
local function sort_completion_items(items)
- if items[1] and items[1].sortText then
- table.sort(items, function(a, b) return a.sortText < b.sortText
- end)
- end
+ table.sort(items, function(a, b)
+ return (a.sortText or a.label) < (b.sortText or b.label)
+ end)
end
--@private
@@ -1438,6 +1437,9 @@ local function make_position_param()
local row, col = unpack(api.nvim_win_get_cursor(0))
row = row - 1
local line = api.nvim_buf_get_lines(0, row, row+1, true)[1]
+ if not line then
+ return { line = 0; character = 0; }
+ end
col = str_utfindex(line, col)
return { line = row; character = col; }
end
diff --git a/runtime/lua/vim/shared.lua b/runtime/lua/vim/shared.lua
index 6e427665f2..5c89c63f7b 100644
--- a/runtime/lua/vim/shared.lua
+++ b/runtime/lua/vim/shared.lua
@@ -190,10 +190,10 @@ function vim.tbl_contains(t, value)
return false
end
--- Returns true if the table is empty, and contains no indexed or keyed values.
---
---@see From https://github.com/premake/premake-core/blob/master/src/base/table.lua
---
+--- Checks if a table is empty.
+---
+--@see https://github.com/premake/premake-core/blob/master/src/base/table.lua
+---
--@param t Table to check
function vim.tbl_isempty(t)
assert(type(t) == 'table', string.format("Expected table, got %s", type(t)))
@@ -347,13 +347,11 @@ function vim.tbl_flatten(t)
return result
end
---- Determine whether a Lua table can be treated as an array.
+--- Tests if a Lua table can be treated as an array.
---
---- An empty table `{}` will default to being treated as an array.
---- Use `vim.emtpy_dict()` to create a table treated as an
---- empty dict. Empty tables returned by `rpcrequest()` and
---- `vim.fn` functions can be checked using this function
---- whether they represent empty API arrays and vimL lists.
+--- Empty table `{}` is assumed to be an array, unless it was created by
+--- |vim.empty_dict()| or returned as a dict-like |API| or Vimscript result,
+--- for example from |rpcrequest()| or |vim.fn|.
---
--@param t Table
--@returns `true` if array-like table, else `false`.
diff --git a/runtime/lua/vim/treesitter.lua b/runtime/lua/vim/treesitter.lua
index 550dee1e3f..3a475b8f98 100644
--- a/runtime/lua/vim/treesitter.lua
+++ b/runtime/lua/vim/treesitter.lua
@@ -33,16 +33,23 @@ function Parser:parse()
return self.tree, changes
end
-function Parser:_on_lines(bufnr, changed_tick, start_row, old_stop_row, stop_row, old_byte_size)
- local start_byte = a.nvim_buf_get_offset(bufnr,start_row)
- local stop_byte = a.nvim_buf_get_offset(bufnr,stop_row)
- local old_stop_byte = start_byte + old_byte_size
- self._parser:edit(start_byte,old_stop_byte,stop_byte,
- start_row,0,old_stop_row,0,stop_row,0)
+function Parser:_on_bytes(bufnr, changed_tick,
+ start_row, start_col, start_byte,
+ old_row, old_col, old_byte,
+ new_row, new_col, new_byte)
+ local old_end_col = old_col + ((old_row == 0) and start_col or 0)
+ local new_end_col = new_col + ((new_row == 0) and start_col or 0)
+ self._parser:edit(start_byte,start_byte+old_byte,start_byte+new_byte,
+ start_row, start_col,
+ start_row+old_row, old_end_col,
+ start_row+new_row, new_end_col)
self.valid = false
- for _, cb in ipairs(self.lines_cbs) do
- cb(bufnr, changed_tick, start_row, old_stop_row, stop_row, old_byte_size)
+ for _, cb in ipairs(self.bytes_cbs) do
+ cb(bufnr, changed_tick,
+ start_row, start_col, start_byte,
+ old_row, old_col, old_byte,
+ new_row, new_col, new_byte)
end
end
@@ -88,12 +95,12 @@ function M._create_parser(bufnr, lang, id)
local self = setmetatable({bufnr=bufnr, lang=lang, valid=false}, Parser)
self._parser = vim._create_ts_parser(lang)
self.changedtree_cbs = {}
- self.lines_cbs = {}
+ self.bytes_cbs = {}
self:parse()
- -- TODO(bfredl): use weakref to self, so that the parser is free'd is no plugin is
- -- using it.
- local function lines_cb(_, ...)
- return self:_on_lines(...)
+ -- TODO(bfredl): use weakref to self, so that the parser is free'd is no plugin is
+ -- using it.
+ local function bytes_cb(_, ...)
+ return self:_on_bytes(...)
end
local detach_cb = nil
if id ~= nil then
@@ -103,7 +110,7 @@ function M._create_parser(bufnr, lang, id)
end
end
end
- a.nvim_buf_attach(self.bufnr, false, {on_lines=lines_cb, on_detach=detach_cb})
+ a.nvim_buf_attach(self.bufnr, false, {on_bytes=bytes_cb, on_detach=detach_cb})
return self
end
@@ -138,8 +145,8 @@ function M.get_parser(bufnr, lang, buf_attach_cbs)
table.insert(parsers[id].changedtree_cbs, buf_attach_cbs.on_changedtree)
end
- if buf_attach_cbs and buf_attach_cbs.on_lines then
- table.insert(parsers[id].lines_cbs, buf_attach_cbs.on_lines)
+ if buf_attach_cbs and buf_attach_cbs.on_bytes then
+ table.insert(parsers[id].bytes_cbs, buf_attach_cbs.on_bytes)
end
return parsers[id]
diff --git a/runtime/lua/vim/treesitter/highlighter.lua b/runtime/lua/vim/treesitter/highlighter.lua
index 681d2c6324..718088e0ad 100644
--- a/runtime/lua/vim/treesitter/highlighter.lua
+++ b/runtime/lua/vim/treesitter/highlighter.lua
@@ -60,14 +60,11 @@ function TSHighlighter.new(query, bufnr, ft)
ft,
{
on_changedtree = function(...) self:on_changedtree(...) end,
- on_lines = function() self.root = self.parser:parse():root() end
+ on_bytes = function() self.parser:parse() end
}
)
self.buf = self.parser.bufnr
-
- local tree = self.parser:parse()
- self.root = tree:root()
self:set_query(query)
self.edit_count = 0
self.redraw_count = 0
@@ -98,7 +95,8 @@ function TSHighlighter:get_hl_from_capture(capture)
return vim.split(name, '.', true)[1]
else
-- Default to false to avoid recomputing
- return 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
@@ -125,27 +123,25 @@ function TSHighlighter:set_query(query)
end
})
- self:on_changedtree({{self.root:range()}})
+ self:on_changedtree({{self.parser:parse():root():range()}})
end
function TSHighlighter:on_changedtree(changes)
-- Get a fresh root
- self.root = self.parser.tree:root()
+ local root = self.parser:parse():root()
for _, ch in ipairs(changes or {}) do
- -- Try to be as exact as possible
- local changed_node = self.root:descendant_for_range(ch[1], ch[2], ch[3], ch[4])
-
- a.nvim_buf_clear_namespace(self.buf, ts_hs_ns, ch[1], ch[3])
+ a.nvim_buf_clear_namespace(self.buf, ts_hs_ns, ch[1], ch[3]+1)
- for capture, node in self.query:iter_captures(changed_node, self.buf, ch[1], ch[3] + 1) do
+ 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_add_decoration(self.buf, ts_hs_ns, hl,
- start_row, start_col,
- end_row, end_col,
- {})
+ 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
end
end
diff --git a/runtime/lua/vim/treesitter/query.lua b/runtime/lua/vim/treesitter/query.lua
index 17f61b24f1..ca27a50c6a 100644
--- a/runtime/lua/vim/treesitter/query.lua
+++ b/runtime/lua/vim/treesitter/query.lua
@@ -17,7 +17,7 @@ local M = {}
function M.parse_query(lang, query)
language.require_language(lang)
local self = setmetatable({}, Query)
- self.query = vim._ts_parse_query(lang, vim.fn.escape(query,'\\'))
+ self.query = vim._ts_parse_query(lang, query)
self.info = self.query:inspect()
self.captures = self.info.captures
return self
@@ -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
@@ -82,7 +82,7 @@ local predicate_handlers = {
local compiled_vim_regexes = setmetatable({}, {
__index = function(t, pattern)
- local res = vim.regex(check_magic(pattern))
+ local res = vim.regex(check_magic(vim.fn.escape(pattern, '\\')))
rawset(t, pattern, res)
return res
end
@@ -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