▍ humdrum codex / glint v1.0.2
license AGPL-3.0

feat: Ctrl+Home / Ctrl+End jump to document start / end

dabc84eb33cfc6b0142323bb1b316179606109d2
humdrum <me@humdrum.me> · 2026-06-29 08:22

parent ff079ce7

feat: Ctrl+Home / Ctrl+End jump to document start / end

MoveDocStart/MoveDocEnd bound to Ctrl+Home/Ctrl+End — the terminal maps
Cmd+Up/Down to these sequences for macOS-style document navigation.

2 files changed

internal/editor/editor.go +20 −0
@@ -127,6 +127,22 @@ 		e.Scroll = max
 	}
 }
 
+// MoveDocStart jumps to the very start of the document (Cmd+Up via the terminal).
+func (e *Editor) MoveDocStart() {
+	e.Cursor = Position{Row: 0, Col: 0}
+	e.setGoal()
+	e.followCursor()
+}
+
+// MoveDocEnd jumps to the end of the last line (Cmd+Down via the terminal).
+func (e *Editor) MoveDocEnd() {
+	last := len(e.Lines) - 1
+	e.Cursor.Row = last
+	e.Cursor.Col = len([]rune(e.Lines[last]))
+	e.setGoal()
+	e.followCursor()
+}
+
 func isWordSpace(r rune) bool { return r == ' ' || r == '\t' }
 
 // MoveWordLeft moves to the start of the previous word (Alt+Left).
@@ -468,6 +484,10 @@ 	case tea.KeyHome:
 		e.MoveHome()
 	case tea.KeyEnd:
 		e.MoveEnd()
+	case tea.KeyCtrlHome:
+		e.MoveDocStart()
+	case tea.KeyCtrlEnd:
+		e.MoveDocEnd()
 	case tea.KeyTab:
 		e.InsertRune('\t')
 	case tea.KeyCtrlU:
internal/editor/editor_test.go +13 −0
@@ -412,3 +412,16 @@ 	if e.Cursor.Col != 16 {
 		t.Errorf("Alt+f → col %d, want 16 (end of gamma)", e.Cursor.Col)
 	}
 }
+
+func TestDocStartEnd(t *testing.T) {
+	e := newEditorWith("first", "middle", "last line")
+	e.Cursor = Position{Row: 1, Col: 2}
+	e.HandleKey(tea.KeyMsg{Type: tea.KeyCtrlEnd})
+	if e.Cursor != (Position{Row: 2, Col: 9}) {
+		t.Errorf("Ctrl+End → %+v, want {2 9}", e.Cursor)
+	}
+	e.HandleKey(tea.KeyMsg{Type: tea.KeyCtrlHome})
+	if e.Cursor != (Position{Row: 0, Col: 0}) {
+		t.Errorf("Ctrl+Home → %+v, want {0 0}", e.Cursor)
+	}
+}