summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--help.c81
1 files changed, 80 insertions, 1 deletions
diff --git a/help.c b/help.c
index e57a50ed59..2cb152d2e1 100644
--- a/help.c
+++ b/help.c
@@ -8,6 +8,9 @@
#include "exec_cmd.h"
#include "common-cmds.h"
#include "parse-options.h"
+#include "run-command.h"
+
+static const char *man_viewer;
enum help_format {
HELP_FORMAT_MAN,
@@ -50,6 +53,8 @@ static int git_help_config(const char *var, const char *value)
help_format = parse_help_format(value);
return 0;
}
+ if (!strcmp(var, "man.viewer"))
+ return git_config_string(&man_viewer, var, value);
return git_default_config(var, value);
}
@@ -345,11 +350,85 @@ static void setup_man_path(void)
strbuf_release(&new_path);
}
+static int check_emacsclient_version(void)
+{
+ struct strbuf buffer = STRBUF_INIT;
+ struct child_process ec_process;
+ const char *argv_ec[] = { "emacsclient", "--version", NULL };
+ int version;
+
+ /* emacsclient prints its version number on stderr */
+ memset(&ec_process, 0, sizeof(ec_process));
+ ec_process.argv = argv_ec;
+ ec_process.err = -1;
+ ec_process.stdout_to_stderr = 1;
+ if (start_command(&ec_process)) {
+ fprintf(stderr, "Failed to start emacsclient.\n");
+ return -1;
+ }
+ strbuf_read(&buffer, ec_process.err, 20);
+ close(ec_process.err);
+
+ /*
+ * Don't bother checking return value, because "emacsclient --version"
+ * seems to always exits with code 1.
+ */
+ finish_command(&ec_process);
+
+ if (prefixcmp(buffer.buf, "emacsclient")) {
+ fprintf(stderr, "Failed to parse emacsclient version.\n");
+ strbuf_release(&buffer);
+ return -1;
+ }
+
+ strbuf_remove(&buffer, 0, strlen("emacsclient"));
+ version = atoi(buffer.buf);
+
+ if (version < 22) {
+ fprintf(stderr,
+ "emacsclient version '%d' too old (< 22).\n",
+ version);
+ strbuf_release(&buffer);
+ return -1;
+ }
+
+ strbuf_release(&buffer);
+ return 0;
+}
+
+static void exec_woman_emacs(const char *page)
+{
+ if (!check_emacsclient_version()) {
+ /* This works only with emacsclient version >= 22. */
+ struct strbuf man_page = STRBUF_INIT;
+ strbuf_addf(&man_page, "(woman \"%s\")", page);
+ execlp("emacsclient", "emacsclient", "-e", man_page.buf, NULL);
+ } else
+ execlp("man", "man", page, NULL);
+}
+
+static void exec_man_konqueror(const char *page)
+{
+ const char *display = getenv("DISPLAY");
+ if (display && *display) {
+ struct strbuf man_page = STRBUF_INIT;
+ strbuf_addf(&man_page, "man:%s(1)", page);
+ execlp("kfmclient", "kfmclient", "newTab", man_page.buf, NULL);
+ } else
+ execlp("man", "man", page, NULL);
+}
+
static void show_man_page(const char *git_cmd)
{
const char *page = cmd_to_page(git_cmd);
setup_man_path();
- execlp("man", "man", page, NULL);
+ if (!man_viewer || !strcmp(man_viewer, "man"))
+ execlp("man", "man", page, NULL);
+ if (!strcmp(man_viewer, "woman"))
+ exec_woman_emacs(page);
+ if (!strcmp(man_viewer, "konqueror"))
+ exec_man_konqueror(page);
+ die("'%s': unsupported man viewer.", man_viewer);
}
static void show_info_page(const char *git_cmd)