From: taylor.fish Date: Wed, 28 Jan 2026 22:04:21 +0000 (+0000) Subject: runtime(rust): Fix Rust indentation when string contains "if" X-Git-Tag: v9.1.2113~2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=663d809194b471ebbdd9e270086c6d0ca53da8fd;p=thirdparty%2Fvim.git runtime(rust): Fix Rust indentation when string contains "if" indent/rust.vim behaves incorrectly when a string literal contains the substring "if". For example, in this code: let x = " motif "; struct X { } indent/rust.vim thinks that the closing "}" should line up with "motif". This patch fixes the issue by checking whether the "if" is in a string literal or comment before considering it to be a match for a subsequent brace (and also by requiring it to start on a word boundary). Add an indent test to ensure this does not regress. closes: #19265 Signed-off-by: taylor.fish Signed-off-by: Christian Brabandt --- diff --git a/runtime/indent/rust.vim b/runtime/indent/rust.vim index 30206be435..f449a19de2 100644 --- a/runtime/indent/rust.vim +++ b/runtime/indent/rust.vim @@ -5,6 +5,7 @@ " 2024 Jul 04 by Vim Project: use shiftwidth() instead of hard-coding shifted values #15138 " 2025 Dec 29 by Vim Project: clean up " 2025 Dec 31 by Vim Project: correcly indent after nested array literal #19042 +" 2026 Jan 28 by Vim Project: fix indentation when a string literal contains 'if' #19265 " For bugs, patches and license go to https://github.com/rust-lang/rust.vim " Note: upstream seems umaintained: https://github.com/rust-lang/rust.vim/issues/502 @@ -139,9 +140,24 @@ function GetRustIndent(lnum) let l:standalone_close = line =~# '\V\^\s\*}\s\*\$' let l:standalone_where = line =~# '\V\^\s\*where\s\*\$' if l:standalone_open || l:standalone_close || l:standalone_where - " ToDo: we can search for more items than 'fn' and 'if'. - let [l:found_line, l:col, l:submatch] = - \ searchpos('\<\(fn\)\|\(if\)\>', 'bnWp') + let l:orig_line = line('.') + let l:orig_col = col('.') + let l:i = 0 + while 1 + " ToDo: we can search for more items than 'fn' and 'if'. + let [l:found_line, l:col, l:submatch] = + \ searchpos('\<\(fn\|if\)\>', 'bWp') + if l:found_line ==# 0 || !s:is_string_comment(l:found_line, l:col) + break + endif + let l:i += 1 + " Limit to 10 iterations as a failsafe against endless looping. + if l:i >= 10 + let l:found_line = 0 + break + endif + endwhile + call cursor(l:orig_line, l:orig_col) if l:found_line !=# 0 " Now we count the number of '{' and '}' in between the match " locations and the current line (there is probably a better diff --git a/runtime/indent/testdir/rust.in b/runtime/indent/testdir/rust.in index 28a68924f6..9b1912b23e 100644 --- a/runtime/indent/testdir/rust.in +++ b/runtime/indent/testdir/rust.in @@ -40,3 +40,11 @@ fn main() { // file goes out of scope, and the "hello.txt" file gets closed } // END_INDENT + +// START_INDENT +let x = " + if fn motif + "; + struct X { + } +// END_INDENT diff --git a/runtime/indent/testdir/rust.ok b/runtime/indent/testdir/rust.ok index 04808e224f..73fff0620f 100644 --- a/runtime/indent/testdir/rust.ok +++ b/runtime/indent/testdir/rust.ok @@ -40,3 +40,11 @@ fn main() { // file goes out of scope, and the "hello.txt" file gets closed } // END_INDENT + +// START_INDENT +let x = " + if fn motif + "; + struct X { +} +// END_INDENT