1
0
Fork 0
mirror of https://github.com/git/git.git synced 2024-10-28 21:07:52 +01:00

help: use man viewer path from "man.<tool>.path" config var

This patch implements reading values from "man.<tool>.path"
configuration variables, and using these values as pathes to
the man viewer <tool>s when lauching them.

This makes it possible to use different version of the tools
than the one on the current PATH, or maybe a custom script.

In this patch we also try to launch "konqueror" using
"kfmclient" even if a path to a konqueror binary is given
in "man.konqueror.path".

The "man_viewer_list" becomes a simple string list to simplify
things for the following patches.

Signed-off-by: Christian Couder <chriscool@tuxfamily.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
Christian Couder 2008-04-25 08:24:22 +02:00 committed by Junio C Hamano
parent 36c79d2bf8
commit 7b15f872f2

143
help.c
View file

@ -11,10 +11,16 @@
#include "run-command.h" #include "run-command.h"
static struct man_viewer_list { static struct man_viewer_list {
void (*exec)(const char *);
struct man_viewer_list *next; struct man_viewer_list *next;
char name[FLEX_ARRAY];
} *man_viewer_list; } *man_viewer_list;
static struct man_viewer_info_list {
struct man_viewer_info_list *next;
const char *info;
char name[FLEX_ARRAY];
} *man_viewer_info_list;
enum help_format { enum help_format {
HELP_FORMAT_MAN, HELP_FORMAT_MAN,
HELP_FORMAT_INFO, HELP_FORMAT_INFO,
@ -49,6 +55,18 @@ static enum help_format parse_help_format(const char *format)
die("unrecognized help format '%s'", format); die("unrecognized help format '%s'", format);
} }
static const char *get_man_viewer_info(const char *name)
{
struct man_viewer_info_list *viewer;
for (viewer = man_viewer_info_list; viewer; viewer = viewer->next)
{
if (!strcasecmp(name, viewer->name))
return viewer->info;
}
return NULL;
}
static int check_emacsclient_version(void) static int check_emacsclient_version(void)
{ {
struct strbuf buffer = STRBUF_INIT; struct strbuf buffer = STRBUF_INIT;
@ -95,56 +113,126 @@ static int check_emacsclient_version(void)
return 0; return 0;
} }
static void exec_woman_emacs(const char *page) static void exec_woman_emacs(const char* path, const char *page)
{ {
if (!check_emacsclient_version()) { if (!check_emacsclient_version()) {
/* This works only with emacsclient version >= 22. */ /* This works only with emacsclient version >= 22. */
struct strbuf man_page = STRBUF_INIT; struct strbuf man_page = STRBUF_INIT;
if (!path)
path = "emacsclient";
strbuf_addf(&man_page, "(woman \"%s\")", page); strbuf_addf(&man_page, "(woman \"%s\")", page);
execlp("emacsclient", "emacsclient", "-e", man_page.buf, NULL); execlp(path, "emacsclient", "-e", man_page.buf, NULL);
warning("failed to exec '%s': %s", path, strerror(errno));
} }
} }
static void exec_man_konqueror(const char *page) static void exec_man_konqueror(const char* path, const char *page)
{ {
const char *display = getenv("DISPLAY"); const char *display = getenv("DISPLAY");
if (display && *display) { if (display && *display) {
struct strbuf man_page = STRBUF_INIT; struct strbuf man_page = STRBUF_INIT;
const char *filename = "kfmclient";
/* It's simpler to launch konqueror using kfmclient. */
if (path) {
const char *file = strrchr(path, '/');
if (file && !strcmp(file + 1, "konqueror")) {
char *new = xstrdup(path);
char *dest = strrchr(new, '/');
/* strlen("konqueror") == strlen("kfmclient") */
strcpy(dest + 1, "kfmclient");
path = new;
}
if (file)
filename = file;
} else
path = "kfmclient";
strbuf_addf(&man_page, "man:%s(1)", page); strbuf_addf(&man_page, "man:%s(1)", page);
execlp("kfmclient", "kfmclient", "newTab", man_page.buf, NULL); execlp(path, filename, "newTab", man_page.buf, NULL);
warning("failed to exec '%s': %s", path, strerror(errno));
} }
} }
static void exec_man_man(const char *page) static void exec_man_man(const char* path, const char *page)
{ {
execlp("man", "man", page, NULL); if (!path)
path = "man";
execlp(path, "man", page, NULL);
warning("failed to exec '%s': %s", path, strerror(errno));
} }
static void do_add_man_viewer(void (*exec)(const char *)) static void do_add_man_viewer(const char *name)
{ {
struct man_viewer_list **p = &man_viewer_list; struct man_viewer_list **p = &man_viewer_list;
size_t len = strlen(name);
while (*p) while (*p)
p = &((*p)->next); p = &((*p)->next);
*p = xmalloc(sizeof(**p)); *p = xcalloc(1, (sizeof(**p) + len + 1));
(*p)->next = NULL; strncpy((*p)->name, name, len);
(*p)->exec = exec; }
static int supported_man_viewer(const char *name, size_t len)
{
return (!strncasecmp("man", name, len) ||
!strncasecmp("woman", name, len) ||
!strncasecmp("konqueror", name, len));
} }
static int add_man_viewer(const char *value) static int add_man_viewer(const char *value)
{ {
if (!strcasecmp(value, "man")) if (supported_man_viewer(value, strlen(value)))
do_add_man_viewer(exec_man_man); do_add_man_viewer(value);
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 else
warning("'%s': unsupported man viewer.", value); warning("'%s': unsupported man viewer.", value);
return 0; return 0;
} }
static void do_add_man_viewer_info(const char *name,
size_t len,
const char *value)
{
struct man_viewer_info_list *new = xcalloc(1, sizeof(*new) + len + 1);
strncpy(new->name, name, len);
new->info = xstrdup(value);
new->next = man_viewer_info_list;
man_viewer_info_list = new;
}
static int add_man_viewer_path(const char *name,
size_t len,
const char *value)
{
if (supported_man_viewer(name, len))
do_add_man_viewer_info(name, len, value);
else
warning("'%s': path for unsupported man viewer.", name);
return 0;
}
static int add_man_viewer_info(const char *var, const char *value)
{
const char *name = var + 4;
const char *subkey = strrchr(name, '.');
if (!subkey)
return error("Config with no key for man viewer: %s", name);
if (!strcmp(subkey, ".path")) {
if (!value)
return config_error_nonbool(var);
return add_man_viewer_path(name, subkey - name, value);
}
warning("'%s': unsupported man viewer sub key.", subkey);
return 0;
}
static int git_help_config(const char *var, const char *value) static int git_help_config(const char *var, const char *value)
{ {
if (!strcmp(var, "help.format")) { if (!strcmp(var, "help.format")) {
@ -158,6 +246,9 @@ static int git_help_config(const char *var, const char *value)
return config_error_nonbool(var); return config_error_nonbool(var);
return add_man_viewer(value); return add_man_viewer(value);
} }
if (!prefixcmp(var, "man."))
return add_man_viewer_info(var, value);
return git_default_config(var, value); return git_default_config(var, value);
} }
@ -453,6 +544,20 @@ static void setup_man_path(void)
strbuf_release(&new_path); strbuf_release(&new_path);
} }
static void exec_viewer(const char *name, const char *page)
{
const char *path = get_man_viewer_info(name);
if (!strcasecmp(name, "man"))
exec_man_man(path, page);
else if (!strcasecmp(name, "woman"))
exec_woman_emacs(path, page);
else if (!strcasecmp(name, "konqueror"))
exec_man_konqueror(path, page);
else
warning("'%s': unsupported man viewer.", name);
}
static void show_man_page(const char *git_cmd) static void show_man_page(const char *git_cmd)
{ {
struct man_viewer_list *viewer; struct man_viewer_list *viewer;
@ -461,9 +566,9 @@ static void show_man_page(const char *git_cmd)
setup_man_path(); setup_man_path();
for (viewer = man_viewer_list; viewer; viewer = viewer->next) for (viewer = man_viewer_list; viewer; viewer = viewer->next)
{ {
viewer->exec(page); /* will return when unable */ exec_viewer(viewer->name, page); /* will return when unable */
} }
exec_man_man(page); exec_viewer("man", page);
die("no man viewer handled the request"); die("no man viewer handled the request");
} }