diff --git a/include/tig/diff.h b/include/tig/diff.h index ea725639e..35bbeb4e7 100644 --- a/include/tig/diff.h +++ b/include/tig/diff.h @@ -40,7 +40,7 @@ enum status_code diff_init_highlight(struct view *view, struct diff_state *state bool diff_done_highlight(struct diff_state *state); unsigned int diff_get_lineno(struct view *view, struct line *line); -const char *diff_get_pathname(struct view *view, struct line *line); +const char *diff_get_pathname(struct view *view, struct line *line, bool strict); extern struct view diff_view; diff --git a/src/diff.c b/src/diff.c index 583f1e0e0..3f35d9873 100644 --- a/src/diff.c +++ b/src/diff.c @@ -348,7 +348,7 @@ diff_save_line(struct view *view, struct diff_state *state, enum open_flags flag { if (flags & OPEN_RELOAD) { struct line *line = &view->line[view->pos.lineno]; - const char *file = view_has_line(view, line) ? diff_get_pathname(view, line) : NULL; + const char *file = view_has_line(view, line) ? diff_get_pathname(view, line, true) : NULL; if (file) { state->file = get_path(file); @@ -367,7 +367,7 @@ diff_restore_line(struct view *view, struct diff_state *state) return; while ((line = find_prev_line_by_type(view, line, LINE_DIFF_HEADER))) { - const char *file = diff_get_pathname(view, line); + const char *file = diff_get_pathname(view, line, true); if (file && !strcmp(file, state->file)) break; @@ -615,7 +615,7 @@ diff_trace_origin(struct view *view, struct line *line) } const char * -diff_get_pathname(struct view *view, struct line *line) +diff_get_pathname(struct view *view, struct line *line, bool strict) { struct line *header; const char *dst; @@ -624,16 +624,20 @@ diff_get_pathname(struct view *view, struct line *line) int i; header = find_prev_line_by_type(view, line, LINE_DIFF_HEADER); - if (!header) - return NULL; - for (i = 0; i < ARRAY_SIZE(prefixes); i++) { - dst = strstr(box_text(header), prefixes[i]); - if (dst) - return dst + strlen(prefixes[i]); + if (strict && !header) { + return NULL; + } else if (strict || header) { + for (i = 0; i < ARRAY_SIZE(prefixes); i++) { + dst = strstr(box_text(header), prefixes[i]); + if (dst) + return dst + strlen(prefixes[i]); + } + header = find_next_line_by_type(view, header, LINE_DIFF_ADD_FILE); + } else { + header = find_next_line_by_type(view, line, LINE_DIFF_ADD_FILE); } - header = find_next_line_by_type(view, header, LINE_DIFF_ADD_FILE); if (!header) return NULL; @@ -661,7 +665,7 @@ diff_common_edit(struct view *view, enum request request, struct line *line) file = view->env->file; lineno = view->env->lineno; } else { - file = diff_get_pathname(view, line); + file = diff_get_pathname(view, line, true); lineno = diff_get_lineno(view, line); } @@ -705,7 +709,7 @@ diff_common_select(struct view *view, struct line *line, const char *changes_msg if (line->type == LINE_DIFF_STAT) { struct line *header = diff_find_header_from_stat(view, line); if (header) { - const char *file = diff_get_pathname(view, header); + const char *file = diff_get_pathname(view, header, true); if (file) { string_format(view->env->file, "%s", file); @@ -717,15 +721,18 @@ diff_common_select(struct view *view, struct line *line, const char *changes_msg string_format(view->ref, "Press '%s' to jump to file diff", get_view_key(view, REQ_ENTER)); } else { - const char *file = diff_get_pathname(view, line); + const char *strict_file = diff_get_pathname(view, line, true); + const char *lax_file = diff_get_pathname(view, line, false); - if (file) { - if (changes_msg) - string_format(view->ref, "%s to '%s'", changes_msg, file); - string_format(view->env->file, "%s", file); + if (lax_file) { + string_format(view->env->file, "%s", lax_file); view->env->lineno = view->env->goto_lineno = diff_get_lineno(view, line); view->env->blob[0] = 0; - } else { + } + + if (strict_file && changes_msg) { + string_format(view->ref, "%s to '%s'", changes_msg, strict_file); + } else if (!strict_file) { string_ncopy(view->ref, view->ops->id, strlen(view->ops->id)); pager_select(view, line); } diff --git a/src/stage.c b/src/stage.c index b70080f63..4aacc4ad5 100644 --- a/src/stage.c +++ b/src/stage.c @@ -438,7 +438,7 @@ stage_request(struct view *view, enum request request, struct line *line) if (stage_status.new.name[0]) { string_copy(view->env->file, stage_status.new.name); } else { - const char *file = diff_get_pathname(view, line); + const char *file = diff_get_pathname(view, line, true); if (file) string_ncopy(view->env->file, file, strlen(file)); diff --git a/test/diff/diff-view-blob-test b/test/diff/diff-view-blob-test new file mode 100755 index 000000000..95b42ec34 --- /dev/null +++ b/test/diff/diff-view-blob-test @@ -0,0 +1,139 @@ +#!/bin/sh + +. libtest.sh +. libgit.sh + +export LINES=10 + +in_work_dir create_repo_from_tgz "$base_dir/files/scala-js-benchmarks.tgz" + +# content window scrolled to avoid trailing backslash and single quote +first_file_blob=' +# Run a benchmark against a JavaScript VM. + +# set -x + +RUN_DIR="$(dirname "$0")" +ROOT_DIR="./$(git rev-parse --show-cdup)" +ENGINES="d8 node" +[blob] common/benchmark-runner.sh - line 9 of 143 11%' + +last_file_blob='// The ray tracer code in this file is written by Adam Burmister. It +// is available in its original form from: +// +// http://labs.flog.co.nz/raytracer/ +// +// Ported from the v8 benchmark suite by Google 2012. +// Ported from the Dart benchmark_harness to Scala.js by Jonas Fonseca 2013 + +[blob] tracer/src/main/scala/org/scalajs/benchmark/tracer/Tracer.scala - line38%' + +test_case view-blob-goto-line-1 \ + --args='show ee912870202200a0b9cf4fd86ba57243212d341e' \ + --script=' + :1 + :view-blob + :scroll-page-down + ' \ + <