Teach fish_indent to remove useless quotes

This tries to see if quotes guard some expansion from happening. If it
detects a "weird" character it'll leave the quotes in place, even in
some cases where it might not trigger.

So

    for i in 'c' 'color'

turns into

    for i in c color

The rationale here is that these quotes are useless, wasting
space (and line length), but more importantly that they are
superstitions. They don't do anything, but look like they do.

The counter argument is that they can be kept in case of later
changes, or that they make the intent clear - "this is supposed to be
a string we pass".
This commit is contained in:
Fabian Homborg 2019-06-11 19:35:49 +02:00
parent 750e6fa663
commit b25f72f391
2 changed files with 23 additions and 5 deletions

View file

@ -36,6 +36,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
#include "color.h"
#include "common.h"
#include "env.h"
#include "expand.h"
#include "fish_version.h"
#include "flog.h"
#include "highlight.h"
@ -251,7 +252,25 @@ void prettifier_t::prettify_node(const parse_node_tree_t &tree, node_offset_t no
if (prev_node_type != parse_token_type_redirection) {
append_whitespace(node_indent);
}
output.append(source, node.source_start, node.source_length);
wcstring unescaped{source, node.source_start, node.source_length};
// Unescape the string - this leaves special markers around if there are any expansions or anything.
// TODO: This also already computes backslash-escapes like \u or \x.
// We probably don't want that - if someone picked `\x20` to spell space, they have a reason.
unescape_string_in_place(&unescaped, UNESCAPE_SPECIAL);
// Remove INTERNAL_SEPARATOR because that's a quote.
auto quote = [](wchar_t ch) { return ch == INTERNAL_SEPARATOR; };
unescaped.erase(std::remove_if(unescaped.begin(), unescaped.end(), quote),
unescaped.end());
// If no non-alphanumeric char is left, use the unescaped version.
// This can be extended to other characters, but giving the precise list is tough,
// can change over time (see "^", "%" and "?", in some cases "{}") and it just makes people feel more at ease.
if (std::find_if_not(unescaped.begin(), unescaped.end(), fish_iswalnum) == unescaped.end() && !unescaped.empty()) {
output.append(unescaped);
} else {
output.append(source, node.source_start, node.source_length);
}
has_new_line = false;
}
}

View file

@ -103,10 +103,9 @@ f true
en\
d
"whil\
e" true
"builtin" yes
en"d"
while true
builtin yes
end
alpha | \
beta