From: urosm <urosm@kompot.si>
Adds a stacked layout option in which windows are "stacked"
horizontally but the focused window takes up the most space.
The easy route was to make unfocused windows take 2 lines of height
to display at least one line of View in addition to the statusline.
---
sam.c | 10 +++++++++-
ui-terminal.c | 7 +++++++
ui.h | 3 ++-
vis-cmds.c | 22 +++++++++++++++++++++-
vis-lua.c | 1 +
5 files changed, 40 insertions(+), 3 deletions(-)
diff --git a/sam.c b/sam.c
index 90d19c2..e1ac3d3 100644
--- a/sam.c
+++ b/sam.c
@@ -133,8 +133,10 @@ static bool cmd_open(Vis*, Win*, Command*, const char *argv[], Selection*, Filer
static bool cmd_qall(Vis*, Win*, Command*, const char *argv[], Selection*, Filerange*);
static bool cmd_split(Vis*, Win*, Command*, const char *argv[], Selection*, Filerange*);
static bool cmd_vsplit(Vis*, Win*, Command*, const char *argv[], Selection*, Filerange*);
+static bool cmd_ssplit(Vis*, Win*, Command*, const char *argv[], Selection*, Filerange*);
static bool cmd_new(Vis*, Win*, Command*, const char *argv[], Selection*, Filerange*);
static bool cmd_vnew(Vis*, Win*, Command*, const char *argv[], Selection*, Filerange*);
+static bool cmd_snew(Vis*, Win*, Command*, const char *argv[], Selection*, Filerange*);
static bool cmd_wq(Vis*, Win*, Command*, const char *argv[], Selection*, Filerange*);
static bool cmd_earlier_later(Vis*, Win*, Command*, const char *argv[], Selection*, Filerange*);
static bool cmd_help(Vis*, Win*, Command*, const char *argv[], Selection*, Filerange*);
@@ -253,9 +255,15 @@ static const CommandDef cmds[] = {
}, {
"vnew", VIS_HELP("As `:new` but split vertically")
CMD_ARGV|CMD_ONCE|CMD_ADDRESS_NONE, NULL, cmd_vnew
+ }, {
+ "snew", VIS_HELP("As `:new` but split stacked")
+ CMD_ARGV|CMD_ONCE|CMD_ADDRESS_NONE, NULL, cmd_snew
}, {
"vsplit", VIS_HELP("Vertically split window")
CMD_ARGV|CMD_ONCE|CMD_ADDRESS_NONE, NULL, cmd_vsplit
+ }, {
+ "ssplit", VIS_HELP("Stackingly split window")
+ CMD_ARGV|CMD_ONCE|CMD_ADDRESS_NONE, NULL, cmd_ssplit
}, {
"wq", VIS_HELP("Write file and quit")
CMD_ARGV|CMD_FORCE|CMD_ONCE|CMD_ADDRESS_ALL|CMD_DESTRUCTIVE, NULL, cmd_wq
@@ -395,7 +403,7 @@ static const OptionDef options[] = {
[OPTION_LAYOUT] = {
{ "layout" },
VIS_OPTION_TYPE_STRING,
- VIS_HELP("Vertical or horizontal window layout")
+ VIS_HELP("Vertical, horizontal or stacked window layout")
},
[OPTION_IGNORECASE] = {
{ "ignorecase", "ic" },
diff --git a/ui-terminal.c b/ui-terminal.c
index 6e78d32..88eeead 100644
--- a/ui-terminal.c
+++ b/ui-terminal.c
@@ -299,6 +299,7 @@ void ui_arrange(Ui *tui, enum UiLayout layout) {
n++;
}
int max_height = tui->height - m;
+ int n0 = n;
int width = (tui->width / MAX(1, n)) - 1;
int height = max_height / MAX(1, n);
for (Win *win = tui->windows; win; win = win->next) {
@@ -310,6 +311,12 @@ void ui_arrange(Ui *tui, enum UiLayout layout) {
ui_window_resize(win, tui->width, h);
ui_window_move(win, x, y);
y += h;
+ } else if (layout == UI_LAYOUT_STACKED) {
+ Win *awin = tui->vis->win;
+ int h = win == awin || (win == awin->parent && !(awin->options & UI_OPTION_SYMBOL_EOF)) ? max_height - 2 * (n0 - 1) : 2;
+ ui_window_resize(win, tui->width, h);
+ ui_window_move(win, x, y);
+ y += h;
} else {
int w = n ? width : tui->width - x;
ui_window_resize(win, w, max_height);
diff --git a/ui.h b/ui.h
index 5680400..d338295 100644
--- a/ui.h
+++ b/ui.h
@@ -16,6 +16,7 @@
enum UiLayout {
UI_LAYOUT_HORIZONTAL,
UI_LAYOUT_VERTICAL,
+ UI_LAYOUT_STACKED,
};
enum UiOption {
@@ -87,7 +88,7 @@ typedef struct {
struct Win *selwin; /* the currently selected layout */
char info[UI_MAX_WIDTH]; /* info message displayed at the bottom of the screen */
int width, height; /* terminal dimensions available for all windows */
- enum UiLayout layout; /* whether windows are displayed horizontally or vertically */
+ enum UiLayout layout; /* whether windows are displayed horizontally, vertically or stacked */
TermKey *termkey; /* libtermkey instance to handle keyboard input (stdin or /dev/tty) */
size_t ids; /* bit mask of in use window ids */
size_t styles_size; /* #bytes allocated for styles array */
diff --git a/vis-cmds.c b/vis-cmds.c
index 4cfb3bd..c42d9ab 100644
--- a/vis-cmds.c
+++ b/vis-cmds.c
@@ -349,8 +349,10 @@ static bool cmd_set(Vis *vis, Win *win, Command *cmd, const char *argv[], Select
layout = UI_LAYOUT_HORIZONTAL;
} else if (strcmp("v", arg.s) == 0) {
layout = UI_LAYOUT_VERTICAL;
+ } else if (strcmp("s", arg.s) == 0) {
+ layout = UI_LAYOUT_STACKED;
} else {
- vis_info_show(vis, "Invalid layout `%s', expected 'h' or 'v'", arg.s);
+ vis_info_show(vis, "Invalid layout `%s', expected 'h', 'v' or 's'", arg.s);
return false;
}
ui_arrange(&vis->ui, layout);
@@ -563,6 +565,19 @@ static bool cmd_vsplit(Vis *vis, Win *win, Command *cmd, const char *argv[], Sel
return ret;
}
+static bool cmd_ssplit(Vis *vis, Win *win, Command *cmd, const char *argv[], Selection *sel, Filerange *range) { // TODO: register cmd
+ if (!win)
+ return false;
+ enum UiOption options = win->options;
+ ui_arrange(&vis->ui, UI_LAYOUT_STACKED);
+ if (!argv[1])
+ return vis_window_split(win);
+ bool ret = openfiles(vis, &argv[1]);
+ if (ret)
+ win_options_set(vis->win, options);
+ return ret;
+}
+
static bool cmd_new(Vis *vis, Win *win, Command *cmd, const char *argv[], Selection *sel, Filerange *range) {
ui_arrange(&vis->ui, UI_LAYOUT_HORIZONTAL);
return vis_window_new(vis, NULL);
@@ -573,6 +588,11 @@ static bool cmd_vnew(Vis *vis, Win *win, Command *cmd, const char *argv[], Selec
return vis_window_new(vis, NULL);
}
+static bool cmd_snew(Vis *vis, Win *win, Command *cmd, const char *argv[], Selection *sel, Filerange *range) {
+ ui_arrange(&vis->ui, UI_LAYOUT_STACKED);
+ return vis_window_new(vis, NULL);
+}
+
static bool cmd_wq(Vis *vis, Win *win, Command *cmd, const char *argv[], Selection *sel, Filerange *range) {
if (!win)
return false;
diff --git a/vis-lua.c b/vis-lua.c
index e3e85c3..649eabb 100644
--- a/vis-lua.c
+++ b/vis-lua.c
@@ -3267,6 +3267,7 @@ static void vis_lua_init(Vis *vis) {
} layouts[] = {
{ UI_LAYOUT_HORIZONTAL, "HORIZONTAL" },
{ UI_LAYOUT_VERTICAL, "VERTICAL" },
+ { UI_LAYOUT_STACKED, "STACKED" },
};
for (size_t i = 0; i < LENGTH(layouts); i++) {
lua_pushunsigned(L, layouts[i].id);
--
2.45.2