diff --git a/include/tig/stage.h b/include/tig/stage.h index e3f2f2aba..cee372d63 100644 --- a/include/tig/stage.h +++ b/include/tig/stage.h @@ -20,7 +20,7 @@ struct status; extern struct view stage_view; -void open_stage_view(struct view *prev, struct status *status, enum line_type type, enum open_flags flags); +void open_stage_view(struct view *prev, struct status *status, enum open_flags flags); #endif /* vim: set ts=8 sw=8 noexpandtab: */ diff --git a/include/tig/view.h b/include/tig/view.h index 794530c1c..6821ae529 100644 --- a/include/tig/view.h +++ b/include/tig/view.h @@ -49,6 +49,7 @@ struct line { unsigned int no_commit_refs:1; unsigned int graph_indent:1; unsigned int search_result:1; + unsigned int stat_header:1; void *data; /* User data */ }; diff --git a/src/main.c b/src/main.c index 2401295be..73d10a698 100644 --- a/src/main.c +++ b/src/main.c @@ -92,6 +92,8 @@ main_add_commit(struct view *view, enum line_type type, struct commit *template, line = add_line_alloc(view, &commit, type, titlelen, custom); if (!line) return NULL; + if (custom) + line->stat_header = 1; *commit = *template; strcpy(commit->title, title); @@ -561,7 +563,7 @@ main_request(struct view *view, enum request request, struct line *line) if (line->type == LINE_STAT_UNSTAGED || line->type == LINE_STAT_STAGED) - open_stage_view(view, NULL, line->type, flags); + open_stage_view(view, NULL, flags); else if (line->type == LINE_STAT_UNTRACKED) open_status_view(view, true, flags); else diff --git a/src/stage.c b/src/stage.c index 6fbc6125c..a3e34ba6e 100644 --- a/src/stage.c +++ b/src/stage.c @@ -38,16 +38,8 @@ typedef enum } update_t; void -open_stage_view(struct view *prev, struct status *status, enum line_type type, enum open_flags flags) +open_stage_view(struct view *prev, struct status *status, enum open_flags flags) { - if (type) { - stage_line_type = type; - if (status) - stage_status = *status; - else - memset(&stage_status, 0, sizeof(stage_status)); - } - open_view(prev, &stage_view, flags); } @@ -700,9 +692,36 @@ stage_select(struct view *view, struct line *line) diff_common_select(view, line, changes_msg); } +static void select_stage_status(struct view *prev) +{ + struct line *line = &prev->line[prev->pos.lineno]; + if (!line) + return; + stage_line_type = line->type; + switch (line->type) { + case LINE_STAT_STAGED: + case LINE_STAT_UNSTAGED: + if (!line->stat_header && !line->data) + return; + break; + case LINE_STAT_UNTRACKED: + if (line->stat_header) + return; + break; + default: + return; + } + if (line->data && !line->stat_header) { + struct status *status = line->data; + stage_status = *status; + } else + memset(&stage_status, 0, sizeof(stage_status)); +} + static enum status_code stage_open(struct view *view, enum open_flags flags) { + enum line_type line_type = (select_stage_status(view->prev), stage_line_type); const char *no_head_diff_argv[] = { GIT_DIFF_STAGED_INITIAL(encoding_arg, diff_context_arg(), ignore_space_arg(), stage_status.new.name) @@ -727,13 +746,13 @@ stage_open(struct view *view, enum open_flags flags) struct stage_state *state = view->private; enum status_code code; - if (!stage_line_type) + if (!line_type) return error("No stage content, press %s to open the status view and choose file", get_view_key(view, REQ_VIEW_STATUS)); view->encoding = NULL; - switch (stage_line_type) { + switch (line_type) { case LINE_STAT_STAGED: watch_register(&view->watch, WATCH_INDEX_STAGED); if (is_initial_commit()) { @@ -758,18 +777,18 @@ stage_open(struct view *view, enum open_flags flags) break; default: - die("line type %d not handled in switch", stage_line_type); + die("line type %d not handled in switch", line_type); } - if (!status_stage_info(view->ref, stage_line_type, &stage_status)) + if (!status_stage_info(view->ref, line_type, &stage_status)) return error("Failed to open staged view"); - if (stage_line_type != LINE_STAT_UNTRACKED) + if (line_type != LINE_STAT_UNTRACKED) diff_save_line(view, &state->diff, flags); view->vid[0] = 0; code = begin_update(view, repo.exec_dir, argv, flags); - if (code == SUCCESS && stage_line_type != LINE_STAT_UNTRACKED) { + if (code == SUCCESS && line_type != LINE_STAT_UNTRACKED) { struct stage_state *state = view->private; return diff_init_highlight(view, &state->diff); diff --git a/src/status.c b/src/status.c index 0855dc34e..a5fcd5cbf 100644 --- a/src/status.c +++ b/src/status.c @@ -94,13 +94,14 @@ status_run(struct view *view, const char *argv[], char status, enum line_type ty const char **status_argv = NULL; bool ok = argv_format(view->env, &status_argv, argv, 0) && io_run(&io, IO_RD, repo.exec_dir, NULL, status_argv); + size_t header_offset; argv_free(status_argv); free(status_argv); if (!ok) return false; - add_line_nodata(view, type); + header_offset = add_line_nodata(view, type) - view->line; while (io_get(&io, &buf, 0, true)) { struct line *line; @@ -171,6 +172,7 @@ status_run(struct view *view, const char *argv[], char status, enum line_type ty watch_apply(&view->watch, WATCH_INDEX_UNTRACKED_NO); } } else { + view->line[header_offset].stat_header = 1; if (type == LINE_STAT_STAGED) { watch_apply(&view->watch, WATCH_INDEX_STAGED_YES); no_files_staged = false; @@ -498,7 +500,7 @@ status_enter(struct view *view, struct line *line) return REQ_NONE; } - open_stage_view(view, status, line->type, flags); + open_stage_view(view, status, flags); return REQ_NONE; } diff --git a/src/tig.c b/src/tig.c index c8e6786cc..5d40121b3 100644 --- a/src/tig.c +++ b/src/tig.c @@ -180,7 +180,7 @@ view_driver(struct view *view, enum request request) break; case REQ_VIEW_DIFF: if (view && string_rev_is_null(view->env->commit)) - open_stage_view(view, NULL, 0, OPEN_DEFAULT); + open_stage_view(view, NULL, OPEN_DEFAULT); else open_diff_view(view, OPEN_DEFAULT); break; @@ -209,7 +209,7 @@ view_driver(struct view *view, enum request request) open_status_view(view, false, OPEN_DEFAULT); break; case REQ_VIEW_STAGE: - open_stage_view(view, NULL, 0, OPEN_DEFAULT); + open_stage_view(view, NULL, OPEN_DEFAULT); break; case REQ_VIEW_PAGER: open_pager_view(view, OPEN_DEFAULT); diff --git a/test/stage/default-test b/test/stage/default-test index cbf6db492..bb1060695 100755 --- a/test/stage/default-test +++ b/test/stage/default-test @@ -8,6 +8,35 @@ export LINES=20 steps ' :save-display status.screen + :2 + :view-stage + :save-display staged-changes-shortcut.screen + :view-close + + :5 + :view-stage + :save-display unstaged-changes-shortcut.screen + :view-close + + :view-main + + :1 + :view-stage + :save-display unstaged-changes-shortcut-from-main.screen + :view-close + + :2 + :view-stage + :save-display staged-changes-shortcut-from-main.screen + :view-close + + :view-close + + :4 + :view-stage + :save-display staged-changes-for-a-shortcut.screen + :view-close + :2 :enter :maximize @@ -39,6 +68,7 @@ steps ' :4 :status-update :save-display unstaged-changes-staged-all.screen + ' in_work_dir create_dirty_workdir @@ -68,6 +98,33 @@ Untracked files: [status] Nothing to update 100% EOF +assert_equals 'staged-changes.screen' < 'staged-changes-shortcut.screen' +assert_equals 'unstaged-changes.screen' < 'unstaged-changes-shortcut.screen' +assert_equals 'staged-changes.screen' < 'staged-changes-shortcut-from-main.screen' +assert_equals 'unstaged-changes.screen' < 'unstaged-changes-shortcut-from-main.screen' + +assert_equals 'staged-changes-for-a-shortcut.screen' <' to jump to file diff - line 1 of 23 78% +EOF + assert_equals 'staged-changes.screen' <