commit - 4b752015b5208a96c2d1b6c1c6b8589884b8b2b6
commit + 917d79a766c47414055c6901624816a41f13597b
blob - 728ba5ee9e20edbde20ed7f0c2ff1cbabad89c0b
blob + ed0412fd13daaa1ea18139730716db483ba49274
--- tog/tog.1
+++ tog/tog.1
(default: 1).
.It Cm w
Toggle display of whitespace-only changes.
+.It Cm A
+Change the diff algorithm.
+Supported diff algorithms are Myers and Patience.
+This is a global setting which also affects the
+.Cm blame
+view.
.El
.Pp
The options for
.It Cm N
Find the Nth previous line which matches the current search pattern
(default: 1).
+.It Cm A
+Change the diff algorithm.
+Supported diff algorithms are Myers and Patience.
+This is a global setting which also affects the
+.Cm diff
+view.
.El
.Pp
The options for
.El
.El
.Sh ENVIRONMENT
-.Bl -tag -width TOG_COLORS
+.Bl -tag -width TOG_DIFF_ALGORITHM
+.It Ev TOG_DIFF_ALGORITHM
+Determines the default diff algorithm used by
+.Nm .
+Valid values are
+.Dq patience
+and
+.Dq myers .
+If unset, the Myers diff algorithm will be used by default.
.It Ev TOG_COLORS
.Nm
shows colorized output if this variable is set to a non-empty value.
blob - 800384dacf0faed4893832dd2760af45e28cb8c7
blob + 3d04465936bab47783593c3f81f0057e2ec865bc
--- tog/tog.c
+++ tog/tog.c
static struct got_reflist_head tog_refs = TAILQ_HEAD_INITIALIZER(tog_refs);
static struct got_reflist_object_id_map *tog_refs_idmap;
+static enum got_diff_algorithm tog_diff_algo = GOT_DIFF_ALGORITHM_MYERS;
static const struct got_error *
tog_ref_cmp_by_name(void *arg, int *cmp, struct got_reference *re1,
int first_displayed_line;
int last_displayed_line;
int eof;
- enum got_diff_algorithm diff_algo;
int diff_context;
int ignore_whitespace;
int force_text_diff;
const struct got_error *(*show)(struct tog_view *);
const struct got_error *(*input)(struct tog_view **,
struct tog_view *, int);
+ const struct got_error *(*reset)(struct tog_view *);
const struct got_error *(*close)(struct tog_view *);
const struct got_error *(*search_start)(struct tog_view *);
static const struct got_error *show_diff_view(struct tog_view *);
static const struct got_error *input_diff_view(struct tog_view **,
struct tog_view *, int);
+static const struct got_error *reset_diff_view(struct tog_view *);
static const struct got_error* close_diff_view(struct tog_view *);
static const struct got_error *search_start_diff_view(struct tog_view *);
static const struct got_error *search_next_diff_view(struct tog_view *);
static const struct got_error *show_blame_view(struct tog_view *);
static const struct got_error *input_blame_view(struct tog_view **,
struct tog_view *, int);
+static const struct got_error *reset_blame_view(struct tog_view *);
static const struct got_error *close_blame_view(struct tog_view *);
static const struct got_error *search_start_blame_view(struct tog_view *);
static const struct got_error *search_next_blame_view(struct tog_view *);
return (tog_sigpipe_received ||
tog_sigint_received || tog_sigint_received);
}
-
static const struct got_error *
view_close(struct tog_view *view)
view->search_next(view);
} else
err = view->input(new, view, ch);
+ break;
+ case 'A':
+ if (tog_diff_algo == GOT_DIFF_ALGORITHM_MYERS)
+ tog_diff_algo = GOT_DIFF_ALGORITHM_PATIENCE;
+ else
+ tog_diff_algo = GOT_DIFF_ALGORITHM_MYERS;
+ TAILQ_FOREACH(v, views, entry) {
+ if (v->reset) {
+ err = v->reset(v);
+ if (err)
+ return err;
+ }
+ if (v->child && v->child->reset) {
+ err = v->child->reset(v->child);
+ if (err)
+ return err;
+ }
+ }
break;
default:
err = view->input(new, view, ch);
case GOT_OBJ_TYPE_BLOB:
err = got_diff_objects_as_blobs(&s->line_offsets, &s->nlines,
s->f1, s->f2, s->fd1, s->fd2, s->id1, s->id2,
- s->label1, s->label2, s->diff_algo, s->diff_context,
+ s->label1, s->label2, tog_diff_algo, s->diff_context,
s->ignore_whitespace, s->force_text_diff, s->repo, s->f);
break;
case GOT_OBJ_TYPE_TREE:
err = got_diff_objects_as_trees(&s->line_offsets, &s->nlines,
s->f1, s->f2, s->fd1, s->fd2, s->id1, s->id2, NULL, "", "",
- s->diff_algo, s->diff_context, s->ignore_whitespace,
+ tog_diff_algo, s->diff_context, s->ignore_whitespace,
s->force_text_diff, s->repo, s->f);
break;
case GOT_OBJ_TYPE_COMMIT: {
err = got_diff_objects_as_commits(&s->line_offsets, &s->nlines,
s->f1, s->f2, s->fd1, s->fd2, s->id1, s->id2, NULL,
- s->diff_algo, s->diff_context, s->ignore_whitespace,
+ tog_diff_algo, s->diff_context, s->ignore_whitespace,
s->force_text_diff, s->repo, s->f);
break;
}
s->first_displayed_line = 1;
s->last_displayed_line = view->nlines;
- s->diff_algo = GOT_DIFF_ALGORITHM_MYERS;
s->diff_context = diff_context;
s->ignore_whitespace = ignore_whitespace;
s->force_text_diff = force_text_diff;
view->show = show_diff_view;
view->input = input_diff_view;
+ view->reset = reset_diff_view;
view->close = close_diff_view;
view->search_start = search_start_diff_view;
view->search_next = search_next_diff_view;
}
static const struct got_error *
+reset_diff_view(struct tog_view *view)
+{
+ struct tog_diff_view_state *s = &view->state.diff;
+
+ view->count = 0;
+ wclear(view->window);
+ s->first_displayed_line = 1;
+ s->last_displayed_line = view->nlines;
+ s->matched_line = 0;
+ diff_view_indicate_progress(view);
+ return create_diff(s);
+}
+
+static const struct got_error *
input_diff_view(struct tog_view **new_view, struct tog_view *view, int ch)
{
const struct got_error *err = NULL;
s->force_text_diff = !s->force_text_diff;
if (ch == 'w')
s->ignore_whitespace = !s->ignore_whitespace;
- wclear(view->window);
- s->first_displayed_line = 1;
- s->last_displayed_line = view->nlines;
- s->matched_line = 0;
- diff_view_indicate_progress(view);
- err = create_diff(s);
- view->count = 0;
+ err = reset_diff_view(view);
break;
case 'g':
case KEY_HOME:
goto done;
err = got_blame(ta->path, a->commit_id, ta->repo,
- GOT_DIFF_ALGORITHM_MYERS, blame_cb, ta->cb_args,
+ tog_diff_algo, blame_cb, ta->cb_args,
ta->cancel_cb, ta->cancel_arg, fd1, fd2, f1, f2);
if (err && err->code == GOT_ERR_CANCELLED)
err = NULL;
view->show = show_blame_view;
view->input = input_blame_view;
+ view->reset = reset_blame_view;
view->close = close_blame_view;
view->search_start = search_start_blame_view;
view->search_next = search_next_blame_view;
break;
}
return thread_err ? thread_err : err;
+}
+
+static const struct got_error *
+reset_blame_view(struct tog_view *view)
+{
+ const struct got_error *err;
+ struct tog_blame_view_state *s = &view->state.blame;
+
+ view->count = 0;
+ s->done = 1;
+ err = stop_blame(&s->blame);
+ s->done = 0;
+ if (err)
+ return err;
+ return run_blame(view);
}
static const struct got_error *
{ "version", no_argument, NULL, 'V' },
{ NULL, 0, NULL, 0}
};
+ char *diff_algo_str = NULL;
setlocale(LC_CTYPE, "");
}
}
+ diff_algo_str = getenv("TOG_DIFF_ALGORITHM");
+ if (diff_algo_str) {
+ if (strcasecmp(diff_algo_str, "patience") == 0)
+ tog_diff_algo = GOT_DIFF_ALGORITHM_PATIENCE;
+ if (strcasecmp(diff_algo_str, "myers") == 0)
+ tog_diff_algo = GOT_DIFF_ALGORITHM_MYERS;
+ }
+
if (cmd == NULL) {
if (argc != 1)
usage(0, 1);