X-Git-Url: https://git.distorted.org.uk/~mdw/tig/blobdiff_plain/6cb291b793ec51232396303bcb3c461650fe511f..415de53cef9d8477e97fbee65403932cd45ed042:/tig.c diff --git a/tig.c b/tig.c index 40942a3..3c267af 100644 --- a/tig.c +++ b/tig.c @@ -208,6 +208,25 @@ sq_quote(char buf[SIZEOF_CMD], size_t bufsize, const char *src) * ------- **/ +static const char usage[] = +VERSION " (" __DATE__ ")\n" +"\n" +"Usage: tig [options]\n" +" or: tig [options] [--] [git log options]\n" +" or: tig [options] log [git log options]\n" +" or: tig [options] diff [git diff options]\n" +" or: tig [options] show [git show options]\n" +" or: tig [options] < [git command output]\n" +"\n" +"Options:\n" +" -l Start up in log view\n" +" -d Start up in diff view\n" +" -n[I], --line-number[=I] Show line numbers with given interval\n" +" -t[N], --tab-size[=N] Set number of spaces for tab expansion\n" +" -- Mark end of tig options\n" +" -v, --version Show version and exit\n" +" -h, --help Show help message and exit\n"; + /* Option and state variables. */ static bool opt_line_number = FALSE; static int opt_num_interval = NUMBER_INTERVAL; @@ -297,6 +316,16 @@ parse_options(int argc, char *argv[]) } /** + * -h, --help:: + * Show help message and exit. + **/ + if (!strcmp(opt, "-h") || + !strcmp(opt, "--help")) { + printf(usage); + return FALSE; + } + + /** * \--:: * End of tig(1) options. Useful when specifying command * options for the main view. Example: @@ -645,7 +674,6 @@ struct view { const char *cmd_fmt; /* Default command line format */ const char *cmd_env; /* Command line set via environment */ const char *id; /* Points to either of ref_{head,commit} */ - size_t objsize; /* Size of objects in the line index */ struct view_ops { /* What type of content being displayed. Used in the @@ -671,6 +699,10 @@ struct view { unsigned long offset; /* Offset of the window top */ unsigned long lineno; /* Current line number */ + /* If non-NULL, points to the view that opened this view. If this view + * is closed tig will switch back to the parent view. */ + struct view *parent; + /* Buffering */ unsigned long lines; /* Total number of lines */ void **line; /* Line index; each line contains user data */ @@ -684,11 +716,11 @@ struct view { static struct view_ops pager_ops; static struct view_ops main_ops; -#define VIEW_STR(name, cmd, env, ref, objsize, ops) \ - { name, cmd, #env, ref, objsize, ops } +#define VIEW_STR(name, cmd, env, ref, ops) \ + { name, cmd, #env, ref, ops } -#define VIEW_(id, name, ops, ref, objsize) \ - VIEW_STR(name, TIG_##id##_CMD, TIG_##id##_CMD, ref, objsize, ops) +#define VIEW_(id, name, ops, ref) \ + VIEW_STR(name, TIG_##id##_CMD, TIG_##id##_CMD, ref, ops) /** * Views @@ -721,11 +753,11 @@ static struct view_ops main_ops; **/ 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, "static", sizeof(char)), - VIEW_(PAGER, "pager", &pager_ops, "static", sizeof(char)), + VIEW_(MAIN, "main", &main_ops, ref_head), + VIEW_(DIFF, "diff", &pager_ops, ref_commit), + VIEW_(LOG, "log", &pager_ops, ref_head), + VIEW_(HELP, "help", &pager_ops, "static"), + VIEW_(PAGER, "pager", &pager_ops, "static"), }; #define VIEW(req) (&views[(req) - REQ_OFFSET - 1]) @@ -1228,21 +1260,7 @@ open_view(struct view *prev, enum request request, enum open_flags flags) bool split = !!(flags & OPEN_SPLIT); bool reload = !!(flags & OPEN_RELOAD); struct view *view = VIEW(request); - struct view *displayed; - int nviews; - - /* Cycle between displayed views and count the views. */ - foreach_view (displayed, nviews) { - if (prev != view && - view == displayed && - !strcmp(view->vid, prev->vid)) { - current_view = nviews; - /* Blur out the title of the previous view. */ - update_view_title(prev); - report(""); - return; - } - } + int nviews = display[1] ? 2 : 1; if (view == prev && nviews == 1 && !reload) { report("Already in %s view", view->name); @@ -1285,6 +1303,7 @@ open_view(struct view *prev, enum request request, enum open_flags flags) /* Continue loading split views in the background. */ if (!split) end_update(prev); + view->parent = prev; } if (view->pipe) { @@ -1403,11 +1422,11 @@ view_driver(struct view *view, enum request request) return TRUE; case REQ_VIEW_CLOSE: - if (display[1]) { - view = display[(current_view + 1) % ARRAY_SIZE(display)]; + if (view->parent) { memset(display, 0, sizeof(display)); current_view = 0; - display[current_view] = view; + display[current_view] = view->parent; + view->parent = NULL; resize_display(); redraw_display(); break; @@ -1535,18 +1554,25 @@ static bool pager_enter(struct view *view) { char *line = view->line[view->lineno]; + int split = 0; - if (view == VIEW(REQ_VIEW_DIFF)) { - scroll_view(view, REQ_SCROLL_LINE_DOWN); - return TRUE; + if ((view == VIEW(REQ_VIEW_LOG) || + view == VIEW(REQ_VIEW_PAGER)) && + get_line_type(line) == LINE_COMMIT) { + open_view(view, REQ_VIEW_DIFF, OPEN_SPLIT); + split = 1; } - if (get_line_type(line) == LINE_COMMIT) { - if (view == VIEW(REQ_VIEW_LOG)) - open_view(view, REQ_VIEW_DIFF, OPEN_SPLIT | OPEN_BACKGROUNDED); - else - open_view(view, REQ_VIEW_DIFF, OPEN_DEFAULT); - } + /* Always scroll the view even if it was split. That way + * you can use Enter to scroll through the log view and + * split open each commit diff. */ + scroll_view(view, REQ_SCROLL_LINE_DOWN); + + /* FIXME: A minor workaround. Scrolling the view will call report("") + * but if we are scolling a non-current view this won't properly update + * the view title. */ + if (split) + update_view_title(view); return TRUE; } @@ -1786,7 +1812,9 @@ static struct keymap keymap[] = { * h:: * Show man page. * q:: - * Close view if multiple views are open, else quit. + * Close view, if multiple views are open it will jump back to the + * previous view in the view stack. If it is the last open view it + * will quit. Use 'Q' to quit all views at once. * 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 @@ -1820,6 +1848,7 @@ static struct keymap keymap[] = { * Move cursor one line down and enter. * PgUp:: * b:: + * -:: * Move cursor one page up. * PgDown:: * Space:: @@ -1839,6 +1868,7 @@ static struct keymap keymap[] = { { ' ', REQ_MOVE_PAGE_DOWN }, { KEY_PPAGE, REQ_MOVE_PAGE_UP }, { 'b', REQ_MOVE_PAGE_UP }, + { '-', REQ_MOVE_PAGE_UP }, /** * Scrolling @@ -1983,7 +2013,7 @@ utf8_to_unicode(const char *string, size_t length) unicode += ((string[3] & 0x3f) << 6); unicode += (string[4] & 0x3f); break; - case 6: + case 6: unicode = (string[0] & 0x01) << 30; unicode += ((string[1] & 0x3f) << 24); unicode += ((string[2] & 0x3f) << 18); @@ -2070,7 +2100,7 @@ utf8_length(const char *string, size_t max_width, int *coloffset, int *trimmed) */ /* Whether or not the curses interface has been initialized. */ -bool cursed = FALSE; +static bool cursed = FALSE; /* The status window is used for polling keystrokes. */ static WINDOW *status_win;