From 18b43c331d8a0ed87d7cbefe2a18543b8e4ad360 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Thu, 17 Oct 2024 11:16:16 +0200 Subject: refactor: rename vim.highlight => vim.hl Problem: - `vim.highlight` module does not follow `:help dev-name-common`, which documents the name for "highlight" as "hl". - Shorter names are usually preferred. Solution: Rename `vim.highlight` to `vim.hl`. This is not a breaking change until 2.0 (or maybe never). --- runtime/doc/deprecated.txt | 1 + runtime/doc/lsp.txt | 6 +- runtime/doc/lua-guide.txt | 4 +- runtime/doc/lua.txt | 17 ++- runtime/doc/vim_diff.txt | 2 +- runtime/lua/vim/_editor.lua | 5 +- runtime/lua/vim/_meta.lua | 2 +- runtime/lua/vim/diagnostic.lua | 4 +- runtime/lua/vim/highlight.lua | 194 ----------------------------- runtime/lua/vim/hl.lua | 194 +++++++++++++++++++++++++++++ runtime/lua/vim/lsp/handlers.lua | 2 +- runtime/lua/vim/lsp/semantic_tokens.lua | 6 +- runtime/lua/vim/lsp/util.lua | 5 +- runtime/lua/vim/treesitter/highlighter.lua | 2 +- scripts/gen_vimdoc.lua | 6 +- test/functional/lua/highlight_spec.lua | 175 -------------------------- test/functional/lua/hl_spec.lua | 175 ++++++++++++++++++++++++++ 17 files changed, 401 insertions(+), 399 deletions(-) delete mode 100644 runtime/lua/vim/highlight.lua create mode 100644 runtime/lua/vim/hl.lua delete mode 100644 test/functional/lua/highlight_spec.lua create mode 100644 test/functional/lua/hl_spec.lua diff --git a/runtime/doc/deprecated.txt b/runtime/doc/deprecated.txt index ace509845a..7a3e2664c2 100644 --- a/runtime/doc/deprecated.txt +++ b/runtime/doc/deprecated.txt @@ -21,6 +21,7 @@ API LUA - vim.region() Use |getregionpos()| instead. +- *vim.highlight* Renamed to |vim.hl|. DIAGNOSTICS - *vim.diagnostic.goto_next()* Use |vim.diagnostic.jump()| with `{count=1, float=true}` instead. diff --git a/runtime/doc/lsp.txt b/runtime/doc/lsp.txt index f601ffab4c..c2410526e7 100644 --- a/runtime/doc/lsp.txt +++ b/runtime/doc/lsp.txt @@ -464,7 +464,7 @@ Use |:Inspect| to view the highlights for a specific token. Use |:hi| or hi @lsp.mod.deprecated gui=strikethrough " deprecated is crossed out hi @lsp.typemod.function.async guifg=Blue " async functions are blue < -The value |vim.highlight.priorities|`.semantic_tokens` is the priority of the +The value |vim.hl.priorities|`.semantic_tokens` is the priority of the `@lsp.type.*` highlights. The `@lsp.mod.*` and `@lsp.typemod.*` highlights have priorities one and two higher, respectively. @@ -1780,8 +1780,8 @@ highlight_token({token}, {bufnr}, {client_id}, {hl_group}, {opts}) • {hl_group} (`string`) Highlight group name • {opts} (`table?`) Optional parameters: • {priority}? (`integer`, default: - `vim.highlight.priorities.semantic_tokens + 3`) - Priority for the applied extmark. + `vim.hl.priorities.semantic_tokens + 3`) Priority for + the applied extmark. start({bufnr}, {client_id}, {opts}) *vim.lsp.semantic_tokens.start()* Start the semantic token highlighting engine for the given buffer with the diff --git a/runtime/doc/lua-guide.txt b/runtime/doc/lua-guide.txt index 5f06d51f42..b40d5a0791 100644 --- a/runtime/doc/lua-guide.txt +++ b/runtime/doc/lua-guide.txt @@ -552,7 +552,7 @@ This means that if your callback itself takes an (even optional) argument, you must wrap it in `function() end` to avoid an error: >lua vim.api.nvim_create_autocmd('TextYankPost', { - callback = function() vim.highlight.on_yank() end + callback = function() vim.hl.on_yank() end }) < (Since unused arguments can be omitted in Lua function definitions, this is @@ -576,7 +576,7 @@ Instead of using a pattern, you can create a buffer-local autocommand (see Similarly to mappings, you can (and should) add a description using `desc`: >lua vim.api.nvim_create_autocmd('TextYankPost', { - callback = function() vim.highlight.on_yank() end, + callback = function() vim.hl.on_yank() end, desc = "Briefly highlight yanked text" }) < diff --git a/runtime/doc/lua.txt b/runtime/doc/lua.txt index aba1ef476b..280e9ebf79 100644 --- a/runtime/doc/lua.txt +++ b/runtime/doc/lua.txt @@ -636,13 +636,13 @@ A subset of the `vim.*` API is available in threads. This includes: ============================================================================== -VIM.HIGHLIGHT *vim.highlight* +VIM.HL *vim.hl* -vim.highlight.on_yank({opts}) *vim.highlight.on_yank()* +vim.hl.on_yank({opts}) *vim.hl.on_yank()* Highlight the yanked text during a |TextYankPost| event. Add the following to your `init.vim`: >vim - autocmd TextYankPost * silent! lua vim.highlight.on_yank {higroup='Visual', timeout=300} + autocmd TextYankPost * silent! lua vim.hl.on_yank {higroup='Visual', timeout=300} < Parameters: ~ @@ -655,9 +655,9 @@ vim.highlight.on_yank({opts}) *vim.highlight.on_yank()* true) • event event structure (default vim.v.event) • priority integer priority (default - |vim.highlight.priorities|`.user`) + |vim.hl.priorities|`.user`) -vim.highlight.priorities *vim.highlight.priorities* +vim.hl.priorities *vim.hl.priorities* Table with default priorities used for highlighting: • `syntax`: `50`, used for standard syntax highlighting • `treesitter`: `100`, used for treesitter-based highlighting @@ -666,8 +666,8 @@ vim.highlight.priorities *vim.highlight.priorities* • `user`: `200`, used for user-triggered highlights such as LSP document symbols or `on_yank` autocommands - *vim.highlight.range()* -vim.highlight.range({bufnr}, {ns}, {higroup}, {start}, {finish}, {opts}) + *vim.hl.range()* +vim.hl.range({bufnr}, {ns}, {higroup}, {start}, {finish}, {opts}) Apply highlight group to range of text. Parameters: ~ @@ -684,8 +684,7 @@ vim.highlight.range({bufnr}, {ns}, {higroup}, {start}, {finish}, {opts}) • {inclusive}? (`boolean`, default: `false`) Indicates whether the range is end-inclusive • {priority}? (`integer`, default: - `vim.highlight.priorities.user`) Indicates priority of - highlight + `vim.hl.priorities.user`) Highlight priority ============================================================================== diff --git a/runtime/doc/vim_diff.txt b/runtime/doc/vim_diff.txt index d032baf55c..78d0329b00 100644 --- a/runtime/doc/vim_diff.txt +++ b/runtime/doc/vim_diff.txt @@ -249,7 +249,7 @@ backwards-compatibility cost. Some examples: Some features are built in that otherwise required external plugins: -- Highlighting the yanked region, see |vim.highlight|. +- Highlighting the yanked region, see |vim.hl|. ARCHITECTURE diff --git a/runtime/lua/vim/_editor.lua b/runtime/lua/vim/_editor.lua index 037cef9383..7aba7498f9 100644 --- a/runtime/lua/vim/_editor.lua +++ b/runtime/lua/vim/_editor.lua @@ -32,7 +32,7 @@ for k, v in pairs({ func = true, F = true, lsp = true, - highlight = true, + hl = true, diagnostic = true, keymap = true, ui = true, @@ -1197,4 +1197,7 @@ require('vim._options') ---@deprecated vim.loop = vim.uv +-- Deprecated. Remove at Nvim 2.0 +vim.highlight = vim._defer_deprecated_module('vim.highlight', 'vim.hl') + return vim diff --git a/runtime/lua/vim/_meta.lua b/runtime/lua/vim/_meta.lua index c9f207cb20..f8672d1f1f 100644 --- a/runtime/lua/vim/_meta.lua +++ b/runtime/lua/vim/_meta.lua @@ -15,7 +15,7 @@ vim.fs = require('vim.fs') vim.func = require('vim.func') vim.glob = require('vim.glob') vim.health = require('vim.health') -vim.highlight = require('vim.highlight') +vim.hl = require('vim.hl') vim.iter = require('vim.iter') vim.keymap = require('vim.keymap') vim.loader = require('vim.loader') diff --git a/runtime/lua/vim/diagnostic.lua b/runtime/lua/vim/diagnostic.lua index 99fcfd57e7..3570956efd 100644 --- a/runtime/lua/vim/diagnostic.lua +++ b/runtime/lua/vim/diagnostic.lua @@ -1498,13 +1498,13 @@ M.handlers.underline = { end end - vim.highlight.range( + vim.hl.range( bufnr, underline_ns, higroup, { diagnostic.lnum, diagnostic.col }, { diagnostic.end_lnum, diagnostic.end_col }, - { priority = vim.highlight.priorities.diagnostics } + { priority = vim.hl.priorities.diagnostics } ) end save_extmarks(underline_ns, bufnr) diff --git a/runtime/lua/vim/highlight.lua b/runtime/lua/vim/highlight.lua deleted file mode 100644 index a8d88db372..0000000000 --- a/runtime/lua/vim/highlight.lua +++ /dev/null @@ -1,194 +0,0 @@ -local api = vim.api - -local M = {} - ---- Table with default priorities used for highlighting: ---- - `syntax`: `50`, used for standard syntax highlighting ---- - `treesitter`: `100`, used for treesitter-based highlighting ---- - `semantic_tokens`: `125`, used for LSP semantic token highlighting ---- - `diagnostics`: `150`, used for code analysis such as diagnostics ---- - `user`: `200`, used for user-triggered highlights such as LSP document ---- symbols or `on_yank` autocommands -M.priorities = { - syntax = 50, - treesitter = 100, - semantic_tokens = 125, - diagnostics = 150, - user = 200, -} - ---- @class vim.highlight.range.Opts ---- @inlinedoc ---- ---- Type of range. See [getregtype()] ---- (default: `'v'` i.e. charwise) ---- @field regtype? string ---- ---- Indicates whether the range is end-inclusive ---- (default: `false`) ---- @field inclusive? boolean ---- ---- Indicates priority of highlight ---- (default: `vim.highlight.priorities.user`) ---- @field priority? integer - ---- Apply highlight group to range of text. ---- ----@param bufnr integer Buffer number to apply highlighting to ----@param ns integer Namespace to add highlight to ----@param higroup string Highlight group to use for highlighting ----@param start integer[]|string Start of region as a (line, column) tuple or string accepted by |getpos()| ----@param finish integer[]|string End of region as a (line, column) tuple or string accepted by |getpos()| ----@param opts? vim.highlight.range.Opts -function M.range(bufnr, ns, higroup, start, finish, opts) - opts = opts or {} - local regtype = opts.regtype or 'v' - local inclusive = opts.inclusive or false - local priority = opts.priority or M.priorities.user - - local v_maxcol = vim.v.maxcol - - local pos1 = type(start) == 'string' and vim.fn.getpos(start) - or { - bufnr, - start[1] + 1, - start[2] ~= -1 and start[2] ~= v_maxcol and start[2] + 1 or v_maxcol, - 0, - } - local pos2 = type(finish) == 'string' and vim.fn.getpos(finish) - or { - bufnr, - finish[1] + 1, - finish[2] ~= -1 and start[2] ~= v_maxcol and finish[2] + 1 or v_maxcol, - 0, - } - - local buf_line_count = vim.api.nvim_buf_line_count(bufnr) - pos1[2] = math.min(pos1[2], buf_line_count) - pos2[2] = math.min(pos2[2], buf_line_count) - - if pos1[2] <= 0 or pos1[3] <= 0 or pos2[2] <= 0 or pos2[3] <= 0 then - return - end - - vim._with({ buf = bufnr }, function() - if pos1[3] ~= v_maxcol then - local max_col1 = vim.fn.col({ pos1[2], '$' }) - pos1[3] = math.min(pos1[3], max_col1) - end - if pos2[3] ~= v_maxcol then - local max_col2 = vim.fn.col({ pos2[2], '$' }) - pos2[3] = math.min(pos2[3], max_col2) - end - end) - - local region = vim.fn.getregionpos(pos1, pos2, { - type = regtype, - exclusive = not inclusive, - eol = true, - }) - -- For non-blockwise selection, use a single extmark. - if regtype == 'v' or regtype == 'V' then - region = { { region[1][1], region[#region][2] } } - if - regtype == 'V' - or region[1][2][2] == pos1[2] and pos1[3] == v_maxcol - or region[1][2][2] == pos2[2] and pos2[3] == v_maxcol - then - region[1][2][2] = region[1][2][2] + 1 - region[1][2][3] = 0 - end - end - - for _, res in ipairs(region) do - local start_row = res[1][2] - 1 - local start_col = res[1][3] - 1 - local end_row = res[2][2] - 1 - local end_col = res[2][3] - api.nvim_buf_set_extmark(bufnr, ns, start_row, start_col, { - hl_group = higroup, - end_row = end_row, - end_col = end_col, - priority = priority, - strict = false, - }) - end -end - -local yank_ns = api.nvim_create_namespace('hlyank') -local yank_timer --- @type uv.uv_timer_t? -local yank_cancel --- @type fun()? - ---- Highlight the yanked text during a |TextYankPost| event. ---- ---- Add the following to your `init.vim`: ---- ---- ```vim ---- autocmd TextYankPost * silent! lua vim.highlight.on_yank {higroup='Visual', timeout=300} ---- ``` ---- ---- @param opts table|nil Optional parameters ---- - higroup highlight group for yanked region (default "IncSearch") ---- - timeout time in ms before highlight is cleared (default 150) ---- - on_macro highlight when executing macro (default false) ---- - on_visual highlight when yanking visual selection (default true) ---- - event event structure (default vim.v.event) ---- - priority integer priority (default |vim.highlight.priorities|`.user`) -function M.on_yank(opts) - vim.validate({ - opts = { - opts, - function(t) - if t == nil then - return true - else - return type(t) == 'table' - end - end, - 'a table or nil to configure options (see `:h highlight.on_yank`)', - }, - }) - opts = opts or {} - local event = opts.event or vim.v.event - local on_macro = opts.on_macro or false - local on_visual = (opts.on_visual ~= false) - - if not on_macro and vim.fn.reg_executing() ~= '' then - return - end - if event.operator ~= 'y' or event.regtype == '' then - return - end - if not on_visual and event.visual then - return - end - - local higroup = opts.higroup or 'IncSearch' - local timeout = opts.timeout or 150 - - local bufnr = vim.api.nvim_get_current_buf() - local winid = vim.api.nvim_get_current_win() - if yank_timer then - yank_timer:close() - assert(yank_cancel) - yank_cancel() - end - - vim.api.nvim__ns_set(yank_ns, { wins = { winid } }) - M.range(bufnr, yank_ns, higroup, "'[", "']", { - regtype = event.regtype, - inclusive = event.inclusive, - priority = opts.priority or M.priorities.user, - }) - - yank_cancel = function() - yank_timer = nil - yank_cancel = nil - pcall(vim.api.nvim_buf_clear_namespace, bufnr, yank_ns, 0, -1) - pcall(vim.api.nvim__ns_set, { wins = {} }) - end - - yank_timer = vim.defer_fn(yank_cancel, timeout) -end - -return M diff --git a/runtime/lua/vim/hl.lua b/runtime/lua/vim/hl.lua new file mode 100644 index 0000000000..49bbaa3cc6 --- /dev/null +++ b/runtime/lua/vim/hl.lua @@ -0,0 +1,194 @@ +local api = vim.api + +local M = {} + +--- Table with default priorities used for highlighting: +--- - `syntax`: `50`, used for standard syntax highlighting +--- - `treesitter`: `100`, used for treesitter-based highlighting +--- - `semantic_tokens`: `125`, used for LSP semantic token highlighting +--- - `diagnostics`: `150`, used for code analysis such as diagnostics +--- - `user`: `200`, used for user-triggered highlights such as LSP document +--- symbols or `on_yank` autocommands +M.priorities = { + syntax = 50, + treesitter = 100, + semantic_tokens = 125, + diagnostics = 150, + user = 200, +} + +--- @class vim.hl.range.Opts +--- @inlinedoc +--- +--- Type of range. See [getregtype()] +--- (default: `'v'` i.e. charwise) +--- @field regtype? string +--- +--- Indicates whether the range is end-inclusive +--- (default: `false`) +--- @field inclusive? boolean +--- +--- Highlight priority +--- (default: `vim.hl.priorities.user`) +--- @field priority? integer + +--- Apply highlight group to range of text. +--- +---@param bufnr integer Buffer number to apply highlighting to +---@param ns integer Namespace to add highlight to +---@param higroup string Highlight group to use for highlighting +---@param start integer[]|string Start of region as a (line, column) tuple or string accepted by |getpos()| +---@param finish integer[]|string End of region as a (line, column) tuple or string accepted by |getpos()| +---@param opts? vim.hl.range.Opts +function M.range(bufnr, ns, higroup, start, finish, opts) + opts = opts or {} + local regtype = opts.regtype or 'v' + local inclusive = opts.inclusive or false + local priority = opts.priority or M.priorities.user + + local v_maxcol = vim.v.maxcol + + local pos1 = type(start) == 'string' and vim.fn.getpos(start) + or { + bufnr, + start[1] + 1, + start[2] ~= -1 and start[2] ~= v_maxcol and start[2] + 1 or v_maxcol, + 0, + } + local pos2 = type(finish) == 'string' and vim.fn.getpos(finish) + or { + bufnr, + finish[1] + 1, + finish[2] ~= -1 and start[2] ~= v_maxcol and finish[2] + 1 or v_maxcol, + 0, + } + + local buf_line_count = vim.api.nvim_buf_line_count(bufnr) + pos1[2] = math.min(pos1[2], buf_line_count) + pos2[2] = math.min(pos2[2], buf_line_count) + + if pos1[2] <= 0 or pos1[3] <= 0 or pos2[2] <= 0 or pos2[3] <= 0 then + return + end + + vim._with({ buf = bufnr }, function() + if pos1[3] ~= v_maxcol then + local max_col1 = vim.fn.col({ pos1[2], '$' }) + pos1[3] = math.min(pos1[3], max_col1) + end + if pos2[3] ~= v_maxcol then + local max_col2 = vim.fn.col({ pos2[2], '$' }) + pos2[3] = math.min(pos2[3], max_col2) + end + end) + + local region = vim.fn.getregionpos(pos1, pos2, { + type = regtype, + exclusive = not inclusive, + eol = true, + }) + -- For non-blockwise selection, use a single extmark. + if regtype == 'v' or regtype == 'V' then + region = { { region[1][1], region[#region][2] } } + if + regtype == 'V' + or region[1][2][2] == pos1[2] and pos1[3] == v_maxcol + or region[1][2][2] == pos2[2] and pos2[3] == v_maxcol + then + region[1][2][2] = region[1][2][2] + 1 + region[1][2][3] = 0 + end + end + + for _, res in ipairs(region) do + local start_row = res[1][2] - 1 + local start_col = res[1][3] - 1 + local end_row = res[2][2] - 1 + local end_col = res[2][3] + api.nvim_buf_set_extmark(bufnr, ns, start_row, start_col, { + hl_group = higroup, + end_row = end_row, + end_col = end_col, + priority = priority, + strict = false, + }) + end +end + +local yank_ns = api.nvim_create_namespace('hlyank') +local yank_timer --- @type uv.uv_timer_t? +local yank_cancel --- @type fun()? + +--- Highlight the yanked text during a |TextYankPost| event. +--- +--- Add the following to your `init.vim`: +--- +--- ```vim +--- autocmd TextYankPost * silent! lua vim.hl.on_yank {higroup='Visual', timeout=300} +--- ``` +--- +--- @param opts table|nil Optional parameters +--- - higroup highlight group for yanked region (default "IncSearch") +--- - timeout time in ms before highlight is cleared (default 150) +--- - on_macro highlight when executing macro (default false) +--- - on_visual highlight when yanking visual selection (default true) +--- - event event structure (default vim.v.event) +--- - priority integer priority (default |vim.hl.priorities|`.user`) +function M.on_yank(opts) + vim.validate({ + opts = { + opts, + function(t) + if t == nil then + return true + else + return type(t) == 'table' + end + end, + 'a table or nil to configure options (see `:h vim.hl.on_yank`)', + }, + }) + opts = opts or {} + local event = opts.event or vim.v.event + local on_macro = opts.on_macro or false + local on_visual = (opts.on_visual ~= false) + + if not on_macro and vim.fn.reg_executing() ~= '' then + return + end + if event.operator ~= 'y' or event.regtype == '' then + return + end + if not on_visual and event.visual then + return + end + + local higroup = opts.higroup or 'IncSearch' + local timeout = opts.timeout or 150 + + local bufnr = vim.api.nvim_get_current_buf() + local winid = vim.api.nvim_get_current_win() + if yank_timer then + yank_timer:close() + assert(yank_cancel) + yank_cancel() + end + + vim.api.nvim__ns_set(yank_ns, { wins = { winid } }) + M.range(bufnr, yank_ns, higroup, "'[", "']", { + regtype = event.regtype, + inclusive = event.inclusive, + priority = opts.priority or M.priorities.user, + }) + + yank_cancel = function() + yank_timer = nil + yank_cancel = nil + pcall(vim.api.nvim_buf_clear_namespace, bufnr, yank_ns, 0, -1) + pcall(vim.api.nvim__ns_set, { wins = {} }) + end + + yank_timer = vim.defer_fn(yank_cancel, timeout) +end + +return M diff --git a/runtime/lua/vim/lsp/handlers.lua b/runtime/lua/vim/lsp/handlers.lua index c87cf94b98..37cb07025c 100644 --- a/runtime/lua/vim/lsp/handlers.lua +++ b/runtime/lua/vim/lsp/handlers.lua @@ -437,7 +437,7 @@ function M.signature_help(_, result, ctx, config) local fbuf, fwin = util.open_floating_preview(lines, 'markdown', config) -- Highlight the active parameter. if hl then - vim.highlight.range( + vim.hl.range( fbuf, sig_help_ns, 'LspSignatureActiveParameter', diff --git a/runtime/lua/vim/lsp/semantic_tokens.lua b/runtime/lua/vim/lsp/semantic_tokens.lua index 2c7958b0d5..0f6e45c330 100644 --- a/runtime/lua/vim/lsp/semantic_tokens.lua +++ b/runtime/lua/vim/lsp/semantic_tokens.lua @@ -443,7 +443,7 @@ function STHighlighter:on_win(topline, botline) vim.api.nvim_buf_set_extmark(self.bufnr, state.namespace, token.line, token.start_col, { hl_group = hl_group, end_col = token.end_col, - priority = vim.highlight.priorities.semantic_tokens + delta, + priority = vim.hl.priorities.semantic_tokens + delta, strict = false, }) end @@ -723,7 +723,7 @@ end --- @inlinedoc --- --- Priority for the applied extmark. ---- (Default: `vim.highlight.priorities.semantic_tokens + 3`) +--- (Default: `vim.hl.priorities.semantic_tokens + 3`) --- @field priority? integer --- Highlight a semantic token. @@ -752,7 +752,7 @@ function M.highlight_token(token, bufnr, client_id, hl_group, opts) end opts = opts or {} - local priority = opts.priority or vim.highlight.priorities.semantic_tokens + 3 + local priority = opts.priority or vim.hl.priorities.semantic_tokens + 3 vim.api.nvim_buf_set_extmark(bufnr, state.namespace, token.line, token.start_col, { hl_group = hl_group, diff --git a/runtime/lua/vim/lsp/util.lua b/runtime/lua/vim/lsp/util.lua index 2c28633e3c..2e9c71cf38 100644 --- a/runtime/lua/vim/lsp/util.lua +++ b/runtime/lua/vim/lsp/util.lua @@ -2,7 +2,6 @@ local protocol = require('vim.lsp.protocol') local validate = vim.validate local api = vim.api local list_extend = vim.list_extend -local highlight = vim.highlight local uv = vim.uv local M = {} @@ -1716,13 +1715,13 @@ do --[[ References ]] [protocol.DocumentHighlightKind.Write] = 'LspReferenceWrite', } local kind = reference['kind'] or protocol.DocumentHighlightKind.Text - highlight.range( + vim.hl.range( bufnr, reference_ns, document_highlight_kind[kind], { start_line, start_idx }, { end_line, end_idx }, - { priority = vim.highlight.priorities.user } + { priority = vim.hl.priorities.user } ) end end diff --git a/runtime/lua/vim/treesitter/highlighter.lua b/runtime/lua/vim/treesitter/highlighter.lua index a94c408f4e..7bdcdc774a 100644 --- a/runtime/lua/vim/treesitter/highlighter.lua +++ b/runtime/lua/vim/treesitter/highlighter.lua @@ -328,7 +328,7 @@ local function on_line_impl(self, buf, line, is_spell_nav) -- The "priority" attribute can be set at the pattern level or on a particular capture local priority = ( tonumber(metadata.priority or metadata[capture] and metadata[capture].priority) - or vim.highlight.priorities.treesitter + or vim.hl.priorities.treesitter ) + spell_pri_offset -- The "conceal" attribute can be set at the pattern level or on a particular capture diff --git a/scripts/gen_vimdoc.lua b/scripts/gen_vimdoc.lua index 8908097397..f7c95e222d 100755 --- a/scripts/gen_vimdoc.lua +++ b/scripts/gen_vimdoc.lua @@ -135,7 +135,7 @@ local config = { lua = { filename = 'lua.txt', section_order = { - 'highlight.lua', + 'hl.lua', 'diff.lua', 'mpack.lua', 'json.lua', @@ -174,7 +174,7 @@ local config = { 'runtime/lua/vim/filetype.lua', 'runtime/lua/vim/keymap.lua', 'runtime/lua/vim/fs.lua', - 'runtime/lua/vim/highlight.lua', + 'runtime/lua/vim/hl.lua', 'runtime/lua/vim/secure.lua', 'runtime/lua/vim/version.lua', 'runtime/lua/vim/_inspector.lua', @@ -221,7 +221,7 @@ local config = { end if contains(name, { - 'highlight', + 'hl', 'mpack', 'json', 'base64', diff --git a/test/functional/lua/highlight_spec.lua b/test/functional/lua/highlight_spec.lua deleted file mode 100644 index c048949df8..0000000000 --- a/test/functional/lua/highlight_spec.lua +++ /dev/null @@ -1,175 +0,0 @@ -local t = require('test.testutil') -local n = require('test.functional.testnvim')() -local Screen = require('test.functional.ui.screen') - -local exec_lua = n.exec_lua -local eq = t.eq -local eval = n.eval -local command = n.command -local clear = n.clear -local api = n.api - -describe('vim.highlight.range', function() - local screen - - before_each(function() - clear() - screen = Screen.new(60, 6) - screen:add_extra_attr_ids({ - [100] = { foreground = Screen.colors.Blue, background = Screen.colors.Yellow, bold = true }, - }) - screen:attach() - api.nvim_set_option_value('list', true, {}) - api.nvim_set_option_value('listchars', 'eol:$', {}) - api.nvim_buf_set_lines(0, 0, -1, true, { - 'asdfghjkl', - '«口=口»', - 'qwertyuiop', - '口口=口口', - 'zxcvbnm', - }) - end) - - it('works with charwise selection', function() - exec_lua(function() - local ns = vim.api.nvim_create_namespace('') - vim.highlight.range(0, ns, 'Search', { 1, 5 }, { 3, 10 }) - end) - screen:expect([[ - ^asdfghjkl{1:$} | - «口{10:=口»}{100:$} | - {10:qwertyuiop}{100:$} | - {10:口口=口}口{1:$} | - zxcvbnm{1:$} | - | - ]]) - end) - - it('works with linewise selection', function() - exec_lua(function() - local ns = vim.api.nvim_create_namespace('') - vim.highlight.range(0, ns, 'Search', { 0, 0 }, { 4, 0 }, { regtype = 'V' }) - end) - screen:expect([[ - {10:^asdfghjkl}{100:$} | - {10:«口=口»}{100:$} | - {10:qwertyuiop}{100:$} | - {10:口口=口口}{100:$} | - {10:zxcvbnm}{100:$} | - | - ]]) - end) - - it('works with blockwise selection', function() - exec_lua(function() - local ns = vim.api.nvim_create_namespace('') - vim.highlight.range(0, ns, 'Search', { 0, 0 }, { 4, 4 }, { regtype = '\022' }) - end) - screen:expect([[ - {10:^asdf}ghjkl{1:$} | - {10:«口=}口»{1:$} | - {10:qwer}tyuiop{1:$} | - {10:口口}=口口{1:$} | - {10:zxcv}bnm{1:$} | - | - ]]) - end) - - it('works with blockwise selection with width', function() - exec_lua(function() - local ns = vim.api.nvim_create_namespace('') - vim.highlight.range(0, ns, 'Search', { 0, 4 }, { 4, 7 }, { regtype = '\0226' }) - end) - screen:expect([[ - ^asdf{10:ghjkl}{1:$} | - «口={10:口»}{1:$} | - qwer{10:tyuiop}{1:$} | - 口口{10:=口口}{1:$} | - zxcv{10:bnm}{1:$} | - | - ]]) - end) - - it('can use -1 or v:maxcol to indicate end of line', function() - exec_lua(function() - local ns = vim.api.nvim_create_namespace('') - vim.highlight.range(0, ns, 'Search', { 0, 4 }, { 1, -1 }, {}) - vim.highlight.range(0, ns, 'Search', { 2, 6 }, { 3, vim.v.maxcol }, {}) - end) - screen:expect([[ - ^asdf{10:ghjkl}{100:$} | - {10:«口=口»}{100:$} | - qwerty{10:uiop}{100:$} | - {10:口口=口口}{1:$} | - zxcvbnm{1:$} | - | - ]]) - end) -end) - -describe('vim.highlight.on_yank', function() - before_each(function() - clear() - end) - - it('does not show errors even if buffer is wiped before timeout', function() - command('new') - exec_lua(function() - vim.highlight.on_yank({ - timeout = 10, - on_macro = true, - event = { operator = 'y', regtype = 'v' }, - }) - vim.cmd('bwipeout!') - end) - vim.uv.sleep(10) - n.feed('') -- avoid hang if error message exists - eq('', eval('v:errmsg')) - end) - - it('does not close timer twice', function() - exec_lua(function() - vim.highlight.on_yank({ timeout = 10, on_macro = true, event = { operator = 'y' } }) - vim.uv.sleep(10) - vim.schedule(function() - vim.highlight.on_yank({ timeout = 0, on_macro = true, event = { operator = 'y' } }) - end) - end) - eq('', eval('v:errmsg')) - end) - - it('does not show in another window', function() - command('vsplit') - exec_lua(function() - vim.api.nvim_buf_set_mark(0, '[', 1, 1, {}) - vim.api.nvim_buf_set_mark(0, ']', 1, 1, {}) - vim.highlight.on_yank({ timeout = math.huge, on_macro = true, event = { operator = 'y' } }) - end) - local ns = api.nvim_create_namespace('hlyank') - local win = api.nvim_get_current_win() - eq({ win }, api.nvim__ns_get(ns).wins) - command('wincmd w') - eq({ win }, api.nvim__ns_get(ns).wins) - end) - - it('removes old highlight if new one is created before old one times out', function() - command('vnew') - exec_lua(function() - vim.api.nvim_buf_set_mark(0, '[', 1, 1, {}) - vim.api.nvim_buf_set_mark(0, ']', 1, 1, {}) - vim.highlight.on_yank({ timeout = math.huge, on_macro = true, event = { operator = 'y' } }) - end) - local ns = api.nvim_create_namespace('hlyank') - eq(api.nvim_get_current_win(), api.nvim__ns_get(ns).wins[1]) - command('wincmd w') - exec_lua(function() - vim.api.nvim_buf_set_mark(0, '[', 1, 1, {}) - vim.api.nvim_buf_set_mark(0, ']', 1, 1, {}) - vim.highlight.on_yank({ timeout = math.huge, on_macro = true, event = { operator = 'y' } }) - end) - local win = api.nvim_get_current_win() - eq({ win }, api.nvim__ns_get(ns).wins) - command('wincmd w') - eq({ win }, api.nvim__ns_get(ns).wins) - end) -end) diff --git a/test/functional/lua/hl_spec.lua b/test/functional/lua/hl_spec.lua new file mode 100644 index 0000000000..a123c79ffb --- /dev/null +++ b/test/functional/lua/hl_spec.lua @@ -0,0 +1,175 @@ +local t = require('test.testutil') +local n = require('test.functional.testnvim')() +local Screen = require('test.functional.ui.screen') + +local exec_lua = n.exec_lua +local eq = t.eq +local eval = n.eval +local command = n.command +local clear = n.clear +local api = n.api + +describe('vim.hl.range', function() + local screen + + before_each(function() + clear() + screen = Screen.new(60, 6) + screen:add_extra_attr_ids({ + [100] = { foreground = Screen.colors.Blue, background = Screen.colors.Yellow, bold = true }, + }) + screen:attach() + api.nvim_set_option_value('list', true, {}) + api.nvim_set_option_value('listchars', 'eol:$', {}) + api.nvim_buf_set_lines(0, 0, -1, true, { + 'asdfghjkl', + '«口=口»', + 'qwertyuiop', + '口口=口口', + 'zxcvbnm', + }) + end) + + it('works with charwise selection', function() + exec_lua(function() + local ns = vim.api.nvim_create_namespace('') + vim.hl.range(0, ns, 'Search', { 1, 5 }, { 3, 10 }) + end) + screen:expect([[ + ^asdfghjkl{1:$} | + «口{10:=口»}{100:$} | + {10:qwertyuiop}{100:$} | + {10:口口=口}口{1:$} | + zxcvbnm{1:$} | + | + ]]) + end) + + it('works with linewise selection', function() + exec_lua(function() + local ns = vim.api.nvim_create_namespace('') + vim.hl.range(0, ns, 'Search', { 0, 0 }, { 4, 0 }, { regtype = 'V' }) + end) + screen:expect([[ + {10:^asdfghjkl}{100:$} | + {10:«口=口»}{100:$} | + {10:qwertyuiop}{100:$} | + {10:口口=口口}{100:$} | + {10:zxcvbnm}{100:$} | + | + ]]) + end) + + it('works with blockwise selection', function() + exec_lua(function() + local ns = vim.api.nvim_create_namespace('') + vim.hl.range(0, ns, 'Search', { 0, 0 }, { 4, 4 }, { regtype = '\022' }) + end) + screen:expect([[ + {10:^asdf}ghjkl{1:$} | + {10:«口=}口»{1:$} | + {10:qwer}tyuiop{1:$} | + {10:口口}=口口{1:$} | + {10:zxcv}bnm{1:$} | + | + ]]) + end) + + it('works with blockwise selection with width', function() + exec_lua(function() + local ns = vim.api.nvim_create_namespace('') + vim.hl.range(0, ns, 'Search', { 0, 4 }, { 4, 7 }, { regtype = '\0226' }) + end) + screen:expect([[ + ^asdf{10:ghjkl}{1:$} | + «口={10:口»}{1:$} | + qwer{10:tyuiop}{1:$} | + 口口{10:=口口}{1:$} | + zxcv{10:bnm}{1:$} | + | + ]]) + end) + + it('can use -1 or v:maxcol to indicate end of line', function() + exec_lua(function() + local ns = vim.api.nvim_create_namespace('') + vim.hl.range(0, ns, 'Search', { 0, 4 }, { 1, -1 }, {}) + vim.hl.range(0, ns, 'Search', { 2, 6 }, { 3, vim.v.maxcol }, {}) + end) + screen:expect([[ + ^asdf{10:ghjkl}{100:$} | + {10:«口=口»}{100:$} | + qwerty{10:uiop}{100:$} | + {10:口口=口口}{1:$} | + zxcvbnm{1:$} | + | + ]]) + end) +end) + +describe('vim.hl.on_yank', function() + before_each(function() + clear() + end) + + it('does not show errors even if buffer is wiped before timeout', function() + command('new') + exec_lua(function() + vim.hl.on_yank({ + timeout = 10, + on_macro = true, + event = { operator = 'y', regtype = 'v' }, + }) + vim.cmd('bwipeout!') + end) + vim.uv.sleep(10) + n.feed('') -- avoid hang if error message exists + eq('', eval('v:errmsg')) + end) + + it('does not close timer twice', function() + exec_lua(function() + vim.hl.on_yank({ timeout = 10, on_macro = true, event = { operator = 'y' } }) + vim.uv.sleep(10) + vim.schedule(function() + vim.hl.on_yank({ timeout = 0, on_macro = true, event = { operator = 'y' } }) + end) + end) + eq('', eval('v:errmsg')) + end) + + it('does not show in another window', function() + command('vsplit') + exec_lua(function() + vim.api.nvim_buf_set_mark(0, '[', 1, 1, {}) + vim.api.nvim_buf_set_mark(0, ']', 1, 1, {}) + vim.hl.on_yank({ timeout = math.huge, on_macro = true, event = { operator = 'y' } }) + end) + local ns = api.nvim_create_namespace('hlyank') + local win = api.nvim_get_current_win() + eq({ win }, api.nvim__ns_get(ns).wins) + command('wincmd w') + eq({ win }, api.nvim__ns_get(ns).wins) + end) + + it('removes old highlight if new one is created before old one times out', function() + command('vnew') + exec_lua(function() + vim.api.nvim_buf_set_mark(0, '[', 1, 1, {}) + vim.api.nvim_buf_set_mark(0, ']', 1, 1, {}) + vim.hl.on_yank({ timeout = math.huge, on_macro = true, event = { operator = 'y' } }) + end) + local ns = api.nvim_create_namespace('hlyank') + eq(api.nvim_get_current_win(), api.nvim__ns_get(ns).wins[1]) + command('wincmd w') + exec_lua(function() + vim.api.nvim_buf_set_mark(0, '[', 1, 1, {}) + vim.api.nvim_buf_set_mark(0, ']', 1, 1, {}) + vim.hl.on_yank({ timeout = math.huge, on_macro = true, event = { operator = 'y' } }) + end) + local win = api.nvim_get_current_win() + eq({ win }, api.nvim__ns_get(ns).wins) + command('wincmd w') + eq({ win }, api.nvim__ns_get(ns).wins) + end) +end) -- cgit