mirror of
https://github.com/neovim/neovim.git
synced 2026-03-31 04:42:03 +00:00
feat(snippet): highlight active tabstop (#35378)
This commit is contained in:
@@ -134,6 +134,7 @@ hi('DiagnosticDeprecated', { sp = 'Red', strikethrough = true, cterm =
|
||||
hi('DiagnosticUnnecessary', { link = 'Comment' })
|
||||
hi('LspInlayHint', { link = 'NonText' })
|
||||
hi('SnippetTabstop', { link = 'Visual' })
|
||||
hi('SnippetTabstopActive', { link = 'SnippetTabstop' })
|
||||
|
||||
-- Text
|
||||
hi('@markup.raw', { link = 'Comment' })
|
||||
|
||||
@@ -4354,7 +4354,8 @@ vim.snippet.expand({input}) *vim.snippet.expand()*
|
||||
https://microsoft.github.io/language-server-protocol/specification/#snippet_syntax
|
||||
for the specification of valid input.
|
||||
|
||||
Tabstops are highlighted with |hl-SnippetTabstop|.
|
||||
Tabstops are highlighted with |hl-SnippetTabstop| and
|
||||
|hl-SnippetTabstopActive|.
|
||||
|
||||
Parameters: ~
|
||||
• {input} (`string`)
|
||||
|
||||
@@ -192,6 +192,7 @@ HIGHLIGHTS
|
||||
|
||||
• |hl-DiffTextAdd| highlights added text within a changed line.
|
||||
• |hl-StderrMsg| |hl-StdoutMsg|
|
||||
• |hl-SnippetTabstopActive| highlights the currently active tabstop.
|
||||
|
||||
LSP
|
||||
|
||||
|
||||
@@ -5343,6 +5343,9 @@ Search Last search pattern highlighting (see 'hlsearch').
|
||||
Also used for similar items that need to stand out.
|
||||
*hl-SnippetTabstop*
|
||||
SnippetTabstop Tabstops in snippets. |vim.snippet|
|
||||
*hl-SnippetTabstopActive*
|
||||
SnippetTabstopActive
|
||||
The currently active tabstop. |vim.snippet|
|
||||
*hl-SpecialKey*
|
||||
SpecialKey Unprintable characters: Text displayed differently from what
|
||||
it really is. But not 'listchars' whitespace. |hl-Whitespace|
|
||||
|
||||
@@ -2,6 +2,7 @@ local G = vim.lsp._snippet_grammar
|
||||
local snippet_group = vim.api.nvim_create_augroup('nvim.snippet', {})
|
||||
local snippet_ns = vim.api.nvim_create_namespace('nvim.snippet')
|
||||
local hl_group = 'SnippetTabstop'
|
||||
local hl_group_active = 'SnippetTabstopActive'
|
||||
|
||||
--- Returns the 0-based cursor position.
|
||||
---
|
||||
@@ -124,7 +125,7 @@ function Tabstop.new(index, bufnr, placement, range, choices)
|
||||
end_right_gravity = false,
|
||||
end_line = range[3],
|
||||
end_col = range[4],
|
||||
hl_group = hl_group,
|
||||
hl_group = index == 1 and hl_group_active or hl_group,
|
||||
})
|
||||
|
||||
local self = setmetatable({
|
||||
@@ -168,19 +169,22 @@ function Tabstop:set_text(text)
|
||||
end
|
||||
|
||||
---@alias (private) vim.snippet.TabStopGravity
|
||||
--- | "expand" Expand the (usually current) tabstop on text insert
|
||||
--- | "expand" Expand the current tabstop on text insert
|
||||
--- | "lock" The tabstop should NOT move on text insert
|
||||
--- | "shift" The tabstop should move on text insert (default)
|
||||
|
||||
--- Sets the right gravity of the tabstop's extmark.
|
||||
--- Sets the active highlight group for current ("expand") tabstops
|
||||
---
|
||||
---@package
|
||||
---@param target vim.snippet.TabStopGravity
|
||||
function Tabstop:set_gravity(target)
|
||||
local hl = hl_group
|
||||
local right_gravity = true
|
||||
local end_right_gravity = true
|
||||
|
||||
if target == 'expand' then
|
||||
hl = hl_group_active
|
||||
right_gravity = false
|
||||
end_right_gravity = true
|
||||
elseif target == 'lock' then
|
||||
@@ -189,12 +193,13 @@ function Tabstop:set_gravity(target)
|
||||
end
|
||||
|
||||
local range = self:get_range()
|
||||
vim.api.nvim_buf_del_extmark(self.bufnr, snippet_ns, self.extmark_id)
|
||||
self.extmark_id = vim.api.nvim_buf_set_extmark(self.bufnr, snippet_ns, range[1], range[2], {
|
||||
right_gravity = right_gravity,
|
||||
end_right_gravity = end_right_gravity,
|
||||
end_line = range[3],
|
||||
end_col = range[4],
|
||||
hl_group = hl_group,
|
||||
hl_group = hl,
|
||||
})
|
||||
end
|
||||
|
||||
@@ -469,7 +474,7 @@ end
|
||||
--- Refer to https://microsoft.github.io/language-server-protocol/specification/#snippet_syntax
|
||||
--- for the specification of valid input.
|
||||
---
|
||||
--- Tabstops are highlighted with |hl-SnippetTabstop|.
|
||||
--- Tabstops are highlighted with |hl-SnippetTabstop| and |hl-SnippetTabstopActive|.
|
||||
---
|
||||
--- @param input string
|
||||
function M.expand(input)
|
||||
|
||||
@@ -221,6 +221,7 @@ static const char *highlight_init_both[] = {
|
||||
"default link LspReferenceTarget LspReferenceText",
|
||||
"default link LspSignatureActiveParameter Visual",
|
||||
"default link SnippetTabstop Visual",
|
||||
"default link SnippetTabstopActive SnippetTabstop",
|
||||
|
||||
// Diagnostic
|
||||
"default link DiagnosticFloatingError DiagnosticError",
|
||||
|
||||
@@ -116,6 +116,20 @@ describe('vim.snippet', function()
|
||||
test_expand_success({ 'print($UNKNOWN)' }, { 'print(UNKNOWN)' })
|
||||
end)
|
||||
|
||||
it('highlights active tabstop with SnippetTabstopActive', function()
|
||||
local function get_extmark_details(col, end_col)
|
||||
return api.nvim_buf_get_extmarks(0, -1, { 0, col }, { 0, end_col }, { details = true })[1][4]
|
||||
end
|
||||
|
||||
test_expand_success({ 'local ${1:name} = ${2:value}' }, { 'local name = value' })
|
||||
eq('SnippetTabstopActive', get_extmark_details(6, 10).hl_group)
|
||||
eq('SnippetTabstop', get_extmark_details(13, 18).hl_group)
|
||||
feed('<Tab>')
|
||||
poke_eventloop()
|
||||
eq('SnippetTabstop', get_extmark_details(6, 10).hl_group)
|
||||
eq('SnippetTabstopActive', get_extmark_details(13, 18).hl_group)
|
||||
end)
|
||||
|
||||
it('does not jump outside snippet range', function()
|
||||
test_expand_success({ 'function $1($2)', ' $0', 'end' }, { 'function ()', ' ', 'end' })
|
||||
eq(false, exec_lua('return vim.snippet.active({ direction = -1 })'))
|
||||
|
||||
Reference in New Issue
Block a user