fish_indent: handle tokens with trailing escaped newlines

Fixes #8197
This commit is contained in:
Johannes Altmanninger 2021-08-01 18:38:18 +02:00
parent 1b20e75f19
commit 66709571ed
3 changed files with 39 additions and 1 deletions

View file

@ -18,6 +18,7 @@ Scripting improvements
- ``$fish_user_paths`` is now automatically deduplicated to fix a common user error of appending to it in config.fish when it is universal (:issue:`8117`). :ref:`fish_add_path <cmd-fish_add_path>` remains the recommended way to add to $PATH. - ``$fish_user_paths`` is now automatically deduplicated to fix a common user error of appending to it in config.fish when it is universal (:issue:`8117`). :ref:`fish_add_path <cmd-fish_add_path>` remains the recommended way to add to $PATH.
- ``return`` can now be used outside of functions. In scripts it does the same thing as :ref:`exit <cmd-exit>`, in the commandline it sets ``$status`` without exiting (:issue:`8148`). - ``return`` can now be used outside of functions. In scripts it does the same thing as :ref:`exit <cmd-exit>`, in the commandline it sets ``$status`` without exiting (:issue:`8148`).
- An oversight prevented all syntax checks from running on commands given to ``fish -c`` (:issue:`8171`). - An oversight prevented all syntax checks from running on commands given to ``fish -c`` (:issue:`8171`).
- ``fish_indent`` now correctly reformats tokens that end with a backslash followed by a newline (:issue:`8197`).
Interactive improvements Interactive improvements
------------------------ ------------------------

View file

@ -550,7 +550,28 @@ struct pretty_printer_t {
template <type_t Type> template <type_t Type>
void emit_node_text(const leaf_t<Type> &node) { void emit_node_text(const leaf_t<Type> &node) {
emit_text(node.range, gap_text_flags_before_node(node)); source_range_t range = node.range;
// Weird special-case: a token may end in an escaped newline. Notably, the newline is
// not part of the following gap text, handle indentation here (#8197).
bool ends_with_escaped_nl = node.range.length >= 2 &&
source.at(node.range.end() - 2) == L'\\' &&
source.at(node.range.end() - 1) == L'\n';
if (ends_with_escaped_nl) {
range = {range.start, range.length - 2};
}
emit_text(range, gap_text_flags_before_node(node));
if (ends_with_escaped_nl) {
// By convention, escaped newlines are preceded with a space.
output.append(L" \\\n");
// TODO Maybe check "allow_escaped_newlines" and use the precomputed indents.
// The cases where this matters are probably very rare.
current_indent++;
emit_space_or_indent();
current_indent--;
}
} }
// Emit one newline. // Emit one newline.

View file

@ -416,3 +416,19 @@ echo "\
a=1 \\ a=1 \\
a=2 echo" | $fish_indent --check a=2 echo" | $fish_indent --check
echo $status #CHECK: 0 echo $status #CHECK: 0
echo 'first-word\\
second-word' | $fish_indent
# CHECK: first-word \
# CHECK: {{^}} second-word
echo 'begin
first-indented-word\\
second-indented-word' | $fish_indent
# CHECK: begin
# CHECK: {{^}} first-indented-word \
# CHECK: {{^}} second-indented-word
echo 'multiline-\\
-word' | $fish_indent --check
echo $status #CHECK: 0