mirror of
https://github.com/fish-shell/fish-shell.git
synced 2024-11-26 10:43:47 +08:00
Simplify slice parsing in highlighting
Factor out parsing of slices, which is only used for highlighting.
This commit is contained in:
parent
a2dfd87928
commit
52c354a60f
|
@ -511,20 +511,18 @@ static size_t color_variable(const wchar_t *in, size_t in_len,
|
|||
|
||||
// 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.
|
||||
for (size_t slice_count = 0; slice_count < dollar_count && in[idx] == L'['; slice_count++) {
|
||||
const wchar_t *slice_begin = nullptr, *slice_end = nullptr;
|
||||
int located = parse_util_locate_slice(in + idx, &slice_begin, &slice_end, false);
|
||||
if (located == 1) {
|
||||
size_t slice_begin_idx = slice_begin - in, slice_end_idx = slice_end - in;
|
||||
assert(slice_end_idx > slice_begin_idx);
|
||||
colors[slice_begin_idx] = highlight_role_t::operat;
|
||||
colors[slice_end_idx] = highlight_role_t::operat;
|
||||
idx = slice_end_idx + 1;
|
||||
} else if (located == 0) {
|
||||
for (size_t slice_count = 0; slice_count < dollar_count; slice_count++) {
|
||||
long slice_len = parse_util_slice_length(in + idx);
|
||||
if (slice_len > 0) {
|
||||
size_t slice_ulen = static_cast<size_t>(slice_len);
|
||||
colors[idx] = highlight_role_t::operat;
|
||||
colors[idx + slice_ulen - 1] = highlight_role_t::operat;
|
||||
idx += slice_ulen;
|
||||
} else if (slice_len == 0) {
|
||||
// not a slice
|
||||
break;
|
||||
} else {
|
||||
assert(located < 0);
|
||||
assert(slice_len < 0);
|
||||
// Syntax error. Normally the entire token is colored red for us, but inside a
|
||||
// double-quoted string 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
|
||||
|
|
|
@ -208,10 +208,46 @@ static int parse_util_locate_brackets_of_type(const wchar_t *in, const wchar_t *
|
|||
return 1;
|
||||
}
|
||||
|
||||
int parse_util_locate_slice(const wchar_t *in, const wchar_t **begin, const wchar_t **end,
|
||||
bool accept_incomplete) {
|
||||
return parse_util_locate_brackets_of_type(in, begin, end, bracket_type_t::slice,
|
||||
accept_incomplete);
|
||||
long parse_util_slice_length(const wchar_t *in) {
|
||||
assert(in && "null parameter");
|
||||
const wchar_t openc = L'[';
|
||||
const wchar_t closec = L']';
|
||||
bool escaped = false;
|
||||
|
||||
// Check for initial opening [
|
||||
if (*in != openc) return 0;
|
||||
int bracket_count = 1;
|
||||
|
||||
assert(in && "null parameter");
|
||||
for (const wchar_t *pos = in + 1; *pos; pos++) {
|
||||
if (!escaped) {
|
||||
if (*pos == L'\'' || *pos == L'"') {
|
||||
const wchar_t *q_end = quote_end(pos, *pos);
|
||||
if (q_end && *q_end) {
|
||||
pos = q_end;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
if (*pos == openc) {
|
||||
bracket_count++;
|
||||
} else if (*pos == closec) {
|
||||
bracket_count--;
|
||||
if (bracket_count == 0) {
|
||||
// pos points at the closing ], so add 1.
|
||||
return pos - in + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (*pos == '\\') {
|
||||
escaped = !escaped;
|
||||
} else {
|
||||
escaped = false;
|
||||
}
|
||||
}
|
||||
assert(bracket_count > 0 && "Should have unclosed brackets");
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int parse_util_locate_brackets_range(const wcstring &str, size_t *inout_cursor_offset,
|
||||
|
|
|
@ -14,9 +14,10 @@ namespace ast {
|
|||
struct argument_t;
|
||||
}
|
||||
|
||||
/// Same as parse_util_locate_cmdsubst, but handles square brackets [ ].
|
||||
int parse_util_locate_slice(const wchar_t *in, const wchar_t **begin, const wchar_t **end,
|
||||
bool accept_incomplete);
|
||||
/// Handles slices: the square brackets in an expression like $foo[5..4]
|
||||
/// \return the length of the slice starting at \p in, or 0 if there is no slice, or -1 on error.
|
||||
/// This never accepts incomplete slices.
|
||||
long parse_util_slice_length(const wchar_t *in);
|
||||
|
||||
/// Alternative API. Iterate over command substitutions.
|
||||
///
|
||||
|
|
Loading…
Reference in New Issue
Block a user