commit 2a2c366a3e48093740444d970e02774436ccc7ad
parent 855fda03aa74c5055ee028e8affe8c089d329224
Author: zeertzjq <zeertzjq@outlook.com>
Date: Wed, 24 Dec 2025 09:43:42 +0800
vim-patch:9.1.2016: cindent wrong indentation after do-while loop (#37087)
Problem: At "if(0) do if(0); while(0); else", else should be aligned
with outer if, but is aligned with inner if.
Solution: In function find_match, ignore "if" and "else" inside a
do-while loop, when looking for "if". (Anttoni Erkkilä)
closes: vim/vim#19004
https://github.com/vim/vim/commit/9d661b057e9f8e4d900b258fa4ed6a265751b7b7
Co-authored-by: Anttoni Erkkilä <anttoni.erkkila@protonmail.com>
Diffstat:
2 files changed, 63 insertions(+), 19 deletions(-)
diff --git a/src/nvim/indent_c.c b/src/nvim/indent_c.c
@@ -3712,16 +3712,29 @@ static int find_match(int lookfor, linenr_T ourscope)
continue;
}
- // if it was an "else" (that's not an "else if")
- // then we need to go back to another if, so
- // increment elselevel
look = cin_skipcomment(get_cursor_line_ptr());
- if (cin_iselse(look)) {
- mightbeif = cin_skipcomment(look + 4);
- if (!cin_isif(mightbeif)) {
- elselevel++;
+ // When looking for if, we ignore "if" and "else" in a deeper do-while loop.
+ if (!(lookfor == LOOKFOR_IF && whilelevel)) {
+ // if it was an "else" (that's not an "else if")
+ // then we need to go back to another if, so
+ // increment elselevel
+ if (cin_iselse(look)) {
+ mightbeif = cin_skipcomment(look + 4);
+ if (!cin_isif(mightbeif)) {
+ elselevel++;
+ }
+ continue;
+ }
+
+ // If it's an "if" decrement elselevel
+ if (cin_isif(look)) {
+ elselevel--;
+ // When looking for an "if" ignore "while"s that
+ // get in the way.
+ if (elselevel == 0 && lookfor == LOOKFOR_IF) {
+ whilelevel = 0;
+ }
}
- continue;
}
// if it was a "while" then we need to go back to
@@ -3731,17 +3744,6 @@ static int find_match(int lookfor, linenr_T ourscope)
continue;
}
- // If it's an "if" decrement elselevel
- look = cin_skipcomment(get_cursor_line_ptr());
- if (cin_isif(look)) {
- elselevel--;
- // When looking for an "if" ignore "while"s that
- // get in the way.
- if (elselevel == 0 && lookfor == LOOKFOR_IF) {
- whilelevel = 0;
- }
- }
-
// If it's a "do" decrement whilelevel
if (cin_isdo(look)) {
whilelevel--;
diff --git a/test/old/testdir/test_cindent.vim b/test/old/testdir/test_cindent.vim
@@ -1106,6 +1106,27 @@ func Test_cindent_1()
b;
}
+ void func() {
+ if (0)
+ do
+ if (0);
+ while (0);
+ else;
+ }
+
+ void func() {
+ if (0)
+ do
+ if (0)
+ do
+ if (0)
+ a();
+ while (0);
+ while (0);
+ else
+ a();
+ }
+
/* end of AUTO */
[CODE]
@@ -2088,6 +2109,27 @@ func Test_cindent_1()
b;
}
+ void func() {
+ if (0)
+ do
+ if (0);
+ while (0);
+ else;
+ }
+
+ void func() {
+ if (0)
+ do
+ if (0)
+ do
+ if (0)
+ a();
+ while (0);
+ while (0);
+ else
+ a();
+ }
+
/* end of AUTO */
[CODE]