X-Git-Url: https://git.distorted.org.uk/~mdw/tig/blobdiff_plain/d0cea5f929be563d049bc5205fb8de08fd080c32..14c778a692e4964286a3a640de07dac9a846b67c:/tig.c?ds=sidebyside diff --git a/tig.c b/tig.c index 4770e72..0d62481 100644 --- a/tig.c +++ b/tig.c @@ -1,8 +1,9 @@ /* Copyright (c) 2006 Jonas Fonseca * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. + * 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. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -63,7 +64,7 @@ static void die(const char *err, ...); static void report(const char *msg, ...); -static int read_properties(const char *cmd, int separator, int (*read)(char *, int, char *, int)); +static int read_properties(FILE *pipe, int separator, int (*read)(char *, int, char *, int)); static void set_nonblocking_input(bool loading); static size_t utf8_length(const char *string, size_t max_width, int *coloffset, int *trimmed); @@ -292,14 +293,14 @@ parse_options(int argc, char *argv[]) } /** - * -t[NSPACES], --tab-size[=NSPACES]:: + * -b[NSPACES], --tab-size[=NSPACES]:: * Set the number of spaces tabs should be expanded to. **/ - if (!strncmp(opt, "-t", 2) || + if (!strncmp(opt, "-b", 2) || !strncmp(opt, "--tab-size", 10)) { char *num = opt; - if (opt[1] == 't') { + if (opt[1] == 'b') { num = opt + 2; } else if (opt[STRING_SIZE("--tab-size")] == '=') { @@ -473,9 +474,9 @@ parse_options(int argc, char *argv[]) "git ls-remote . 2>/dev/null" /** - * [[view-commands]] - * View commands - * ~~~~~~~~~~~~~ + * [[history-commands]] + * History commands + * ~~~~~~~~~~~~~~~~ * It is possible to alter which commands are used for the different views. * If for example you prefer commits in the main view to be sorted by date * and only show 500 commits, use: @@ -819,6 +820,10 @@ redraw_view(struct view *view) * [main] c622eefaa485995320bc743431bae0d497b1d875 - commit 1 of 61 (1%) * * By default, the title of the current view is highlighted using bold font. + * For long loading views (taking over 3 seconds) the time since loading + * started will be appended: + * + * [main] 77d9e40fbcea3238015aea403e06f61542df9a31 - commit 1 of 779 (0%) 5s **/ static void @@ -857,7 +862,7 @@ update_view_title(struct view *view) wprintw(view->title, " %lds", secs); } - + wmove(view->title, 0, view->width - 1); wrefresh(view->title); } @@ -906,7 +911,6 @@ resize_display(void) wresize(view->win, view->height, view->width); mvwin(view->win, offset, 0); mvwin(view->title, offset + view->height, 0); - wrefresh(view->win); } offset += view->height + 1; @@ -925,6 +929,20 @@ redraw_display(void) } } +static void +update_display_cursor(void) +{ + struct view *view = display[current_view]; + + /* Move the cursor to the right-most column of the cursor line. + * + * XXX: This could turn out to be a bit expensive, but it ensures that + * the cursor does not jump around. */ + if (view->lines) { + wmove(view->win, view->lineno - view->offset, view->width - 1); + wrefresh(view->win); + } +} /* * Navigation @@ -1344,17 +1362,15 @@ open_view(struct view *prev, enum request request, enum open_flags flags) } if (prev && view != prev) { - /* Continue loading split views in the background. */ - if (!split) - end_update(prev); - else if (!backgrounded) + if (split && !backgrounded) { /* "Blur" the previous view. */ update_view_title(prev); + } view->parent = prev; } - if (view->pipe) { + if (view->pipe && view->lines == 0) { /* Clear the old view and let the incremental updating refill * the screen. */ wclear(view->win); @@ -1460,9 +1476,10 @@ view_driver(struct view *view, enum request request) break; case REQ_STOP_LOADING: - foreach_view (view, i) { + for (i = 0; i < ARRAY_SIZE(views); i++) { + view = &views[i]; if (view->pipe) - report("Stopped loaded the %s view", view->name), + report("Stopped loading the %s view", view->name), end_update(view); } break; @@ -1483,11 +1500,15 @@ view_driver(struct view *view, enum request request) return TRUE; case REQ_VIEW_CLOSE: - if (view->parent) { + /* XXX: Mark closed views by letting view->parent point to the + * view itself. Parents to closed view should never be + * followed. */ + if (view->parent && + view->parent->parent != view->parent) { memset(display, 0, sizeof(display)); current_view = 0; display[current_view] = view->parent; - view->parent = NULL; + view->parent = view; resize_display(); redraw_display(); break; @@ -1621,8 +1642,8 @@ pager_enter(struct view *view, struct line *line) 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. */ + * but if we are scrolling a non-current view this won't properly + * update the view title. */ if (split) update_view_title(view); @@ -2207,15 +2228,7 @@ report(const char *msg, ...) } update_view_title(view); - - /* Move the cursor to the right-most column of the cursor line. - * - * XXX: This could turn out to be a bit expensive, but it ensures that - * the cursor does not jump around. */ - if (view->lines) { - wmove(view->win, view->lineno - view->offset, view->width - 1); - wrefresh(view->win); - } + update_display_cursor(); } /* Controls when nodelay should be in effect when polling user input. */ @@ -2376,11 +2389,11 @@ load_refs(void) const char *cmd_env = getenv("TIG_LS_REMOTE"); const char *cmd = cmd_env && *cmd_env ? cmd_env : TIG_LS_REMOTE; - return read_properties(cmd, '\t', read_ref); + return read_properties(popen(cmd, "r"), '\t', read_ref); } static int -read_config_option(char *name, int namelen, char *value, int valuelen) +read_repo_config_option(char *name, int namelen, char *value, int valuelen) { if (!strcmp(name, "i18n.commitencoding")) { string_copy(opt_encoding, value); @@ -2390,17 +2403,16 @@ read_config_option(char *name, int namelen, char *value, int valuelen) } static int -load_config(void) +load_repo_config(void) { - return read_properties("git repo-config --list", '=', - read_config_option); + return read_properties(popen("git repo-config --list", "r"), + "=", read_repo_config_option); } static int -read_properties(const char *cmd, int separator, +read_properties(FILE *pipe, int separator, int (*read_property)(char *, int, char *, int)) { - FILE *pipe = popen(cmd, "r"); char buffer[BUFSIZ]; char *name; int state = OK; @@ -2417,8 +2429,10 @@ read_properties(const char *cmd, int separator, namelen = value - name; *value++ = 0; valuelen = strlen(value); - if (valuelen > 0) - value[valuelen - 1] = 0; + if (valuelen > 0) { + valuelen--; + value[valuelen] = 0; + } } else { namelen = strlen(name); @@ -2426,7 +2440,8 @@ read_properties(const char *cmd, int separator, valuelen = 0; } - state = read_property(name, namelen, value, valuelen); + if (namelen) + state = read_property(name, namelen, value, valuelen); } if (state != ERR && ferror(pipe)) @@ -2484,7 +2499,7 @@ main(int argc, char *argv[]) /* Load the repo config file first so options can be overwritten from * the command line. */ - if (load_config() == ERR) + if (load_repo_config() == ERR) die("Failed to load repo config."); if (!parse_options(argc, argv)) @@ -2529,7 +2544,9 @@ main(int argc, char *argv[]) memcpy(opt_cmd, "git ", 4); opt_request = REQ_VIEW_PAGER; } else { - request = ERR; + report("Prompt interrupted by loading view, " + "press 'z' to stop loading views"); + request = REQ_SCREEN_UPDATE; } noecho(); @@ -2571,7 +2588,8 @@ main(int argc, char *argv[]) * * You can tune the interaction with git by making use of the options * explained in this section. For example, by configuring the environment - * variables described in the <> section. + * variables described in the <> + * section. * * Limit by path name * ~~~~~~~~~~~~~~~~~~ @@ -2667,6 +2685,8 @@ main(int argc, char *argv[]) * - The cursor can wrap-around on the last line and cause the * window to scroll. * + * - The prompt doesn't work while loading. + * * TODO * ---- * Features that should be explored. @@ -2690,7 +2710,7 @@ main(int argc, char *argv[]) * - link:http://www.kernel.org/pub/software/scm/cogito/docs/[cogito(7)] * * Other git repository browsers: -* + * * - gitk(1) * - qgit(1) * - gitview(1)