From 16484a8a1506abcac057825dc5d28c52949023cc Mon Sep 17 00:00:00 2001 From: Zbigniew Jędrzejewski-Szmek Date: Mon, 17 Oct 2016 11:37:41 -0400 Subject: systemctl: use underlines to seperate unit types in listing MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit (printf("%.*s", -1, "…") is the same as not specifying the precision at all.) v2: also underline highlighted (failing) units Fixes #4137. --- src/basic/terminal-util.h | 20 ++++++++++++++ src/systemctl/systemctl.c | 69 ++++++++++++++++++++++++++++------------------- 2 files changed, 62 insertions(+), 27 deletions(-) (limited to 'src') diff --git a/src/basic/terminal-util.h b/src/basic/terminal-util.h index 169ab772ff..6b47c17278 100644 --- a/src/basic/terminal-util.h +++ b/src/basic/terminal-util.h @@ -36,6 +36,10 @@ #define ANSI_HIGHLIGHT_YELLOW "\x1B[0;1;33m" #define ANSI_HIGHLIGHT_BLUE "\x1B[0;1;34m" #define ANSI_HIGHLIGHT_UNDERLINE "\x1B[0;1;4m" +#define ANSI_HIGHLIGHT_RED_UNDERLINE "\x1B[0;1;4;31m" +#define ANSI_HIGHLIGHT_GREEN_UNDERLINE "\x1B[0;1;4;32m" +#define ANSI_HIGHLIGHT_YELLOW_UNDERLINE "\x1B[0;1;4;33m" +#define ANSI_HIGHLIGHT_BLUE_UNDERLINE "\x1B[0;1;4;34m" #define ANSI_NORMAL "\x1B[0m" #define ANSI_ERASE_TO_END_OF_LINE "\x1B[K" @@ -111,6 +115,22 @@ static inline const char *ansi_highlight_blue(void) { return colors_enabled() ? ANSI_HIGHLIGHT_BLUE : ""; } +static inline const char *ansi_highlight_red_underline(void) { + return colors_enabled() ? ANSI_HIGHLIGHT_RED_UNDERLINE : ""; +} + +static inline const char *ansi_highlight_green_underline(void) { + return colors_enabled() ? ANSI_HIGHLIGHT_GREEN_UNDERLINE : ""; +} + +static inline const char *ansi_highlight_yellow_underline(void) { + return colors_enabled() ? ANSI_HIGHLIGHT_YELLOW_UNDERLINE : ""; +} + +static inline const char *ansi_highlight_blue_underline(void) { + return colors_enabled() ? ANSI_HIGHLIGHT_BLUE_UNDERLINE : ""; +} + static inline const char *ansi_normal(void) { return colors_enabled() ? ANSI_NORMAL : ""; } diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c index 7ed60dbe87..8b08b1762f 100644 --- a/src/systemctl/systemctl.c +++ b/src/systemctl/systemctl.c @@ -362,22 +362,24 @@ static int compare_unit_info(const void *a, const void *b) { return strcasecmp(u->id, v->id); } +static const char* unit_type_suffix(const char *name) { + const char *dot; + + dot = strrchr(name, '.'); + if (!dot) + return ""; + + return dot + 1; +} + static bool output_show_unit(const UnitInfo *u, char **patterns) { assert(u); if (!strv_fnmatch_or_empty(patterns, u->id, FNM_NOESCAPE)) return false; - if (arg_types) { - const char *dot; - - dot = strrchr(u->id, '.'); - if (!dot) - return false; - - if (!strv_find(arg_types, dot+1)) - return false; - } + if (arg_types && !strv_find(arg_types, unit_type_suffix(u->id))) + return false; if (arg_all) return true; @@ -403,10 +405,10 @@ static bool output_show_unit(const UnitInfo *u, char **patterns) { } static int output_units_list(const UnitInfo *unit_infos, unsigned c) { - unsigned circle_len = 0, id_len, max_id_len, load_len, active_len, sub_len, job_len, desc_len; + unsigned circle_len = 0, id_len, max_id_len, load_len, active_len, sub_len, job_len; const UnitInfo *u; unsigned n_shown = 0; - int job_count = 0; + int job_count = 0, desc_len; max_id_len = strlen("UNIT"); load_len = strlen("LOAD"); @@ -464,18 +466,20 @@ static int output_units_list(const UnitInfo *unit_infos, unsigned c) { for (u = unit_infos; u < unit_infos + c; u++) { _cleanup_free_ char *e = NULL, *j = NULL; + const char *on_underline = "", *off_underline = ""; const char *on_loaded = "", *off_loaded = ""; const char *on_active = "", *off_active = ""; const char *on_circle = "", *off_circle = ""; const char *id; - bool circle = false; + bool circle = false, underline = false; if (!n_shown && !arg_no_legend) { if (circle_len > 0) fputs(" ", stdout); - printf("%-*s %-*s %-*s %-*s ", + printf("%s%-*s %-*s %-*s %-*s ", + ansi_underline(), id_len, "UNIT", load_len, "LOAD", active_len, "ACTIVE", @@ -484,23 +488,33 @@ static int output_units_list(const UnitInfo *unit_infos, unsigned c) { if (job_count) printf("%-*s ", job_len, "JOB"); - if (!arg_full && arg_no_pager) - printf("%.*s\n", desc_len, "DESCRIPTION"); - else - printf("%s\n", "DESCRIPTION"); + printf("%.*s%s\n", + !arg_full && arg_no_pager ? desc_len : -1, + "DESCRIPTION", + ansi_normal()); } n_shown++; + if (u + 1 < unit_infos + c && + !streq(unit_type_suffix(u->id), unit_type_suffix((u + 1)->id))) { + on_underline = ansi_underline(); + off_underline = ansi_normal(); + underline = true; + } + if (STR_IN_SET(u->load_state, "error", "not-found", "masked") && !arg_plain) { - on_loaded = ansi_highlight_red(); on_circle = ansi_highlight_yellow(); - off_loaded = off_circle = ansi_normal(); + off_circle = ansi_normal(); circle = true; + on_loaded = underline ? ansi_highlight_red_underline() : ansi_highlight_red(); + off_loaded = on_underline; } else if (streq(u->active_state, "failed") && !arg_plain) { - on_circle = on_active = ansi_highlight_red(); - off_circle = off_active = ansi_normal(); + on_circle = ansi_highlight_red(); + off_circle = ansi_normal(); circle = true; + on_active = underline ? ansi_highlight_red_underline() : ansi_highlight_red(); + off_active = on_underline; } if (u->machine) { @@ -523,17 +537,18 @@ static int output_units_list(const UnitInfo *unit_infos, unsigned c) { if (circle_len > 0) printf("%s%s%s ", on_circle, circle ? special_glyph(BLACK_CIRCLE) : " ", off_circle); - printf("%s%-*s%s %s%-*s%s %s%-*s %-*s%s %-*s", + printf("%s%s%-*s%s %s%-*s%s %s%-*s %-*s%s %-*s", + on_underline, on_active, id_len, id, off_active, on_loaded, load_len, u->load_state, off_loaded, on_active, active_len, u->active_state, sub_len, u->sub_state, off_active, job_count ? job_len + 1 : 0, u->job_id ? u->job_type : ""); - if (desc_len > 0) - printf("%.*s\n", desc_len, u->description); - else - printf("%s\n", u->description); + printf("%.*s%s\n", + desc_len > 0 ? desc_len : -1, + u->description, + off_underline); } if (!arg_no_legend) { -- cgit v1.2.3-54-g00ecf From 6ae3e62a5415ec367528456e230e75800045d276 Mon Sep 17 00:00:00 2001 From: Zbigniew Jędrzejewski-Szmek Date: Mon, 17 Oct 2016 11:37:55 -0400 Subject: systemctl: ditto for list-unit-files --- src/systemctl/systemctl.c | 37 ++++++++++++++++++++++++------------- 1 file changed, 24 insertions(+), 13 deletions(-) (limited to 'src') diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c index 8b08b1762f..129706d15f 100644 --- a/src/systemctl/systemctl.c +++ b/src/systemctl/systemctl.c @@ -1410,35 +1410,46 @@ static void output_unit_file_list(const UnitFileList *units, unsigned c) { id_cols = max_id_len; if (!arg_no_legend && c > 0) - printf("%-*s %-*s\n", + printf("%s%-*s %-*s%s\n", + ansi_underline(), id_cols, "UNIT FILE", - state_cols, "STATE"); + state_cols, "STATE", + ansi_normal()); for (u = units; u < units + c; u++) { _cleanup_free_ char *e = NULL; - const char *on, *off; + const char *on, *off, *on_underline = "", *off_underline = ""; const char *id; + bool underline = false; + + if (u + 1 < units + c && + !streq(unit_type_suffix(u->path), unit_type_suffix((u + 1)->path))) { + on_underline = ansi_underline(); + off_underline = ansi_normal(); + underline = true; + } if (IN_SET(u->state, UNIT_FILE_MASKED, UNIT_FILE_MASKED_RUNTIME, UNIT_FILE_DISABLED, - UNIT_FILE_BAD)) { - on = ansi_highlight_red(); - off = ansi_normal(); - } else if (u->state == UNIT_FILE_ENABLED) { - on = ansi_highlight_green(); - off = ansi_normal(); - } else - on = off = ""; + UNIT_FILE_BAD)) + on = underline ? ansi_highlight_red_underline() : ansi_highlight_red(); + else if (u->state == UNIT_FILE_ENABLED) + on = underline ? ansi_highlight_green_underline() : ansi_highlight_green(); + else + on = on_underline; + off = off_underline; id = basename(u->path); e = arg_full ? NULL : ellipsize(id, id_cols, 33); - printf("%-*s %s%-*s%s\n", + printf("%s%-*s %s%-*s%s%s\n", + on_underline, id_cols, e ? e : id, - on, state_cols, unit_file_state_to_string(u->state), off); + on, state_cols, unit_file_state_to_string(u->state), off, + off_underline); } if (!arg_no_legend) -- cgit v1.2.3-54-g00ecf From 5c98198f67199802a760851d969fc6a9cf8eae9b Mon Sep 17 00:00:00 2001 From: Zbigniew Jędrzejewski-Szmek Date: Mon, 17 Oct 2016 11:48:12 -0400 Subject: terminal-util: helper macro for highlighting functions --- src/basic/terminal-util.h | 65 +++++++++++++---------------------------------- 1 file changed, 18 insertions(+), 47 deletions(-) (limited to 'src') diff --git a/src/basic/terminal-util.h b/src/basic/terminal-util.h index 6b47c17278..b862bfaf05 100644 --- a/src/basic/terminal-util.h +++ b/src/basic/terminal-util.h @@ -87,53 +87,24 @@ bool on_tty(void); bool terminal_is_dumb(void); bool colors_enabled(void); -static inline const char *ansi_underline(void) { - return colors_enabled() ? ANSI_UNDERLINE : ""; -} - -static inline const char *ansi_highlight(void) { - return colors_enabled() ? ANSI_HIGHLIGHT : ""; -} - -static inline const char *ansi_highlight_underline(void) { - return colors_enabled() ? ANSI_HIGHLIGHT_UNDERLINE : ""; -} - -static inline const char *ansi_highlight_red(void) { - return colors_enabled() ? ANSI_HIGHLIGHT_RED : ""; -} - -static inline const char *ansi_highlight_green(void) { - return colors_enabled() ? ANSI_HIGHLIGHT_GREEN : ""; -} - -static inline const char *ansi_highlight_yellow(void) { - return colors_enabled() ? ANSI_HIGHLIGHT_YELLOW : ""; -} - -static inline const char *ansi_highlight_blue(void) { - return colors_enabled() ? ANSI_HIGHLIGHT_BLUE : ""; -} - -static inline const char *ansi_highlight_red_underline(void) { - return colors_enabled() ? ANSI_HIGHLIGHT_RED_UNDERLINE : ""; -} - -static inline const char *ansi_highlight_green_underline(void) { - return colors_enabled() ? ANSI_HIGHLIGHT_GREEN_UNDERLINE : ""; -} - -static inline const char *ansi_highlight_yellow_underline(void) { - return colors_enabled() ? ANSI_HIGHLIGHT_YELLOW_UNDERLINE : ""; -} - -static inline const char *ansi_highlight_blue_underline(void) { - return colors_enabled() ? ANSI_HIGHLIGHT_BLUE_UNDERLINE : ""; -} - -static inline const char *ansi_normal(void) { - return colors_enabled() ? ANSI_NORMAL : ""; -} +#define DEFINE_ANSI_FUNC(name, NAME) \ + static inline const char *ansi_##name(void) { \ + return colors_enabled() ? ANSI_##NAME : ""; \ + } \ + struct __useless_struct_to_allow_trailing_semicolon__ + +DEFINE_ANSI_FUNC(underline, UNDERLINE); +DEFINE_ANSI_FUNC(highlight, HIGHLIGHT); +DEFINE_ANSI_FUNC(highlight_underline, HIGHLIGHT_UNDERLINE); +DEFINE_ANSI_FUNC(highlight_red, HIGHLIGHT_RED); +DEFINE_ANSI_FUNC(highlight_green, HIGHLIGHT_GREEN); +DEFINE_ANSI_FUNC(highlight_yellow, HIGHLIGHT_YELLOW); +DEFINE_ANSI_FUNC(highlight_blue, HIGHLIGHT_BLUE); +DEFINE_ANSI_FUNC(highlight_red_underline, HIGHLIGHT_RED_UNDERLINE); +DEFINE_ANSI_FUNC(highlight_green_underline, HIGHLIGHT_GREEN_UNDERLINE); +DEFINE_ANSI_FUNC(highlight_yellow_underline, HIGHLIGHT_YELLOW_UNDERLINE); +DEFINE_ANSI_FUNC(highlight_blue_underline, HIGHLIGHT_BLUE_UNDERLINE); +DEFINE_ANSI_FUNC(normal, NORMAL); int get_ctty_devnr(pid_t pid, dev_t *d); int get_ctty(pid_t, dev_t *_devnr, char **r); -- cgit v1.2.3-54-g00ecf