X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=tig.c;h=047b853b67396961cd12361489cb9a911843c140;hb=745649df49e55942b95ee2aacd619bb1cf6359b0;hp=1d3122db059320cb194783ea24b0e0607808dd7a;hpb=fc7fd6f2aae126dc1bcb9dcd2a5762d3a9903c7c;p=tig.git diff --git a/tig.c b/tig.c index 1d3122d..047b853 100644 --- a/tig.c +++ b/tig.c @@ -1435,6 +1435,7 @@ enum open_flags { OPEN_RELOAD = 4, /* Reload view even if it is the current. */ OPEN_REFRESH = 16, /* Refresh view using previous command. */ OPEN_PREPARED = 32, /* Open already prepared command. */ + OPEN_EXTRA = 64, /* Open extra data from command. */ }; struct view_ops { @@ -1977,14 +1978,16 @@ toggle_option(enum request request) } static void -maximize_view(struct view *view) +maximize_view(struct view *view, bool redraw) { memset(display, 0, sizeof(display)); current_view = 0; display[current_view] = view; resize_display(); - redraw_display(FALSE); - report(""); + if (redraw) { + redraw_display(FALSE); + report(""); + } } @@ -2388,7 +2391,7 @@ format_arg(const char *name) } static bool -format_argv(const char ***dst_argv, const char *src_argv[], bool replace, bool first) +format_argv(const char ***dst_argv, const char *src_argv[], bool first) { char buf[SIZEOF_STR]; int argc; @@ -2426,7 +2429,7 @@ format_argv(const char ***dst_argv, const char *src_argv[], bool replace, bool f int len = next - arg; const char *value; - if (!next || !replace) { + if (!next) { len = strlen(arg); value = ""; @@ -2441,7 +2444,7 @@ format_argv(const char ***dst_argv, const char *src_argv[], bool replace, bool f if (!string_format_from(buf, &bufpos, "%.*s%s", len, arg, value)) return FALSE; - arg = next && replace ? strchr(next, ')') + 1 : NULL; + arg = next ? strchr(next, ')') + 1 : NULL; } if (!argv_append(dst_argv, buf)) @@ -2497,53 +2500,26 @@ setup_update(struct view *view, const char *vid) view->start_time = time(NULL); } -static bool -prepare_io(struct view *view, const char *dir, const char *argv[], bool replace) -{ - view->dir = dir; - return format_argv(&view->argv, argv, replace, !view->prev); -} - -static bool -prepare_update(struct view *view, const char *argv[], const char *dir) -{ - if (view->pipe) - end_update(view, TRUE); - return prepare_io(view, dir, argv, FALSE); -} - -static bool -start_update(struct view *view, const char **argv, const char *dir) -{ - if (view->pipe) - io_done(view->pipe); - return prepare_io(view, dir, argv, FALSE) && - io_run(&view->io, IO_RD, dir, view->argv); -} - -static bool -prepare_update_file(struct view *view, const char *name) -{ - if (view->pipe) - end_update(view, TRUE); - argv_free(view->argv); - return io_open(&view->io, "%s/%s", opt_cdup[0] ? opt_cdup : ".", name); -} - static bool begin_update(struct view *view, const char *dir, const char **argv, enum open_flags flags) { - bool reload = !!(flags & (OPEN_RELOAD | OPEN_REFRESH | OPEN_PREPARED)); + bool extra = !!(flags & (OPEN_EXTRA)); + bool reload = !!(flags & (OPEN_RELOAD | OPEN_REFRESH | OPEN_PREPARED | OPEN_EXTRA)); bool refresh = flags & (OPEN_REFRESH | OPEN_PREPARED); if (!reload && !strcmp(view->vid, view->id)) return TRUE; - if (view->pipe) - end_update(view, TRUE); + if (view->pipe) { + if (extra) + io_done(view->pipe); + else + end_update(view, TRUE); + } if (!refresh) { - if (!prepare_io(view, dir, argv, TRUE)) + view->dir = dir; + if (!format_argv(&view->argv, argv, !view->prev)) return FALSE; /* Put the current ref_* value to the view title ref @@ -2557,7 +2533,8 @@ begin_update(struct view *view, const char *dir, const char **argv, enum open_fl !io_run(&view->io, IO_RD, view->dir, view->argv)) return FALSE; - setup_update(view, view->id); + if (!extra) + setup_update(view, view->id); return TRUE; } @@ -2704,15 +2681,63 @@ add_line_format(struct view *view, enum line_type type, const char *fmt, ...) * View opening */ +static void +load_view(struct view *view, enum open_flags flags) +{ + if (view->pipe) + end_update(view, TRUE); + if (!view->ops->open(view, flags)) { + report("Failed to load %s view", view->name); + return; + } + restore_view_position(view); + + if (view->pipe && view->lines == 0) { + /* Clear the old view and let the incremental updating refill + * the screen. */ + werase(view->win); + view->p_restore = flags & (OPEN_RELOAD | OPEN_REFRESH); + report(""); + } else if (view_is_displayed(view)) { + redraw_view(view); + report(""); + } +} + +#define refresh_view(view) load_view(view, OPEN_REFRESH) + +static void +split_view(struct view *prev, struct view *view) +{ + display[1] = view; + current_view = 1; + view->parent = prev; + resize_display(); + + if (prev->lineno - prev->offset >= prev->height) { + /* Take the title line into account. */ + int lines = prev->lineno - prev->offset - prev->height + 1; + + /* Scroll the view that was split if the current line is + * outside the new limited view. */ + do_scroll_view(prev, lines); + } + + if (view != prev && view_is_displayed(prev)) { + /* "Blur" the previous view. */ + update_view_title(prev); + } +} + static void open_view(struct view *prev, enum request request, enum open_flags flags) { bool split = !!(flags & OPEN_SPLIT); - bool reload = !!(flags & (OPEN_RELOAD | OPEN_REFRESH | OPEN_PREPARED)); - bool nomaximize = !!(flags & OPEN_REFRESH); + bool reload = !!(flags & (OPEN_RELOAD | OPEN_PREPARED)); struct view *view = VIEW(request); int nviews = displayed_views(); - struct view *base_view = display[0]; + + assert(flags ^ OPEN_REFRESH); if (view == prev && nviews == 1 && !reload) { report("Already in %s view", view->name); @@ -2725,14 +2750,9 @@ open_view(struct view *prev, enum request request, enum open_flags flags) } if (split) { - display[1] = view; - current_view = 1; - view->parent = prev; - } else if (!nomaximize) { - /* Maximize the current view. */ - memset(display, 0, sizeof(display)); - current_view = 0; - display[current_view] = view; + split_view(prev, view); + } else { + maximize_view(view, FALSE); } /* No prev signals that this is the first loaded view. */ @@ -2740,46 +2760,31 @@ open_view(struct view *prev, enum request request, enum open_flags flags) view->prev = prev; } - /* Resize the view when switching between split- and full-screen, - * or when switching between two different full-screen views. */ - if (nviews != displayed_views() || - (nviews == 1 && base_view != display[0])) - resize_display(); - - if (view->ops->open) { - if (view->pipe) - end_update(view, TRUE); - if (!view->ops->open(view, flags)) { - report("Failed to load %s view", view->name); - return; - } - restore_view_position(view); - } + load_view(view, flags); +} - if (split && prev->lineno - prev->offset >= prev->height) { - /* Take the title line into account. */ - int lines = prev->lineno - prev->offset - prev->height + 1; +static void +open_argv(struct view *prev, struct view *view, const char *argv[], const char *dir, enum open_flags flags) +{ + enum request request = view - views + REQ_OFFSET + 1; - /* Scroll the view that was split if the current line is - * outside the new limited view. */ - do_scroll_view(prev, lines); + if (view->pipe) + end_update(view, TRUE); + view->dir = dir; + + if (!argv_copy(&view->argv, argv)) { + report("Failed to open %s view: %s", view->name, io_strerror(&view->io)); + } else { + open_view(prev, request, flags | OPEN_PREPARED); } +} - if (prev && view != prev && split && view_is_displayed(prev)) { - /* "Blur" the previous view. */ - update_view_title(prev); - } +static void +open_file(struct view *prev, struct view *view, const char *file, enum open_flags flags) +{ + const char *file_argv[] = { opt_cdup, file , NULL }; - if (view->pipe && view->lines == 0) { - /* Clear the old view and let the incremental updating refill - * the screen. */ - werase(view->win); - view->p_restore = flags & (OPEN_RELOAD | OPEN_REFRESH); - report(""); - } else if (view_is_displayed(view)) { - redraw_view(view); - report(""); - } + open_argv(prev, view, file_argv, opt_cdup, flags); } static void @@ -2833,7 +2838,7 @@ open_run_request(enum request request) return; } - if (format_argv(&argv, req->argv, TRUE, FALSE)) + if (format_argv(&argv, req->argv, FALSE)) open_external_viewer(argv, NULL); if (argv) argv_free(argv); @@ -2983,7 +2988,7 @@ view_driver(struct view *view, enum request request) case REQ_MAXIMIZE: if (displayed_views() == 2) - maximize_view(view); + maximize_view(view, TRUE); break; case REQ_OPTIONS: @@ -3040,7 +3045,7 @@ view_driver(struct view *view, enum request request) * view itself. Parents to closed view should never be * followed. */ if (view->prev && view->prev != view) { - maximize_view(view->prev); + maximize_view(view->prev, TRUE); view->prev = view; break; } @@ -3361,7 +3366,7 @@ log_request(struct view *view, enum request request, struct line *line) switch (request) { case REQ_REFRESH: load_refs(); - open_view(view, REQ_VIEW_LOG, OPEN_REFRESH); + refresh_view(view); return REQ_NONE; default: return pager_request(view, request, line); @@ -3537,8 +3542,7 @@ help_request(struct view *view, enum request request, struct line *line) if (line->type == LINE_HELP_KEYMAP) { help_keymap_hidden[line->other] = !help_keymap_hidden[line->other]; - view->p_restore = TRUE; - open_view(view, REQ_VIEW_HELP, OPEN_REFRESH); + refresh_view(view); } return REQ_NONE; @@ -3706,11 +3710,10 @@ tree_read_date(struct view *view, char *text, bool *read_date) return TRUE; } else if (!text) { - char *path = *opt_path ? opt_path : "."; /* Find next entry to process */ const char *log_file[] = { "git", "log", "--no-color", "--pretty=raw", - "--cc", "--raw", view->id, "--", path, NULL + "--cc", "--raw", view->id, "--", "%(directory)", NULL }; if (!view->lines) { @@ -3719,7 +3722,7 @@ tree_read_date(struct view *view, char *text, bool *read_date) return TRUE; } - if (!start_update(view, log_file, opt_cdup)) { + if (!begin_update(view, opt_cdup, log_file, OPEN_EXTRA)) { report("Failed to load tree data"); return TRUE; } @@ -4094,6 +4097,7 @@ struct blame { static bool blame_open(struct view *view, enum open_flags flags) { + const char *file_argv[] = { opt_cdup, opt_file , NULL }; char path[SIZEOF_STR]; size_t i; @@ -4103,13 +4107,13 @@ blame_open(struct view *view, enum open_flags flags) return FALSE; } - if (*opt_ref || !io_open(&view->io, "%s%s", opt_cdup, opt_file)) { + if (*opt_ref || !begin_update(view, opt_cdup, file_argv, flags)) { const char *blame_cat_file_argv[] = { "git", "cat-file", "blob", path, NULL }; if (!string_format(path, "%s:%s", opt_ref, opt_file) || - !start_update(view, blame_cat_file_argv, opt_cdup)) + !begin_update(view, opt_cdup, blame_cat_file_argv, flags)) return FALSE; } @@ -4131,7 +4135,7 @@ blame_open(struct view *view, enum open_flags flags) free(blame->commit); } - setup_update(view, opt_file); + string_format(view->vid, "%s:%s", opt_ref, opt_file); string_format(view->ref, "%s ...", opt_file); return TRUE; @@ -4225,7 +4229,7 @@ blame_read_file(struct view *view, const char *line, bool *read_file) if (view->lines == 0 && !view->prev) die("No blame exist for %s", view->vid); - if (view->lines == 0 || !start_update(view, blame_argv, opt_cdup)) { + if (view->lines == 0 || !begin_update(view, opt_cdup, blame_argv, OPEN_EXTRA)) { report("Failed to load blame data"); return TRUE; } @@ -4408,7 +4412,7 @@ blame_request(struct view *view, enum request request, struct line *line) string_copy(opt_file, blame->commit->filename); if (blame->lineno) view->lineno = blame->lineno; - open_view(view, REQ_VIEW_BLAME, OPEN_REFRESH); + refresh_view(view); } break; @@ -4421,7 +4425,7 @@ blame_request(struct view *view, enum request request, struct line *line) string_copy_rev(opt_ref, blame->commit->parent_id); string_copy(opt_file, blame->commit->parent_filename); setup_blame_parent_line(view, blame); - open_view(view, REQ_VIEW_BLAME, OPEN_REFRESH); + refresh_view(view); } break; @@ -4447,14 +4451,10 @@ blame_request(struct view *view, enum request request, struct line *line) diff_index_argv[7] = "/dev/null"; } - if (!prepare_update(diff, diff_index_argv, NULL)) { - report("Failed to allocate diff command"); - break; - } - flags |= OPEN_PREPARED; + open_argv(view, diff, diff_index_argv, NULL, flags); + } else { + open_view(view, REQ_VIEW_DIFF, flags); } - - open_view(view, REQ_VIEW_DIFF, flags); if (VIEW(REQ_VIEW_DIFF)->pipe && !strcmp(blame->commit->id, NULL_ID)) string_copy_rev(VIEW(REQ_VIEW_DIFF)->ref, NULL_ID); break; @@ -4568,7 +4568,7 @@ branch_request(struct view *view, enum request request, struct line *line) switch (request) { case REQ_REFRESH: load_refs(); - open_view(view, REQ_VIEW_BRANCH, OPEN_REFRESH); + refresh_view(view); return REQ_NONE; case REQ_TOGGLE_SORT_FIELD: @@ -4586,10 +4586,7 @@ branch_request(struct view *view, enum request request, struct line *line) }; struct view *main_view = VIEW(REQ_VIEW_MAIN); - if (!prepare_update(main_view, all_branches_argv, NULL)) - report("Failed to load view of all branches"); - else - open_view(view, REQ_VIEW_MAIN, OPEN_PREPARED | OPEN_SPLIT); + open_argv(view, main_view, all_branches_argv, NULL, OPEN_SPLIT); return REQ_NONE; } default: @@ -4663,12 +4660,11 @@ branch_open(struct view *view, enum open_flags flags) "--simplify-by-decoration", "--all", NULL }; - if (!start_update(view, branch_log, NULL)) { + if (!begin_update(view, NULL, branch_log, flags)) { report("Failed to load branch data"); return TRUE; } - setup_update(view, view->id); branch_open_visitor(view, &branch_all); foreach_ref(branch_open_visitor, view); view->p_restore = TRUE; @@ -5034,15 +5030,6 @@ status_draw(struct view *view, struct line *line, unsigned int lineno) return TRUE; } -static enum request -status_load_error(struct view *view, struct view *stage, const char *path) -{ - if (displayed_views() == 2 || display[current_view] != view) - maximize_view(view); - report("Failed to load '%s': %s", path, io_strerror(&stage->io)); - return REQ_NONE; -} - static enum request status_enter(struct view *view, struct line *line) { @@ -5052,7 +5039,7 @@ status_enter(struct view *view, struct line *line) * path, so leave it empty. */ const char *newpath = status && status->status != 'U' ? status->new.name : NULL; const char *info; - enum open_flags split; + enum open_flags flags = view_is_displayed(view) ? OPEN_SPLIT : OPEN_DEFAULT; struct view *stage = VIEW(REQ_VIEW_STAGE); if (line->type == LINE_STAT_NONE || @@ -5069,8 +5056,7 @@ status_enter(struct view *view, struct line *line) "--", "/dev/null", newpath, NULL }; - if (!prepare_update(stage, no_head_diff_argv, opt_cdup)) - return status_load_error(view, stage, newpath); + open_argv(view, stage, no_head_diff_argv, opt_cdup, flags); } else { const char *index_show_argv[] = { "git", "diff-index", "--root", "--patch-with-stat", @@ -5078,8 +5064,7 @@ status_enter(struct view *view, struct line *line) oldpath, newpath, NULL }; - if (!prepare_update(stage, index_show_argv, opt_cdup)) - return status_load_error(view, stage, newpath); + open_argv(view, stage, index_show_argv, opt_cdup, flags); } if (status) @@ -5095,8 +5080,7 @@ status_enter(struct view *view, struct line *line) "-C", "-M", "--", oldpath, newpath, NULL }; - if (!prepare_update(stage, files_show_argv, opt_cdup)) - return status_load_error(view, stage, newpath); + open_argv(view, stage, files_show_argv, opt_cdup, flags); if (status) info = "Unstaged changes to %s"; else @@ -5114,8 +5098,7 @@ status_enter(struct view *view, struct line *line) return REQ_NONE; } - if (!prepare_update_file(stage, newpath)) - return status_load_error(view, stage, newpath); + open_file(view, stage, newpath, flags); info = "Untracked file %s"; break; @@ -5126,8 +5109,6 @@ status_enter(struct view *view, struct line *line) die("line type %d not handled in switch", line->type); } - split = view_is_displayed(view) ? OPEN_SPLIT : OPEN_DEFAULT; - open_view(view, REQ_VIEW_STAGE, OPEN_PREPARED | split); if (view_is_displayed(VIEW(REQ_VIEW_STAGE))) { if (status) { stage_status = *status; @@ -5397,7 +5378,7 @@ status_request(struct view *view, enum request request, struct line *line) return request; } - open_view(view, REQ_VIEW_STATUS, OPEN_RELOAD); + refresh_view(view); return REQ_NONE; } @@ -5677,8 +5658,7 @@ stage_request(struct view *view, enum request request, struct line *line) return request; } - VIEW(REQ_VIEW_STATUS)->p_restore = TRUE; - open_view(view, REQ_VIEW_STATUS, OPEN_REFRESH); + refresh_view(view->parent); /* Check whether the staged entry still exists, and close the * stage view if it doesn't. */ @@ -5687,18 +5667,7 @@ stage_request(struct view *view, enum request request, struct line *line) return REQ_VIEW_CLOSE; } - if (stage_line_type == LINE_STAT_UNTRACKED) { - if (!suffixcmp(stage_status.new.name, -1, "/")) { - report("Cannot display a directory"); - return REQ_NONE; - } - - if (!prepare_update_file(view, stage_status.new.name)) { - report("Failed to open file: %s", strerror(errno)); - return REQ_NONE; - } - } - open_view(view, REQ_VIEW_STAGE, OPEN_REFRESH); + refresh_view(view); return REQ_NONE; } @@ -5953,12 +5922,12 @@ main_request(struct view *view, enum request request, struct line *line) switch (request) { case REQ_ENTER: if (view_is_displayed(view) && display[0] != view) - maximize_view(view); + maximize_view(view, TRUE); open_view(view, REQ_VIEW_DIFF, flags); break; case REQ_REFRESH: load_refs(); - open_view(view, REQ_VIEW_MAIN, OPEN_REFRESH); + refresh_view(view); break; default: return request; @@ -6968,10 +6937,8 @@ main(int argc, const char *argv[]) if (!argv_from_string(argv, &argc, cmd)) { report("Too many arguments"); - } else if (!prepare_update(next, argv, NULL)) { - report("Failed to format command"); } else { - open_view(view, REQ_VIEW_PAGER, OPEN_PREPARED); + open_argv(view, next, argv, NULL, OPEN_DEFAULT); } }