diff options
Diffstat (limited to 'pager.c')
-rw-r--r-- | pager.c | 124 |
1 files changed, 71 insertions, 53 deletions
@@ -6,33 +6,36 @@ #define DEFAULT_PAGER "less" #endif -struct pager_config { - const char *cmd; - int want; - char *value; -}; - /* * This is split up from the rest of git so that we can do * something different on Windows. */ -static const char *pager_argv[] = { NULL, NULL }; -static struct child_process pager_process; +static struct child_process pager_process = CHILD_PROCESS_INIT; -static void wait_for_pager(void) +static void wait_for_pager(int in_signal) { - fflush(stdout); - fflush(stderr); + if (!in_signal) { + fflush(stdout); + fflush(stderr); + } /* signal EOF to pager */ close(1); close(2); - finish_command(&pager_process); + if (in_signal) + finish_command_in_signal(&pager_process); + else + finish_command(&pager_process); +} + +static void wait_for_pager_atexit(void) +{ + wait_for_pager(0); } static void wait_for_pager_signal(int signo) { - wait_for_pager(); + wait_for_pager(1); sigchain_pop(signo); raise(signo); } @@ -60,6 +63,40 @@ const char *git_pager(int stdout_is_tty) return pager; } +static void setup_pager_env(struct argv_array *env) +{ + const char **argv; + int i; + char *pager_env = xstrdup(PAGER_ENV); + int n = split_cmdline(pager_env, &argv); + + if (n < 0) + die("malformed build-time PAGER_ENV: %s", + split_cmdline_strerror(n)); + + for (i = 0; i < n; i++) { + char *cp = strchr(argv[i], '='); + + if (!cp) + die("malformed build-time PAGER_ENV"); + + *cp = '\0'; + if (!getenv(argv[i])) { + *cp = '='; + argv_array_push(env, argv[i]); + } + } + free(pager_env); + free(argv); +} + +void prepare_pager_args(struct child_process *pager_process, const char *pager) +{ + argv_array_push(&pager_process->args, pager); + pager_process->use_shell = 1; + setup_pager_env(&pager_process->env_array); +} + void setup_pager(void) { const char *pager = git_pager(isatty(1)); @@ -76,21 +113,9 @@ void setup_pager(void) setenv("GIT_PAGER_IN_USE", "true", 1); /* spawn the pager */ - pager_argv[0] = pager; - pager_process.use_shell = 1; - pager_process.argv = pager_argv; + prepare_pager_args(&pager_process, pager); pager_process.in = -1; - if (!getenv("LESS") || !getenv("LV")) { - static const char *env[3]; - int i = 0; - - if (!getenv("LESS")) - env[i++] = "LESS=FRSX"; - if (!getenv("LV")) - env[i++] = "LV=-c"; - env[i] = NULL; - pager_process.env = env; - } + argv_array_push(&pager_process.env_array, "GIT_PAGER_IN_USE"); if (start_command(&pager_process)) return; @@ -102,7 +127,7 @@ void setup_pager(void) /* this makes sure that the parent terminates after the pager */ sigchain_push_common(wait_for_pager_signal); - atexit(wait_for_pager); + atexit(wait_for_pager_atexit); } int pager_in_use(void) @@ -146,39 +171,32 @@ int term_columns(void) /* * How many columns do we need to show this number in decimal? */ -int decimal_width(int number) +int decimal_width(uintmax_t number) { - int i, width; + int width; - for (width = 1, i = 10; i <= number; width++) - i *= 10; + for (width = 1; number >= 10; width++) + number /= 10; return width; } -static int pager_command_config(const char *var, const char *value, void *data) +/* returns 0 for "no pager", 1 for "use pager", and -1 for "not specified" */ +int check_pager_config(const char *cmd) { - struct pager_config *c = data; - if (starts_with(var, "pager.") && !strcmp(var + 6, c->cmd)) { - int b = git_config_maybe_bool(var, value); + int want = -1; + struct strbuf key = STRBUF_INIT; + const char *value = NULL; + strbuf_addf(&key, "pager.%s", cmd); + if (git_config_key_is_valid(key.buf) && + !git_config_get_value(key.buf, &value)) { + int b = git_config_maybe_bool(key.buf, value); if (b >= 0) - c->want = b; + want = b; else { - c->want = 1; - c->value = xstrdup(value); + want = 1; + pager_program = xstrdup(value); } } - return 0; -} - -/* returns 0 for "no pager", 1 for "use pager", and -1 for "not specified" */ -int check_pager_config(const char *cmd) -{ - struct pager_config c; - c.cmd = cmd; - c.want = -1; - c.value = NULL; - git_config(pager_command_config, &c); - if (c.value) - pager_program = c.value; - return c.want; + strbuf_release(&key); + return want; } |