fish_indent: preserve escaped newlines around variable assignments

In many cases we currently discard escaped newlines, since they
are often unnecessary (when used around &|;). Escaped newlines
are useful for structuring argument lists. Allow them for variable
assignments since they are similar.

Closes #7955
This commit is contained in:
Johannes Altmanninger 2021-04-27 00:00:32 +02:00
parent 15e265f209
commit 9d7f6db792
3 changed files with 31 additions and 1 deletions

View File

@ -22,6 +22,7 @@ Scripting improvements
- Builtins now properly report a ``$status`` of 1 upon unsuccessful writes (:issue:`7857`).
- ``string match`` with unmatched capture groups and without the ``--all`` flag now sets an empty variable instead of a variable containing the empty string. It also correctly imports the first match if multiple arguments are provided, matching the documentation. (:issue:`7938`).
- Better errors when a command in a command substitution wasn't found or is not allowed.
- ``fish_indent`` allows to write inline variable assignments on multiple lines (ending in a backslash), instead of joining them into one line (:issue:`7955`).
Interactive improvements
-------------------------

View File

@ -167,9 +167,10 @@ struct pretty_printer_t {
static gap_flags_t gap_text_flags_before_node(const node_t &node) {
gap_flags_t result = default_flags;
switch (node.type) {
// Allow escaped newlines in argument and redirection lists.
// Allow escaped newlines before leaf nodes that can be part of a long command.
case type_t::argument:
case type_t::redirection:
case type_t::variable_assignment:
result |= allow_escaped_newlines;
break;
@ -181,6 +182,23 @@ struct pretty_printer_t {
case parse_token_type_t::pipe:
result |= allow_escaped_newlines;
break;
case parse_token_type_t::string: {
// Allow escaped newlines before commands that follow a variable assignment
// since both can be long (#7955).
const node_t *p = node.parent;
if (p->type != type_t::decorated_statement) break;
p = p->parent;
assert(p->type == type_t::statement);
p = p->parent;
if (auto job = p->try_as<job_t>()) {
if (!job->variables.empty()) result |= allow_escaped_newlines;
} else if (auto job_cnt = p->try_as<job_continuation_t>()) {
if (!job_cnt->variables.empty()) result |= allow_escaped_newlines;
} else if (auto not_stmt = p->try_as<not_statement_t>()) {
if (!not_stmt->variables.empty()) result |= allow_escaped_newlines;
}
break;
}
default:
break;
}

View File

@ -405,3 +405,14 @@ function hello_continuations
#CHECK: {{^}} echo --opt2 \
#CHECK: {{^}} echo --opt3
#CHECK: end
echo "\
a=1 \\
a=2 \\
echo" | $fish_indent --check
echo $status #CHECK: 0
echo "\
a=1 \\
a=2 echo" | $fish_indent --check
echo $status #CHECK: 0