vim-patch:9.1.1145: multi-line completion has wrong indentation for last line (#32625)

Problem:  When expanding omni completion items with newlines (e.g.
          `then\n\t\nend`), the end statement gets wrong indentation.
Solution: Add OPENLINE_FORCE_INDENT flag to make open_line() use
          second_line_indent directly (glepnir)

closes: vim/vim#16614

5090a1fecb
This commit is contained in:
glepnir
2025-02-25 14:30:21 +08:00
committed by GitHub
parent 095c0876c2
commit c9a2b16c48
5 changed files with 78 additions and 10 deletions

View File

@@ -1071,6 +1071,7 @@ bool copy_indent(int size, char *src)
/// OPENLINE_KEEPTRAIL keep trailing spaces /// OPENLINE_KEEPTRAIL keep trailing spaces
/// OPENLINE_MARKFIX adjust mark positions after the line break /// OPENLINE_MARKFIX adjust mark positions after the line break
/// OPENLINE_COM_LIST format comments with list or 2nd line indent /// OPENLINE_COM_LIST format comments with list or 2nd line indent
/// OPENLINE_FORCE_INDENT set indent from second_line_indent, ignore 'autoindent'
/// ///
/// "second_line_indent": indent for after ^^D in Insert mode or if flag /// "second_line_indent": indent for after ^^D in Insert mode or if flag
/// OPENLINE_COM_LIST /// OPENLINE_COM_LIST
@@ -1162,9 +1163,11 @@ bool open_line(int dir, int flags, int second_line_indent, bool *did_do_comment)
trunc_line = true; trunc_line = true;
} }
// If 'autoindent' and/or 'smartindent' is set, try to figure out what if ((flags & OPENLINE_FORCE_INDENT)) {
// indent to use for the new line. newindent = second_line_indent;
if (curbuf->b_p_ai || do_si) { } else if (curbuf->b_p_ai || do_si) {
// If 'autoindent' and/or 'smartindent' is set, try to figure out what
// indent to use for the new line.
// count white space on current line // count white space on current line
newindent = indent_size_ts(saved_line, curbuf->b_p_ts, curbuf->b_p_vts_array); newindent = indent_size_ts(saved_line, curbuf->b_p_ts, curbuf->b_p_vts_array);
if (newindent == 0 && !(flags & OPENLINE_COM_LIST)) { if (newindent == 0 && !(flags & OPENLINE_COM_LIST)) {

View File

@@ -7,12 +7,13 @@
/// flags for open_line() /// flags for open_line()
enum { enum {
OPENLINE_DELSPACES = 0x01, ///< delete spaces after cursor OPENLINE_DELSPACES = 0x01, ///< delete spaces after cursor
OPENLINE_DO_COM = 0x02, ///< format comments OPENLINE_DO_COM = 0x02, ///< format comments
OPENLINE_KEEPTRAIL = 0x04, ///< keep trailing spaces OPENLINE_KEEPTRAIL = 0x04, ///< keep trailing spaces
OPENLINE_MARKFIX = 0x08, ///< fix mark positions OPENLINE_MARKFIX = 0x08, ///< fix mark positions
OPENLINE_COM_LIST = 0x10, ///< format comments with list/2nd line indent OPENLINE_COM_LIST = 0x10, ///< format comments with list/2nd line indent
OPENLINE_FORMAT = 0x20, ///< formatting long comment OPENLINE_FORMAT = 0x20, ///< formatting long comment
OPENLINE_FORCE_INDENT = 0x40, ///< use second_line_indent without indent logic
}; };
#ifdef INCLUDE_GENERATED_DECLARATIONS #ifdef INCLUDE_GENERATED_DECLARATIONS

View File

@@ -3833,6 +3833,7 @@ static void ins_compl_expand_multiple(char *str)
{ {
char *start = str; char *start = str;
char *curr = str; char *curr = str;
int base_indent = get_indent();
while (*curr != NUL) { while (*curr != NUL) {
if (*curr == '\n') { if (*curr == '\n') {
// Insert the text chunk before newline // Insert the text chunk before newline
@@ -3841,7 +3842,7 @@ static void ins_compl_expand_multiple(char *str)
} }
// Handle newline // Handle newline
open_line(FORWARD, OPENLINE_KEEPTRAIL, false, NULL); open_line(FORWARD, OPENLINE_KEEPTRAIL | OPENLINE_FORCE_INDENT, base_indent, NULL);
start = curr + 1; start = curr + 1;
} }
curr++; curr++;

View File

@@ -6042,6 +6042,52 @@ describe('builtin popupmenu', function()
{2:-- }{5:match 1 of 3} | {2:-- }{5:match 1 of 3} |
]]) ]])
feed('<C-E><ESC>') feed('<C-E><ESC>')
command('setlocal autoindent shiftwidth=2 tabstop=2')
feed('Slocal a = <C-X><C-O>')
screen:expect([[
local a = {8:func ()} |
{8: } |
{8:end}^ |
{1:~ }{s: function () }{1: }|
{1:~ }{n: foobar }{1: }|
{1:~ }{n: 你好^@ ^@我好 }{1: }|
{1:~ }|*13
{2:-- }{5:match 1 of 3} |
]])
feed('<C-Y>')
screen:expect([[
local a = {8:func ()} |
{8: } |
end^ |
{1:~ }|*16
{2:-- INSERT --} |
]])
feed('<ESC>kAlocal b = <C-X><C-O>')
screen:expect([[
local a = {8:func ()} |
local b = {8:func ()} |
{8: } |
{8: end}^ |
end {s: function () } |
{1:~ }{n: foobar }{1: }|
{1:~ }{n: 你好^@ ^@我好 }{1: }|
{1:~ }|*12
{2:-- }{5:match 1 of 3} |
]])
feed('<C-Y>')
screen:expect([[
local a = {8:func ()} |
local b = {8:func ()} |
{8: } |
end^ |
end |
{1:~ }|*14
{2:-- INSERT --} |
]])
end) end)
end end
end end

View File

@@ -1937,6 +1937,23 @@ func Test_pum_complete_with_special_characters()
call VerifyScreenDump(buf, 'Test_pum_with_special_characters_08', {}) call VerifyScreenDump(buf, 'Test_pum_with_special_characters_08', {})
call term_sendkeys(buf, "\<C-E>\<Esc>") call term_sendkeys(buf, "\<C-E>\<Esc>")
call term_sendkeys(buf, ":setlocal autoindent tabstop=2 shiftwidth=2\<CR>")
call term_sendkeys(buf, "Slocal a = \<C-X>\<C-O>")
call TermWait(buf, 50)
call VerifyScreenDump(buf, 'Test_pum_with_special_characters_09', {})
call term_sendkeys(buf, "\<C-Y>")
call TermWait(buf, 50)
call VerifyScreenDump(buf, 'Test_pum_with_special_characters_10', {})
call term_sendkeys(buf, "\<ESC>kAlocal b = \<C-X>\<C-O>")
call TermWait(buf, 50)
call VerifyScreenDump(buf, 'Test_pum_with_special_characters_11', {})
call term_sendkeys(buf, "\<C-Y>")
call TermWait(buf, 50)
call VerifyScreenDump(buf, 'Test_pum_with_special_characters_12', {})
call StopVimInTerminal(buf) call StopVimInTerminal(buf)
endfunc endfunc