X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=pager.c;h=b7909678f459d90d1c8907c78bb5fcb512fe558d;hb=78ed1d2d63390694cb6c451896086fb7338f75b6;hp=4921843577e42b774457a61277b9bc3441d3ab6b;hpb=77f143bf3e218857ec8e5244d7e862e8e0c1a041;p=git.git diff --git a/pager.c b/pager.c index 492184357..b7909678f 100644 --- a/pager.c +++ b/pager.c @@ -2,14 +2,16 @@ #include "run-command.h" #include "sigchain.h" +#ifndef DEFAULT_PAGER +#define DEFAULT_PAGER "less" +#endif + /* * This is split up from the rest of git so that we can do * something different on Windows. */ -static int spawned_pager; - -#ifndef __MINGW32__ +#ifndef WIN32 static void pager_preexec(void) { /* @@ -21,12 +23,10 @@ static void pager_preexec(void) FD_ZERO(&in); FD_SET(0, &in); select(1, &in, NULL, &in, NULL); - - setenv("LESS", "FRSX", 0); } #endif -static const char *pager_argv[] = { "sh", "-c", NULL, NULL }; +static const char *pager_argv[] = { NULL, NULL }; static struct child_process pager_process; static void wait_for_pager(void) @@ -46,12 +46,14 @@ static void wait_for_pager_signal(int signo) raise(signo); } -void setup_pager(void) +const char *git_pager(int stdout_is_tty) { - const char *pager = getenv("GIT_PAGER"); + const char *pager; - if (!isatty(1)) - return; + if (!stdout_is_tty) + return NULL; + + pager = getenv("GIT_PAGER"); if (!pager) { if (!pager_program) git_config(git_default_config, NULL); @@ -60,17 +62,38 @@ void setup_pager(void) if (!pager) pager = getenv("PAGER"); if (!pager) - pager = "less"; + pager = DEFAULT_PAGER; else if (!*pager || !strcmp(pager, "cat")) + pager = NULL; + + return pager; +} + +void setup_pager(void) +{ + const char *pager = git_pager(isatty(1)); + + if (!pager) return; - spawned_pager = 1; /* means we are emitting to terminal */ + /* + * force computing the width of the terminal before we redirect + * the standard output to the pager. + */ + (void) term_columns(); + + setenv("GIT_PAGER_IN_USE", "true", 1); /* spawn the pager */ - pager_argv[2] = pager; + pager_argv[0] = pager; + pager_process.use_shell = 1; pager_process.argv = pager_argv; pager_process.in = -1; -#ifndef __MINGW32__ + if (!getenv("LESS")) { + static const char *env[] = { "LESS=FRSX", NULL }; + pager_process.env = env; + } +#ifndef WIN32 pager_process.preexec_cb = pager_preexec; #endif if (start_command(&pager_process)) @@ -90,10 +113,37 @@ void setup_pager(void) int pager_in_use(void) { const char *env; - - if (spawned_pager) - return 1; - env = getenv("GIT_PAGER_IN_USE"); return env ? git_config_bool("GIT_PAGER_IN_USE", env) : 0; } + +/* + * Return cached value (if set) or $COLUMNS environment variable (if + * set and positive) or ioctl(1, TIOCGWINSZ).ws_col (if positive), + * and default to 80 if all else fails. + */ +int term_columns(void) +{ + static int term_columns_at_startup; + + char *col_string; + int n_cols; + + if (term_columns_at_startup) + return term_columns_at_startup; + + term_columns_at_startup = 80; + + col_string = getenv("COLUMNS"); + if (col_string && (n_cols = atoi(col_string)) > 0) + term_columns_at_startup = n_cols; +#ifdef TIOCGWINSZ + else { + struct winsize ws; + if (!ioctl(1, TIOCGWINSZ, &ws) && ws.ws_col) + term_columns_at_startup = ws.ws_col; + } +#endif + + return term_columns_at_startup; +}