commit 917d79a766c47414055c6901624816a41f13597b from: Stefan Sperling date: Fri Jul 01 21:15:13 2022 UTC make the diff algorithm used by 'tog diff' and 'tog blame' configurable ok jamsek commit - 4b752015b5208a96c2d1b6c1c6b8589884b8b2b6 commit + 917d79a766c47414055c6901624816a41f13597b blob - 728ba5ee9e20edbde20ed7f0c2ff1cbabad89c0b blob + ed0412fd13daaa1ea18139730716db483ba49274 --- tog/tog.1 +++ tog/tog.1 @@ -295,6 +295,12 @@ Find the Nth previous line which matches the current s (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 @@ -379,6 +385,12 @@ Find the Nth next line which matches the current searc .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 @@ -560,7 +572,15 @@ work tree, use the repository path associated with thi .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 @@ -136,6 +136,7 @@ STAILQ_HEAD(tog_colors, tog_color); 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, @@ -321,7 +322,6 @@ struct tog_diff_view_state { 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; @@ -544,6 +544,7 @@ struct tog_view { 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 *); @@ -567,6 +568,7 @@ static const struct got_error *open_diff_view(struct t 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 *); @@ -586,6 +588,7 @@ static const struct got_error *open_blame_view(struct 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 *); @@ -650,7 +653,6 @@ tog_fatal_signal_received(void) return (tog_sigpipe_received || tog_sigint_received || tog_sigint_received); } - static const struct got_error * view_close(struct tog_view *view) @@ -1216,6 +1218,24 @@ view_input(struct tog_view **new, int *done, struct to 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); @@ -3966,13 +3986,13 @@ create_diff(struct tog_diff_view_state *s) 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: { @@ -4008,7 +4028,7 @@ create_diff(struct tog_diff_view_state *s) 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; } @@ -4219,7 +4239,6 @@ open_diff_view(struct tog_view *view, struct got_objec 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; @@ -4273,6 +4292,7 @@ open_diff_view(struct tog_view *view, struct got_objec 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; @@ -4343,6 +4363,20 @@ set_selected_commit(struct tog_diff_view_state *s, } 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; @@ -4381,13 +4415,7 @@ input_diff_view(struct tog_view **new_view, struct tog 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: @@ -4950,7 +4978,7 @@ blame_thread(void *arg) 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; @@ -5225,6 +5253,7 @@ open_blame_view(struct tog_view *view, char *path, 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; @@ -5638,6 +5667,21 @@ input_blame_view(struct tog_view **new_view, struct to 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 * @@ -7839,6 +7883,7 @@ main(int argc, char *argv[]) { "version", no_argument, NULL, 'V' }, { NULL, 0, NULL, 0} }; + char *diff_algo_str = NULL; setlocale(LC_CTYPE, ""); @@ -7892,6 +7937,14 @@ main(int argc, char *argv[]) } } + 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);