diff --git a/src/fish_indent.cpp b/src/fish_indent.cpp index 4c53484ae..d7279acc4 100644 --- a/src/fish_indent.cpp +++ b/src/fish_indent.cpp @@ -224,17 +224,27 @@ void prettifier_t::prettify_node(const parse_node_tree_t &tree, node_offset_t no // instead of the semicolons. Semicolons are just ignored, unless they are followed by a // command. So `echo;` removes the semicolon, but `echo; echo` removes it and adds a // newline. + last_was_semicolon = false; if (node.get_source(source) == L"\n") { append_newline(); - } else { + } else if (!has_new_line) { + // The semicolon is only useful if we haven't just had a newline. last_was_semicolon = true; } } else if ((node_type >= FIRST_PARSE_TOKEN_TYPE && node_type <= LAST_PARSE_TOKEN_TYPE) || node_type == parse_special_type_parse_error) { if (last_was_semicolon) { - append_newline(); + // We keep the semicolon for `; and` and `; or`, + // others we turn into newlines. + if (node.keyword != parse_keyword_and + && node.keyword != parse_keyword_or) { + append_newline(); + } else { + output.push_back(L';'); + } last_was_semicolon = false; } + if (node.keyword != parse_keyword_none) { append_whitespace(node_indent); output.append(keyword_description(node.keyword)); diff --git a/tests/indent.in b/tests/indent.in index 73f5489a3..9d704afc6 100644 --- a/tests/indent.in +++ b/tests/indent.in @@ -1,3 +1,5 @@ +set -l indent ../test/root/bin/fish_indent + echo Test1 echo -n ' begin @@ -5,7 +7,7 @@ echo hi end | cat | cat | begin ; echo hi ; end | begin ; begin ; echo hi ; end ; end arg -' | ../test/root/bin/fish_indent +' | $indent echo \nTest2 echo -n ' @@ -18,7 +20,7 @@ switch aloha echo hi end -' | ../test/root/bin/fish_indent +' | $indent echo \nTest3 echo -n ' @@ -33,7 +35,7 @@ function hello_world echo hello end -' | ../test/root/bin/fish_indent +' | $indent echo \nTest4 echo -n ' @@ -53,7 +55,7 @@ switch foo #abc qqq case "*" echo sup -end' | ../test/root/bin/fish_indent +end' | $indent echo \nTest5 echo -n ' @@ -65,7 +67,7 @@ switch beta echo delta end end -' | ../test/root/bin/fish_indent -i +' | $indent -i echo \nTest6 # Test errors @@ -75,20 +77,20 @@ echo hi else echo bye end; echo alpha " -' | ../test/root/bin/fish_indent +' | $indent echo \nTest7 # issue 1665 echo -n ' if begin ; false; end; echo hi ; end while begin ; false; end; echo hi ; end -' | ../test/root/bin/fish_indent +' | $indent echo \nTest redir formatting # issue 2899 echo -n ' echo < stdin >>appended yes 2>&1 no > stdout maybe 2>& 4 | cat 2>| cat -' | ../test/root/bin/fish_indent +' | $indent echo \nTest normalization of keywords # issue 2921 @@ -122,7 +124,13 @@ echo abc;end echo hi | echo bye -' | ../test/root/bin/fish_indent +' | $indent -echo 'a;;;;;;' | ../test/root/bin/fish_indent -echo 'echo; echo' | ../test/root/bin/fish_indent +echo 'a;;;;;;' | $indent +echo 'echo; echo' | $indent + +# Check that we keep semicolons for and and or, but only on the same line. +printf '%s\n' "a; and b" | $indent +printf '%s\n' "a;" "and b" | $indent +printf '%s\n' "a" "; and b" | $indent +printf '%s\n' "a; b" | $indent diff --git a/tests/indent.out b/tests/indent.out index 811c58174..e9e7008c5 100644 --- a/tests/indent.out +++ b/tests/indent.out @@ -36,7 +36,6 @@ function hello_world echo sup echo hello - echo hello end @@ -128,3 +127,10 @@ echo bye a echo echo +a; and b +a +and b +a +and b +a +b