Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 164 lines (137 sloc) 3.37 kb
f67b45f Introduce trivial new pager.c helper infrastructure
Linus Torvalds authored
1 #include "cache.h"
ea27a18 @peff spawn pager via run_command interface
peff authored
2 #include "run-command.h"
a3da882 @peff pager: do wait_for_pager on signal death
peff authored
3 #include "sigchain.h"
f67b45f Introduce trivial new pager.c helper infrastructure
Linus Torvalds authored
4
a3d023d @gitster Provide a build time default-pager setting
gitster authored
5 #ifndef DEFAULT_PAGER
6 #define DEFAULT_PAGER "less"
7 #endif
8
f67b45f Introduce trivial new pager.c helper infrastructure
Linus Torvalds authored
9 /*
bfdd9ff Windows: Make the pager work.
Johannes Sixt authored
10 * This is split up from the rest of git so that we can do
11 * something different on Windows.
f67b45f Introduce trivial new pager.c helper infrastructure
Linus Torvalds authored
12 */
13
ac0ba18 @peff run-command: convert simple callsites to use_shell
peff authored
14 static const char *pager_argv[] = { NULL, NULL };
d318027 run-command: introduce CHILD_PROCESS_INIT
René Scharfe authored
15 static struct child_process pager_process = CHILD_PROCESS_INIT;
ea27a18 @peff spawn pager via run_command interface
peff authored
16
bfdd9ff Windows: Make the pager work.
Johannes Sixt authored
17 static void wait_for_pager(void)
18 {
19 fflush(stdout);
20 fflush(stderr);
21 /* signal EOF to pager */
22 close(1);
23 close(2);
24 finish_command(&pager_process);
25 }
f67b45f Introduce trivial new pager.c helper infrastructure
Linus Torvalds authored
26
a3da882 @peff pager: do wait_for_pager on signal death
peff authored
27 static void wait_for_pager_signal(int signo)
28 {
29 wait_for_pager();
30 sigchain_pop(signo);
31 raise(signo);
32 }
33
64778d2 @jrn Make 'git var GIT_PAGER' always print the configured pager
jrn authored
34 const char *git_pager(int stdout_is_tty)
f67b45f Introduce trivial new pager.c helper infrastructure
Linus Torvalds authored
35 {
6361824 @jrn Teach git var about GIT_PAGER
jrn authored
36 const char *pager;
f67b45f Introduce trivial new pager.c helper infrastructure
Linus Torvalds authored
37
64778d2 @jrn Make 'git var GIT_PAGER' always print the configured pager
jrn authored
38 if (!stdout_is_tty)
6361824 @jrn Teach git var about GIT_PAGER
jrn authored
39 return NULL;
40
41 pager = getenv("GIT_PAGER");
cad3a20 @gitster pager: find out pager setting from configuration
gitster authored
42 if (!pager) {
43 if (!pager_program)
ef90d6d @dscho Provide git_config with a callback-data parameter
dscho authored
44 git_config(git_default_config, NULL);
54adf37 @Benabik Add core.pager config variable.
Benabik authored
45 pager = pager_program;
cad3a20 @gitster pager: find out pager setting from configuration
gitster authored
46 }
54adf37 @Benabik Add core.pager config variable.
Benabik authored
47 if (!pager)
c27d205 @matled pager: environment variable GIT_PAGER to override PAGER
matled authored
48 pager = getenv("PAGER");
49 if (!pager)
a3d023d @gitster Provide a build time default-pager setting
gitster authored
50 pager = DEFAULT_PAGER;
ed01661 @peff pager: turn on "cat" optimization for DEFAULT_PAGER
peff authored
51 if (!*pager || !strcmp(pager, "cat"))
6361824 @jrn Teach git var about GIT_PAGER
jrn authored
52 pager = NULL;
53
54 return pager;
55 }
56
57 void setup_pager(void)
58 {
64778d2 @jrn Make 'git var GIT_PAGER' always print the configured pager
jrn authored
59 const char *pager = git_pager(isatty(1));
6361824 @jrn Teach git var about GIT_PAGER
jrn authored
60
c0459ca pager: do allow spawning pager recursively
Jörn Engel authored
61 if (!pager)
402461a @dscho pager: do not fork a pager if PAGER is set to empty.
dscho authored
62 return;
63
ad6c373 @keszybz pager: find out the terminal width before spawning the pager
keszybz authored
64 /*
65 * force computing the width of the terminal before we redirect
66 * the standard output to the pager.
67 */
68 (void) term_columns();
69
2e6c012 @peff setup_pager: set GIT_PAGER_IN_USE
peff authored
70 setenv("GIT_PAGER_IN_USE", "true", 1);
85fb65e "git -p cmd" to page anywhere
Junio C Hamano authored
71
bfdd9ff Windows: Make the pager work.
Johannes Sixt authored
72 /* spawn the pager */
ac0ba18 @peff run-command: convert simple callsites to use_shell
peff authored
73 pager_argv[0] = pager;
74 pager_process.use_shell = 1;
ea27a18 @peff spawn pager via run_command interface
peff authored
75 pager_process.argv = pager_argv;
76 pager_process.in = -1;
a915459 use env_array member of struct child_process
René Scharfe authored
77 if (!getenv("LESS"))
78 argv_array_push(&pager_process.env_array, "LESS=FRX");
79 if (!getenv("LV"))
80 argv_array_push(&pager_process.env_array, "LV=-c");
bfdd9ff Windows: Make the pager work.
Johannes Sixt authored
81 if (start_command(&pager_process))
82 return;
83
84 /* original process continues, but writes to the pipe */
85 dup2(pager_process.in, 1);
a833502 @gitster pager: do not dup2 stderr if it is already redirected
gitster authored
86 if (isatty(2))
87 dup2(pager_process.in, 2);
bfdd9ff Windows: Make the pager work.
Johannes Sixt authored
88 close(pager_process.in);
89
90 /* this makes sure that the parent terminates after the pager */
a3da882 @peff pager: do wait_for_pager on signal death
peff authored
91 sigchain_push_common(wait_for_pager_signal);
bfdd9ff Windows: Make the pager work.
Johannes Sixt authored
92 atexit(wait_for_pager);
f67b45f Introduce trivial new pager.c helper infrastructure
Linus Torvalds authored
93 }
6e9af86 @peff Support GIT_PAGER_IN_USE environment variable
peff authored
94
95 int pager_in_use(void)
96 {
97 const char *env;
98 env = getenv("GIT_PAGER_IN_USE");
99 return env ? git_config_bool("GIT_PAGER_IN_USE", env) : 0;
100 }
ad6c373 @keszybz pager: find out the terminal width before spawning the pager
keszybz authored
101
102 /*
103 * Return cached value (if set) or $COLUMNS environment variable (if
104 * set and positive) or ioctl(1, TIOCGWINSZ).ws_col (if positive),
105 * and default to 80 if all else fails.
106 */
107 int term_columns(void)
108 {
109 static int term_columns_at_startup;
110
111 char *col_string;
112 int n_cols;
113
114 if (term_columns_at_startup)
115 return term_columns_at_startup;
116
117 term_columns_at_startup = 80;
118
119 col_string = getenv("COLUMNS");
120 if (col_string && (n_cols = atoi(col_string)) > 0)
121 term_columns_at_startup = n_cols;
122 #ifdef TIOCGWINSZ
123 else {
124 struct winsize ws;
125 if (!ioctl(1, TIOCGWINSZ, &ws) && ws.ws_col)
126 term_columns_at_startup = ws.ws_col;
127 }
128 #endif
129
130 return term_columns_at_startup;
131 }
4d9e079 @gitster Merge branch 'zj/decimal-width'
gitster authored
132
133 /*
ec7ff5b @keszybz make lineno_width() from blame reusable for others
keszybz authored
134 * How many columns do we need to show this number in decimal?
135 */
d306f3d @peff decimal_width: avoid integer overflow
peff authored
136 int decimal_width(uintmax_t number)
ec7ff5b @keszybz make lineno_width() from blame reusable for others
keszybz authored
137 {
d306f3d @peff decimal_width: avoid integer overflow
peff authored
138 int width;
ec7ff5b @keszybz make lineno_width() from blame reusable for others
keszybz authored
139
d306f3d @peff decimal_width: avoid integer overflow
peff authored
140 for (width = 1; number >= 10; width++)
141 number /= 10;
ec7ff5b @keszybz make lineno_width() from blame reusable for others
keszybz authored
142 return width;
143 }
4914c96 @pclouds Move setup_diff_pager to libgit.a
pclouds authored
144
586f414 @tanayabh pager.c: replace `git_config()` with `git_config_get_value()`
tanayabh authored
145 /* returns 0 for "no pager", 1 for "use pager", and -1 for "not specified" */
146 int check_pager_config(const char *cmd)
4914c96 @pclouds Move setup_diff_pager to libgit.a
pclouds authored
147 {
586f414 @tanayabh pager.c: replace `git_config()` with `git_config_get_value()`
tanayabh authored
148 int want = -1;
149 struct strbuf key = STRBUF_INIT;
150 const char *value = NULL;
151 strbuf_addf(&key, "pager.%s", cmd);
152 if (!git_config_get_value(key.buf, &value)) {
153 int b = git_config_maybe_bool(key.buf, value);
4914c96 @pclouds Move setup_diff_pager to libgit.a
pclouds authored
154 if (b >= 0)
586f414 @tanayabh pager.c: replace `git_config()` with `git_config_get_value()`
tanayabh authored
155 want = b;
4914c96 @pclouds Move setup_diff_pager to libgit.a
pclouds authored
156 else {
586f414 @tanayabh pager.c: replace `git_config()` with `git_config_get_value()`
tanayabh authored
157 want = 1;
158 pager_program = xstrdup(value);
4914c96 @pclouds Move setup_diff_pager to libgit.a
pclouds authored
159 }
160 }
586f414 @tanayabh pager.c: replace `git_config()` with `git_config_get_value()`
tanayabh authored
161 strbuf_release(&key);
162 return want;
4914c96 @pclouds Move setup_diff_pager to libgit.a
pclouds authored
163 }
Something went wrong with that request. Please try again.