commit c42c9805fb36a73a8de6f81318a07617264ca7e0 from: Stefan Sperling date: Tue Nov 24 22:17:55 2020 UTC support opening a tree view from the ref view; requested by naddy commit - f2f6d207e8856d57057b4c2e3237fcfade4278ed commit + c42c9805fb36a73a8de6f81318a07617264ca7e0 blob - b9039109116c48628a65c69638b420af1b40844d blob + 10aa4faaaa396db46f4ad7b4b3d7298f8d6a02ed --- tog/tog.1 +++ tog/tog.1 @@ -400,6 +400,10 @@ Move the selection cursor up one page. .It Cm Enter Open a log view which begins traversing history at the commit resolved via the currently selected reference. +.It Cm t +Open a +.Cm tree +view showing the tree resolved via the currently selected reference. .It Cm i Show object IDs for all non-symbolic references displayed in the .Cm ref blob - 1f5eb46438cd3951cfcc43a13ec23c941b538143 blob + 271c8a99135a8ba952cac81f6a4ab6c07a67e10c --- tog/tog.c +++ tog/tog.c @@ -5757,17 +5757,15 @@ close_ref_view(struct tog_view *view) } static const struct got_error * -log_ref_entry(struct tog_view **new_view, int begin_x, +resolve_reflist_entry(struct got_object_id **commit_id, struct tog_reflist_entry *re, struct got_repository *repo) { - struct tog_view *log_view; const struct got_error *err = NULL; - struct got_object_id *obj_id = NULL; - struct got_object_id *commit_id = NULL; + struct got_object_id *obj_id; struct got_tag_object *tag = NULL; int obj_type; - *new_view = NULL; + *commit_id = NULL; err = got_ref_resolve(&obj_id, repo, re->ref); if (err) @@ -5779,22 +5777,61 @@ log_ref_entry(struct tog_view **new_view, int begin_x, switch (obj_type) { case GOT_OBJ_TYPE_COMMIT: - commit_id = obj_id; + *commit_id = obj_id; break; case GOT_OBJ_TYPE_TAG: err = got_object_open_as_tag(&tag, repo, obj_id); if (err) goto done; - commit_id = got_object_tag_get_object_id(tag); - err = got_object_get_type(&obj_type, repo, commit_id); - if (err || obj_type != GOT_OBJ_TYPE_COMMIT) + free(obj_id); + err = got_object_get_type(&obj_type, repo, + got_object_tag_get_object_id(tag)); + if (err) goto done; + if (obj_type != GOT_OBJ_TYPE_COMMIT) { + err = got_error(GOT_ERR_OBJ_TYPE); + goto done; + } + *commit_id = got_object_id_dup( + got_object_tag_get_object_id(tag)); + if (*commit_id == NULL) { + err = got_error_from_errno("got_object_id_dup"); + goto done; + } break; default: - free(obj_id); - return NULL; + err = got_error(GOT_ERR_OBJ_TYPE); + break; } +done: + if (tag) + got_object_tag_close(tag); + if (err) { + free(*commit_id); + *commit_id = NULL; + } + return err; +} + +static const struct got_error * +log_ref_entry(struct tog_view **new_view, int begin_x, + struct tog_reflist_entry *re, struct got_repository *repo) +{ + struct tog_view *log_view; + const struct got_error *err = NULL; + struct got_object_id *commit_id = NULL; + + *new_view = NULL; + + err = resolve_reflist_entry(&commit_id, re, repo); + if (err) { + if (err->code != GOT_ERR_OBJ_TYPE) + return err; + else + return NULL; + } + log_view = view_open(0, 0, 0, begin_x, TOG_VIEW_LOG); if (log_view == NULL) { err = got_error_from_errno("view_open"); @@ -5807,9 +5844,7 @@ done: view_close(log_view); else *new_view = log_view; - if (tag) - got_object_tag_close(tag); - free(obj_id); + free(commit_id); return err; } @@ -6057,12 +6092,59 @@ show_ref_view(struct tog_view *view) } static const struct got_error * +browse_ref_tree(struct tog_view **new_view, int begin_x, + struct tog_reflist_entry *re, struct got_repository *repo) +{ + const struct got_error *err = NULL; + struct got_object_id *commit_id = NULL, *tree_id = NULL; + struct got_tree_object *tree = NULL; + struct tog_view *tree_view; + + *new_view = NULL; + + err = resolve_reflist_entry(&commit_id, re, repo); + if (err) { + if (err->code != GOT_ERR_OBJ_TYPE) + return err; + else + return NULL; + } + + err = got_object_id_by_path(&tree_id, repo, commit_id, "/"); + if (err) + goto done; + + err = got_object_open_as_tree(&tree, repo, tree_id); + if (err) + goto done; + + tree_view = view_open(0, 0, 0, begin_x, TOG_VIEW_TREE); + if (tree_view == NULL) { + err = got_error_from_errno("view_open"); + goto done; + } + + err = open_tree_view(tree_view, tree, commit_id, repo); + if (err) + goto done; + + *new_view = tree_view; +done: + free(commit_id); + free(tree_id); + if (err) { + if (tree) + got_object_tree_close(tree); + } + return err; +} +static const struct got_error * input_ref_view(struct tog_view **new_view, struct tog_view **dead_view, struct tog_view **focus_view, struct tog_view *view, int ch) { const struct got_error *err = NULL; struct tog_ref_view_state *s = &view->state.ref; - struct tog_view *log_view; + struct tog_view *log_view, *tree_view; int begin_x = 0, nscrolled; switch (ch) { @@ -6091,6 +6173,29 @@ input_ref_view(struct tog_view **new_view, struct tog_ } else *new_view = log_view; break; + case 't': + if (!s->selected_entry) + break; + if (view_is_parent_view(view)) + begin_x = view_split_begin_x(view->begin_x); + err = browse_ref_tree(&tree_view, begin_x, s->selected_entry, + s->repo); + if (err || tree_view == NULL) + break; + if (view_is_parent_view(view)) { + err = view_close_child(view); + if (err) + return err; + err = view_set_child(view, tree_view); + if (err) { + view_close(tree_view); + break; + } + *focus_view = tree_view; + view->child_focussed = 1; + } else + *new_view = tree_view; + break; case 'k': case KEY_UP: if (s->selected > 0) {