7 * gitzilla - cursed git browser
48 #define MSG_HELP "(q)uit, (s)hell, (j) down, (k) up"
57 void (*reader
)(char *, int);
64 static struct view main_view
;
65 static struct view diff_view
;
66 static struct view log_view
;
67 static struct view status_view
;
72 put_status(char *msg
, ...)
77 werase(status_view
.win
);
78 wmove(status_view
.win
, 0, 0);
79 vwprintw(status_view
.win
, msg
, args
);
80 wrefresh(status_view
.win
);
89 getmaxyx(stdscr
, y
, x
);
92 delwin(status_view
.win
);
93 status_view
.win
= newwin(1, 0, y
- 1, 0);
95 wattrset(status_view
.win
, COLOR_PAIR(COLOR_GREEN
));
99 delwin(main_view
.win
);
100 main_view
.win
= newwin(y
- 1, 0, 0, 0);
102 scrollok(main_view
.win
, TRUE
);
103 keypad(main_view
.win
, TRUE
); /* enable keyboard mapping */
104 put_status("%d %d", y
, x
);
116 /* do your non-curses wrapup here */
124 int bg
= COLOR_BLACK
;
128 if (use_default_colors() != ERR
)
131 init_pair(COLOR_BLACK
, COLOR_BLACK
, bg
);
132 init_pair(COLOR_GREEN
, COLOR_GREEN
, bg
);
133 init_pair(COLOR_RED
, COLOR_RED
, bg
);
134 init_pair(COLOR_CYAN
, COLOR_CYAN
, bg
);
135 init_pair(COLOR_WHITE
, COLOR_WHITE
, bg
);
136 init_pair(COLOR_MAGENTA
, COLOR_MAGENTA
, bg
);
137 init_pair(COLOR_BLUE
, COLOR_BLUE
, bg
);
138 init_pair(COLOR_YELLOW
, COLOR_YELLOW
, bg
);
144 signal(SIGINT
, quit
);
146 initscr(); /* initialize the curses library */
147 nonl(); /* tell curses not to do NL->CR/NL on output */
148 cbreak(); /* take input chars one at a time, no wait for \n */
149 noecho(); /* don't echo input */
150 leaveok(stdscr
, TRUE
);
162 "git log --stat -n1 HEAD ; echo; " \
163 "git diff --find-copies-harder -B -C HEAD^ HEAD"
166 "git log --stat -n100"
169 log_reader(char *line
, int lineno
)
171 static int log_reader_skip
;
174 wattrset(main_view
.win
, A_NORMAL
);
179 if (!strncmp("commit ", line
, 7)) {
180 wattrset(main_view
.win
, COLOR_PAIR(COLOR_GREEN
));
182 } else if (!strncmp("Author: ", line
, 8)) {
183 wattrset(main_view
.win
, COLOR_PAIR(COLOR_CYAN
));
185 } else if (!strncmp("Date: ", line
, 8)) {
186 wattrset(main_view
.win
, COLOR_PAIR(COLOR_YELLOW
));
188 } else if (!strncmp("diff --git ", line
, 11)) {
189 wattrset(main_view
.win
, COLOR_PAIR(COLOR_YELLOW
));
191 } else if (!strncmp("diff-tree ", line
, 10)) {
192 wattrset(main_view
.win
, COLOR_PAIR(COLOR_BLUE
));
194 } else if (!strncmp("index ", line
, 6)) {
195 wattrset(main_view
.win
, COLOR_PAIR(COLOR_BLUE
));
197 } else if (line
[0] == '-') {
198 wattrset(main_view
.win
, COLOR_PAIR(COLOR_RED
));
200 } else if (line
[0] == '+') {
201 wattrset(main_view
.win
, COLOR_PAIR(COLOR_GREEN
));
203 } else if (line
[0] == '@') {
204 wattrset(main_view
.win
, COLOR_PAIR(COLOR_MAGENTA
));
206 } else if (line
[0] == ':') {
211 } else if (log_reader_skip
) {
217 wattrset(main_view
.win
, A_NORMAL
);
220 mvwaddstr(main_view
.win
, lineno
, 0, line
);
224 update_view(struct view
*view
, char *cmd
)
227 view
->pipe
= popen(cmd
, "r");
230 view
->reader
= log_reader
;
233 wmove(view
->win
, 0, 0);
235 put_status("Loading...");
241 read_pipe(struct view
*view
, int lines
)
247 while ((line
= fgets(buffer
, sizeof(buffer
), view
->pipe
))) {
253 linelen
= strlen(line
);
255 line
[linelen
- 1] = 0;
257 view
->reader(line
, view
->lines
++);
260 if (ferror(view
->pipe
)) {
261 put_status("Failed to read %s", view
->cmd
, view
->lines
- 1);
263 } else if (feof(view
->pipe
)) {
264 put_status("%s (lines %d)", MSG_HELP
, view
->lines
- 1);
270 view
->reader(NULL
, view
->lines
- 1);
281 main(int argc
, char *argv
[])
283 static struct view
*loading_view
;
287 //pipe = open_pipe(LOG_CMD, log_reader);
297 if (loading_view
&& (loading_view
= read_pipe(loading_view
, 20)))
298 nodelay(loading_view
->win
, TRUE
);
300 c
= wgetch(main_view
.win
); /* refresh, accept single keystroke of input */
303 nodelay(loading_view
->win
, FALSE
);
305 /* No input from wgetch() with nodelay() enabled. */
311 /* Process the command keystroke */
314 fprintf(stderr
, "resize");
329 getmaxyx(main_view
.win
, y
, x
);
330 if (main_view
.lineno
+ y
< main_view
.lines
) {
331 wscrl(main_view
.win
, 1);
333 put_status("line %d out of %d (%d%%)",
336 100 * main_view
.lineno
/ main_view
.lines
);
338 put_status("last line reached");
344 if (main_view
.lineno
> 1) {
345 wscrl(main_view
.win
, -1);
347 put_status("line %d out of %d (%d%%)",
350 100 * main_view
.lineno
/ main_view
.lines
);
352 put_status("first line reached");
357 wclear(main_view
.win
);
361 loading_view
= update_view(&main_view
, DIFF_CMD
);
365 loading_view
= update_view(&main_view
, LOG_CMD
);
369 mvwaddstr(status_view
.win
, 0, 0, "Shelling out...");
370 def_prog_mode(); /* save current tty modes */
371 endwin(); /* restore original tty modes */
372 system("sh"); /* run shell */
374 werase(status_view
.win
);
375 mvwaddstr(status_view
.win
, 0, 0, MSG_HELP
);
380 redrawwin(main_view
.win
);
381 wrefresh(main_view
.win
);
390 * Copyright (c) Jonas Fonseca, 2006
392 * This program is free software; you can redistribute it and/or modify
393 * it under the terms of the GNU General Public License as published by
394 * the Free Software Foundation; either version 2 of the License, or
395 * (at your option) any later version.