X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=tig.c;h=199eb34b7cfc434e915bf9026114dafb68ca280d;hb=831f6e48c51076d8f714978f6709a4491bee4a19;hp=9132d3a77683227c2508c9900d64ef6c4bf2c496;hpb=c2e1c3fc6576afe962ebaa82a8578210563be99d;p=tig.git diff --git a/tig.c b/tig.c index 9132d3a..199eb34 100644 --- a/tig.c +++ b/tig.c @@ -365,6 +365,7 @@ static FILE *opt_tty = NULL; static const char **opt_diff_argv = NULL; static const char **opt_rev_argv = NULL; static const char **opt_file_argv = NULL; +static const char **opt_blame_argv = NULL; #define is_initial_commit() (!get_ref_head()) #define is_head_commit(rev) (!strcmp((rev), "HEAD") || (get_ref_head() && !strcmp(rev, get_ref_head()->id))) @@ -933,6 +934,7 @@ add_builtin_run_requests(void) OPT_ERR_(NO_OPTION_VALUE, "No option value"), \ OPT_ERR_(NO_VALUE_ASSIGNED, "No value assigned"), \ OPT_ERR_(OBSOLETE_REQUEST_NAME, "Obsolete request name"), \ + OPT_ERR_(OUT_OF_MEMORY, "Out of memory"), \ OPT_ERR_(TOO_MANY_OPTION_ARGUMENTS, "Too many option arguments"), \ OPT_ERR_(UNKNOWN_ATTRIBUTE, "Unknown attribute"), \ OPT_ERR_(UNKNOWN_COLOR, "Unknown color"), \ @@ -1110,16 +1112,30 @@ parse_string(char *opt, const char *arg, size_t optsize) } } +static enum option_code +parse_args(const char ***args, const char *argv[]) +{ + if (*args == NULL && !argv_copy(args, argv)) + return OPT_ERR_OUT_OF_MEMORY; + return OPT_OK; +} + /* Wants: name = value */ static enum option_code option_set_command(int argc, const char *argv[]) { - if (argc != 3) + if (argc < 3) return OPT_ERR_WRONG_NUMBER_OF_ARGUMENTS; if (strcmp(argv[1], "=")) return OPT_ERR_NO_VALUE_ASSIGNED; + if (!strcmp(argv[0], "blame-options")) + return parse_args(&opt_blame_argv, argv + 2); + + if (argc != 3) + return OPT_ERR_WRONG_NUMBER_OF_ARGUMENTS; + if (!strcmp(argv[0], "show-author")) return parse_enum(&opt_author, argv[2], author_map); @@ -1362,7 +1378,6 @@ enum view_type { struct view { enum view_type type; /* View type */ const char *name; /* View name */ - const char *cmd_env; /* Command line set via environment */ const char *id; /* Points to either of ref_{head,commit,blob} */ struct view_ops *ops; /* View operations */ @@ -1414,13 +1429,19 @@ struct view { time_t update_secs; }; +enum open_flags { + OPEN_DEFAULT = 0, /* Use default view switching. */ + OPEN_SPLIT = 1, /* Split current view. */ + 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. */ +}; + struct view_ops { /* What type of content being displayed. Used in the title bar. */ const char *type; - /* Default command arguments. */ - const char **argv; /* Open and reads in all view content. */ - bool (*open)(struct view *view); + bool (*open)(struct view *view, enum open_flags flags); /* Read one line; updates view->line. */ bool (*read)(struct view *view, char *data); /* Draw one line; @lineno must be < view->height. */ @@ -1431,8 +1452,6 @@ struct view_ops { bool (*grep)(struct view *view, struct line *line); /* Select line */ void (*select)(struct view *view, struct line *line); - /* Prepare view for loading */ - bool (*prepare)(struct view *view); }; static struct view_ops blame_ops; @@ -1447,11 +1466,11 @@ static struct view_ops status_ops; static struct view_ops tree_ops; static struct view_ops branch_ops; -#define VIEW_STR(type, name, env, ref, ops, map, git) \ - { type, name, #env, ref, ops, map, git } +#define VIEW_STR(type, name, ref, ops, map, git) \ + { type, name, ref, ops, map, git } #define VIEW_(id, name, ops, git, ref) \ - VIEW_STR(VIEW_##id, name, TIG_##id##_CMD, ref, ops, KEYMAP_##id, git) + VIEW_STR(VIEW_##id, name, ref, ops, KEYMAP_##id, git) static struct view views[] = { VIEW_(MAIN, "main", &main_ops, TRUE, ref_head), @@ -1498,7 +1517,9 @@ set_view_attr(struct view *view, enum line_type type) } } -static int +#define VIEW_MAX_LEN(view) ((view)->width + (view)->yoffset - (view)->col) + +static bool draw_chars(struct view *view, enum line_type type, const char *string, int max_len, bool use_tilde) { @@ -1509,7 +1530,7 @@ draw_chars(struct view *view, enum line_type type, const char *string, size_t skip = view->yoffset > view->col ? view->yoffset - view->col : 0; if (max_len <= 0) - return 0; + return VIEW_MAX_LEN(view) <= 0; len = utf8_length(&string, skip, &col, max_len, &trimmed, use_tilde, opt_tab_size); @@ -1540,25 +1561,26 @@ draw_chars(struct view *view, enum line_type type, const char *string, } } - return col; + view->col += col; + return VIEW_MAX_LEN(view) <= 0; } -static int +static bool draw_space(struct view *view, enum line_type type, int max, int spaces) { static char space[] = " "; - int col = 0; spaces = MIN(max, spaces); while (spaces > 0) { int len = MIN(spaces, sizeof(space) - 1); - col += draw_chars(view, type, space, len, FALSE); + if (draw_chars(view, type, space, len, FALSE)) + return TRUE; spaces -= len; } - return col; + return VIEW_MAX_LEN(view) <= 0; } static bool @@ -1569,18 +1591,19 @@ draw_text(struct view *view, enum line_type type, const char *string) do { size_t pos = string_expand(text, sizeof(text), string, opt_tab_size); - view->col += draw_chars(view, type, text, view->width + view->yoffset - view->col, TRUE); + if (draw_chars(view, type, text, VIEW_MAX_LEN(view), TRUE)) + return TRUE; string += pos; - } while (*string && view->width + view->yoffset > view->col); + } while (*string); - return view->width + view->yoffset <= view->col; + return VIEW_MAX_LEN(view) <= 0; } static bool draw_graphic(struct view *view, enum line_type type, const chtype graphic[], size_t size, bool separator) { size_t skip = view->yoffset > view->col ? view->yoffset - view->col : 0; - int max = view->width + view->yoffset - view->col; + int max = VIEW_MAX_LEN(view); int i; if (max < size) @@ -1599,23 +1622,20 @@ draw_graphic(struct view *view, enum line_type type, const chtype graphic[], siz view->col++; } - return view->width + view->yoffset <= view->col; + return VIEW_MAX_LEN(view) <= 0; } static bool draw_field(struct view *view, enum line_type type, const char *text, int len, bool trim) { - int max = MIN(view->width + view->yoffset - view->col, len); - int col; + int max = MIN(VIEW_MAX_LEN(view), len); + int col = view->col; - if (text) - col = draw_chars(view, type, text, max - 1, trim); - else - col = draw_space(view, type, max - 1, max - 1); + if (!text) + return draw_space(view, type, max, max); - view->col += col; - view->col += draw_space(view, LINE_DEFAULT, max - col, max - col); - return view->width + view->yoffset <= view->col; + return draw_chars(view, type, text, max - 1, trim) + || draw_space(view, LINE_DEFAULT, max - (view->col - col), max); } static bool @@ -1624,6 +1644,9 @@ draw_date(struct view *view, struct time *time) const char *date = mkdate(time, opt_date); int cols = opt_date == DATE_SHORT ? DATE_SHORT_COLS : DATE_COLS; + if (opt_date == DATE_NO) + return FALSE; + return draw_field(view, LINE_DATE, date, cols, FALSE); } @@ -1633,6 +1656,9 @@ draw_author(struct view *view, const char *author) bool trim = opt_author_cols == 0 || opt_author_cols > 5; bool abbreviate = opt_author == AUTHOR_ABBREVIATED || !trim; + if (opt_author == AUTHOR_NO) + return FALSE; + if (abbreviate && author) author = get_author_initials(author); @@ -1665,7 +1691,7 @@ draw_lineno(struct view *view, unsigned int lineno) { char number[10]; int digits3 = view->digits < 3 ? 3 : view->digits; - int max = MIN(view->width + view->yoffset - view->col, digits3); + int max = MIN(VIEW_MAX_LEN(view), digits3); char *text = NULL; chtype separator = opt_line_graphics ? ACS_VLINE : '|'; @@ -1678,9 +1704,9 @@ draw_lineno(struct view *view, unsigned int lineno) text = number; } if (text) - view->col += draw_chars(view, LINE_LINE_NUMBER, text, max, TRUE); + draw_chars(view, LINE_LINE_NUMBER, text, max, TRUE); else - view->col += draw_space(view, LINE_LINE_NUMBER, max, digits3); + draw_space(view, LINE_LINE_NUMBER, max, digits3); return draw_graphic(view, LINE_DEFAULT, &separator, 1, TRUE); } @@ -2343,7 +2369,7 @@ format_arg(const char *name) } vars[] = { #define FORMAT_VAR(name, value, value_if_empty) \ { name, STRING_SIZE(name), value, value_if_empty } - FORMAT_VAR("%(directory)", opt_path, ""), + FORMAT_VAR("%(directory)", opt_path, "."), FORMAT_VAR("%(file)", opt_file, ""), FORMAT_VAR("%(ref)", opt_ref, "HEAD"), FORMAT_VAR("%(head)", ref_head, ""), @@ -2383,6 +2409,11 @@ format_argv(const char ***dst_argv, const char *src_argv[], bool replace, bool f break; continue; + } else if (!strcmp(arg, "%(blameargs)")) { + if (!argv_append_array(dst_argv, opt_blame_argv)) + break; + continue; + } else if (!strcmp(arg, "%(revargs)") || (first && !strcmp(arg, "%(commit)"))) { if (!argv_append_array(dst_argv, opt_rev_argv)) @@ -2473,14 +2504,6 @@ prepare_io(struct view *view, const char *dir, const char *argv[], bool replace) 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) { @@ -2491,27 +2514,20 @@ start_update(struct view *view, const char **argv, const char *dir) } static bool -prepare_update_file(struct view *view, const char *name) +begin_update(struct view *view, const char *dir, const char **argv, enum open_flags flags) { - if (view->pipe) - end_update(view, TRUE); - argv_free(view->argv); - return io_open(&view->io, "%s/%s", opt_cdup[0] ? opt_cdup : ".", name); -} + bool reload = !!(flags & (OPEN_RELOAD | OPEN_REFRESH | OPEN_PREPARED)); + bool refresh = flags & (OPEN_REFRESH | OPEN_PREPARED); + + if (!reload && !strcmp(view->vid, view->id)) + return TRUE; -static bool -begin_update(struct view *view, bool refresh) -{ if (view->pipe) end_update(view, TRUE); if (!refresh) { - if (view->ops->prepare) { - if (!view->ops->prepare(view)) - return FALSE; - } else if (!prepare_io(view, NULL, view->ops->argv, TRUE)) { + if (!prepare_io(view, dir, argv, TRUE)) return FALSE; - } /* Put the current ref_* value to the view title ref * member. This is needed by the blob view. Most other @@ -2523,12 +2539,21 @@ begin_update(struct view *view, bool refresh) if (view->argv && view->argv[0] && !io_run(&view->io, IO_RD, view->dir, view->argv)) return FALSE; + else if (view->argv && !strcmp(view->argv[0], opt_cdup) && + !io_open(&view->io, "%s%s", opt_cdup, view->argv[1])) + return FALSE; setup_update(view, view->id); return TRUE; } +static bool +view_open(struct view *view, enum open_flags flags) +{ + return begin_update(view, NULL, NULL, flags); +} + static bool update_view(struct view *view) { @@ -2665,14 +2690,6 @@ add_line_format(struct view *view, enum line_type type, const char *fmt, ...) * View opening */ -enum open_flags { - OPEN_DEFAULT = 0, /* Use default view switching. */ - OPEN_SPLIT = 1, /* Split current view. */ - 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. */ -}; - static void open_view(struct view *prev, enum request request, enum open_flags flags) { @@ -2718,16 +2735,11 @@ open_view(struct view *prev, enum request request, enum open_flags flags) if (view->ops->open) { if (view->pipe) end_update(view, TRUE); - if (!view->ops->open(view)) { + if (!view->ops->open(view, flags)) { report("Failed to load %s view", view->name); return; } restore_view_position(view); - - } else if ((reload || strcmp(view->vid, view->id)) && - !begin_update(view, flags & (OPEN_REFRESH | OPEN_PREPARED))) { - report("Failed to load %s view", view->name); - return; } if (split && prev->lineno - prev->offset >= prev->height) { @@ -2756,6 +2768,35 @@ open_view(struct view *prev, enum request request, enum open_flags flags) } } +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; + + if (view->pipe) + end_update(view, TRUE); + if (!prepare_io(view, dir, argv, FALSE)) { + report("Failed to open %s view: %s", view->name, io_strerror(&view->io)); + } else { + open_view(prev, request, flags | OPEN_PREPARED); + } +} + +static void +open_file(struct view *prev, struct view *view, const char *file, enum open_flags flags) +{ + enum request request = view - views + REQ_OFFSET + 1; + const char *file_argv[] = { opt_cdup, file , NULL }; + + if (view->pipe) + end_update(view, TRUE); + if (!argv_copy(&view->argv, file_argv)) { + report("Failed to load %s: out of memory", file); + } else { + open_view(prev, request, flags | OPEN_PREPARED); + } +} + static void open_external_viewer(const char *argv[], const char *dir) { @@ -3311,8 +3352,7 @@ pager_select(struct view *view, struct line *line) static struct view_ops pager_ops = { "line", - NULL, - NULL, + view_open, pager_read, pager_draw, pager_request, @@ -3320,9 +3360,15 @@ static struct view_ops pager_ops = { pager_select, }; -static const char *log_argv[SIZEOF_ARG] = { - "git", "log", "--no-color", "--cc", "--stat", "-n100", "%(head)", NULL -}; +static bool +log_open(struct view *view, enum open_flags flags) +{ + static const char *log_argv[] = { + "git", "log", "--no-color", "--cc", "--stat", "-n100", "%(head)", NULL + }; + + return begin_update(view, NULL, log_argv, flags); +} static enum request log_request(struct view *view, enum request request, struct line *line) @@ -3339,8 +3385,7 @@ log_request(struct view *view, enum request request, struct line *line) static struct view_ops log_ops = { "line", - log_argv, - NULL, + log_open, pager_read, pager_draw, log_request, @@ -3348,11 +3393,17 @@ static struct view_ops log_ops = { pager_select, }; -static const char *diff_argv[SIZEOF_ARG] = { - "git", "show", "--pretty=fuller", "--no-color", "--root", - "--patch-with-stat", "--find-copies-harder", "-C", - "%(diffargs)", "%(commit)", "--", "%(fileargs)", NULL -}; +static bool +diff_open(struct view *view, enum open_flags flags) +{ + static const char *diff_argv[] = { + "git", "show", "--pretty=fuller", "--no-color", "--root", + "--patch-with-stat", "--find-copies-harder", "-C", + "%(diffargs)", "%(commit)", "--", "%(fileargs)", NULL + }; + + return begin_update(view, NULL, diff_argv, flags); +} static bool diff_read(struct view *view, char *data) @@ -3383,8 +3434,7 @@ diff_read(struct view *view, char *data) static struct view_ops diff_ops = { "line", - diff_argv, - NULL, + diff_open, diff_read, pager_draw, pager_request, @@ -3480,7 +3530,7 @@ help_open_keymap(struct view *view, enum keymap keymap) } static bool -help_open(struct view *view) +help_open(struct view *view, enum open_flags flags) { enum keymap keymap; @@ -3514,7 +3564,6 @@ help_request(struct view *view, enum request request, struct line *line) static struct view_ops help_ops = { "line", - NULL, help_open, NULL, pager_draw, @@ -3806,10 +3855,10 @@ tree_draw(struct view *view, struct line *line, unsigned int lineno) if (draw_mode(view, entry->mode)) return TRUE; - if (opt_author && draw_author(view, entry->author)) + if (draw_author(view, entry->author)) return TRUE; - if (opt_date && draw_date(view, &entry->time)) + if (draw_date(view, &entry->time)) return TRUE; } @@ -3951,8 +4000,12 @@ tree_select(struct view *view, struct line *line) } static bool -tree_prepare(struct view *view) +tree_open(struct view *view, enum open_flags flags) { + static const char *tree_argv[] = { + "git", "ls-tree", "%(commit)", "%(directory)", NULL + }; + if (view->lines == 0 && opt_prefix[0]) { char *pos = opt_prefix; @@ -3973,25 +4026,29 @@ tree_prepare(struct view *view) opt_path[0] = 0; } - return prepare_io(view, opt_cdup, view->ops->argv, TRUE); + return begin_update(view, opt_cdup, tree_argv, flags); } -static const char *tree_argv[SIZEOF_ARG] = { - "git", "ls-tree", "%(commit)", "%(directory)", NULL -}; - static struct view_ops tree_ops = { "file", - tree_argv, - NULL, + tree_open, tree_read, tree_draw, tree_request, tree_grep, tree_select, - tree_prepare, }; +static bool +blob_open(struct view *view, enum open_flags flags) +{ + static const char *blob_argv[] = { + "git", "cat-file", "blob", "%(blob)", NULL + }; + + return begin_update(view, NULL, blob_argv, flags); +} + static bool blob_read(struct view *view, char *line) { @@ -4012,14 +4069,9 @@ blob_request(struct view *view, enum request request, struct line *line) } } -static const char *blob_argv[SIZEOF_ARG] = { - "git", "cat-file", "blob", "%(blob)", NULL -}; - static struct view_ops blob_ops = { "line", - blob_argv, - NULL, + blob_open, blob_read, pager_draw, blob_request, @@ -4055,7 +4107,7 @@ struct blame { }; static bool -blame_open(struct view *view) +blame_open(struct view *view, enum open_flags flags) { char path[SIZEOF_STR]; size_t i; @@ -4181,7 +4233,7 @@ blame_read_file(struct view *view, const char *line, bool *read_file) { if (!line) { const char *blame_argv[] = { - "git", "blame", "--incremental", + "git", "blame", "%(blameargs)", "--incremental", *opt_ref ? opt_ref : "--incremental", "--", opt_file, NULL }; @@ -4290,10 +4342,10 @@ blame_draw(struct view *view, struct line *line, unsigned int lineno) time = &blame->commit->time; } - if (opt_date && draw_date(view, time)) + if (draw_date(view, time)) return TRUE; - if (opt_author && draw_author(view, author)) + if (draw_author(view, author)) return TRUE; if (draw_field(view, LINE_BLAME_ID, id, ID_COLS, FALSE)) @@ -4410,14 +4462,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; @@ -4463,7 +4511,6 @@ blame_select(struct view *view, struct line *line) static struct view_ops blame_ops = { "line", - NULL, blame_open, blame_read, blame_draw, @@ -4514,10 +4561,10 @@ branch_draw(struct view *view, struct line *line, unsigned int lineno) struct branch *branch = line->data; enum line_type type = branch->ref->head ? LINE_MAIN_HEAD : LINE_DEFAULT; - if (opt_date && draw_date(view, &branch->time)) + if (draw_date(view, &branch->time)) return TRUE; - if (opt_author && draw_author(view, branch->author)) + if (draw_author(view, branch->author)) return TRUE; draw_text(view, type, branch->ref == &branch_all ? "All branches" : branch->ref->name); @@ -4550,10 +4597,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: @@ -4620,7 +4664,7 @@ branch_open_visitor(void *data, const struct ref *ref) } static bool -branch_open(struct view *view) +branch_open(struct view *view, enum open_flags flags) { const char *branch_log[] = { "git", "log", "--no-color", "--pretty=raw", @@ -4666,7 +4710,6 @@ branch_select(struct view *view, struct line *line) static struct view_ops branch_ops = { "branch", - NULL, branch_open, branch_read, branch_draw, @@ -4918,7 +4961,7 @@ status_update_onbranch(void) * info using git-diff-files(1), and finally untracked files using * git-ls-files(1). */ static bool -status_open(struct view *view) +status_open(struct view *view, enum open_flags flags) { reset_view(view); @@ -4999,15 +5042,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) { @@ -5017,7 +5051,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 || @@ -5034,8 +5068,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", @@ -5043,8 +5076,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) @@ -5060,8 +5092,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 @@ -5079,8 +5110,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; @@ -5091,8 +5121,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; @@ -5433,7 +5461,6 @@ status_grep(struct view *view, struct line *line) static struct view_ops status_ops = { "file", - NULL, status_open, NULL, status_draw, @@ -5653,17 +5680,6 @@ 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); return REQ_NONE; @@ -5671,8 +5687,7 @@ stage_request(struct view *view, enum request request, struct line *line) static struct view_ops stage_ops = { "line", - NULL, - NULL, + view_open, pager_read, pager_draw, stage_request, @@ -5763,11 +5778,17 @@ struct commit { struct graph_canvas graph; /* Ancestry chain graphics. */ }; -static const char *main_argv[SIZEOF_ARG] = { - "git", "log", "--no-color", "--pretty=raw", "--parents", - "--topo-order", "%(diffargs)", "%(revargs)", - "--", "%(fileargs)", NULL -}; +static bool +main_open(struct view *view, enum open_flags flags) +{ + static const char *main_argv[] = { + "git", "log", "--no-color", "--pretty=raw", "--parents", + "--topo-order", "%(diffargs)", "%(revargs)", + "--", "%(fileargs)", NULL + }; + + return begin_update(view, NULL, main_argv, flags); +} static bool main_draw(struct view *view, struct line *line, unsigned int lineno) @@ -5777,10 +5798,10 @@ main_draw(struct view *view, struct line *line, unsigned int lineno) if (!commit->author) return FALSE; - if (opt_date && draw_date(view, &commit->time)) + if (draw_date(view, &commit->time)) return TRUE; - if (opt_author && draw_author(view, commit->author)) + if (draw_author(view, commit->author)) return TRUE; if (opt_rev_graph && draw_graph(view, &commit->graph)) @@ -5970,8 +5991,7 @@ main_select(struct view *view, struct line *line) static struct view_ops main_ops = { "commit", - main_argv, - NULL, + main_open, main_read, main_draw, main_request, @@ -6695,7 +6715,7 @@ static const char usage[] = "\n" "Usage: tig [options] [revs] [--] [paths]\n" " or: tig show [options] [revs] [--] [paths]\n" -" or: tig blame [rev] path\n" +" or: tig blame [options] [rev] [--] path\n" " or: tig status\n" " or: tig < [git command output]\n" "\n" @@ -6792,16 +6812,18 @@ parse_options(int argc, const char *argv[]) return REQ_VIEW_STATUS; } else if (!strcmp(subcommand, "blame")) { - if (argc <= 2 || argc > 4) + filter_rev_parse(&opt_file_argv, "--no-revs", "--no-flags", argv + 2); + filter_rev_parse(&opt_blame_argv, "--no-revs", "--flags", argv + 2); + filter_rev_parse(&opt_rev_argv, "--symbolic", "--revs-only", argv + 2); + + if (!opt_file_argv || opt_file_argv[1] || (opt_rev_argv && opt_rev_argv[1])) die("invalid number of options to blame\n\n%s", usage); - i = 2; - if (argc == 4) { - string_ncopy(opt_ref, argv[i], strlen(argv[i])); - i++; + if (opt_rev_argv) { + string_ncopy(opt_ref, opt_rev_argv[0], strlen(opt_rev_argv[0])); } - string_ncopy(opt_file, argv[i], strlen(argv[i])); + string_ncopy(opt_file, opt_file_argv[0], strlen(opt_file_argv[0])); return REQ_VIEW_BLAME; } else if (!strcmp(subcommand, "show")) { @@ -6851,7 +6873,6 @@ main(int argc, const char *argv[]) const char *codeset = "UTF-8"; enum request request = parse_options(argc, argv); struct view *view; - size_t i; signal(SIGINT, quit); signal(SIGPIPE, SIG_IGN); @@ -6888,16 +6909,6 @@ main(int argc, const char *argv[]) if (load_refs() == ERR) die("Failed to load refs."); - foreach_view (view, i) { - if (getenv(view->cmd_env)) - warn("Use of the %s environment variable is deprecated," - " use options or TIG_DIFF_ARGS instead", - view->cmd_env); - if (!argv_from_env(view->ops->argv, view->cmd_env)) - die("Too many arguments in the `%s` environment variable", - view->cmd_env); - } - init_display(); while (view_driver(display[current_view], request)) { @@ -6939,10 +6950,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); } }