fix(snippet): wrong indentation when snippet contains "^" #32970

## Problem
The pattern used to match indentation is wrong as can be seen in

```lua
-- current pattern doesn't match starting space
print(vim.inspect(("   xyz"):match("(^%s+)%S")))
-- nil

-- instead, it matches characters `^ ` in text
print(vim.inspect(("x^ yz"):match("(^%s+)%S")))
-- "^ "

-- indentation could've been matched by, however not required
print(vim.inspect(("   xyz"):match("^(%s+)%S")))
-- "   "
```

## Solution
We don't even need to modify `base_indent` at every line. If every line's indentation is calculated by the previous line's indentation (which already has starting indentation) added to the starting indentation, we see that indentation is multiplied on every line.

Hence, we only add the starting line indentation to every line.
This commit is contained in:
Avinash Thakur
2025-03-19 20:17:59 +05:30
committed by GitHub
parent 42db8b1759
commit 424f4cc038
2 changed files with 5 additions and 6 deletions

View File

@ -420,6 +420,7 @@ end
function M.expand(input)
local snippet = G.parse(input)
local snippet_text = {}
---@type string
local base_indent = vim.api.nvim_get_current_line():match('^%s*') or ''
-- Get the placeholders we should use for each tabstop index.
@ -454,12 +455,6 @@ function M.expand(input)
---
--- @param text string|string[]
local function append_to_snippet(text)
local snippet_lines = text_to_lines(snippet_text)
-- Get the base indentation based on the current line and the last line of the snippet.
if #snippet_lines > 0 then
base_indent = base_indent .. (snippet_lines[#snippet_lines]:match('(^%s+)%S') or '') --- @type string
end
local shiftwidth = vim.fn.shiftwidth()
local curbuf = vim.api.nvim_get_current_buf()
local expandtab = vim.bo[curbuf].expandtab

View File

@ -79,6 +79,10 @@ describe('vim.snippet', function()
-- Regression test: #29658
api.nvim_buf_set_lines(curbuf, 0, -1, false, {})
test_expand_success({ '${1:foo^bar}\n' }, { 'foo^bar', '' })
-- Regression test: #30950
api.nvim_buf_set_lines(curbuf, 0, -1, false, {})
test_expand_success({ 'a^ b$1', 'b$2', 'd' }, { 'a^ b', 'b', 'd' })
end)
it('replaces tabs with spaces when expandtab is set', function()