summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: a74fa19)
raw | patch | inline | side by side (parent: a74fa19)
author | Jonas Fonseca <fonseca@diku.dk> | |
Sat, 22 Apr 2006 19:39:33 +0000 (21:39 +0200) | ||
committer | Jonas Fonseca <fonseca@antimatter.localdomain> | |
Sat, 22 Apr 2006 19:39:33 +0000 (21:39 +0200) |
Makefile | patch | blob | history | |
asciidoc.conf | [new file with mode: 0644] | patch | blob |
cgit.c | patch | blob | history |
diff --git a/Makefile b/Makefile
index eec1e0301682a79a2fd583c0321abe8f0b3c57ec..efeca0d36e948b5f8bb57a95447204c66c046734 100644 (file)
--- a/Makefile
+++ b/Makefile
LDFLAGS = -lcurses
CFLAGS = -g
+PROGS = cgit
+DOCS = cgit.1.txt cgit.1 cgit.1.html
-all: cgit
+all: $(PROGS)
+docs: $(DOCS)
install: all
- install cgit $(HOME)/bin
+ for prog in $(PROGS); do \
+ install $$prog $(HOME)/bin; \
+ done
clean:
- rm -f cgit
+ rm -f $(PROGS) $(DOCS)
cgit: cgit.c
+
+cgit.1.txt: cgit.c
+ sed -n '/\*\*/,/\*\*/p' < $< | \
+ sed '/\*\*/d' | \
+ sed -n 's/^ \* *//p' > $@
+
+%.1.html : %.1.txt
+ asciidoc -b xhtml11 -d manpage -f asciidoc.conf $<
+
+%.1.xml : %.1.txt
+ asciidoc -b docbook -d manpage -f asciidoc.conf $<
+
+%.1 : %.1.xml
+ xmlto man $<
diff --git a/asciidoc.conf b/asciidoc.conf
--- /dev/null
+++ b/asciidoc.conf
@@ -0,0 +1,25 @@
+## gitlink: macro
+#
+# Usage: gitlink:command[manpage-section]
+#
+# Note, {0} is the manpage section, while {target} is the command.
+#
+# Show GIT link as: <command>(<section>); if section is defined, else just show
+# the command.
+
+ifdef::backend-docbook[]
+[gitlink-inlinemacro]
+{0%{target}}
+{0#<citerefentry>}
+{0#<refentrytitle>{target}</refentrytitle><manvolnum>{0}</manvolnum>}
+{0#</citerefentry>}
+endif::backend-docbook[]
+
+ifdef::backend-xhtml11[]
+[gitlink-inlinemacro]
+<a href="{target}{0?.{0}}.html">{target}{0?({0})}</a>
+endif::backend-xhtml11[]
+
+[attributes]
+# Five non breaking spaces used for option indentation in the quick reference
+cg-refopt=     
index a05103ec8ed0dedd12fafec64063824c7c10db52..20d58fa5801b16f35d4f5aeec2295001947f7a5f 100644 (file)
--- a/cgit.c
+++ b/cgit.c
-/* Cursed git browser
+/**
+ * gitzilla(1)
+ * ===========
*
- * Copyright (c) Jonas Fonseca, 2006
+ * NAME
+ * ----
+ * gitzilla - cursed git browser
*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
+ * SYNOPSIS
+ * --------
+ * gitzilla
+ *
+ * DESCRIPTION
+ * -----------
+ *
+ * a
+ *
+ **/
#include <stdarg.h>
#include <stdlib.h>
#include <curses.h>
+/**
+ * OPTIONS
+ * -------
+ *
+ * None
+ *
+ **/
+
+/**
+ * KEYS
+ * ----
+ *
+ * q:: quit
+ * s:: shell
+ * j:: down
+ * k:: up
+ *
+ **/
#define MSG_HELP "(q)uit, (s)hell, (j) down, (k) up"
#define KEY_ESC 27
#define KEY_TAB 9
-//WINDOW *titlewin;
-WINDOW *mainwin;
-WINDOW *statuswin;
+struct view {
+ WINDOW *win;
-typedef void (*pipe_reader_T)(char *, int);
+ char *cmd;
+ void (*reader)(char *, int);
+ FILE *pipe;
-FILE *pipe;
-long pipe_lineno;
-pipe_reader_T pipe_reader;
+ unsigned long lines;
+ unsigned long lineno;
+};
+static struct view main_view;
+static struct view diff_view;
+static struct view log_view;
+static struct view status_view;
+
+int do_resize = 1;
static void
put_status(char *msg, ...)
va_list args;
va_start(args, msg);
- werase(statuswin);
- wmove(statuswin, 0, 0);
- vwprintw(statuswin, msg, args);
- wrefresh(statuswin);
+ werase(status_view.win);
+ wmove(status_view.win, 0, 0);
+ vwprintw(status_view.win, msg, args);
+ wrefresh(status_view.win);
va_end(args);
}
+static void
+resize_views(void)
+{
+ int x, y;
+
+ getmaxyx(stdscr, y, x);
+
+ if (status_view.win)
+ delwin(status_view.win);
+ status_view.win = newwin(1, 0, y - 1, 0);
+
+ wattrset(status_view.win, COLOR_PAIR(COLOR_GREEN));
+ put_status(MSG_HELP);
+
+ if (main_view.win)
+ delwin(main_view.win);
+ main_view.win = newwin(y - 1, 0, 0, 0);
+
+ scrollok(main_view.win, TRUE);
+ keypad(main_view.win, TRUE); /* enable keyboard mapping */
+ put_status("%d %d", y, x);
+}
+
/*
* Init and quit
*/
static void
init(void)
{
- int x, y;
-
signal(SIGINT, quit);
initscr(); /* initialize the curses library */
cbreak(); /* take input chars one at a time, no wait for \n */
noecho(); /* don't echo input */
leaveok(stdscr, TRUE);
+ /* curs_set(0); */
if (has_colors())
init_colors();
-
- getmaxyx(stdscr, y, x);
-
-#if 0
- titlewin = newwin(1, 0, y - 2, 0);
-
- wattrset(titlewin, COLOR_PAIR(COLOR_GREEN));
- waddch(titlewin, ACS_VLINE);
- wprintw(titlewin, "%s", "cg-view");
- waddch(titlewin, ACS_LTEE);
- whline(titlewin, ACS_HLINE, x);
- wrefresh(titlewin);
-#endif
- statuswin = newwin(1, 0, y - 1, 0);
-
- wattrset(statuswin, COLOR_PAIR(COLOR_GREEN));
- put_status(MSG_HELP);
-
- mainwin = newwin(y - 1, 0, 0, 0);
- scrollok(mainwin, TRUE);
- keypad(mainwin, TRUE); /* enable keyboard mapping */
}
/*
*/
#define DIFF_CMD \
- "git-rev-list HEAD^..HEAD | " \
- "git-diff-tree --stdin --pretty -r --cc --always --stat"
-
-
-#define LOG_CMD0 \
- "git-rev-list $(git-rev-parse --since=1.month) HEAD | " \
- "git-diff-tree --stdin --pretty -r --root"
+ "git log --stat -n1 HEAD ; echo; " \
+ "git diff --find-copies-harder -B -C HEAD^ HEAD"
#define LOG_CMD \
- "git-rev-list HEAD | git-diff-tree --stdin --pretty -r --root"
+ "git log --stat -n100"
static void
log_reader(char *line, int lineno)
static int log_reader_skip;
if (!line) {
- wattrset(mainwin, A_NORMAL);
+ wattrset(main_view.win, A_NORMAL);
log_reader_skip = 0;
return;
}
if (!strncmp("commit ", line, 7)) {
- wattrset(mainwin, COLOR_PAIR(COLOR_GREEN));
+ wattrset(main_view.win, COLOR_PAIR(COLOR_GREEN));
} else if (!strncmp("Author: ", line, 8)) {
- wattrset(mainwin, COLOR_PAIR(COLOR_CYAN));
+ wattrset(main_view.win, COLOR_PAIR(COLOR_CYAN));
- } else if (!strncmp("Date: ", line, 6)) {
- wattrset(mainwin, COLOR_PAIR(COLOR_YELLOW));
+ } else if (!strncmp("Date: ", line, 8)) {
+ wattrset(main_view.win, COLOR_PAIR(COLOR_YELLOW));
} else if (!strncmp("diff --git ", line, 11)) {
- wattrset(mainwin, COLOR_PAIR(COLOR_YELLOW));
+ wattrset(main_view.win, COLOR_PAIR(COLOR_YELLOW));
} else if (!strncmp("diff-tree ", line, 10)) {
- wattrset(mainwin, COLOR_PAIR(COLOR_BLUE));
+ wattrset(main_view.win, COLOR_PAIR(COLOR_BLUE));
} else if (!strncmp("index ", line, 6)) {
- wattrset(mainwin, COLOR_PAIR(COLOR_BLUE));
+ wattrset(main_view.win, COLOR_PAIR(COLOR_BLUE));
} else if (line[0] == '-') {
- wattrset(mainwin, COLOR_PAIR(COLOR_RED));
+ wattrset(main_view.win, COLOR_PAIR(COLOR_RED));
} else if (line[0] == '+') {
- wattrset(mainwin, COLOR_PAIR(COLOR_GREEN));
+ wattrset(main_view.win, COLOR_PAIR(COLOR_GREEN));
} else if (line[0] == '@') {
- wattrset(mainwin, COLOR_PAIR(COLOR_MAGENTA));
+ wattrset(main_view.win, COLOR_PAIR(COLOR_MAGENTA));
} else if (line[0] == ':') {
- pipe_lineno--;
+ main_view.lines--;
log_reader_skip = 1;
return;
} else if (log_reader_skip) {
- pipe_lineno--;
+ main_view.lines--;
log_reader_skip = 0;
return;
} else {
- wattrset(mainwin, A_NORMAL);
+ wattrset(main_view.win, A_NORMAL);
}
- mvwaddstr(mainwin, lineno, 0, line);
+ mvwaddstr(main_view.win, lineno, 0, line);
}
-static FILE *
-open_pipe(char *cmd, pipe_reader_T reader)
+static struct view *
+update_view(struct view *view, char *cmd)
{
- pipe = popen(cmd, "r");
- pipe_lineno = 0;
- pipe_reader = reader;
- wclear(mainwin);
- wmove(mainwin, 0, 0);
+ view->cmd = cmd;
+ view->pipe = popen(cmd, "r");
+ view->lines = 0;
+ view->lineno = 0;
+ view->reader = log_reader;
+
+ wclear(view->win);
+ wmove(view->win, 0, 0);
+
put_status("Loading...");
- return pipe;
+
+ return view;
}
-static void
-read_pipe(int lines)
+static struct view *
+read_pipe(struct view *view, int lines)
{
char buffer[BUFSIZ];
char *line;
int x, y;
- while ((line = fgets(buffer, sizeof(buffer), pipe))) {
+ while ((line = fgets(buffer, sizeof(buffer), view->pipe))) {
int linelen;
if (!--lines)
if (linelen)
line[linelen - 1] = 0;
- pipe_reader(line, pipe_lineno++);
+ view->reader(line, view->lines++);
}
- if (feof(pipe) || ferror(pipe)) {
- pipe_reader(NULL, pipe_lineno - 1);
- pclose(pipe);
- pipe = NULL;
- pipe_reader = NULL;
- put_status("%s (lines %d)", MSG_HELP, pipe_lineno - 1);
+ if (ferror(view->pipe)) {
+ put_status("Failed to read %s", view->cmd, view->lines - 1);
+
+ } else if (feof(view->pipe)) {
+ put_status("%s (lines %d)", MSG_HELP, view->lines - 1);
+
+ } else {
+ return view;
}
+
+ view->reader(NULL, view->lines - 1);
+ pclose(view->pipe);
+ view->pipe = NULL;
+ view->reader = NULL;
}
/*
int
main(int argc, char *argv[])
{
+ static struct view *loading_view;
+
init();
//pipe = open_pipe(LOG_CMD, log_reader);
for (;;) {
int c;
- if (pipe) read_pipe(20);
- if (pipe) nodelay(mainwin, TRUE);
+ if (do_resize) {
+ resize_views();
+ do_resize = 0;
+ }
+
+ if (loading_view && (loading_view = read_pipe(loading_view, 20)))
+ nodelay(loading_view->win, TRUE);
- c = wgetch(mainwin); /* refresh, accept single keystroke of input */
+ c = wgetch(main_view.win); /* refresh, accept single keystroke of input */
- if (pipe) nodelay(mainwin, FALSE);
+ if (loading_view)
+ nodelay(loading_view->win, FALSE);
/* No input from wgetch() with nodelay() enabled. */
- if (c == ERR)
+ if (c == ERR) {
+ doupdate();
continue;
+ }
/* Process the command keystroke */
switch (c) {
+ case KEY_RESIZE:
+ fprintf(stderr, "resize");
+ exit;
+ break;
+
case KEY_ESC:
case 'q':
quit(0);
+ main_view.lineno--;
return 0;
case KEY_DOWN:
case 'j':
- wscrl(mainwin, 1);
+ {
+ int x, y;
+
+ getmaxyx(main_view.win, y, x);
+ if (main_view.lineno + y < main_view.lines) {
+ wscrl(main_view.win, 1);
+ main_view.lineno++;
+ put_status("line %d out of %d (%d%%)",
+ main_view.lineno,
+ main_view.lines,
+ 100 * main_view.lineno / main_view.lines);
+ } else {
+ put_status("last line reached");
+ }
break;
-
+ }
case KEY_UP:
case 'k':
- wscrl(mainwin, -1);
+ if (main_view.lineno > 1) {
+ wscrl(main_view.win, -1);
+ main_view.lineno--;
+ put_status("line %d out of %d (%d%%)",
+ main_view.lineno,
+ main_view.lines,
+ 100 * main_view.lineno / main_view.lines);
+ } else {
+ put_status("first line reached");
+ }
break;
case 'c':
- wclear(mainwin);
+ wclear(main_view.win);
break;
case 'd':
- pipe = open_pipe(DIFF_CMD, log_reader);
+ loading_view = update_view(&main_view, DIFF_CMD);
break;
case 'l':
- pipe = open_pipe(LOG_CMD, log_reader);
+ loading_view = update_view(&main_view, LOG_CMD);
break;
case 's':
- mvwaddstr(statuswin, 0, 0, "Shelling out...");
+ mvwaddstr(status_view.win, 0, 0, "Shelling out...");
def_prog_mode(); /* save current tty modes */
endwin(); /* restore original tty modes */
system("sh"); /* run shell */
- werase(statuswin);
- mvwaddstr(statuswin, 0, 0, MSG_HELP);
+ werase(status_view.win);
+ mvwaddstr(status_view.win, 0, 0, MSG_HELP);
reset_prog_mode();
break;
}
- redrawwin(mainwin);
- wrefresh(mainwin);
+ redrawwin(main_view.win);
+ wrefresh(main_view.win);
}
quit(0);
}
+
+/**
+ * COPYRIGHT
+ * ---------
+ * Copyright (c) Jonas Fonseca, 2006
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * SEE ALSO
+ * --------
+ * gitlink:cogito[7],
+ * gitlink:git[7]
+ **/