From a47f498516b3dea986dc43fc0d9e94479e755314 Mon Sep 17 00:00:00 2001 From: ridiculousfish Date: Mon, 15 Nov 2021 22:52:12 -0800 Subject: [PATCH] Correct syntax highlighting for variables spanning multiple lines A variable may be broken across multiple lines with a backslash, for example: > echo $FISH_\ VERSION Teach syntax highlighting about this line breaking. Fixes #8444 --- src/fish_tests.cpp | 7 +++++++ src/highlight.cpp | 12 ++++++++++-- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/src/fish_tests.cpp b/src/fish_tests.cpp index 8c1326a23..2e9054fea 100644 --- a/src/fish_tests.cpp +++ b/src/fish_tests.cpp @@ -5525,6 +5525,13 @@ static void test_highlighting() { {L"=", highlight_role_t::operat, ns}, }); + // Highlighting works across escaped line breaks (#8444). + highlight_tests.push_back({ + {L"echo", highlight_role_t::command}, + {L"$FISH_\\\n", highlight_role_t::operat}, + {L"VERSION", highlight_role_t::operat, ns}, + }); + auto &vars = parser_t::principal_parser().vars(); // Verify variables and wildcards in commands using /bin/cat. vars.set(L"VARIABLE_IN_COMMAND", ENV_LOCAL, {L"a"}); diff --git a/src/highlight.cpp b/src/highlight.cpp index d4c9442a8..9f7d7f41f 100644 --- a/src/highlight.cpp +++ b/src/highlight.cpp @@ -489,8 +489,16 @@ static size_t color_variable(const wchar_t *in, size_t in_len, } // Handle a sequence of variable characters. - while (valid_var_name_char(in[idx])) { - colors[idx++] = highlight_role_t::operat; + // It may contain an escaped newline - see #8444. + for (;;) { + if (valid_var_name_char(in[idx])) { + colors[idx++] = highlight_role_t::operat; + } else if (in[idx] == L'\\' && in[idx + 1] == L'\n') { + colors[idx++] = highlight_role_t::operat; + colors[idx++] = highlight_role_t::operat; + } else { + break; + } } // Handle a slice, up to dollar_count of them. Note that we currently don't do any validation of