help: implement multi-valued "man.viewer" config option
This allows multiple viewer candidates to be listed in the configuration file, like this: [man] viewer = woman viewer = konqueror viewer = man The candidates are tried in the order listed in the configuration file, and the first suitable one (e.g. konqueror cannot be used outside windowed environment) is used. Signed-off-by: Christian Couder <chriscool@tuxfamily.org> Tested-by: Xavier Maillard <xma@gnu.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
parent
b5578f3335
commit
69099d6bed
191
help.c
191
help.c
@ -10,7 +10,10 @@
|
||||
#include "parse-options.h"
|
||||
#include "run-command.h"
|
||||
|
||||
static const char *man_viewer;
|
||||
static struct man_viewer_list {
|
||||
void (*exec)(const char *);
|
||||
struct man_viewer_list *next;
|
||||
} *man_viewer_list;
|
||||
|
||||
enum help_format {
|
||||
HELP_FORMAT_MAN,
|
||||
@ -45,6 +48,102 @@ static enum help_format parse_help_format(const char *format)
|
||||
die("unrecognized help format '%s'", format);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
static void exec_man_man(const char *page)
|
||||
{
|
||||
execlp("man", "man", page, NULL);
|
||||
}
|
||||
|
||||
static void do_add_man_viewer(void (*exec)(const char *))
|
||||
{
|
||||
struct man_viewer_list **p = &man_viewer_list;
|
||||
|
||||
while (*p)
|
||||
p = &((*p)->next);
|
||||
*p = xmalloc(sizeof(**p));
|
||||
(*p)->next = NULL;
|
||||
(*p)->exec = exec;
|
||||
}
|
||||
|
||||
static int add_man_viewer(const char *value)
|
||||
{
|
||||
if (!strcasecmp(value, "man"))
|
||||
do_add_man_viewer(exec_man_man);
|
||||
else if (!strcasecmp(value, "woman"))
|
||||
do_add_man_viewer(exec_woman_emacs);
|
||||
else if (!strcasecmp(value, "konqueror"))
|
||||
do_add_man_viewer(exec_man_konqueror);
|
||||
else
|
||||
return error("'%s': unsupported man viewer.", value);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int git_help_config(const char *var, const char *value)
|
||||
{
|
||||
if (!strcmp(var, "help.format")) {
|
||||
@ -53,8 +152,11 @@ 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);
|
||||
if (!strcmp(var, "man.viewer")) {
|
||||
if (!value)
|
||||
return config_error_nonbool(var);
|
||||
return add_man_viewer(value);
|
||||
}
|
||||
return git_default_config(var, value);
|
||||
}
|
||||
|
||||
@ -350,85 +452,18 @@ 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)
|
||||
{
|
||||
struct man_viewer_list *viewer;
|
||||
const char *page = cmd_to_page(git_cmd);
|
||||
|
||||
setup_man_path();
|
||||
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);
|
||||
for (viewer = man_viewer_list; viewer; viewer = viewer->next)
|
||||
{
|
||||
viewer->exec(page); /* will return when unable */
|
||||
}
|
||||
exec_man_man(page);
|
||||
die("no man viewer handled the request");
|
||||
}
|
||||
|
||||
static void show_info_page(const char *git_cmd)
|
||||
|
Loading…
Reference in New Issue
Block a user