From cb79d8fa970c8ea6d537887e693dd23052aa194e Mon Sep 17 00:00:00 2001 From: Aaron Gyes Date: Thu, 19 Sep 2019 04:27:33 -0700 Subject: [PATCH] Colorize `complete` output If interactive, `complete` commands are highlighted like they would be if typed. Adds a little fun contrast and it's easier to read. Moved a function out of fish_indent to highlight.h --- src/builtin_complete.cpp | 14 +++++++++++++- src/fish_indent.cpp | 22 +--------------------- src/highlight.cpp | 19 +++++++++++++++++++ src/highlight.h | 2 ++ 4 files changed, 35 insertions(+), 22 deletions(-) diff --git a/src/builtin_complete.cpp b/src/builtin_complete.cpp index 8ae0bb528..7a7faa8ed 100644 --- a/src/builtin_complete.cpp +++ b/src/builtin_complete.cpp @@ -17,6 +17,8 @@ #include "parse_constants.h" #include "parse_util.h" #include "parser.h" +#include "highlight.h" +#include "color.h" #include "reader.h" #include "wgetopt.h" #include "wutil.h" // IWYU pragma: keep @@ -378,7 +380,17 @@ int builtin_complete(parser_t &parser, io_streams_t &streams, wchar_t **argv) { } else if (cmd_to_complete.empty() && path.empty()) { // No arguments specified, meaning we print the definitions of all specified completions // to stdout. - streams.out.append(complete_print()); + const wcstring repr = complete_print(); + + // colorize if interactive + if (!streams.out_is_redirected && isatty(STDOUT_FILENO)) { + std::vector colors; + size_t len = repr.size(); + highlight_shell_no_io(repr, colors, len, nullptr, env_stack_t::globals()); + streams.out.append(str2wcstring(colorize(repr, colors))); + } else { + streams.out.append(repr); + } } else { int flags = COMPLETE_AUTO_SPACE; if (preserve_order) { diff --git a/src/fish_indent.cpp b/src/fish_indent.cpp index 4d78166fc..0d77e26ae 100644 --- a/src/fish_indent.cpp +++ b/src/fish_indent.cpp @@ -375,26 +375,6 @@ static wcstring prettify(const wcstring &src, bool do_indent) { return std::move(prettifier.output); } -/// Given a string and list of colors of the same size, return the string with ANSI escape sequences -/// representing the colors. -static std::string ansi_colorize(const wcstring &text, - const std::vector &colors) { - assert(colors.size() == text.size()); - outputter_t outp; - - highlight_spec_t last_color = highlight_role_t::normal; - for (size_t i = 0; i < text.size(); i++) { - highlight_spec_t color = colors.at(i); - if (color != last_color) { - outp.set_color(highlight_get_color(color, false), rgb_color_t::normal()); - last_color = color; - } - outp.writech(text.at(i)); - } - outp.set_color(rgb_color_t::normal(), rgb_color_t::normal()); - return outp.contents(); -} - /// Given a string and list of colors of the same size, return the string with HTML span elements /// for the various colors. static const wchar_t *html_class_name_for_color(highlight_spec_t spec) { @@ -676,7 +656,7 @@ int main(int argc, char *argv[]) { break; } case output_type_ansi: { - colored_output = ansi_colorize(output_wtext, colors); + colored_output = colorize(output_wtext, colors); break; } case output_type_html: { diff --git a/src/highlight.cpp b/src/highlight.cpp index 2a8fa179d..dbb4bd293 100644 --- a/src/highlight.cpp +++ b/src/highlight.cpp @@ -1297,6 +1297,25 @@ highlighter_t::color_array_t highlighter_t::highlight() { return std::move(color_array); } +/// Given a string and list of colors of the same size, return the string with ANSI escape sequences +/// representing the colors. +std::string colorize(const wcstring &text, const std::vector &colors) { + assert(colors.size() == text.size()); + outputter_t outp; + + highlight_spec_t last_color = highlight_role_t::normal; + for (size_t i = 0; i < text.size(); i++) { + highlight_spec_t color = colors.at(i); + if (color != last_color) { + outp.set_color(highlight_get_color(color, false), rgb_color_t::normal()); + last_color = color; + } + outp.writech(text.at(i)); + } + outp.set_color(rgb_color_t::normal(), rgb_color_t::normal()); + return outp.contents(); +} + void highlight_shell(const wcstring &buff, std::vector &color, size_t pos, wcstring_list_t *error, const environment_t &vars) { UNUSED(error); diff --git a/src/highlight.h b/src/highlight.h index a75b76481..fdf7f761e 100644 --- a/src/highlight.h +++ b/src/highlight.h @@ -72,6 +72,8 @@ struct highlight_spec_t { class history_item_t; +std::string colorize(const wcstring &text, const std::vector &colors); + /// Perform syntax highlighting for the shell commands in buff. The result is stored in the color /// array as a color_code from the HIGHLIGHT_ enum for each character in buff. ///