From: Zbigniew Jędrzejewski-Szmek Date: Fri, 8 Sep 2023 15:02:57 +0000 (+0200) Subject: systemctl: link to all non-man-page files in help X-Git-Tag: v255-rc1~465 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=67bc612cbc4e0720b37022a6a00d94130258adc7;p=thirdparty%2Fsystemd.git systemctl: link to all non-man-page files in help 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. --- diff --git a/src/systemctl/systemctl-show.c b/src/systemctl/systemctl-show.c index e1133963315..c0f9747dd81 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) {