X-Git-Url: https://git.distorted.org.uk/~mdw/tig/blobdiff_plain/a9274b95c642f101382a4b617de2e9dadf5f5ec8..19f862bdd79fbdba6c857713425e91f8190dadc5:/tig.c diff --git a/tig.c b/tig.c index 78e8851..da2af8f 100644 --- a/tig.c +++ b/tig.c @@ -68,7 +68,7 @@ static void set_nonblocking_input(bool loading); /* This color name can be used to refer to the default term colors. */ #define COLOR_DEFAULT (-1) -#define TIG_HELP "(d)iff, (l)og, (m)ain, (q)uit, (h)elp, (Enter) show diff" +#define TIG_HELP "(d)iff, (l)og, (m)ain, (q)uit, (h)elp" /* The format and size of the date column in the main view. */ #define DATE_FORMAT "%Y-%m-%d %H:%M" @@ -591,37 +591,51 @@ init_colors(void) #define TIG_PAGER_CMD \ "" + /** * The viewer * ---------- + * The display consists of a status window on the last line of the screen and + * one or more views. The default is to only show one view at the time but it + * is possible to split both the main and log view to also show the commit + * diff. * - * tig(1) presents various 'views' of a repository. Each view is based on output - * from an external command, most often 'git log', 'git diff', or 'git show'. + * If you are in the log view and press 'Enter' when the current line is a + * commit line, such as: * - * The main view:: - * Is the default view, and it shows a one line summary of each commit - * in the chosen list of revisions. The summary includes commit date, - * author, and the first line of the log message. Additionally, any - * repository references, such as tags, will be shown. + * commit 4d55caff4cc89335192f3e566004b4ceef572521 * - * The log view:: - * Presents a more rich view of the revision log showing the whole log - * message and the diffstat. - * - * The diff view:: - * Shows either the diff of the current working tree, that is, what - * has changed since the last commit, or the commit diff complete - * with log message, diffstat and diff. - * - * The pager view:: - * Is used for displaying both input from stdin and output from git - * commands entered in the internal prompt. + * You will split the view so that the log view is displayed in the top window + * and the diff view in the bottom window. You can switch between the two + * views by pressing 'Tab'. To maximize the log view again, simply press 'l'. + **/ + +struct view; + +/* The display array of active views and the index of the current view. */ +static struct view *display[2]; +static unsigned int current_view; + +#define foreach_view(view, i) \ + for (i = 0; i < ARRAY_SIZE(display) && (view = display[i]); i++) + + +/** + * Current head and commit ID + * ~~~~~~~~~~~~~~~~~~~~~~~~~~ + * The viewer keeps track of both what head and commit ID you are currently + * viewing. The commit ID will follow the cursor line and change everytime time + * you highlight a different commit. Whenever you reopen the diff view it + * will be reloaded, if the commit ID changed. * - * The help view:: - * Displays the information from the tig(1) man page. For the help view - * to work you need to have the tig(1) man page installed. + * The head ID is used when opening the main and log view to indicate from + * what revision to show history. **/ +static char ref_commit[SIZEOF_REF] = "HEAD"; +static char ref_head[SIZEOF_REF] = "HEAD"; + + struct view { const char *name; /* View name */ const char *cmd_fmt; /* Default command line format */ @@ -666,32 +680,52 @@ struct view { static struct view_ops pager_ops; static struct view_ops main_ops; -static char ref_head[SIZEOF_REF] = "HEAD"; -static char ref_commit[SIZEOF_REF] = "HEAD"; - #define VIEW_STR(name, cmd, env, ref, objsize, ops) \ { name, cmd, #env, ref, objsize, ops } #define VIEW_(id, name, ops, ref, objsize) \ VIEW_STR(name, TIG_##id##_CMD, TIG_##id##_CMD, ref, objsize, ops) +/** + * Views + * ~~~~~ + * tig(1) presents various 'views' of a repository. Each view is based on output + * from an external command, most often 'git log', 'git diff', or 'git show'. + * + * The main view:: + * Is the default view, and it shows a one line summary of each commit + * in the chosen list of revisions. The summary includes commit date, + * author, and the first line of the log message. Additionally, any + * repository references, such as tags, will be shown. + * + * The log view:: + * Presents a more rich view of the revision log showing the whole log + * message and the diffstat. + * + * The diff view:: + * Shows either the diff of the current working tree, that is, what + * has changed since the last commit, or the commit diff complete + * with log message, diffstat and diff. + * + * The pager view:: + * Is used for displaying both input from stdin and output from git + * commands entered in the internal prompt. + * + * The help view:: + * Displays the information from the tig(1) man page. For the help view + * to work you need to have the tig(1) man page installed. + **/ + static struct view views[] = { VIEW_(MAIN, "main", &main_ops, ref_head, sizeof(struct commit)), VIEW_(DIFF, "diff", &pager_ops, ref_commit, sizeof(char)), VIEW_(LOG, "log", &pager_ops, ref_head, sizeof(char)), - VIEW_(HELP, "help", &pager_ops, ref_head, sizeof(char)), + VIEW_(HELP, "help", &pager_ops, "static", sizeof(char)), VIEW_(PAGER, "pager", &pager_ops, "static", sizeof(char)), }; #define VIEW(req) (&views[(req) - REQ_OFFSET - 1]) -/* The display array of active views and the index of the current view. */ -static struct view *display[2]; -static unsigned int current_view; - -#define foreach_view(view, i) \ - for (i = 0; i < ARRAY_SIZE(display) && (view = display[i]); i++) - static void redraw_view_from(struct view *view, int lineno) @@ -714,6 +748,45 @@ redraw_view(struct view *view) redraw_view_from(view, 0); } + +/** + * Title windows + * ~~~~~~~~~~~~~ + * Each view has a title window which shows the name of the view, current + * commit ID if available, and where the view is positioned: + * + * [main] c622eefaa485995320bc743431bae0d497b1d875 - commit 1 of 61 (1%) + * + * By default, the title of the current view is highlighted using bold font. + **/ + +static void +update_view_title(struct view *view) +{ + if (view == display[current_view]) + wbkgdset(view->title, get_line_attr(LINE_TITLE_FOCUS)); + else + wbkgdset(view->title, get_line_attr(LINE_TITLE_BLUR)); + + werase(view->title); + wmove(view->title, 0, 0); + + if (*view->ref) + wprintw(view->title, "[%s] %s", view->name, view->ref); + else + wprintw(view->title, "[%s]", view->name); + + if (view->lines) { + wprintw(view->title, " - %s %d of %d (%d%%)", + view->ops->type, + view->lineno + 1, + view->lines, + (view->lineno + 1) * 100 / view->lines); + } + + wrefresh(view->title); +} + static void resize_display(void) { @@ -744,9 +817,9 @@ resize_display(void) offset = 0; foreach_view (view, i) { - /* Keep the size of the all view windows one lager than is - * required. This makes current line management easier when the - * cursor will go outside the window. */ + /* Keep the height of all view->win windows one larger than is + * required so that the cursor can wrap-around on the last line + * without scrolling the window. */ if (!view->win) { view->win = newwin(view->height + 1, 0, offset, 0); if (!view->win) @@ -770,34 +843,18 @@ resize_display(void) } static void -update_view_title(struct view *view) +redraw_display(void) { - if (view == display[current_view]) - wbkgdset(view->title, get_line_attr(LINE_TITLE_FOCUS)); - else - wbkgdset(view->title, get_line_attr(LINE_TITLE_BLUR)); - - werase(view->title); - wmove(view->title, 0, 0); - - /* [main] ref: 334b506... - commit 6 of 4383 (0%) */ - - if (*view->ref) - wprintw(view->title, "[%s] %s", view->name, view->ref); - else - wprintw(view->title, "[%s]", view->name); + struct view *view; + int i; - if (view->lines) { - wprintw(view->title, " - %s %d of %d (%d%%)", - view->ops->type, - view->lineno + 1, - view->lines, - (view->lineno + 1) * 100 / view->lines); + foreach_view (view, i) { + redraw_view(view); + update_view_title(view); } - - wrefresh(view->title); } + /* * Navigation */ @@ -1310,8 +1367,7 @@ view_driver(struct view *view, enum request request) } case REQ_TOGGLE_LINE_NUMBERS: opt_line_number = !opt_line_number; - redraw_view(view); - update_view_title(view); + redraw_display(); break; case REQ_PROMPT: @@ -1335,10 +1391,7 @@ view_driver(struct view *view, enum request request) resize_display(); /* Fall-through */ case REQ_SCREEN_REDRAW: - foreach_view (view, i) { - redraw_view(view); - update_view_title(view); - } + redraw_display(); break; case REQ_SCREEN_UPDATE: @@ -1468,6 +1521,11 @@ pager_enter(struct view *view) { char *line = view->line[view->lineno]; + if (view == VIEW(REQ_VIEW_DIFF)) { + scroll_view(view, REQ_SCROLL_LINE_DOWN); + return TRUE; + } + if (get_line_type(line) == LINE_COMMIT) { if (view == VIEW(REQ_VIEW_LOG)) open_view(view, REQ_VIEW_DIFF, OPEN_SPLIT | OPEN_BACKGROUNDED); @@ -1707,10 +1765,11 @@ static struct keymap keymap[] = { * Switch to pager view. * h:: * Show man page. - * Return:: - * If on a commit line show the commit diff. Additionally, if in - * main or log view this will split the view. To open the commit - * diff in full size view either use 'd' or press Return twice. + * Enter:: + * This key is "context sensitive" depending on what view you are + * currently in. When in log view on a commit line or in the main + * view, split the view and show the commit diff. In the diff view + * pressing Enter will simply scroll the view one line down. * Tab:: * Switch to next view. **/ @@ -1737,8 +1796,10 @@ static struct keymap keymap[] = { * j:: * Move cursor one line down and enter. * PgUp:: + * b:: * Move cursor one page up. * PgDown:: + * Space:: * Move cursor one page down. * Home:: * Jump to first line. @@ -1752,7 +1813,9 @@ static struct keymap keymap[] = { { KEY_HOME, REQ_MOVE_FIRST_LINE }, { KEY_END, REQ_MOVE_LAST_LINE }, { KEY_NPAGE, REQ_MOVE_PAGE_DOWN }, + { ' ', REQ_MOVE_PAGE_DOWN }, { KEY_PPAGE, REQ_MOVE_PAGE_UP }, + { 'b', REQ_MOVE_PAGE_UP }, /** * Scrolling @@ -2158,7 +2221,7 @@ main(int argc, char *argv[]) * If you are interested only in those revisions that made changes to a * specific file (or even several files) list the files like this: * - * $ tig log Makefile + * $ tig log Makefile README * * To avoid ambiguity with repository references such as tag name, be sure * to separate file names from other git options using "\--". So if you @@ -2180,11 +2243,10 @@ main(int argc, char *argv[]) * If you are only interested in changed that happened between two dates * you can use: * - * $ tig -- --after=May.5th --before=2006-05-16.15:44 + * $ tig -- --after="May 5th" --before="2006-05-16 15:44" * - * NOTE: The dot (".") is used as a separator instead of a space to avoid - * having to quote the option value. If you prefer use `--after="May 5th"` - * instead of `--after="May 5th"`. + * NOTE: If you want to avoid having to quote dates containing spaces you + * can use "." instead, e.g. `--after=May.5th`. * * Limiting by commit ranges * ~~~~~~~~~~~~~~~~~~~~~~~~~