static bool tree_open(struct view *view, enum open_flags flags) { static const char *tree_argv[] = { "git", "ls-tree", "-l", "%(commit)", "%(directory)", NULL }; if (string_rev_is_null(view->env->commit)) { report("No tree exists for this commit"); return FALSE; } if (view->lines == 0 && repo.prefix[0]) { char *pos = repo.prefix; while (pos && *pos) { char *end = strchr(pos, '/'); if (end) *end = 0; push_tree_stack_entry(view, pos, &view->pos); pos = end; if (end) { *end = '/'; pos++; } } } else if (strcmp(view->vid, view->ops->id)) { view->env->directory[0] = 0; } return begin_update(view, repo.cdup, tree_argv, flags); }
static enum request blame_request(struct view *view, enum request request, struct line *line) { enum open_flags flags = view_is_displayed(view) ? OPEN_SPLIT : OPEN_DEFAULT; struct blame *blame = line->data; switch (request) { case REQ_VIEW_BLAME: case REQ_PARENT: if (!check_blame_commit(blame, TRUE)) break; blame_go_forward(view, blame, request == REQ_PARENT); break; case REQ_BACK: blame_go_back(view); break; case REQ_ENTER: if (!check_blame_commit(blame, FALSE)) break; if (view_is_displayed(VIEW(REQ_VIEW_DIFF)) && !strcmp(blame->commit->id, VIEW(REQ_VIEW_DIFF)->ref)) break; if (string_rev_is_null(blame->commit->id)) { struct view *diff = VIEW(REQ_VIEW_DIFF); const char *diff_parent_argv[] = { GIT_DIFF_BLAME(encoding_arg, opt_diff_context_arg, opt_ignore_space_arg, view->vid) }; const char *diff_no_parent_argv[] = { GIT_DIFF_BLAME_NO_PARENT(encoding_arg, opt_diff_context_arg, opt_ignore_space_arg, view->vid) }; const char **diff_index_argv = *blame->commit->parent_id ? diff_parent_argv : diff_no_parent_argv; open_argv(view, diff, diff_index_argv, NULL, flags); if (diff->pipe) string_copy_rev(diff->ref, NULL_ID); } else { open_view(view, REQ_VIEW_DIFF, flags); } break; default: return request; } return REQ_NONE; }
static bool check_blame_commit(struct blame *blame, bool check_null_id) { if (!blame->commit) report("Commit data not loaded yet"); else if (check_null_id && string_rev_is_null(blame->commit->id)) report("No commit exist for the selected line"); else return TRUE; return FALSE; }
static void blame_select(struct view *view, struct line *line) { struct blame *blame = line->data; struct blame_commit *commit = blame->commit; if (!commit) return; if (string_rev_is_null(commit->id)) string_ncopy(view->env->commit, "HEAD", 4); else string_copy_rev(view->env->commit, commit->id); }
static bool view_driver(struct view *view, enum request request) { int i; if (request == REQ_NONE) return true; if (request >= REQ_RUN_REQUESTS) { request = open_run_request(view, request); // exit quickly rather than going through view_request and back if (request == REQ_QUIT) return false; } request = view_request(view, request); if (request == REQ_NONE) return true; switch (request) { case REQ_MOVE_UP: case REQ_MOVE_DOWN: case REQ_MOVE_PAGE_UP: case REQ_MOVE_PAGE_DOWN: case REQ_MOVE_HALF_PAGE_UP: case REQ_MOVE_HALF_PAGE_DOWN: case REQ_MOVE_FIRST_LINE: case REQ_MOVE_LAST_LINE: case REQ_MOVE_WHEEL_DOWN: case REQ_MOVE_WHEEL_UP: move_view(view, request); break; case REQ_SCROLL_FIRST_COL: case REQ_SCROLL_LEFT: case REQ_SCROLL_RIGHT: case REQ_SCROLL_LINE_DOWN: case REQ_SCROLL_LINE_UP: case REQ_SCROLL_PAGE_DOWN: case REQ_SCROLL_PAGE_UP: case REQ_SCROLL_WHEEL_DOWN: case REQ_SCROLL_WHEEL_UP: scroll_view(view, request); break; case REQ_VIEW_GREP: open_grep_view(view); break; case REQ_VIEW_MAIN: open_main_view(view, OPEN_DEFAULT); break; case REQ_VIEW_DIFF: if (view && string_rev_is_null(view->env->commit)) open_stage_view(view, NULL, 0, OPEN_DEFAULT); else open_diff_view(view, OPEN_DEFAULT); break; case REQ_VIEW_LOG: open_log_view(view, OPEN_DEFAULT); break; case REQ_VIEW_TREE: open_tree_view(view, OPEN_DEFAULT); break; case REQ_VIEW_HELP: open_help_view(view, OPEN_DEFAULT); break; case REQ_VIEW_REFS: open_refs_view(view, OPEN_DEFAULT); break; case REQ_VIEW_BLAME: open_blame_view(view, OPEN_DEFAULT); break; case REQ_VIEW_BLOB: open_blob_view(view, OPEN_DEFAULT); break; case REQ_VIEW_STATUS: open_status_view(view, false, OPEN_DEFAULT); break; case REQ_VIEW_STAGE: open_stage_view(view, NULL, 0, OPEN_DEFAULT); break; case REQ_VIEW_PAGER: open_pager_view(view, OPEN_DEFAULT); break; case REQ_VIEW_STASH: open_stash_view(view, OPEN_DEFAULT); break; case REQ_NEXT: case REQ_PREVIOUS: if (view->parent && view == display[1]) { int line; view = view->parent; line = view->pos.lineno; view_request(view, request); move_view(view, request); if (view_is_displayed(view)) update_view_title(view); if (line != view->pos.lineno) view_request(view, REQ_ENTER); } else { move_view(view, request); } break; case REQ_VIEW_NEXT: { int nviews = displayed_views(); int next_view = nviews ? (current_view + 1) % nviews : current_view; if (next_view == current_view) { report("Only one view is displayed"); break; } current_view = next_view; /* Blur out the title of the previous view. */ update_view_title(view); report_clear(); break; } case REQ_REFRESH: report("Refreshing is not supported by the %s view", view->name); break; case REQ_PARENT: report("Moving to parent is not supported by the %s view", view->name); break; case REQ_BACK: report("Going back is not supported by the %s view", view->name); break; case REQ_MAXIMIZE: if (displayed_views() == 2) maximize_view(view, true); break; case REQ_OPTIONS: toggle_option(view); break; case REQ_SEARCH: case REQ_SEARCH_BACK: search_view(view, request); break; case REQ_FIND_NEXT: case REQ_FIND_PREV: find_next(view, request); break; case REQ_MOVE_NEXT_MERGE: case REQ_MOVE_PREV_MERGE: report("Moving between merge commits is not supported by the %s view", view->name); break; case REQ_STOP_LOADING: foreach_view(view, i) { if (view->pipe) report("Stopped loading the %s view", view->name), end_update(view, true); if (view_is_displayed(view)) update_view_title(view); } break; case REQ_SHOW_VERSION: report("tig-%s", TIG_VERSION); return true; case REQ_SCREEN_REDRAW: redraw_display(true); break; case REQ_EDIT: report("Nothing to edit"); break; case REQ_ENTER: report("Nothing to enter"); break; case REQ_VIEW_CLOSE_NO_QUIT: case REQ_VIEW_CLOSE: /* XXX: Mark closed views by letting view->prev point to the * view itself. Parents to closed view should never be * followed. */ if (view->prev && view->prev != view) { maximize_view(view->prev, true); view->prev = view; watch_unregister(&view->watch); view->parent = NULL; break; } if (request == REQ_VIEW_CLOSE_NO_QUIT) { report("Can't close last remaining view"); break; } /* Fall-through */ case REQ_QUIT: return false; default: report("Unknown key, press %s for help", get_view_key(view, REQ_VIEW_HELP)); return true; } return true; }