Show root; blast raw diff lines
[tig] / cgit.c
CommitLineData
800a900c
JF
1/*
2 *
3 *
4 */
5
6#include <stdlib.h>
7#include <stdio.h>
8#include <ctype.h>
9#include <signal.h>
10
11#include <curses.h>
12
05f1685b
JF
13#define CGIT_HELP "(q)uit, (s)hell, (j) down, (k) up"
14#define KEY_ESC 27
15#define KEY_TAB 9
16
17/* +------------------------------------+
18 * |titlewin |
19 * +------------------------------------+
20 * |mainwin |
21 * | |
22 * | |
23 * | |
24 * | |
25 * +------------------------------------+
26 * |statuswin |
27 * +------------------------------------+
28 */
29
30WINDOW *titlewin;
31WINDOW *mainwin;
32WINDOW *statuswin;
33
34typedef void (*pipe_filter_T)(char *, int);
35
36FILE *pipe;
37long pipe_lineno;
38pipe_filter_T pipe_filter;
39
800a900c
JF
40/*
41 * Init and quit
42 */
43
05f1685b
JF
44static void
45quit(int sig)
800a900c
JF
46{
47 endwin();
48
49 /* do your non-curses wrapup here */
50
51 exit(0);
52}
53
54static void
55init_colors(void)
56{
05f1685b
JF
57 int bg = COLOR_BLACK;
58
800a900c
JF
59 start_color();
60
05f1685b
JF
61 if (use_default_colors())
62 bg = -1;
63
64 init_pair(COLOR_BLACK, COLOR_BLACK, bg);
65 init_pair(COLOR_GREEN, COLOR_GREEN, bg);
66 init_pair(COLOR_RED, COLOR_RED, bg);
67 init_pair(COLOR_CYAN, COLOR_CYAN, bg);
68 init_pair(COLOR_WHITE, COLOR_WHITE, bg);
69 init_pair(COLOR_MAGENTA, COLOR_MAGENTA, bg);
70 init_pair(COLOR_BLUE, COLOR_BLUE, bg);
71 init_pair(COLOR_YELLOW, COLOR_YELLOW, bg);
800a900c
JF
72}
73
74static void
75init(void)
76{
05f1685b 77 int x, y;
800a900c 78
05f1685b
JF
79 signal(SIGINT, quit);
80
81 initscr(); /* initialize the curses library */
82 nonl(); /* tell curses not to do NL->CR/NL on output */
83 cbreak(); /* take input chars one at a time, no wait for \n */
84 noecho(); /* don't echo input */
800a900c
JF
85
86 if (has_colors())
87 init_colors();
05f1685b
JF
88
89 getmaxyx(stdscr, y, x);
90
91 titlewin = newwin(1, 0, 0, 0);
92
93 wattrset(titlewin, COLOR_PAIR(COLOR_GREEN));
94 waddch(titlewin, ACS_VLINE);
95 wprintw(titlewin, "%s", "cg-view");
96 waddch(titlewin, ACS_LTEE);
97 whline(titlewin, ACS_HLINE, x);
98 wrefresh(titlewin);
99
100 statuswin = newwin(1, 0, y - 1, 0);
101
102 wattrset(statuswin, COLOR_PAIR(COLOR_GREEN));
103 wprintw(statuswin, "%s", CGIT_HELP);
104 wrefresh(statuswin);
105
106 mainwin = newwin(y - 2, 0, 1, 0);
107 scrollok(mainwin, TRUE);
108 keypad(mainwin, TRUE); /* enable keyboard mapping */
109}
110
111/*
112 * Pipe filters
113 */
114
115#define DIFF_CMD \
116 "git-rev-list $(git-rev-parse --since=1.month) HEAD^..HEAD | " \
117 "git-diff-tree --stdin --pretty -r --cc --always"
118
119
120#define LOG_CMD \
121 "git-rev-list $(git-rev-parse --since=1.month) HEAD | " \
67392cc4 122 "git-diff-tree --stdin --pretty -r --root"
05f1685b
JF
123
124static void
125log_filter(char *line, int lineno)
126{
127 static int log_filter_skip;
128
129 if (!line) {
130 wattrset(mainwin, A_NORMAL);
131 log_filter_skip = 0;
132 return;
133 }
134
135 if (!strncmp("commit ", line, 7)) {
136 attrset(COLOR_PAIR(COLOR_GREEN));
137
138 } else if (!strncmp("Author: ", line, 8)) {
139 wattrset(mainwin, COLOR_PAIR(COLOR_CYAN));
140
141 } else if (!strncmp("Date: ", line, 6)) {
142 wattrset(mainwin, COLOR_PAIR(COLOR_YELLOW));
143
144 } else if (!strncmp("diff --git ", line, 11)) {
145 wattrset(mainwin, COLOR_PAIR(COLOR_YELLOW));
146
147 } else if (!strncmp("diff-tree ", line, 10)) {
148 wattrset(mainwin, COLOR_PAIR(COLOR_BLUE));
149
150 } else if (!strncmp("index ", line, 6)) {
151 wattrset(mainwin, COLOR_PAIR(COLOR_BLUE));
152
153 } else if (line[0] == '-') {
154 wattrset(mainwin, COLOR_PAIR(COLOR_RED));
155
156 } else if (line[0] == '+') {
157 wattrset(mainwin, COLOR_PAIR(COLOR_GREEN));
158
159 } else if (line[0] == '@') {
160 wattrset(mainwin, COLOR_PAIR(COLOR_MAGENTA));
161
162 } else if (line[0] == ':') {
67392cc4 163 pipe_lineno--;
05f1685b
JF
164 log_filter_skip = 1;
165 return;
166
167 } else if (log_filter_skip) {
67392cc4 168 pipe_lineno--;
05f1685b
JF
169 log_filter_skip = 0;
170 return;
171
172 } else {
173 wattrset(mainwin, A_NORMAL);
174 }
175
176 mvwaddstr(mainwin, lineno, 0, line);
177}
178
179static FILE *
180open_pipe(char *cmd, pipe_filter_T filter)
181{
182 pipe = popen(cmd, "r");
183 pipe_lineno = 1;
184 pipe_filter = filter;
185 return pipe;
186}
187
188static void
189read_pipe(int lines)
190{
191 char buffer[BUFSIZ];
192 char *line;
193
194 while ((line = fgets(buffer, sizeof(buffer), pipe))) {
195 pipe_filter(line, pipe_lineno++);
196 if (!--lines)
197 break;
198 }
199
200 if (feof(pipe) || ferror(pipe)) {
201 pipe_filter(NULL, pipe_lineno - 1);
202 pclose(pipe);
203 pipe = NULL;
204 pipe_filter = NULL;
205 }
800a900c
JF
206}
207
208/*
209 * Main
210 */
211
212int
213main(int argc, char *argv[])
214{
800a900c
JF
215 init();
216
05f1685b 217 pipe = open_pipe(LOG_CMD, log_filter);
800a900c
JF
218
219 for (;;) {
05f1685b
JF
220 int c;
221
222 if (pipe) read_pipe(20);
223 if (pipe) nodelay(mainwin, TRUE);
224
225 c = wgetch(mainwin); /* refresh, accept single keystroke of input */
226
227 if (pipe) nodelay(mainwin, FALSE);
228
229 if (c == ERR)
230 continue;
800a900c
JF
231
232 /* Process the command keystroke */
233 switch (c) {
05f1685b 234 case KEY_ESC:
800a900c
JF
235 case 'q':
236 quit(0);
237 return 0;
238
05f1685b
JF
239 case KEY_DOWN:
240 case 'j':
241 wscrl(mainwin, 1);
242 break;
243
244 case KEY_UP:
245 case 'k':
246 wscrl(mainwin, -1);
247 break;
248
249 case 'd':
250 pipe = open_pipe(DIFF_CMD, log_filter);
251 wclear(mainwin);
252 wmove(mainwin, 0, 0);
253 break;
254
255 case 'l':
256 pipe = open_pipe(LOG_CMD, log_filter);
257 wclear(mainwin);
258 wmove(mainwin, 0, 0);
259 break;
260
800a900c 261 case 's':
05f1685b 262 mvwaddstr(statuswin, 0, 0, "Shelling out......................");
800a900c
JF
263 def_prog_mode(); /* save current tty modes */
264 endwin(); /* restore original tty modes */
265 system("sh"); /* run shell */
05f1685b
JF
266
267 wclear(statuswin);
268 mvwaddstr(statuswin, 0, 0, CGIT_HELP);
800a900c
JF
269 reset_prog_mode();
270 //refresh(); /* restore save modes, repaint screen */
271 break;
272
05f1685b
JF
273/* default:*/
274/* if (isprint(c) || isspace(c))*/
275/* addch(c);*/
800a900c
JF
276 }
277
05f1685b
JF
278 redrawwin(mainwin);
279 wrefresh(mainwin);
280/* redrawwin(titlewin);*/
281/* wrefresh(titlewin);*/
282/* redrawwin(statuswin);*/
283/* wrefresh(statuswin);*/
800a900c
JF
284 }
285
286 quit(0);
287}
05f1685b
JF
288
289/* addch(ACS_LTEE);*/
290/* addch(ACS_HLINE);*/