mirror of
https://github.com/fish-shell/fish-shell
synced 2024-12-25 12:23:09 +00:00
Add support for ! as an analog to 'not'
! and not are effectively interchangeable now. Mark them both as operators for syntax highlighting.
This commit is contained in:
parent
f83742d579
commit
c7f16439bf
10 changed files with 70 additions and 16 deletions
|
@ -3961,6 +3961,11 @@ static void test_highlighting() {
|
|||
{L"||", highlight_spec_operator},
|
||||
{L"true", highlight_spec_command},
|
||||
{L";", highlight_spec_statement_terminator},
|
||||
{L"and", highlight_spec_operator},
|
||||
{L"not", highlight_spec_operator},
|
||||
{L"!", highlight_spec_operator},
|
||||
{L"true", highlight_spec_command},
|
||||
{L";", highlight_spec_statement_terminator},
|
||||
{L"end", highlight_spec_command},
|
||||
{NULL, -1}};
|
||||
|
||||
|
|
|
@ -1033,7 +1033,6 @@ const highlighter_t::color_array_t &highlighter_t::highlight() {
|
|||
case symbol_if_clause:
|
||||
case symbol_else_clause:
|
||||
case symbol_case_item:
|
||||
case symbol_not_statement:
|
||||
case symbol_decorated_statement:
|
||||
case symbol_if_statement: {
|
||||
this->color_children(node, parse_token_type_string, highlight_spec_command);
|
||||
|
@ -1065,6 +1064,10 @@ const highlighter_t::color_array_t &highlighter_t::highlight() {
|
|||
this->color_node(node, highlight_spec_operator);
|
||||
break;
|
||||
|
||||
case symbol_not_statement:
|
||||
this->color_children(node, parse_token_type_string, highlight_spec_operator);
|
||||
break;
|
||||
|
||||
case symbol_job_decorator:
|
||||
this->color_node(node, highlight_spec_operator);
|
||||
break;
|
||||
|
|
|
@ -111,21 +111,30 @@ enum parse_keyword_t {
|
|||
parse_keyword_if,
|
||||
parse_keyword_in,
|
||||
parse_keyword_not,
|
||||
parse_keyword_exclam,
|
||||
parse_keyword_or,
|
||||
parse_keyword_switch,
|
||||
parse_keyword_while,
|
||||
} __packed;
|
||||
|
||||
const enum_map<parse_keyword_t> keyword_enum_map[] = {
|
||||
{parse_keyword_and, L"and"}, {parse_keyword_begin, L"begin"},
|
||||
{parse_keyword_builtin, L"builtin"}, {parse_keyword_case, L"case"},
|
||||
{parse_keyword_command, L"command"}, {parse_keyword_else, L"else"},
|
||||
{parse_keyword_end, L"end"}, {parse_keyword_exec, L"exec"},
|
||||
{parse_keyword_for, L"for"}, {parse_keyword_function, L"function"},
|
||||
{parse_keyword_if, L"if"}, {parse_keyword_in, L"in"},
|
||||
{parse_keyword_not, L"not"}, {parse_keyword_or, L"or"},
|
||||
{parse_keyword_switch, L"switch"}, {parse_keyword_while, L"while"},
|
||||
{parse_keyword_none, NULL}};
|
||||
const enum_map<parse_keyword_t> keyword_enum_map[] = {{parse_keyword_exclam, L"!"},
|
||||
{parse_keyword_and, L"and"},
|
||||
{parse_keyword_begin, L"begin"},
|
||||
{parse_keyword_builtin, L"builtin"},
|
||||
{parse_keyword_case, L"case"},
|
||||
{parse_keyword_command, L"command"},
|
||||
{parse_keyword_else, L"else"},
|
||||
{parse_keyword_end, L"end"},
|
||||
{parse_keyword_exec, L"exec"},
|
||||
{parse_keyword_for, L"for"},
|
||||
{parse_keyword_function, L"function"},
|
||||
{parse_keyword_if, L"if"},
|
||||
{parse_keyword_in, L"in"},
|
||||
{parse_keyword_not, L"not"},
|
||||
{parse_keyword_or, L"or"},
|
||||
{parse_keyword_switch, L"switch"},
|
||||
{parse_keyword_while, L"while"},
|
||||
{parse_keyword_none, NULL}};
|
||||
#define keyword_enum_map_len (sizeof keyword_enum_map / sizeof *keyword_enum_map)
|
||||
|
||||
// Node tag values.
|
||||
|
|
|
@ -924,7 +924,8 @@ bool parse_execution_context_t::determine_io_chain(tnode_t<g::arguments_or_redir
|
|||
parse_execution_result_t parse_execution_context_t::populate_not_process(
|
||||
job_t *job, process_t *proc, tnode_t<g::not_statement> not_statement) {
|
||||
job->set_flag(JOB_NEGATE, !job->get_flag(JOB_NEGATE));
|
||||
return this->populate_job_process(job, proc, not_statement.child<1>());
|
||||
return this->populate_job_process(job, proc,
|
||||
not_statement.require_get_child<g::statement, 1>());
|
||||
}
|
||||
|
||||
template <typename Type>
|
||||
|
|
|
@ -312,8 +312,10 @@ DEF(function_header)
|
|||
produces_sequence<keyword<parse_keyword_function>, argument, argument_list, tok_end>{
|
||||
BODY(function_header)};
|
||||
|
||||
DEF(not_statement) produces_sequence<keyword<parse_keyword_not>, statement> {
|
||||
BODY(not_statement);
|
||||
DEF_ALT(not_statement) {
|
||||
using nots = seq<keyword<parse_keyword_not>, statement>;
|
||||
using exclams = seq<keyword<parse_keyword_exclam>, statement>;
|
||||
ALT_BODY(not_statement, nots, exclams);
|
||||
};
|
||||
|
||||
// An andor_job_list is zero or more job lists, where each starts with an `and` or `or` boolean
|
||||
|
|
|
@ -143,7 +143,8 @@ RESOLVE(statement) {
|
|||
switch (token1.type) {
|
||||
case parse_token_type_string: {
|
||||
switch (token1.keyword) {
|
||||
case parse_keyword_not: {
|
||||
case parse_keyword_not:
|
||||
case parse_keyword_exclam: {
|
||||
return production_for<nots>();
|
||||
}
|
||||
case parse_keyword_for:
|
||||
|
@ -215,6 +216,19 @@ RESOLVE(case_item_list) {
|
|||
return production_for<empty>();
|
||||
}
|
||||
|
||||
RESOLVE(not_statement) {
|
||||
UNUSED(token2);
|
||||
UNUSED(out_tag);
|
||||
switch (token1.keyword) {
|
||||
case parse_keyword_not:
|
||||
return production_for<nots>();
|
||||
case parse_keyword_exclam:
|
||||
return production_for<exclams>();
|
||||
default:
|
||||
return NO_PRODUCTION;
|
||||
}
|
||||
}
|
||||
|
||||
RESOLVE(andor_job_list) {
|
||||
UNUSED(out_tag);
|
||||
|
||||
|
|
|
@ -960,7 +960,7 @@ static inline parse_keyword_t keyword_with_name(const wchar_t *name) {
|
|||
|
||||
static bool is_keyword_char(wchar_t c) {
|
||||
return (c >= L'a' && c <= L'z') || (c >= L'A' && c <= L'Z') || (c >= L'0' && c <= L'9') ||
|
||||
c == L'\'' || c == L'"' || c == L'\\' || c == '\n';
|
||||
c == L'\'' || c == L'"' || c == L'\\' || c == '\n' || c == L'!';
|
||||
}
|
||||
|
||||
/// Given a token, returns the keyword it matches, or parse_keyword_none.
|
||||
|
|
|
@ -8,5 +8,8 @@
|
|||
####################
|
||||
# && and || in while statements
|
||||
|
||||
####################
|
||||
# Nots
|
||||
|
||||
####################
|
||||
# Complex scenarios
|
||||
|
|
|
@ -28,6 +28,14 @@ while [ $alpha -lt 2 ] && [ $beta -lt 3 ]
|
|||
set delta ( math $delta + 1 )
|
||||
end
|
||||
|
||||
logmsg "Nots"
|
||||
|
||||
true && ! false ; echo $status
|
||||
not true && ! false ; echo $status
|
||||
not not not true ; echo $status
|
||||
not ! ! not true ; echo $status
|
||||
not ! echo not ! ; echo $status
|
||||
|
||||
logmsg "Complex scenarios"
|
||||
|
||||
begin; echo 1 ; false ; end || begin ; echo 2 && echo 3 ; end
|
||||
|
|
|
@ -23,6 +23,15 @@ if test 4 ok
|
|||
3 3 3
|
||||
4 4 4
|
||||
|
||||
####################
|
||||
# Nots
|
||||
0
|
||||
1
|
||||
1
|
||||
0
|
||||
not !
|
||||
0
|
||||
|
||||
####################
|
||||
# Complex scenarios
|
||||
1
|
||||
|
|
Loading…
Reference in a new issue