Half working prototype
[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 | " \
122 "git-diff-tree --stdin --pretty -r"
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] == ':') {
163 log_filter_skip = 1;
164 return;
165
166 } else if (log_filter_skip) {
167 log_filter_skip = 0;
168 return;
169
170 } else {
171 wattrset(mainwin, A_NORMAL);
172 }
173
174 mvwaddstr(mainwin, lineno, 0, line);
175}
176
177static FILE *
178open_pipe(char *cmd, pipe_filter_T filter)
179{
180 pipe = popen(cmd, "r");
181 pipe_lineno = 1;
182 pipe_filter = filter;
183 return pipe;
184}
185
186static void
187read_pipe(int lines)
188{
189 char buffer[BUFSIZ];
190 char *line;
191
192 while ((line = fgets(buffer, sizeof(buffer), pipe))) {
193 pipe_filter(line, pipe_lineno++);
194 if (!--lines)
195 break;
196 }
197
198 if (feof(pipe) || ferror(pipe)) {
199 pipe_filter(NULL, pipe_lineno - 1);
200 pclose(pipe);
201 pipe = NULL;
202 pipe_filter = NULL;
203 }
800a900c
JF
204}
205
206/*
207 * Main
208 */
209
210int
211main(int argc, char *argv[])
212{
800a900c
JF
213 init();
214
05f1685b 215 pipe = open_pipe(LOG_CMD, log_filter);
800a900c
JF
216
217 for (;;) {
05f1685b
JF
218 int c;
219
220 if (pipe) read_pipe(20);
221 if (pipe) nodelay(mainwin, TRUE);
222
223 c = wgetch(mainwin); /* refresh, accept single keystroke of input */
224
225 if (pipe) nodelay(mainwin, FALSE);
226
227 if (c == ERR)
228 continue;
800a900c
JF
229
230 /* Process the command keystroke */
231 switch (c) {
05f1685b 232 case KEY_ESC:
800a900c
JF
233 case 'q':
234 quit(0);
235 return 0;
236
05f1685b
JF
237 case KEY_DOWN:
238 case 'j':
239 wscrl(mainwin, 1);
240 break;
241
242 case KEY_UP:
243 case 'k':
244 wscrl(mainwin, -1);
245 break;
246
247 case 'd':
248 pipe = open_pipe(DIFF_CMD, log_filter);
249 wclear(mainwin);
250 wmove(mainwin, 0, 0);
251 break;
252
253 case 'l':
254 pipe = open_pipe(LOG_CMD, log_filter);
255 wclear(mainwin);
256 wmove(mainwin, 0, 0);
257 break;
258
800a900c 259 case 's':
05f1685b 260 mvwaddstr(statuswin, 0, 0, "Shelling out......................");
800a900c
JF
261 def_prog_mode(); /* save current tty modes */
262 endwin(); /* restore original tty modes */
263 system("sh"); /* run shell */
05f1685b
JF
264
265 wclear(statuswin);
266 mvwaddstr(statuswin, 0, 0, CGIT_HELP);
800a900c
JF
267 reset_prog_mode();
268 //refresh(); /* restore save modes, repaint screen */
269 break;
270
05f1685b
JF
271/* default:*/
272/* if (isprint(c) || isspace(c))*/
273/* addch(c);*/
800a900c
JF
274 }
275
05f1685b
JF
276 redrawwin(mainwin);
277 wrefresh(mainwin);
278/* redrawwin(titlewin);*/
279/* wrefresh(titlewin);*/
280/* redrawwin(statuswin);*/
281/* wrefresh(statuswin);*/
800a900c
JF
282 }
283
284 quit(0);
285}
05f1685b
JF
286
287/* addch(ACS_LTEE);*/
288/* addch(ACS_HLINE);*/