Code

Use view_request to unconditionally refresh views after run requests
[tig.git] / tig.c
diff --git a/tig.c b/tig.c
index f08117e58da7979dbaa57fe83bb0c7664d1cdd3d..eaff28cdc04f98bdbffbd4f8e89b8da8e054feb0 100644 (file)
--- a/tig.c
+++ b/tig.c
@@ -678,6 +678,15 @@ 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]);
+}
+
 
 /*
  * Executing external commands.
@@ -2214,7 +2223,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 +2300,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,8 +2328,18 @@ static struct view views[] = {
 #define view_is_displayed(view) \
        (view == display[0] || view == display[1])
 
-#define view_has_parent(view, child_type, parent_type) \
-       (view->type == child_type && view->parent && view->parent->type == parent_type)
+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)
@@ -2712,6 +2730,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)
@@ -3135,15 +3158,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)
 {
@@ -3180,7 +3194,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];
@@ -3379,7 +3393,8 @@ update_view(struct view *view)
                end_update(view, TRUE);
 
        } else if (io_eof(view->pipe)) {
-               report("");
+               if (view_is_displayed(view))
+                       report("");
                end_update(view, FALSE);
        }
 
@@ -3589,7 +3604,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);
 }
 
 /*
@@ -3606,18 +3621,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:
@@ -3695,11 +3705,7 @@ view_driver(struct view *view, enum request request)
        case REQ_PREVIOUS:
                request = request == REQ_NEXT ? REQ_MOVE_DOWN : REQ_MOVE_UP;
 
-               if (view_has_parent(view, VIEW_DIFF, VIEW_MAIN) ||
-                   view_has_parent(view, VIEW_DIFF, VIEW_BLAME) ||
-                   view_has_parent(view, VIEW_STAGE, VIEW_STATUS) ||
-                   view_has_parent(view, VIEW_BLOB, VIEW_TREE) ||
-                   view_has_parent(view, VIEW_MAIN, VIEW_BRANCH)) {
+               if (view->parent) {
                        int line;
 
                        view = view->parent;
@@ -3708,9 +3714,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);
                }
@@ -4019,7 +4023,9 @@ select_commit_parent(const char *id, char rev[SIZEOF_REV], const char *path)
                return FALSE;
        }
 
-       if (parents > 1 && !open_commit_parent_menu(buf, &parents))
+       if (parents == 1)
+               parents = 0;
+       else if (!open_commit_parent_menu(buf, &parents))
                return FALSE;
 
        string_copy_rev(rev, &buf[41 * parents]);
@@ -4656,14 +4662,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, FORMAT_NONE, fd))
                report("Failed to save blob data to file");
        else
                open_editor(file);
@@ -4675,6 +4682,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:
@@ -4690,7 +4698,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);
                }
@@ -4741,7 +4749,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;
 
@@ -4841,7 +4849,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);
@@ -5178,7 +5186,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) {
@@ -5904,7 +5912,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) {
@@ -6874,7 +6882,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: