mirror of
https://github.com/fish-shell/fish-shell
synced 2024-12-25 12:23:09 +00:00
Teach the highlighter about multiple adjacent square bracket expansions
Fixes #1627
This commit is contained in:
parent
d67800bbce
commit
c181de1d7f
2 changed files with 39 additions and 22 deletions
|
@ -3620,8 +3620,19 @@ static void test_highlighting(void)
|
||||||
{NULL, -1}
|
{NULL, -1}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const highlight_component_t components13[] =
|
||||||
|
{
|
||||||
|
{L"echo", highlight_spec_command},
|
||||||
|
{L"$$foo[", highlight_spec_operator},
|
||||||
|
{L"1", highlight_spec_param},
|
||||||
|
{L"][", highlight_spec_operator},
|
||||||
|
{L"2", highlight_spec_param},
|
||||||
|
{L"]", highlight_spec_operator},
|
||||||
|
{L"[3]", highlight_spec_param}, // two dollar signs, so last one is not an expansion
|
||||||
|
{NULL, -1}
|
||||||
|
};
|
||||||
|
|
||||||
const highlight_component_t *tests[] = {components1, components2, components3, components4, components5, components6, components7, components8, components9, components10, components11, components12};
|
const highlight_component_t *tests[] = {components1, components2, components3, components4, components5, components6, components7, components8, components9, components10, components11, components12, components13};
|
||||||
for (size_t which = 0; which < sizeof tests / sizeof *tests; which++)
|
for (size_t which = 0; which < sizeof tests / sizeof *tests; which++)
|
||||||
{
|
{
|
||||||
const highlight_component_t *components = tests[which];
|
const highlight_component_t *components = tests[which];
|
||||||
|
|
|
@ -591,6 +591,7 @@ static size_t color_variable(const wchar_t *in, size_t in_len, std::vector<highl
|
||||||
|
|
||||||
// Handle an initial run of $s.
|
// Handle an initial run of $s.
|
||||||
size_t idx = 0;
|
size_t idx = 0;
|
||||||
|
size_t dollar_count = 0;
|
||||||
while (in[idx] == '$')
|
while (in[idx] == '$')
|
||||||
{
|
{
|
||||||
// Our color depends on the next char
|
// Our color depends on the next char
|
||||||
|
@ -604,6 +605,7 @@ static size_t color_variable(const wchar_t *in, size_t in_len, std::vector<highl
|
||||||
colors[idx] = highlight_spec_error;
|
colors[idx] = highlight_spec_error;
|
||||||
}
|
}
|
||||||
idx++;
|
idx++;
|
||||||
|
dollar_count++;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle a sequence of variable characters
|
// Handle a sequence of variable characters
|
||||||
|
@ -612,30 +614,34 @@ static size_t color_variable(const wchar_t *in, size_t in_len, std::vector<highl
|
||||||
colors[idx++] = highlight_spec_operator;
|
colors[idx++] = highlight_spec_operator;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle a slice. Note that we currently don't do any validation of the slice's contents, e.g. $foo[blah] will not show an error even though it's invalid.
|
// Handle a slice, up to dollar_count of them. Note that we currently don't do any validation of the slice's contents, e.g. $foo[blah] will not show an error even though it's invalid.
|
||||||
if (in[idx] == L'[')
|
for (size_t slice_count=0; slice_count < dollar_count && in[idx] == L'['; slice_count++)
|
||||||
{
|
{
|
||||||
wchar_t *slice_begin = NULL, *slice_end = NULL;
|
wchar_t *slice_begin = NULL, *slice_end = NULL;
|
||||||
switch (parse_util_locate_slice(in, &slice_begin, &slice_end, false))
|
int located = parse_util_locate_slice(in + idx, &slice_begin, &slice_end, false);
|
||||||
|
if (located == 1)
|
||||||
{
|
{
|
||||||
case 1:
|
size_t slice_begin_idx = slice_begin - in, slice_end_idx = slice_end - in;
|
||||||
{
|
assert(slice_end_idx > slice_begin_idx);
|
||||||
size_t slice_begin_idx = slice_begin - in, slice_end_idx = slice_end - in;
|
colors[slice_begin_idx] = highlight_spec_operator;
|
||||||
assert(slice_end_idx > slice_begin_idx);
|
colors[slice_end_idx] = highlight_spec_operator;
|
||||||
colors[slice_begin_idx] = highlight_spec_operator;
|
idx = slice_end_idx + 1;
|
||||||
colors[slice_end_idx] = highlight_spec_operator;
|
}
|
||||||
break;
|
else if (located == 0)
|
||||||
}
|
{
|
||||||
case -1:
|
// not a slice
|
||||||
{
|
break;
|
||||||
// syntax error
|
}
|
||||||
// Normally the entire token is colored red for us, but inside a double-quoted string
|
else
|
||||||
// that doesn't happen. As such, color the variable + the slice start red. Coloring any
|
{
|
||||||
// more than that looks bad, unless we're willing to try and detect where the double-quoted
|
assert(located < 0);
|
||||||
// string ends, and I'd rather not do that.
|
// syntax error
|
||||||
std::fill(colors, colors + idx + 1, (highlight_spec_t)highlight_spec_error);
|
// Normally the entire token is colored red for us, but inside a double-quoted string
|
||||||
break;
|
// that doesn't happen. As such, color the variable + the slice start red. Coloring any
|
||||||
}
|
// more than that looks bad, unless we're willing to try and detect where the double-quoted
|
||||||
|
// string ends, and I'd rather not do that.
|
||||||
|
std::fill(colors, colors + idx + 1, (highlight_spec_t)highlight_spec_error);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return idx;
|
return idx;
|
||||||
|
|
Loading…
Reference in a new issue