Commit | Line | Data |
---|---|---|
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 | ||
30 | WINDOW *titlewin; | |
31 | WINDOW *mainwin; | |
32 | WINDOW *statuswin; | |
33 | ||
34 | typedef void (*pipe_filter_T)(char *, int); | |
35 | ||
36 | FILE *pipe; | |
37 | long pipe_lineno; | |
38 | pipe_filter_T pipe_filter; | |
39 | ||
800a900c JF |
40 | /* |
41 | * Init and quit | |
42 | */ | |
43 | ||
05f1685b JF |
44 | static void |
45 | quit(int sig) | |
800a900c JF |
46 | { |
47 | endwin(); | |
48 | ||
49 | /* do your non-curses wrapup here */ | |
50 | ||
51 | exit(0); | |
52 | } | |
53 | ||
54 | static void | |
55 | init_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 | ||
74 | static void | |
75 | init(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 | |
124 | static void | |
125 | log_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 | ||
179 | static FILE * | |
180 | open_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 | ||
188 | static void | |
189 | read_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 | ||
212 | int | |
213 | main(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);*/ |