summaryrefslogtreecommitdiff
path: root/src/builtins.zig
diff options
context:
space:
mode:
Diffstat (limited to 'src/builtins.zig')
-rw-r--r--src/builtins.zig66
1 files changed, 57 insertions, 9 deletions
diff --git a/src/builtins.zig b/src/builtins.zig
index cf144d33..7e20a95b 100644
--- a/src/builtins.zig
+++ b/src/builtins.zig
@@ -351,13 +351,12 @@ pub const Right = struct {
}
};
-/// The file<->terminal hop. "Latest" is already recorded: focus_hist is the
-/// MRU sync() rebuilds every update (most recent last), the same list a
-/// closing pane hands focus back through — so this walks it instead of keeping
-/// a second one. Which side is which: only a shell is a terminal; a file, an
-/// image and an output buffer (+Search/+Help) are all DOCS you read, so
-/// isTerminal is the whole test. Landing pushes this pane to the top of that
-/// same history, which is why the hop back is the same key.
+/// The file<->terminal hop. "Latest" is already recorded: the jump stack runs
+/// oldest-first and a closing pane hands focus back through the same list — so
+/// this walks it instead of keeping a second one. Which side is which: only a
+/// shell is a terminal; a file, an image and an output buffer (+Search/+Help)
+/// are all DOCS you read, so isTerminal is the whole test. Landing pushes this
+/// pane onto that same history, which is why the hop back is the same key.
pub const Toggleterm = struct {
pub fn run(c: Ctx) void {
const want_term = !c.pane.isTerminal();
@@ -369,10 +368,10 @@ pub const Toggleterm = struct {
if (k != c.id and op.isTerminal() == want_term) t = k;
}
// ...but the most recently focused one wins
- var i = c.p.nfocus;
+ var i = c.p.njumps;
while (i > 0) {
i -= 1;
- const hid = c.p.focus_hist[i];
+ const hid = c.p.jumps[i].pane;
const hp = c.p.panes[hid] orelse continue;
if (hid != c.id and hp.isTerminal() == want_term) {
t = hid;
@@ -386,6 +385,55 @@ pub const Toggleterm = struct {
}
};
+// ---- the jump group ----
+
+// Where focus HAS BEEN, as three verbs and a list over the one stack pardes
+// keeps (Pardes.jumps — see trackJump for what gets onto it). Builtins rather
+// than bare key handlers for the same reason the four directions are: one
+// implementation, reachable by chord, by `SPC j ...`, and by executing the
+// word wherever it is written.
+
+/// Ctrl-o: one step back into the history.
+pub const Back = struct {
+ pub fn run(c: Ctx) void {
+ c.p.jumpBy(-1);
+ }
+};
+
+/// Ctrl-i: one step forward again, up to wherever Back started.
+pub const Forward = struct {
+ pub fn run(c: Ctx) void {
+ c.p.jumpBy(1);
+ }
+};
+
+/// vim's Ctrl-^: the pane you were in before this one, whichever it was — the
+/// hop you press twice a minute and never want to count steps for.
+///
+/// It does NOT move the stack cursor: it goes somewhere, so trackJump records
+/// it like any other move, and that is exactly what makes it an involution —
+/// after the hop, the pane you came from is the newest OTHER pane, so pressing
+/// it again comes straight back. Back/Forward walk history; this one makes it.
+pub const Last = struct {
+ pub fn run(c: Ctx) void {
+ var i = c.p.njumps;
+ while (i > 0) {
+ i -= 1;
+ const j = c.p.jumps[i];
+ if (j.pane != c.id) return c.p.focusPaneLine(j.pane, j.line, j.col);
+ }
+ }
+};
+
+/// The same stack, as text you can read and click. Not a copy of it and not a
+/// second list kept in step — the buffer is RENDERED from the stack when you
+/// ask, the way +Search is rendered from a walk.
+pub const Jumplist = struct {
+ pub fn run(c: Ctx) void {
+ output_pane.openJumps(c.p, c.id);
+ }
+};
+
// ---- the language group ----
// Reached as `SPC l <helix's letter>` — see leader_path for why the prefix