X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=tig.c;h=199eb34b7cfc434e915bf9026114dafb68ca280d;hb=831f6e48c51076d8f714978f6709a4491bee4a19;hp=e7e34b1a3d3546f2e4b9f2192a2c65665467a766;hpb=aba2a4d67800ccf267dd7e80c008674beb1258b9;p=tig.git diff --git a/tig.c b/tig.c index e7e34b1..199eb34 100644 --- a/tig.c +++ b/tig.c @@ -1440,8 +1440,6 @@ enum open_flags { 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, enum open_flags flags); /* Read one line; updates view->line. */ @@ -1454,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; @@ -1523,7 +1519,7 @@ set_view_attr(struct view *view, enum line_type type) #define VIEW_MAX_LEN(view) ((view)->width + (view)->yoffset - (view)->col) -static int +static bool draw_chars(struct view *view, enum line_type type, const char *string, int max_len, bool use_tilde) { @@ -1534,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); @@ -1565,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 @@ -1594,9 +1591,10 @@ 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_MAX_LEN(view), TRUE); + if (draw_chars(view, type, text, VIEW_MAX_LEN(view), TRUE)) + return TRUE; string += pos; - } while (*string && VIEW_MAX_LEN(view) > 0); + } while (*string); return VIEW_MAX_LEN(view) <= 0; } @@ -1631,16 +1629,13 @@ static bool draw_field(struct view *view, enum line_type type, const char *text, int len, bool trim) { int max = MIN(VIEW_MAX_LEN(view), len); - int col; + 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_MAX_LEN(view) <= 0; + return draw_chars(view, type, text, max - 1, trim) + || draw_space(view, LINE_DEFAULT, max - (view->col - col), max); } static bool @@ -1649,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); } @@ -1658,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); @@ -1703,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); } @@ -2503,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) { @@ -2521,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 @@ -2553,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) { @@ -2745,11 +2740,6 @@ open_view(struct view *prev, enum request request, enum open_flags flags) 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) { @@ -2778,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) { @@ -3333,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, @@ -3342,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) @@ -3361,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, @@ -3370,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) @@ -3405,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, @@ -3536,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, @@ -3828,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; } @@ -3973,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; @@ -3995,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) { @@ -4034,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, @@ -4312,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)) @@ -4432,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; @@ -4485,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, @@ -4536,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); @@ -4572,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: @@ -4688,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, @@ -5021,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) { @@ -5039,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 || @@ -5056,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", @@ -5065,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) @@ -5082,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 @@ -5101,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; @@ -5113,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; @@ -5455,7 +5461,6 @@ status_grep(struct view *view, struct line *line) static struct view_ops status_ops = { "file", - NULL, status_open, NULL, status_draw, @@ -5675,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; @@ -5693,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, @@ -5785,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) @@ -5799,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)) @@ -5992,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, @@ -6952,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); } }