From 67bc612cbc4e0720b37022a6a00d94130258adc7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Fri, 8 Sep 2023 17:02:57 +0200 Subject: [PATCH] systemctl: link to all non-man-page files in help MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit For file:// links, we urlify the link so that the user can click and either open the file in a editor or some viewer. The detection is chosen via some mechanism implemented by the terminal emulator. This seems too DTRT for text files and PDFs, which should cover the majority of realistic cases. If the file is not viable, the terminal emulator will say "Could not open file://…. No application is registered to view this file type." or similar. For all other links, which are primarily http:// and https://, we just show the link, letting the terminal handle the hyperlinking. The user can then ctrl-click and open the file it their browser. If we tried to open the files automatically, we'd would need to open many pages, and we'd need to figure out what browser to use, etc. When the user picks whether to open the file, this leads to a nicer user experience. Man pages are separated by an empty line from preceding in and following output. In my testing, this makes the output easier to read. A bit of explicit flushing is needed to make sure that various outputs are not interleaved. Fixes https://github.com/systemd/systemd/issues/29061. --- src/systemctl/systemctl-show.c | 30 +++++++++++++++++++++++++----- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/src/systemctl/systemctl-show.c b/src/systemctl/systemctl-show.c index e113396331..c0f9747dd8 100644 --- a/src/systemctl/systemctl-show.c +++ b/src/systemctl/systemctl-show.c @@ -821,6 +821,8 @@ static void print_status_info( } static void show_unit_help(UnitStatusInfo *i) { + bool previous_man_page = false; + assert(i); if (!i->documentation) { @@ -828,11 +830,29 @@ static void show_unit_help(UnitStatusInfo *i) { return; } - STRV_FOREACH(p, i->documentation) - if (startswith(*p, "man:")) - show_man_page(*p + 4, false); - else - log_info("Can't show: %s", *p); + STRV_FOREACH(doc, i->documentation) { + const char *p; + + p = startswith(*doc, "man:"); + + if (p ? doc != i->documentation : previous_man_page) { + puts(""); + fflush(stdout); + } + + previous_man_page = p; + + if (p) + show_man_page(p, /* null_stdio= */ false); + else { + _cleanup_free_ char *t = NULL; + + if ((p = startswith(*doc, "file://"))) + (void) terminal_urlify_path(p, NULL, &t); + + printf("Additional documentation: %s\n", t ?: p ?: *doc); + } + } } static int map_main_pid(sd_bus *bus, const char *member, sd_bus_message *m, sd_bus_error *error, void *userdata) {