From: Mark Jamsek Subject: tog: keymaps to resize splits To: gameoftrees@openbsd.org Date: Fri, 8 Jul 2022 03:17:37 +1000 This introduces +/- key maps to increase/decrease the size of the active split. We make user-resized splits persist for the session. So if you resize a h- or v-split, or both, with a log/diff view, after closing the diff view, if you reopen another commit or a tree or ref view, the resize sticks. I found this more useful than reverting to defaults each time you close a child view. We also limit the resize rather than allow increasing/decreasing all the way to a fullscreen as we already have the 'F' key map. And we still honour the no vsplit when COLS < 120, but we might want to reconsider this with resizable splits. diff refs/heads/main refs/heads/stash/02a commit - d2366e29426c9d2c88244cf41683f6574928caff commit + 21e9e58baedee170f8c72f30eba1d45424ba41fd blob - fabe11c6154ce842f41946267fdf3f30c963da54 blob + 36292761a7044253e6fba53a3708ee5e68f8ce0b --- tog/tog.1 +++ tog/tog.1 @@ -86,6 +86,10 @@ When in a split-screen view, will switch to the alternate split mode. If the current view is in a horizontal split and the terminal window is not wide enough, the view will remain unchanged. +.It Cm - +When in a split-screen view, decrease the split that is currently in focus. +.It Cm + +When in a split-screen view, increase the split that is currently in focus. .El .Pp Global options must precede the command name, and are as follows: blob - 7dc49c638a583244ce89554bdfee75bd523d1a99 blob + bfa6432f0a263cd4b3a0ffaab0f09bd6d69c5f5f --- tog/tog.c +++ tog/tog.c @@ -510,10 +510,12 @@ struct tog_view { WINDOW *window; PANEL *panel; int nlines, ncols, begin_y, begin_x; /* based on split height/width */ + int resized_y, resized_x; /* begin_y/x based on user resizing */ int maxx, x; /* max column and current start column */ int lines, cols; /* copies of LINES and COLS */ int nscrolled, offset; /* lines scrolled and hsplit line offset */ int ch, count; /* current keymap and count prefix */ + int resize; /* set when in a resize event */ int focussed; /* Only set on one parent or child view at a time. */ int dying; struct tog_view *parent; @@ -727,11 +729,18 @@ view_splitscreen(struct tog_view *view) { const struct got_error *err = NULL; - if (view->mode == TOG_VIEW_SPLIT_HRZN) { - view->begin_y = view_split_begin_y(view->nlines); + if (!view->resize && view->mode == TOG_VIEW_SPLIT_HRZN) { + if (view->resized_y && view->resized_y < view->lines) + view->begin_y = view->resized_y; + else + view->begin_y = view_split_begin_y(view->nlines); view->begin_x = 0; - } else { - view->begin_x = view_split_begin_x(0); + } else if (!view->resize) { + if (view->resized_x && view->resized_x < view->cols - 1 && + view->cols > 119) + view->begin_x = view->resized_x; + else + view->begin_x = view_split_begin_x(0); view->begin_y = 0; } view->nlines = LINES - view->begin_y; @@ -757,8 +766,8 @@ view_fullscreen(struct tog_view *view) const struct got_error *err = NULL; view->begin_x = 0; - view->begin_y = 0; - view->nlines = LINES; + view->begin_y = view->resize ? view->begin_y : 0; + view->nlines = view->resize ? view->nlines : LINES; view->ncols = COLS; view->lines = LINES; view->cols = COLS; @@ -820,9 +829,11 @@ view_border(struct tog_view *view) got_locale_is_utf8() ? ACS_VLINE : '|', view->nlines); } +static const struct got_error *view_init_hsplit(struct tog_view *, int); static const struct got_error *request_log_commits(struct tog_view *); static const struct got_error *offset_selection_down(struct tog_view *); static void offset_selection_up(struct tog_view *); +static void view_get_split(struct tog_view *, int *, int *); static const struct got_error * view_resize(struct tog_view *view) @@ -917,6 +928,90 @@ view_resize(struct tog_view *view) } static const struct got_error * +view_resize_split(struct tog_view *view, int resize) +{ + const struct got_error *err = NULL; + struct tog_view *v = NULL; + + if (view->parent) + v = view->parent; + else + v = view; + + if (!v->child || !view_is_splitscreen(v->child)) + return NULL; + + v->resize = v->child->resize = resize; /* lock for resize event */ + + if (view->mode == TOG_VIEW_SPLIT_HRZN) { + if (v->child->resized_y) + v->child->begin_y = v->child->resized_y; + if (view->parent) + v->child->begin_y -= resize; + else + v->child->begin_y += resize; + if (v->child->begin_y < 3) + v->child->begin_y = 3; + else if (v->child->begin_y > LINES - 1) + v->child->begin_y = LINES - 1; + v->ncols = COLS; + v->child->ncols = COLS; + err = view_init_hsplit(v, v->child->begin_y); + if (err) + return err; + v->child->resized_y = v->child->begin_y; + } else { + if (v->child->resized_x) + v->child->begin_x = v->child->resized_x; + if (view->parent) + v->child->begin_x -= resize; + else + v->child->begin_x += resize; + if (v->child->begin_x < 11) + v->child->begin_x = 11; + else if (v->child->begin_x > COLS - 1) + v->child->begin_x = COLS - 1; + v->child->resized_x = v->child->begin_x; + } + + v->child->mode = v->mode; + v->child->nlines = v->lines - v->child->begin_y; + v->child->ncols = v->cols - v->child->begin_x; + v->focus_child = 1; + + err = view_fullscreen(v); + if (err) + return err; + err = view_splitscreen(v->child); + if (err) + return err; + + if (v->mode == TOG_VIEW_SPLIT_HRZN) { + err = offset_selection_down(v->child); + if (err) + return err; + } + + if (v->type == TOG_VIEW_LOG) + err = request_log_commits(v); + else if (v->child->type == TOG_VIEW_LOG) + err = request_log_commits(v->child); + + v->resize = v->child->resize = 0; + + return err; +} + +static void +view_transfer_size(struct tog_view *dst, struct tog_view *src) +{ + struct tog_view *v = src->child ? src->child : src; + + dst->resized_x = v->resized_x; + dst->resized_y = v->resized_y; +} + +static const struct got_error * view_close_child(struct tog_view *view) { const struct got_error *err = NULL; @@ -932,10 +1027,19 @@ view_close_child(struct tog_view *view) static const struct got_error * view_set_child(struct tog_view *view, struct tog_view *child) { + const struct got_error *err = NULL; + view->child = child; child->parent = view; - return view_resize(view); + err = view_resize(view); + if (err) + return err; + + if (view->child->resized_x || view->child->resized_y) + err = view_resize_split(view, 0); + + return err; } static void @@ -1004,9 +1108,6 @@ view_search_start(struct tog_view *view) return NULL; } -static void view_get_split(struct tog_view *, int *, int *); -static const struct got_error *view_init_hsplit(struct tog_view *, int); - /* * If view is a parent or child view and is currently in a splitscreen, switch * to the alternate split. If in a hsplit and LINES < 120, don't vsplit. @@ -1034,6 +1135,10 @@ switch_split(struct tog_view *view) v->mode = TOG_VIEW_SPLIT_HRZN; view_get_split(v, &v->child->begin_y, &v->child->begin_x); + if (v->mode == TOG_VIEW_SPLIT_HRZN && v->child->resized_y) + v->child->begin_y = v->child->resized_y; + if (v->mode == TOG_VIEW_SPLIT_VERT && v->child->resized_x) + v->child->begin_x = v->child->resized_x; if (v->mode == TOG_VIEW_SPLIT_HRZN) { v->ncols = COLS; @@ -1184,6 +1289,11 @@ view_input(struct tog_view **new, int *done, struct to KEY_RESIZE); if (err) return err; + if (v->child->resized_x || v->child->resized_y) { + err = view_resize_split(v, 0); + if (err) + return err; + } } } } @@ -1238,8 +1348,11 @@ view_input(struct tog_view **new, int *done, struct to view->focussed = 0; view->child->focussed = 1; err = view_fullscreen(view->child); - } else + } else { err = view_splitscreen(view->child); + if (!err) + err = view_resize_split(view, 0); + } if (err) break; err = view->child->input(new, view->child, @@ -1253,6 +1366,8 @@ view_input(struct tog_view **new, int *done, struct to err = view_splitscreen(view); if (!err && view->mode != TOG_VIEW_SPLIT_HRZN) err = view_resize(view->parent); + if (!err) + err = view_resize_split(view, 0); } if (err) break; @@ -1273,6 +1388,12 @@ view_input(struct tog_view **new, int *done, struct to case 'S': err = switch_split(view); break; + case '-': + err = view_resize_split(view, -1); + break; + case '+': + err = view_resize_split(view, 1); + break; case KEY_RESIZE: break; case '/': @@ -1386,6 +1507,8 @@ view_loop(struct tog_view *view) err = view_resize(view->parent); if (err) break; + /* Make resized splits persist. */ + view_transfer_size(view->parent, view); } else TAILQ_REMOVE(&views, view, entry); @@ -2958,10 +3081,17 @@ view_get_split(struct tog_view *view, int *y, int *x) *x = 0; *y = 0; - if (view->mode == TOG_VIEW_SPLIT_HRZN) - *y = view_split_begin_y(view->lines); - else - *x = view_split_begin_x(view->begin_x); + if (view->mode == TOG_VIEW_SPLIT_HRZN) { + if (view->child && view->child->resized_y) + *y = view->child->resized_y; + else + *y = view_split_begin_y(view->lines); + } else { + if (view->child && view->child->resized_x) + *x = view->child->resized_x; + else + *x = view_split_begin_x(view->begin_x); + } } /* Split view horizontally at y and offset view->state->selected line. */ @@ -3132,6 +3262,7 @@ input_log_view(struct tog_view **new_view, struct tog_ diff_view->nlines = view->lines - begin_y; if (view_is_parent_view(view)) { + view_transfer_size(diff_view, view); err = view_close_child(view); if (err) return err; @@ -3164,6 +3295,7 @@ input_log_view(struct tog_view **new_view, struct tog_ tree_view->mode = view->mode; tree_view->nlines = view->lines - begin_y; if (view_is_parent_view(view)) { + view_transfer_size(tree_view, view); err = view_close_child(view); if (err) return err; @@ -3261,6 +3393,7 @@ input_log_view(struct tog_view **new_view, struct tog_ ref_view->mode = view->mode; ref_view->nlines = view->lines - begin_y; if (view_is_parent_view(view)) { + view_transfer_size(ref_view, view); err = view_close_child(view); if (err) return err; @@ -5699,6 +5832,7 @@ input_blame_view(struct tog_view **new_view, struct to diff_view->mode = view->mode; diff_view->nlines = view->lines - begin_y; if (view_is_parent_view(view)) { + view_transfer_size(diff_view, view); err = view_close_child(view); if (err) break; @@ -6479,6 +6613,7 @@ input_tree_view(struct tog_view **new_view, struct tog log_view->mode = view->mode; log_view->nlines = view->lines - begin_y; if (view_is_parent_view(view)) { + view_transfer_size(log_view, view); err = view_close_child(view); if (err) return err; @@ -6512,6 +6647,7 @@ input_tree_view(struct tog_view **new_view, struct tog ref_view->mode = view->mode; ref_view->nlines = view->lines - begin_y; if (view_is_parent_view(view)) { + view_transfer_size(ref_view, view); err = view_close_child(view); if (err) return err; @@ -6691,6 +6827,7 @@ input_tree_view(struct tog_view **new_view, struct tog blame_view->mode = view->mode; blame_view->nlines = view->lines - begin_y; if (view_is_parent_view(view)) { + view_transfer_size(blame_view, view); err = view_close_child(view); if (err) return err; @@ -7444,6 +7581,7 @@ input_ref_view(struct tog_view **new_view, struct tog_ log_view->mode = view->mode; log_view->nlines = view->lines - begin_y; if (view_is_parent_view(view)) { + view_transfer_size(log_view, view); err = view_close_child(view); if (err) return err; @@ -7475,6 +7613,7 @@ input_ref_view(struct tog_view **new_view, struct tog_ tree_view->mode = view->mode; tree_view->nlines = view->lines - begin_y; if (view_is_parent_view(view)) { + view_transfer_size(tree_view, view); err = view_close_child(view); if (err) return err; -- Mark Jamsek GPG: F2FF 13DE 6A06 C471 CA80 E6E2 2930 DC66 86EE CF68