From: Hirohito Higashi Date: Thu, 28 May 2026 19:18:38 +0000 (+0000) Subject: patch 9.2.0547: "%v" in 'errorformat' is affected by 'tabstop' X-Git-Tag: v9.2.0547^0 X-Git-Url: http://git.ipfire.org/gitweb/index.cgi?a=commitdiff_plain;h=44dcad20f2781ce5c1bd9a851212377859cc5bea;p=thirdparty%2Fvim.git patch 9.2.0547: "%v" in 'errorformat' is affected by 'tabstop' Problem: The "%v" item in 'errorformat' interprets the reported screen column using the buffer's 'tabstop', so the cursor jumps to the wrong column when 'tabstop' is not 8 (vimpostor). Solution: When resolving a "%v" column, always count a as 8 screen columns, independent of 'tabstop', matching the column numbers reported by compilers; keep the multi-byte handling. Also use "%v" in the gcc compiler file and update the documentation (Hirohito Higashi). fixes: #20321 closes: #20359 Co-Authored-By: vimpostor <21310755+vimpostor@users.noreply.github.com> Co-Authored-By: Claude Opus 4.7 (1M context) Signed-off-by: Hirohito Higashi Signed-off-by: Christian Brabandt --- diff --git a/runtime/compiler/gcc.vim b/runtime/compiler/gcc.vim index 1d5900eb27..6fe751c50a 100644 --- a/runtime/compiler/gcc.vim +++ b/runtime/compiler/gcc.vim @@ -7,6 +7,7 @@ " added line suggested by Anton Lindqvist 2016 Mar 31 " 2024 Apr 03 by The Vim Project (removed :CompilerSet definition) " 2025 Dec 17 by The Vim Project (correctly parse: 'make: *** [Makefile:2: all] Error 1') +" 2026 May 28 by The Vim Project (Use %v to parse column number) if exists("current_compiler") finish @@ -24,9 +25,9 @@ CompilerSet errorformat= \\"%f\"%*\\D%l:\ %m, \%-G%f:%l:\ %trror:\ (Each\ undeclared\ identifier\ is\ reported\ only\ once, \%-G%f:%l:\ %trror:\ for\ each\ function\ it\ appears\ in.), - \%f:%l:%c:\ %trror:\ %m, - \%f:%l:%c:\ %tarning:\ %m, - \%f:%l:%c:\ %m, + \%f:%l:%v:\ %trror:\ %m, + \%f:%l:%v:\ %tarning:\ %m, + \%f:%l:%v:\ %m, \%f:%l:\ %trror:\ %m, \%f:%l:\ %tarning:\ %m, \%f:%l:\ %m, diff --git a/runtime/doc/quickfix.txt b/runtime/doc/quickfix.txt index 581d00b7a7..4b24d12980 100644 --- a/runtime/doc/quickfix.txt +++ b/runtime/doc/quickfix.txt @@ -1,4 +1,4 @@ -*quickfix.txt* For Vim version 9.2. Last change: 2026 Feb 14 +*quickfix.txt* For Vim version 9.2. Last change: 2026 May 28 VIM REFERENCE MANUAL by Bram Moolenaar @@ -1821,9 +1821,9 @@ Basic items %c column number (finds a number representing character column of the error, byte index, a is 1 character column) - %v virtual column number (finds a number representing - screen column of the error (1 == 8 screen - columns)) + %v virtual column number (finds a number representing the + screen column of the error, where a is always 8 + screen columns regardless of 'tabstop') %k end column number (finds a number representing the character column of the error, byte index, or a number representing screen end column of the error if diff --git a/src/quickfix.c b/src/quickfix.c index 3fe015ee58..2470902fd1 100644 --- a/src/quickfix.c +++ b/src/quickfix.c @@ -3626,6 +3626,32 @@ qf_jump_edit_buffer( return retval; } +/* + * Return the byte index in the current line for screen column "vcol" + * (zero-based). A is always counted as 8 screen columns, matching the + * column numbers compilers report for the "%v" item in 'errorformat', + * regardless of the buffer's 'tabstop'. + */ + static int +qf_screen_col_to_idx(colnr_T vcol) +{ + char_u *line = ml_get_curline(); + char_u *p = line; + colnr_T col = 0; + + while (*p != NUL && col < vcol) + { + if (*p == TAB) + col += 8 - (col % 8); + else + col += ptr2cells(p); + if (col > vcol) + break; + MB_PTR_ADV(p); + } + return (int)(p - line); +} + /* * Go to the error line in the current file using either line/column number or * a search pattern. @@ -3653,7 +3679,7 @@ qf_jump_goto_line( { curwin->w_cursor.coladd = 0; if (qf_viscol == TRUE) - coladvance(qf_col - 1); + curwin->w_cursor.col = qf_screen_col_to_idx(qf_col - 1); else curwin->w_cursor.col = qf_col - 1; curwin->w_set_curswant = true; diff --git a/src/testdir/test_quickfix.vim b/src/testdir/test_quickfix.vim index e1dbaa7c59..c656d205f0 100644 --- a/src/testdir/test_quickfix.vim +++ b/src/testdir/test_quickfix.vim @@ -5004,6 +5004,34 @@ func Test_viscol() set efm& endfunc +" Test that '%v' is not affected by 'tabstop': a is always counted as +" 8 screen columns, matching the column numbers reported by compilers. +func Test_viscol_tabstop() + enew + call writefile(["\tABCDEFGH"], 'Xfile1', 'D') + edit Xfile1 + set efm=%f:%l:%v:%m + + " gcc reports column 9 for 'A' (the expands to 8 columns). The jump + " must land on 'A' (byte 2) for any 'tabstop' value. + for ts in [8, 4, 2, 13] + exe 'setlocal tabstop=' .. ts + cexpr "Xfile1:1:9:XX" + call assert_equal(2, col('.'), 'tabstop=' .. ts) + endfor + + " A multi-byte character after the tab: 'ä' is 2 bytes but 1 screen cell, + " so screen column 10 is the next character 'b' (byte 4). + call writefile(["\täbc"], 'Xfile1') + edit! Xfile1 + setlocal tabstop=4 + cexpr "Xfile1:1:10:XX" + call assert_equal(4, col('.')) + + enew | only + set efm& +endfunc + " Test for the quickfix window buffer func Xqfbuf_test(cchar) call s:setup_commands(a:cchar) diff --git a/src/version.c b/src/version.c index 4382b5fddb..5fda77f1bc 100644 --- a/src/version.c +++ b/src/version.c @@ -729,6 +729,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 547, /**/ 546, /**/