X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=tig.c;h=a9924c91a7192d6745440f17124e044d4dda6017;hb=c3961fe1f3310d5c8ebfd993e9d3be24beb09ed0;hp=35b0cfa0e25389cbd95bd5c9d7179f450e90edb9;hpb=0ff67fd52c98c24653faeb7262adea299271b2e1;p=tig.git diff --git a/tig.c b/tig.c index 35b0cfa..a9924c9 100644 --- a/tig.c +++ b/tig.c @@ -678,6 +678,24 @@ argv_from_env(const char **argv, const char *name) return !env || argv_from_string(argv, &argc, env); } +static void +argv_free(const char *argv[]) +{ + int argc; + + for (argc = 0; argv[argc]; argc++) + free((void *) argv[argc]); +} + +static void +argv_copy(const char *dst[], const char *src[]) +{ + int argc; + + for (argc = 0; src[argc]; argc++) + dst[argc] = src[argc]; +} + /* * Executing external commands. @@ -725,6 +743,13 @@ io_init(struct io *io, const char *dir, enum io_type type) io->dir = dir; } +static void +io_prepare(struct io *io, const char *dir, enum io_type type, const char *argv[]) +{ + io_init(io, dir, type); + argv_copy(io->argv, argv); +} + static bool io_format(struct io *io, const char *dir, enum io_type type, const char *argv[], enum format_flags flags) @@ -850,56 +875,42 @@ io_start(struct io *io) static bool io_run(struct io *io, const char **argv, const char *dir, enum io_type type) { - io_init(io, dir, type); - if (!format_argv(io->argv, argv, FORMAT_NONE)) - return FALSE; + io_prepare(io, dir, type, argv); return io_start(io); } -static int -io_complete(struct io *io) +static bool +io_complete(enum io_type type, const char **argv, const char *dir, int fd) { - return io_start(io) && io_done(io); + struct io io = {}; + + io_prepare(&io, dir, type, argv); + io.pipe = fd; + return io_start(&io) && io_done(&io); } -static int +static bool io_run_bg(const char **argv) { - struct io io = {}; - - if (!io_format(&io, NULL, IO_BG, argv, FORMAT_NONE)) - return FALSE; - return io_complete(&io); + return io_complete(IO_BG, argv, NULL, -1); } static bool io_run_fg(const char **argv, const char *dir) { - struct io io = {}; - - if (!io_format(&io, dir, IO_FG, argv, FORMAT_NONE)) - return FALSE; - return io_complete(&io); + return io_complete(IO_FG, argv, dir, -1); } static bool -io_run_append(const char **argv, enum format_flags flags, int fd) +io_run_append(const char **argv, int fd) { - struct io io = {}; - - if (!io_format(&io, NULL, IO_AP, argv, flags)) { - close(fd); - return FALSE; - } - - io.pipe = fd; - return io_complete(&io); + return io_complete(IO_AP, argv, NULL, -1); } static bool -io_run_rd(struct io *io, const char **argv, const char *dir, enum format_flags flags) +io_run_rd(struct io *io, const char **argv, const char *dir) { - return io_format(io, dir, IO_RD, argv, flags) && io_start(io); + return io_format(io, dir, IO_RD, argv, FORMAT_NONE) && io_start(io); } static bool @@ -1036,8 +1047,8 @@ io_run_buf(const char **argv, char buf[], size_t bufsize) { struct io io = {}; - return io_run_rd(&io, argv, NULL, FORMAT_NONE) - && io_read_buf(&io, buf, bufsize); + io_prepare(&io, NULL, IO_RD, argv); + return io_start(&io) && io_read_buf(&io, buf, bufsize); } static int @@ -1084,8 +1095,8 @@ io_run_load(const char **argv, const char *separators, { struct io io = {}; - return io_format(&io, NULL, IO_RD, argv, FORMAT_NONE) - ? io_load(&io, separators, read_property) : ERR; + io_prepare(&io, NULL, IO_RD, argv); + return io_load(&io, separators, read_property); } @@ -2214,7 +2225,6 @@ struct view { enum keymap keymap; /* What keymap does this view have */ bool git_dir; /* Whether the view requires a git directory. */ - bool refresh; /* Whether the view supports refreshing. */ char ref[SIZEOF_REF]; /* Hovered commit reference */ char vid[SIZEOF_REF]; /* View ID. Set to id member when updating. */ @@ -2292,24 +2302,24 @@ 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, refresh) \ - { type, name, #env, ref, ops, map, git, refresh } +#define VIEW_STR(type, name, env, ref, ops, map, git) \ + { type, name, #env, ref, ops, map, git } -#define VIEW_(id, name, ops, git, refresh, ref) \ - VIEW_STR(VIEW_##id, name, TIG_##id##_CMD, ref, ops, KEYMAP_##id, git, refresh) +#define VIEW_(id, name, ops, git, ref) \ + VIEW_STR(VIEW_##id, name, TIG_##id##_CMD, ref, ops, KEYMAP_##id, git) static struct view views[] = { - VIEW_(MAIN, "main", &main_ops, TRUE, TRUE, ref_head), - VIEW_(DIFF, "diff", &diff_ops, TRUE, FALSE, ref_commit), - VIEW_(LOG, "log", &log_ops, TRUE, TRUE, ref_head), - VIEW_(TREE, "tree", &tree_ops, TRUE, FALSE, ref_commit), - VIEW_(BLOB, "blob", &blob_ops, TRUE, FALSE, ref_blob), - VIEW_(BLAME, "blame", &blame_ops, TRUE, FALSE, ref_commit), - VIEW_(BRANCH, "branch", &branch_ops, TRUE, TRUE, ref_head), - VIEW_(HELP, "help", &help_ops, FALSE, FALSE, ""), - VIEW_(PAGER, "pager", &pager_ops, FALSE, FALSE, "stdin"), - VIEW_(STATUS, "status", &status_ops, TRUE, TRUE, ""), - VIEW_(STAGE, "stage", &stage_ops, TRUE, TRUE, ""), + VIEW_(MAIN, "main", &main_ops, TRUE, ref_head), + VIEW_(DIFF, "diff", &diff_ops, TRUE, ref_commit), + VIEW_(LOG, "log", &log_ops, TRUE, ref_head), + VIEW_(TREE, "tree", &tree_ops, TRUE, ref_commit), + VIEW_(BLOB, "blob", &blob_ops, TRUE, ref_blob), + VIEW_(BLAME, "blame", &blame_ops, TRUE, ref_commit), + VIEW_(BRANCH, "branch", &branch_ops, TRUE, ref_head), + VIEW_(HELP, "help", &help_ops, FALSE, ""), + VIEW_(PAGER, "pager", &pager_ops, FALSE, "stdin"), + VIEW_(STATUS, "status", &status_ops, TRUE, ""), + VIEW_(STAGE, "stage", &stage_ops, TRUE, ""), }; #define VIEW(req) (&views[(req) - REQ_OFFSET - 1]) @@ -2320,6 +2330,19 @@ static struct view views[] = { #define view_is_displayed(view) \ (view == display[0] || view == display[1]) +static enum request +view_request(struct view *view, enum request request) +{ + if (!view || !view->lines) + return request; + return view->ops->request(view, request, &view->line[view->lineno]); +} + + +/* + * View drawing. + */ + static inline void set_view_attr(struct view *view, enum line_type type) { @@ -2709,6 +2732,11 @@ redraw_display(bool clear) } } + +/* + * Option management + */ + static void toggle_enum_option_do(unsigned int *opt, const char *help, const struct enum_map *map, size_t size) @@ -3132,15 +3160,6 @@ reset_view(struct view *view) view->update_secs = 0; } -static void -free_argv(const char *argv[]) -{ - int argc; - - for (argc = 0; argv[argc]; argc++) - free((void *) argv[argc]); -} - static const char * format_arg(const char *name) { @@ -3177,7 +3196,7 @@ format_argv(const char *dst_argv[], const char *src_argv[], enum format_flags fl int argc; bool noreplace = flags == FORMAT_NONE; - free_argv(dst_argv); + argv_free(dst_argv); for (argc = 0; src_argv[argc]; argc++) { const char *arg = src_argv[argc]; @@ -3587,7 +3606,7 @@ open_run_request(enum request request) if (format_argv(argv, req->argv, FORMAT_ALL)) open_external_viewer(argv, NULL); - free_argv(argv); + argv_free(argv); } /* @@ -3604,18 +3623,13 @@ view_driver(struct view *view, enum request request) if (request > REQ_NONE) { open_run_request(request); - /* FIXME: When all views can refresh always do this. */ - if (view->refresh) - request = REQ_REFRESH; - else - return TRUE; + view_request(view, REQ_REFRESH); + return TRUE; } - if (view && view->lines) { - request = view->ops->request(view, request, &view->line[view->lineno]); - if (request == REQ_NONE) - return TRUE; - } + request = view_request(view, request); + if (request == REQ_NONE) + return TRUE; switch (request) { case REQ_MOVE_UP: @@ -3702,9 +3716,7 @@ view_driver(struct view *view, enum request request) if (view_is_displayed(view)) update_view_title(view); if (line != view->lineno) - view->ops->request(view, REQ_ENTER, - &view->line[view->lineno]); - + view_request(view, REQ_ENTER); } else { move_view(view, request); } @@ -4517,7 +4529,7 @@ tree_read_date(struct view *view, char *text, bool *read_date) return TRUE; } - if (!io_run_rd(&io, log_file, opt_cdup, FORMAT_NONE)) { + if (!io_run_rd(&io, log_file, opt_cdup)) { report("Failed to load tree data"); return TRUE; } @@ -4652,14 +4664,15 @@ tree_draw(struct view *view, struct line *line, unsigned int lineno) } static void -open_blob_editor() +open_blob_editor(const char *id) { + const char *blob_argv[] = { "git", "cat-file", "blob", id, NULL }; char file[SIZEOF_STR] = "/tmp/tigblob.XXXXXX"; int fd = mkstemp(file); if (fd == -1) report("Failed to create temporary file"); - else if (!io_run_append(blob_ops.argv, FORMAT_ALL, fd)) + else if (!io_run_append(blob_argv, fd)) report("Failed to save blob data to file"); else open_editor(file); @@ -4671,6 +4684,7 @@ static enum request tree_request(struct view *view, enum request request, struct line *line) { enum open_flags flags; + struct tree_entry *entry = line->data; switch (request) { case REQ_VIEW_BLAME: @@ -4686,7 +4700,7 @@ tree_request(struct view *view, enum request request, struct line *line) if (line->type != LINE_TREE_FILE) { report("Edit only supported for files"); } else if (!is_head_commit(view->vid)) { - open_blob_editor(); + open_blob_editor(entry->id); } else { open_editor(opt_file); } @@ -4737,7 +4751,7 @@ tree_request(struct view *view, enum request request, struct line *line) break; case LINE_TREE_FILE: - flags = display[0] == view ? OPEN_SPLIT : OPEN_DEFAULT; + flags = view_is_displayed(view) ? OPEN_SPLIT : OPEN_DEFAULT; request = REQ_VIEW_BLOB; break; @@ -4837,7 +4851,7 @@ blob_request(struct view *view, enum request request, struct line *line) { switch (request) { case REQ_EDIT: - open_blob_editor(); + open_blob_editor(view->vid); return REQ_NONE; default: return pager_request(view, request, line); @@ -4870,18 +4884,6 @@ static struct view_ops blob_ops = { * reading output from git-blame. */ -static const char *blame_head_argv[] = { - "git", "blame", "--incremental", "--", "%(file)", NULL -}; - -static const char *blame_ref_argv[] = { - "git", "blame", "--incremental", "%(ref)", "--", "%(file)", NULL -}; - -static const char *blame_cat_file_argv[] = { - "git", "cat-file", "blob", "%(ref):%(file)", NULL -}; - struct blame_commit { char id[SIZEOF_REV]; /* SHA1 ID. */ char title[128]; /* First line of the commit message. */ @@ -4909,7 +4911,12 @@ blame_open(struct view *view) } if (*opt_ref || !io_open(&view->io, "%s%s", opt_cdup, opt_file)) { - if (!io_run_rd(&view->io, blame_cat_file_argv, opt_cdup, FORMAT_ALL)) + const char *blame_cat_file_argv[] = { + "git", "cat-file", "blob", path, NULL + }; + + if (!string_format(path, "%s:%s", opt_ref, opt_file) || + !io_run_rd(&view->io, blame_cat_file_argv, opt_cdup)) return FALSE; } @@ -4999,13 +5006,16 @@ static bool blame_read_file(struct view *view, const char *line, bool *read_file) { if (!line) { - const char **argv = *opt_ref ? blame_ref_argv : blame_head_argv; + const char *blame_argv[] = { + "git", "blame", "--incremental", + *opt_ref ? opt_ref : "--incremental", "--", opt_file, NULL + }; struct io io = {}; if (view->lines == 0 && !view->prev) die("No blame exist for %s", view->vid); - if (view->lines == 0 || !io_run_rd(&io, argv, opt_cdup, FORMAT_ALL)) { + if (view->lines == 0 || !io_run_rd(&io, blame_argv, opt_cdup)) { report("Failed to load blame data"); return TRUE; } @@ -5174,7 +5184,7 @@ setup_blame_parent_line(struct view *view, struct blame *blame) static enum request blame_request(struct view *view, enum request request, struct line *line) { - enum open_flags flags = display[0] == view ? OPEN_SPLIT : OPEN_DEFAULT; + enum open_flags flags = view_is_displayed(view) ? OPEN_SPLIT : OPEN_DEFAULT; struct blame *blame = line->data; switch (request) { @@ -5439,7 +5449,7 @@ branch_open(struct view *view) "--simplify-by-decoration", "--all", NULL }; - if (!io_run_rd(&view->io, branch_log, NULL, FORMAT_NONE)) { + if (!io_run_rd(&view->io, branch_log, NULL)) { report("Failed to load branch data"); return TRUE; } @@ -5900,7 +5910,7 @@ 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 : 0; + 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) { @@ -6870,7 +6880,7 @@ main_read(struct view *view, char *line) static enum request main_request(struct view *view, enum request request, struct line *line) { - enum open_flags flags = display[0] == view ? OPEN_SPLIT : OPEN_DEFAULT; + enum open_flags flags = view_is_displayed(view) ? OPEN_SPLIT : OPEN_DEFAULT; switch (request) { case REQ_ENTER: