Implement Tier 0 + Tier 1: scaffold and core modules for jemacs

ober

f9d8f465b7ceee29055a7a4efbbd5a9460750e32

diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..aae5805
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,13 @@
+SCHEME = scheme
+LIBDIRS = --libdirs lib:$(HOME)/mine/jerboa/lib:$(HOME)/mine/chez-pcre2
+export LD_LIBRARY_PATH := $(HOME)/mine/chez-pcre2:$(LD_LIBRARY_PATH)
+
+.PHONY: all test-tier0 clean
+
+all: test-tier0
+
+test-tier0:
+	$(SCHEME) $(LIBDIRS) --script tests/test-tier0.ss
+
+clean:
+	find lib -name '*.so' -delete 2>/dev/null; true
diff --git a/lib/jerboa-emacs/core.sls b/lib/jerboa-emacs/core.sls
new file mode 100644
index 0000000..7462a28
--- /dev/null
+++ b/lib/jerboa-emacs/core.sls
@@ -0,0 +1,2013 @@
+#!chezscheme
+;;; core.sls — Shared core for jemacs
+;;;
+;;; Ported from gerbil-emacs/core.ss
+;;; Backend-agnostic logic: keymap data structures, command registry,
+;;; echo state, buffer metadata, app state, file I/O helpers.
+;;; No Scintilla or TUI imports — this module is pure logic.
+
+(library (jerboa-emacs core)
+  (export
+    ;; Quit flag
+    keyboard-quit-exception? make-keyboard-quit-exception
+    quit-flag-set! quit-flag-clear! quit-flag?
+
+    ;; Keymap data structures
+    make-keymap keymap-bind! keymap-lookup keymap-entries
+    key-state? make-key-state
+    key-state-keymap key-state-keymap-set!
+    key-state-prefix-keys key-state-prefix-keys-set!
+    make-initial-key-state
+
+    ;; Global keymaps
+    *global-keymap* *ctrl-x-map* *meta-g-map* *help-map*
+    *ctrl-x-r-map* *ctrl-c-map* *ctrl-c-l-map* *ctrl-c-m-map*
+    lsp-server-command lsp-server-command-set!
+    *meta-s-map* *ctrl-x-4-map* *ctrl-x-5-map* *ctrl-x-p-map*
+    *all-commands*
+    setup-default-bindings!
+
+    ;; Mode keymaps
+    *mode-keymaps* *buffer-name-mode-map*
+    mode-keymap-set! mode-keymap-get mode-keymap-lookup
+    setup-mode-keymaps!
+
+    ;; Echo state
+    echo-state? make-echo-state
+    echo-state-message echo-state-message-set!
+    echo-state-error? echo-state-error?-set!
+    make-initial-echo-state
+    echo-message! echo-error! echo-clear!
+    notification-push! notification-get-recent
+    notification-log
+
+    ;; Hooks
+    *hooks* add-hook! remove-hook! run-hooks!
+
+    ;; Buffer metadata
+    buffer? make-buffer
+    buffer-name buffer-name-set!
+    buffer-file-path buffer-file-path-set!
+    buffer-doc-pointer buffer-doc-pointer-set!
+    buffer-mark buffer-mark-set!
+    buffer-modified buffer-modified-set!
+    buffer-lexer-lang buffer-lexer-lang-set!
+    buffer-backup-done? buffer-backup-done?-set!
+    buffer-list buffer-list-add! buffer-list-remove!
+    buffer-by-name buffer-scratch-name
+
+    ;; App state
+    app-state? make-app-state
+    app-state-frame app-state-frame-set!
+    app-state-echo app-state-echo-set!
+    app-state-key-state app-state-key-state-set!
+    app-state-running app-state-running-set!
+    app-state-last-search app-state-last-search-set!
+    app-state-kill-ring app-state-kill-ring-set!
+    app-state-kill-ring-idx app-state-kill-ring-idx-set!
+    app-state-last-yank-pos app-state-last-yank-pos-set!
+    app-state-last-yank-len app-state-last-yank-len-set!
+    app-state-last-compile app-state-last-compile-set!
+    app-state-bookmarks app-state-bookmarks-set!
+    app-state-rect-kill app-state-rect-kill-set!
+    app-state-dabbrev-state app-state-dabbrev-state-set!
+    app-state-macro-recording app-state-macro-recording-set!
+    app-state-macro-last app-state-macro-last-set!
+    app-state-macro-named app-state-macro-named-set!
+    app-state-mark-ring app-state-mark-ring-set!
+    app-state-registers app-state-registers-set!
+    app-state-last-command app-state-last-command-set!
+    app-state-prefix-arg app-state-prefix-arg-set!
+    app-state-prefix-digit-mode? app-state-prefix-digit-mode?-set!
+    app-state-key-handler app-state-key-handler-set!
+    app-state-winner-history app-state-winner-history-set!
+    app-state-winner-history-idx app-state-winner-history-idx-set!
+    app-state-tabs app-state-tabs-set!
+    app-state-current-tab-idx app-state-current-tab-idx-set!
+    app-state-key-lossage app-state-key-lossage-set!
+    new-app-state get-prefix-arg
+
+    ;; Frame management
+    frame-list frame-list-set!
+    current-frame-idx current-frame-idx-set!
+    frame-count
+
+    ;; Key lossage
+    key-lossage-record! key-lossage->string
+
+    ;; Command registry
+    register-command! find-command execute-command!
+    *command-docs*
+    register-command-doc! command-doc command-name->description
+    find-keybinding-for-command setup-command-docs!
+
+    ;; Shared helpers
+    electric-indent-mode? electric-indent-mode-set!
+    brace-char? safe-string-trim safe-string-trim-both
+
+    ;; File I/O
+    read-file-as-string write-string-to-file
+
+    ;; Dired
+    *dired-entries*
+    dired-buffer? strip-trailing-slash dired-format-listing
+
+    ;; Logging
+    init-jemacs-log! jemacs-log!
+    init-verbose-log! verbose-log!
+
+    ;; Captured output
+    append-error-log! append-output-log!
+    get-error-log get-output-log
+    clear-error-log! clear-output-log!
+    has-captured-output?
+
+    ;; REPL
+    repl-buffer? *repl-state*
+    eval-expression-string
+    load-user-file! load-user-string!
+
+    ;; Fuzzy matching
+    fuzzy-match? fuzzy-score fuzzy-filter-sort
+
+    ;; Paredit strict mode
+    paredit-strict-mode? paredit-strict-mode-set!
+
+    ;; Helm mode
+    helm-mode? helm-mode-set!
+
+    ;; Key translation
+    *key-translation-map*
+    key-translate! key-translate-char
+
+    ;; Key-chord
+    *chord-map* *chord-first-chars*
+    chord-timeout chord-timeout-set!
+    chord-mode? chord-mode-set!
+    key-chord-define-global chord-lookup chord-start-char?
+
+    ;; Repeat-mode
+    repeat-mode? repeat-mode-set!
+    *repeat-maps*
+    active-repeat-map active-repeat-map-set!
+    register-repeat-map! register-default-repeat-maps!
+    repeat-map-for-command repeat-map-lookup repeat-map-hint
+    clear-repeat-map!
+
+    ;; Image buffer
+    *editor-window-map* *image-buffer-state*
+    image-buffer?
+    find-defun-boundaries
+
+    ;; Re-exports from face
+    face? make-face face-fg face-bg face-bold face-italic face-underline
+    new-face define-face! face-get face-ref set-face-attribute! face-clear!
+    default-font-family default-font-size
+    set-default-font! get-default-font parse-hex-color rgb->hex
+    define-standard-faces! set-frame-font
+    load-theme! current-theme-name
+    face-fg-rgb face-bg-rgb face-has-bold? face-has-italic? face-has-underline?
+
+    ;; Re-exports from themes
+    register-theme! theme-get theme-names
+    theme-dark theme-light theme-solarized-dark theme-solarized-light
+    theme-monokai theme-gruvbox-dark theme-gruvbox-light
+    theme-dracula theme-nord theme-zenburn
+
+    ;; Re-exports from customize
+    defvar! custom-get custom-set! custom-reset!
+    custom-describe custom-list-group custom-list-all
+    custom-groups custom-registered? *custom-registry*
+    defhook! hook-doc hook-list-all)
+
+  (import (except (chezscheme)
+            make-hash-table hash-table? iota 1+ 1- sort sort!)
+          (jerboa core)
+          (jerboa runtime)
+          (std sugar)
+          (std sort)
+          (std string)
+          (only (std srfi srfi-19) current-date date->string)
+          (std misc rwlock)
+          (jerboa-emacs customize)
+          (jerboa-emacs face)
+          (jerboa-emacs themes))
+
+  ;;;============================================================================
+  ;;; Quit flag (C-g subprocess interruption)
+  ;;;============================================================================
+
+  (defstruct keyboard-quit-exception ())
+
+  (def *quit-flag* #f)
+
+  (def (quit-flag-set!) (set! *quit-flag* #t))
+  (def (quit-flag-clear!) (set! *quit-flag* #f))
+  (def (quit-flag?) *quit-flag*)
+
+  ;;;============================================================================
+  ;;; Keymap data structure
+  ;;;============================================================================
+
+  (def (make-keymap) (make-hash-table))
+
+  (def (keymap-bind! km key-str value)
+    (hash-put! km key-str value))
+
+  (def (keymap-lookup km key-str)
+    (hash-get km key-str))
+
+  (def (keymap-entries km)
+    (hash->list km))
+
+  ;;;============================================================================
+  ;;; Key state machine for multi-key sequences
+  ;;;============================================================================
+
+  (defstruct key-state (keymap prefix-keys))
+
+  ;;; Global keymaps
+  (def *global-keymap* (make-keymap))
+  (def *ctrl-x-map*   (make-keymap))
+  (def *ctrl-x-r-map* (make-keymap))
+  (def *ctrl-c-map*   (make-keymap))
+  (def *ctrl-c-l-map* (make-keymap))
+  (def *ctrl-c-m-map* (make-keymap))
+  (def *lsp-server-command* "chez-lsp")
+  (def (lsp-server-command) *lsp-server-command*)
+  (def (lsp-server-command-set! v) (set! *lsp-server-command* v))
+  (def *meta-g-map*   (make-keymap))
+  (def *help-map*     (make-keymap))
+  (def *meta-s-map*   (make-keymap))
+  (def *ctrl-x-4-map* (make-keymap))
+  (def *ctrl-x-5-map* (make-keymap))
+  (def *ctrl-x-p-map* (make-keymap))
+
+  ;;;============================================================================
+  ;;; Mode keymaps — per-mode key bindings
+  ;;;============================================================================
+
+  (def *mode-keymaps* (make-hash-table))
+  (def *buffer-name-mode-map* (make-hash-table))
+
+  (def (mode-keymap-set! mode-sym km)
+    (hash-put! *mode-keymaps* mode-sym km))
+
+  (def (mode-keymap-get mode-sym)
+    (hash-get *mode-keymaps* mode-sym))
+
+  (def (mode-keymap-lookup buf key-str)
+    (let* ((lang (buffer-lexer-lang buf))
+           (km (or (hash-get *mode-keymaps* lang)
+                   (hash-get *buffer-name-mode-map* (buffer-name buf)))))
+      (and km (keymap-lookup km key-str))))
+
+  (def (setup-mode-keymaps!)
+    ;; Buffer name -> mode mapping for special buffers
+    (for-each
+      (lambda (pair)
+        (hash-put! *buffer-name-mode-map* (car pair) (cdr pair)))
+      '(("*compilation*" . compilation) ("*Grep*" . grep) ("*Occur*" . occur)
+        ("*calendar*" . calendar) ("*eww*" . eww) ("*Magit*" . magit)
+        ("*Magit: Commit*" . magit-commit) ("*Magit Log*" . magit-log)
+        ("*Magit Commit*" . magit-commit-view) ("*Magit Stash*" . magit-stash)
+        ("*Magit Stash Diff*" . magit-stash-diff) ("*Org Capture*" . org-capture)
+        ("*IBBuffer*" . ibuffer)))
+
+    ;; Dired mode
+    (let ((km (make-keymap)))
+      (for-each (lambda (p) (keymap-bind! km (car p) (cdr p)))
+        '(("n" . next-line) ("p" . previous-line) ("g" . revert-buffer)
+          ("d" . dired-do-delete) ("R" . dired-do-rename) ("C" . dired-do-copy)
+          ("+" . dired-create-directory) ("q" . kill-buffer-cmd) ("^" . dired)
+          ("m" . dired-mark) ("u" . dired-unmark) ("U" . dired-unmark-all)
+          ("t" . dired-toggle-marks) ("D" . dired-do-delete-marked) ("x" . dired-do-delete-marked)))
+      (mode-keymap-set! 'dired km))
+
+    ;; Compilation mode
+    (let ((km (make-keymap)))
+      (for-each (lambda (p) (keymap-bind! km (car p) (cdr p)))
+        '(("n" . next-error) ("p" . previous-error) ("g" . recompile) ("q" . kill-buffer-cmd)))
+      (mode-keymap-set! 'compilation km))
+
+    ;; Grep results mode
+    (let ((km (make-keymap)))
+      (for-each (lambda (p) (keymap-bind! km (car p) (cdr p)))
+        '(("n" . next-grep-result) ("p" . previous-grep-result) ("q" . kill-buffer-cmd)))
+      (mode-keymap-set! 'grep km))
+
+    ;; Buffer list mode
+    (let ((km (make-keymap)))
+      (for-each (lambda (p) (keymap-bind! km (car p) (cdr p)))
+        '(("n" . next-line) ("p" . previous-line) ("q" . kill-buffer-cmd)))
+      (mode-keymap-set! 'buffer-list km))
+
+    ;; IBBuffer mode
+    (let ((km (make-keymap)))
+      (for-each (lambda (p) (keymap-bind! km (car p) (cdr p)))
+        '(("d" . ibuffer-mark-delete) ("s" . ibuffer-mark-save)
+          ("u" . ibuffer-unmark) ("x" . ibuffer-execute) ("RET" . ibuffer-goto-buffer)
+          ("/" . ibuffer-filter-name) ("S" . ibuffer-sort-name) ("z" . ibuffer-sort-size)
+          ("t" . ibuffer-toggle-marks) ("g" . ibuffer-refresh)
+          ("n" . next-line) ("p" . previous-line) ("q" . kill-buffer-cmd)))
+      (mode-keymap-set! 'ibuffer km))
+
+    ;; Occur mode
+    (let ((km (make-keymap)))
+      (for-each (lambda (p) (keymap-bind! km (car p) (cdr p)))
+        '(("n" . next-line) ("p" . previous-line) ("q" . kill-buffer-cmd)))
+      (mode-keymap-set! 'occur km))
+
+    ;; Calendar mode
+    (let ((km (make-keymap)))
+      (for-each (lambda (p) (keymap-bind! km (car p) (cdr p)))
+        '(("p" . calendar-prev-month) ("n" . calendar-next-month)
+          ("<" . calendar-prev-year) (">" . calendar-next-year)
+          ("." . calendar-today) ("q" . kill-buffer-cmd)))
+      (mode-keymap-set! 'calendar km))
+
+    ;; EWW browser mode
+    (let ((km (make-keymap)))
+      (for-each (lambda (p) (keymap-bind! km (car p) (cdr p)))
+        '(("g" . eww) ("l" . eww-back) ("r" . eww-reload) ("q" . kill-buffer-cmd)))
+      (mode-keymap-set! 'eww km))
+
+    ;; Magit mode
+    (let ((km (make-keymap)))
+      (for-each (lambda (p) (keymap-bind! km (car p) (cdr p)))
+        '(("s" . magit-stage) ("S" . magit-stage-all) ("u" . magit-unstage)
+          ("c" . magit-commit) ("a" . magit-amend) ("d" . magit-diff)
+          ("l" . magit-log) ("b" . magit-branch) ("B" . magit-blame)
+          ("f" . magit-fetch) ("F" . magit-pull) ("P" . magit-push)
+          ("r" . magit-rebase) ("m" . magit-merge) ("z" . magit-stash)
+          ("Z" . magit-stash-pop) ("x" . magit-cherry-pick) ("X" . magit-revert-commit)
+          ("w" . magit-worktree) ("k" . magit-checkout) ("g" . magit-status)
+          ("n" . next-line) ("p" . previous-line) ("q" . kill-buffer-cmd)))
+      (mode-keymap-set! 'magit km))
+
+    ;; Magit commit mode
+    (let ((km (make-keymap)))
+      (keymap-bind! km "C-c C-c" 'magit-commit-finalize)
+      (keymap-bind! km "C-c C-k" 'magit-commit-abort)
+      (mode-keymap-set! 'magit-commit km))
+
+    ;; Magit log mode
+    (let ((km (make-keymap)))
+      (for-each (lambda (p) (keymap-bind! km (car p) (cdr p)))
+        '(("RET" . magit-log-show-commit) ("n" . next-line) ("p" . previous-line) ("q" . kill-buffer-cmd)))
+      (mode-keymap-set! 'magit-log km))
+
+    ;; Magit commit/diff view (shared by stash-diff)
+    (let ((km (make-keymap)))
+      (for-each (lambda (p) (keymap-bind! km (car p) (cdr p)))
+        '(("n" . next-line) ("p" . previous-line) ("q" . kill-buffer-cmd)))
+      (mode-keymap-set! 'magit-commit-view km)
+      (mode-keymap-set! 'magit-stash-diff km))
+
+    ;; Magit stash list
+    (let ((km (make-keymap)))
+      (for-each (lambda (p) (keymap-bind! km (car p) (cdr p)))
+        '(("RET" . magit-stash-show) ("n" . next-line) ("p" . previous-line) ("q" . kill-buffer-cmd)))
+      (mode-keymap-set! 'magit-stash km))
+
+    ;; Image mode
+    (let ((km (make-keymap)))
+      (for-each (lambda (p) (keymap-bind! km (car p) (cdr p)))
+        '(("+" . image-zoom-in) ("=" . image-zoom-in) ("-" . image-zoom-out)
+          ("0" . image-zoom-fit) ("1" . image-zoom-reset) ("q" . kill-buffer-cmd)))
+      (mode-keymap-set! 'image km))
+
+    ;; Org capture mode
+    (let ((km (make-keymap)))
+      (keymap-bind! km "C-c C-c" 'org-capture-finalize)
+      (keymap-bind! km "C-c C-k" 'org-capture-abort)
+      (mode-keymap-set! 'org-capture km)))
+
+  (def (make-initial-key-state)
+    (make-key-state *global-keymap* '()))
+
+  ;;;============================================================================
+  ;;; Default Emacs-like keybindings
+  ;;;============================================================================
+
+  (def (setup-default-bindings!)
+    ;; C-x prefix
+    (keymap-bind! *global-keymap* "C-x" *ctrl-x-map*)
+
+    ;; Navigation
+    (keymap-bind! *global-keymap* "C-f" 'forward-char)
+    (keymap-bind! *global-keymap* "C-b" 'backward-char)
+    (keymap-bind! *global-keymap* "C-n" 'next-line)
+    (keymap-bind! *global-keymap* "C-p" 'previous-line)
+    (keymap-bind! *global-keymap* "C-a" 'beginning-of-line)
+    (keymap-bind! *global-keymap* "C-e" 'end-of-line)
+    (keymap-bind! *global-keymap* "C-v" 'scroll-down)
+    (keymap-bind! *global-keymap* "C-l" 'recenter-top-bottom)
+
+    ;; Arrow keys and navigation
+    (keymap-bind! *global-keymap* "<up>"     'previous-line)
+    (keymap-bind! *global-keymap* "<down>"   'next-line)
+    (keymap-bind! *global-keymap* "<left>"   'backward-char)
+    (keymap-bind! *global-keymap* "<right>"  'forward-char)
+    (keymap-bind! *global-keymap* "<home>"   'beginning-of-line)
+    (keymap-bind! *global-keymap* "<end>"    'end-of-line)
+    (keymap-bind! *global-keymap* "<prior>"  'scroll-up)
+    (keymap-bind! *global-keymap* "<next>"   'scroll-down)
+    (keymap-bind! *global-keymap* "<delete>" 'delete-char)
+
+    ;; Alt/Meta navigation
+    (keymap-bind! *global-keymap* "M-f" 'forward-word)
+    (keymap-bind! *global-keymap* "M-b" 'backward-word)
+    (keymap-bind! *global-keymap* "M-v" 'scroll-up)
+    (keymap-bind! *global-keymap* "M-<" 'beginning-of-buffer)
+    (keymap-bind! *global-keymap* "M->" 'end-of-buffer)
+
+    ;; Editing
+    (keymap-bind! *global-keymap* "C-d" 'delete-char)
+    (keymap-bind! *global-keymap* "DEL" 'backward-delete-char)
+    (keymap-bind! *global-keymap* "C-h" 'backward-delete-char)
+    (keymap-bind! *global-keymap* "C-k" 'kill-line)
+    (keymap-bind! *global-keymap* "C-y" 'yank)
+    (keymap-bind! *global-keymap* "C-w" 'kill-region)
+    (keymap-bind! *global-keymap* "M-w" 'copy-region)
+    (keymap-bind! *global-keymap* "C-_" 'undo)
+    (keymap-bind! *global-keymap* "C-/" 'undo)
+    (keymap-bind! *global-keymap* "C-m" 'newline)
+    (keymap-bind! *global-keymap* "C-j" 'newline)
+    (keymap-bind! *global-keymap* "C-o" 'open-line)
+
+    ;; Mark
+    (keymap-bind! *global-keymap* "C-@" 'set-mark)
+
+    ;; Search
+    (keymap-bind! *global-keymap* "C-s" 'search-forward)
+    (keymap-bind! *global-keymap* "C-r" 'search-backward)
+
+    ;; Function keys
+    (keymap-bind! *global-keymap* "<f11>" 'uncomment-region)
+    (keymap-bind! *global-keymap* "<f12>" 'comment-region)
+
+    ;; Universal argument
+    (keymap-bind! *global-keymap* "C-u" 'universal-argument)
+
+    ;; Digit arguments
+    (keymap-bind! *global-keymap* "M-0" 'digit-argument-0)
+    (keymap-bind! *global-keymap* "M-1" 'digit-argument-1)
+    (keymap-bind! *global-keymap* "M-2" 'digit-argument-2)
+    (keymap-bind! *global-keymap* "M-3" 'digit-argument-3)
+    (keymap-bind! *global-keymap* "M-4" 'digit-argument-4)
+    (keymap-bind! *global-keymap* "M-5" 'digit-argument-5)
+    (keymap-bind! *global-keymap* "M-6" 'digit-argument-6)
+    (keymap-bind! *global-keymap* "M-7" 'digit-argument-7)
+    (keymap-bind! *global-keymap* "M-8" 'digit-argument-8)
+    (keymap-bind! *global-keymap* "M-9" 'digit-argument-9)
+    (keymap-bind! *global-keymap* "M--" 'negative-argument)
+
+    ;; Misc
+    (keymap-bind! *global-keymap* "C-g" 'keyboard-quit)
+
+    ;; C-x commands
+    (keymap-bind! *ctrl-x-map* "C-s" 'save-buffer)
+    (keymap-bind! *ctrl-x-map* "C-f" 'find-file)
+    (keymap-bind! *ctrl-x-map* "C-r" 'recentf-open)
+    (keymap-bind! *ctrl-x-map* "C-c" 'quit)
+    (keymap-bind! *ctrl-x-map* "b"   'switch-buffer)
+    (keymap-bind! *ctrl-x-map* "k"   'kill-buffer-cmd)
+    (keymap-bind! *ctrl-x-map* "2"   'split-window)
+    (keymap-bind! *ctrl-x-map* "o"   'other-window)
+    (keymap-bind! *ctrl-x-map* "0"   'delete-window)
+    (keymap-bind! *ctrl-x-map* "1"   'delete-other-windows)
+    (keymap-bind! *ctrl-x-map* "3"   'split-window-right)
+
+    ;; REPL
+    (keymap-bind! *global-keymap* "M-:" 'eval-expression)
+    ;; C-c prefix
+    (keymap-bind! *global-keymap* "C-c" *ctrl-c-map*)
+    (keymap-bind! *ctrl-c-map* "z"   'repl)
+
+    ;; C-x r prefix (registers/bookmarks/rectangles)
+    (keymap-bind! *ctrl-x-map* "r"   *ctrl-x-r-map*)
+    (keymap-bind! *ctrl-x-r-map* "m" 'bookmark-set)
+    (keymap-bind! *ctrl-x-r-map* "b" 'bookmark-jump)
+    (keymap-bind! *ctrl-x-r-map* "l" 'bookmark-list)
+    (keymap-bind! *ctrl-x-r-map* "k" 'kill-rectangle)
+    (keymap-bind! *ctrl-x-r-map* "d" 'delete-rectangle)
+    (keymap-bind! *ctrl-x-r-map* "y" 'yank-rectangle)
+
+    ;; M-x
+    (keymap-bind! *global-keymap* "M-x" 'execute-extended-command)
+
+    ;; Goto line (M-g prefix map)
+    (keymap-bind! *global-keymap* "M-g" *meta-g-map*)
+    (keymap-bind! *meta-g-map* "g"     'goto-line)
+    (keymap-bind! *meta-g-map* "M-g"   'goto-line)
+
+    ;; Help (C-h prefix map)
+    (keymap-bind! *global-keymap* "C-h" *help-map*)
+    (keymap-bind! *help-map* "k"     'describe-key)
+    (keymap-bind! *help-map* "b"     'list-bindings)
+    (keymap-bind! *help-map* "f"     'describe-command)
+
+    ;; Buffer list
+    (keymap-bind! *ctrl-x-map* "C-b" 'list-buffers)
+
+    ;; Query replace
+    (keymap-bind! *global-keymap* "M-%" 'query-replace)
+
+    ;; Regex search and replace
+    (keymap-bind! *global-keymap* "C-M-s" 'isearch-forward-regexp)
+    (keymap-bind! *global-keymap* "C-M-%" 'query-replace-regexp)
+    (keymap-bind! *global-keymap* "C-M-i" 'complete-at-point)
+
+    ;; Tab
+    (keymap-bind! *global-keymap* "TAB" 'indent-or-complete)
+
+    ;; Eshell, Shell
+    (keymap-bind! *ctrl-c-map* "e"   'eshell)
+    (keymap-bind! *ctrl-c-map* "$"   'shell)
+
+    ;; Redo
+    (keymap-bind! *global-keymap* "M-_" 'redo)
+
+    ;; Toggles
+    (keymap-bind! *ctrl-x-map* "l"   'toggle-line-numbers)
+    (keymap-bind! *ctrl-x-map* "w"   'toggle-word-wrap)
+    (keymap-bind! *ctrl-x-map* "t"   'toggle-whitespace)
+
+    ;; Zoom
+    (keymap-bind! *global-keymap* "C-=" 'zoom-in)
+    (keymap-bind! *global-keymap* "C--" 'zoom-out)
+    (keymap-bind! *ctrl-x-map* "C-0" 'zoom-reset)
+
+    ;; Select all
+    (keymap-bind! *ctrl-x-map* "h"   'select-all)
+
+    ;; Duplicate line
+    (keymap-bind! *ctrl-x-map* "d"   'dired)
+
+    ;; Comment toggle
+    (keymap-bind! *global-keymap* "M-;" 'toggle-comment)
+
+    ;; Transpose chars
+    (keymap-bind! *global-keymap* "C-t" 'transpose-chars)
+
+    ;; Case
+    (keymap-bind! *global-keymap* "M-u" 'upcase-word)
+    (keymap-bind! *global-keymap* "M-l" 'downcase-word)
+    (keymap-bind! *global-keymap* "M-c" 'capitalize-word)
+
+    ;; Kill word
+    (keymap-bind! *global-keymap* "M-d" 'kill-word)
+
+    ;; What line
+    (keymap-bind! *meta-g-map* "l"   'what-line)
+
+    ;; Write file (save as)
+    (keymap-bind! *ctrl-x-map* "C-w" 'write-file)
+
+    ;; Beginning/end of defun
+    (keymap-bind! *global-keymap* "M-a" 'backward-sentence)
+    (keymap-bind! *global-keymap* "M-e" 'forward-sentence)
+
+    ;; Count words
+    (keymap-bind! *global-keymap* "M-=" 'count-words)
+
+    ;; Yank-pop
+    (keymap-bind! *global-keymap* "M-y" 'yank-pop)
+
+    ;; Occur (search prefix M-s)
+    (keymap-bind! *global-keymap* "M-s" *meta-s-map*)
+    (keymap-bind! *meta-s-map* "o" 'occur)
+
+    ;; Compile
+    (keymap-bind! *ctrl-x-map* "c" 'compile)
+
+    ;; Pipe region to shell
+    (keymap-bind! *global-keymap* "M-|" 'shell-command-on-region)
+
+    ;; Sort lines
+    (keymap-bind! *ctrl-c-map* "^" 'sort-lines)
+
+    ;; Go to matching paren
+    (keymap-bind! *ctrl-c-map* "p" 'goto-matching-paren)
+
+    ;; Join lines
+    (keymap-bind! *global-keymap* "M-j" 'join-line)
+
+    ;; Delete blank lines
+    (keymap-bind! *ctrl-x-map* "C-o" 'delete-blank-lines)
+
+    ;; Indent region
+    (keymap-bind! *ctrl-c-map* "TAB" 'indent-region)
+
+    ;; Case region
+    (keymap-bind! *ctrl-x-map* "C-l" 'downcase-region)
+    (keymap-bind! *ctrl-x-map* "C-u" 'upcase-region)
+
+    ;; Shell command
+    (keymap-bind! *global-keymap* "M-!" 'shell-command)
+
+    ;; Fill paragraph
+    (keymap-bind! *global-keymap* "M-q" 'fill-paragraph)
+
+    ;; Insert file
+    (keymap-bind! *ctrl-x-map* "i" 'insert-file)
+
+    ;; Dynamic abbreviation / hippie expand
+    (keymap-bind! *global-keymap* "M-/" 'hippie-expand)
+
+    ;; Xref
+    (keymap-bind! *global-keymap* "M-." 'goto-definition)
+    (keymap-bind! *global-keymap* "M-," 'xref-back)
+
+    ;; What cursor position
+    (keymap-bind! *ctrl-x-map* "=" 'what-cursor-position)
+
+    ;; Keyboard macros
+    (keymap-bind! *ctrl-x-map* "(" 'start-kbd-macro)
+    (keymap-bind! *ctrl-x-map* ")" 'end-kbd-macro)
+    (keymap-bind! *ctrl-x-map* "e" 'call-last-kbd-macro)
+
+    ;; Mark ring
+    (keymap-bind! *ctrl-c-map* "SPC" 'pop-mark)
+
+    ;; Registers
+    (keymap-bind! *ctrl-x-r-map* "s" 'copy-to-register)
+    (keymap-bind! *ctrl-x-r-map* "i" 'insert-register)
+    (keymap-bind! *ctrl-x-r-map* "SPC" 'point-to-register)
+    (keymap-bind! *ctrl-x-r-map* "j" 'jump-to-register)
+    (keymap-bind! *ctrl-x-r-map* "w" 'window-configuration-to-register)
+    (keymap-bind! *ctrl-x-r-map* "f" 'file-to-register)
+
+    ;; Backward kill word
+    (keymap-bind! *global-keymap* "M-DEL" 'backward-kill-word)
+
+    ;; Zap to char
+    (keymap-bind! *global-keymap* "M-z" 'zap-to-char)
+
+    ;; Go to char position
+    (keymap-bind! *meta-g-map* "c" 'goto-char)
+
+    ;; Transpose
+    (keymap-bind! *global-keymap* "M-t" 'transpose-words)
+    (keymap-bind! *ctrl-x-map* "C-t" 'transpose-lines)
+
+    ;; Repeat
+    (keymap-bind! *ctrl-x-map* "z" 'repeat)
+
+    ;; Just one space
+    (keymap-bind! *global-keymap* "M-SPC" 'just-one-space)
+
+    ;; Next/previous error
+    (keymap-bind! *meta-g-map* "n" 'next-error)
+    (keymap-bind! *meta-g-map* "p" 'previous-error)
+    (keymap-bind! *meta-g-map* "M-n" 'next-error)
+    (keymap-bind! *meta-g-map* "M-p" 'previous-error)
+
+    ;; Kill whole line
+    (keymap-bind! *ctrl-c-map* "k" 'kill-whole-line)
+
+    ;; Move line up/down
+    (keymap-bind! *global-keymap* "M-<up>" 'move-line-up)
+    (keymap-bind! *global-keymap* "M-<down>" 'move-line-down)
+
+    ;; Pipe buffer
+    (keymap-bind! *ctrl-c-map* "!" 'pipe-buffer)
+
+    ;; Narrow/widen
+    (keymap-bind! *ctrl-c-map* "n" 'narrow-to-region)
+    (keymap-bind! *ctrl-c-map* "w" 'widen)
+
+    ;; String insert
+    (keymap-bind! *ctrl-c-map* "i" 'string-insert-file)
+
+    ;; Rectangle
+    (keymap-bind! *ctrl-x-r-map* "t" 'string-rectangle)
+    (keymap-bind! *ctrl-x-r-map* "o" 'open-rectangle)
+
+    ;; Number lines, reverse region
+    (keymap-bind! *ctrl-c-map* "#" 'number-lines)
+    (keymap-bind! *ctrl-c-map* "r" 'reverse-region)
+
+    ;; Flush/keep lines
+    (keymap-bind! *meta-s-map* "f" 'flush-lines)
+    (keymap-bind! *meta-s-map* "k" 'keep-lines)
+
+    ;; Align regexp
+    (keymap-bind! *ctrl-c-map* "a" 'align-regexp)
+
+    ;; Sort fields
+    (keymap-bind! *ctrl-c-map* "s" 'sort-fields)
+
+    ;; Mark word, mark paragraph, paragraph navigation
+    (keymap-bind! *global-keymap* "M-@" 'mark-word)
+    (keymap-bind! *global-keymap* "M-h" 'mark-paragraph)
+    (keymap-bind! *global-keymap* "M-}" 'forward-paragraph)
+    (keymap-bind! *global-keymap* "M-{" 'backward-paragraph)
+
+    ;; Back to indentation, delete indentation
+    (keymap-bind! *global-keymap* "M-m" 'back-to-indentation)
+    (keymap-bind! *global-keymap* "M-^" 'delete-indentation)
+
+    ;; Exchange point and mark
+    (keymap-bind! *ctrl-x-map* "C-x" 'exchange-point-and-mark)
+
+    ;; C-c l → LSP prefix map
+    (keymap-bind! *ctrl-c-map* "l" *ctrl-c-l-map*)
+
+    ;; Copy line
+    (keymap-bind! *ctrl-c-map* "c" 'copy-line)
+
+    ;; Help extras
+    (keymap-bind! *help-map* "w" 'where-is)
+    (keymap-bind! *help-map* "a" 'apropos-command)
+    (keymap-bind! *ctrl-x-map* "C-q" 'toggle-read-only)
+    (keymap-bind! *ctrl-x-r-map* "n" 'rename-buffer)
+
+    ;; Other-window commands (C-x 4 prefix)
+    (keymap-bind! *ctrl-x-map* "4" *ctrl-x-4-map*)
+    (keymap-bind! *ctrl-x-4-map* "b" 'switch-buffer-other-window)
+    (keymap-bind! *ctrl-x-4-map* "f" 'find-file-other-window)
+
+    ;; Frame commands (C-x 5 prefix)
+    (keymap-bind! *ctrl-x-map* "5" *ctrl-x-5-map*)
+    (keymap-bind! *ctrl-x-5-map* "2" 'make-frame-command)
+    (keymap-bind! *ctrl-x-5-map* "0" 'delete-frame)
+    (keymap-bind! *ctrl-x-5-map* "o" 'other-frame)
+    (keymap-bind! *ctrl-x-5-map* "f" 'find-file-other-frame)
+    (keymap-bind! *ctrl-x-5-map* "b" 'switch-to-buffer-other-frame)
+
+    ;; Text transforms
+    (keymap-bind! *ctrl-c-map* "t" 'tabify)
+    (keymap-bind! *ctrl-c-map* "3" 'rot13-region)
+    (keymap-bind! *ctrl-c-map* "x" 'hexl-mode)
+
+    ;; Count matches, dedup
+    (keymap-bind! *meta-s-map* "c" 'count-matches)
+    (keymap-bind! *ctrl-c-map* "u" 'delete-duplicate-lines)
+
+    ;; Diff, checksum
+    (keymap-bind! *ctrl-c-map* "d" 'diff-buffer-with-file)
+    (keymap-bind! *ctrl-c-map* "5" 'checksum)
+
+    ;; Async shell command
+    (keymap-bind! *global-keymap* "M-&" 'async-shell-command)
+
+    ;; Selective display
+    (keymap-bind! *ctrl-x-map* "$" 'set-selective-display)
+
+    ;; Grep buffer
+    (keymap-bind! *meta-s-map* "g" 'grep-buffer)
+    (keymap-bind! *meta-s-map* "r" 'consult-ripgrep)
+
+    ;; Insert date, insert char
+    (keymap-bind! *ctrl-c-map* "D" 'insert-date)
+    (keymap-bind! *ctrl-c-map* "8" 'insert-char)
+
+    ;; Eval
+    (keymap-bind! *ctrl-c-map* "E" 'eval-buffer)
+    (keymap-bind! *ctrl-c-map* "v" 'eval-region)
+    (keymap-bind! *ctrl-x-map* "C-e" 'eval-last-sexp)
+    (keymap-bind! *ctrl-c-map* "C-e" 'eval-last-sexp)
+    (keymap-bind! *ctrl-c-map* "C-d" 'eval-defun)
+
+    ;; Org-mode
+    (keymap-bind! *ctrl-c-map* "C-n" 'org-next-heading)
+    (keymap-bind! *ctrl-c-map* "C-p" 'org-prev-heading)
+    (keymap-bind! *ctrl-c-map* "C-t" 'org-todo)
+    (keymap-bind! *ctrl-c-map* "C-l" 'org-link)
+    (keymap-bind! *ctrl-c-map* "C-o" 'org-open-at-point)
+    (keymap-bind! *ctrl-c-map* "C-s" 'org-schedule)
+    (keymap-bind! *ctrl-c-map* "C-q" 'org-set-tags)
+    (keymap-bind! *ctrl-c-map* ","   'org-priority)
+
+    ;; Clone buffer, scratch
+    (keymap-bind! *ctrl-c-map* "b" 'clone-buffer)
+    (keymap-bind! *ctrl-c-map* "S" 'scratch-buffer)
+
+    ;; Save some buffers
+    (keymap-bind! *ctrl-x-map* "s" 'save-some-buffers)
+
+    ;; Revert quick
+    (keymap-bind! *ctrl-c-map* "R" 'revert-buffer-quick)
+
+    ;; Toggle highlighting
+    (keymap-bind! *ctrl-c-map* "f" 'toggle-highlighting)
+
+    ;; Display time
+    (keymap-bind! *ctrl-c-map* "T" 'display-time)
+
+    ;; Calculator
+    (keymap-bind! *ctrl-c-map* "=" 'calc)
+
+    ;; Case fold search toggle
+    (keymap-bind! *ctrl-c-map* "C" 'toggle-case-fold-search)
+
+    ;; Describe bindings
+    (keymap-bind! *help-map* "B" 'describe-bindings)
+
+    ;; Center line
+    (keymap-bind! *global-keymap* "M-o" 'center-line)
+
+    ;; What face
+    (keymap-bind! *ctrl-c-map* "F" 'what-face)
+
+    ;; List processes
+    (keymap-bind! *ctrl-c-map* "P" 'list-processes)
+
+    ;; View messages
+    (keymap-bind! *ctrl-c-map* "m" 'view-messages)
+
+    ;; Auto fill toggle
+    (keymap-bind! *ctrl-c-map* "q" 'toggle-auto-fill)
+
+    ;; Delete trailing whitespace
+    (keymap-bind! *ctrl-c-map* "W" 'delete-trailing-whitespace)
+
+    ;; Ediff buffers
+    (keymap-bind! *ctrl-c-map* "B" 'ediff-buffers)
+
+    ;; Rename/delete file
+    (keymap-bind! *ctrl-c-map* "M" 'rename-file-and-buffer)
+
+    ;; Sudo write
+    (keymap-bind! *ctrl-c-map* "X" 'sudo-write)
+
+    ;; Sort numeric
+    (keymap-bind! *ctrl-c-map* "N" 'sort-numeric)
+
+    ;; Count words region
+    (keymap-bind! *ctrl-c-map* "L" 'count-words-region)
+
+    ;; Overwrite mode
+    (keymap-bind! *global-keymap* "<insert>" 'toggle-overwrite-mode)
+
+    ;; Visual line mode
+    (keymap-bind! *ctrl-c-map* "V" 'toggle-visual-line-mode)
+
+    ;; Fill column
+    (keymap-bind! *ctrl-c-map* "." 'set-fill-column)
+    (keymap-bind! *ctrl-c-map* "|" 'toggle-fill-column-indicator)
+
+    ;; Repeat complex command
+    (keymap-bind! *ctrl-c-map* "Z" 'repeat-complex-command)
+
+    ;; Eldoc
+    (keymap-bind! *ctrl-c-map* "I" 'eldoc)
+
+    ;; Highlight symbol
+    (keymap-bind! *ctrl-c-map* "h" 'highlight-symbol)
+    (keymap-bind! *ctrl-c-map* "H" 'clear-highlight)
+
+    ;; Indent rigidly
+    (keymap-bind! *ctrl-c-map* ">" 'indent-rigidly-right)
+    (keymap-bind! *ctrl-c-map* "<" 'indent-rigidly-left)
+
+    ;; Buffer stats
+    (keymap-bind! *ctrl-c-map* "?" 'buffer-stats)
+
+    ;; Show tabs/eol
+    (keymap-bind! *ctrl-c-map* "4" 'toggle-show-tabs)
+    (keymap-bind! *ctrl-c-map* "6" 'toggle-show-eol)
+
+    ;; Copy from above
+    (keymap-bind! *ctrl-c-map* "A" 'copy-from-above)
+
+    ;; Open line above
+    (keymap-bind! *ctrl-c-map* "O" 'open-line-above)
+
+    ;; Select line
+    (keymap-bind! *ctrl-c-map* "G" 'select-line)
+
+    ;; Split line
+    (keymap-bind! *ctrl-c-map* "J" 'split-line)
+
+    ;; Hippie expand
+    (keymap-bind! *global-keymap* "M-TAB" 'hippie-expand)
+
+    ;; Swap buffers
+    (keymap-bind! *ctrl-c-map* "9" 'swap-buffers)
+
+    ;; Tab width cycle
+    (keymap-bind! *ctrl-c-map* "7" 'cycle-tab-width)
+
+    ;; Indent tabs mode
+    (keymap-bind! *ctrl-c-map* "0" 'toggle-indent-tabs-mode)
+
+    ;; Buffer info
+    (keymap-bind! *ctrl-c-map* "j" 'buffer-info)
+
+    ;; Window resize
+    (keymap-bind! *ctrl-x-map* "^" 'enlarge-window)
+    (keymap-bind! *ctrl-x-map* "-" 'shrink-window)
+    (keymap-bind! *ctrl-x-map* "{" 'shrink-window-horizontally)
+    (keymap-bind! *ctrl-x-map* "}" 'enlarge-window-horizontally)
+
+    ;; Whitespace cleanup
+    (keymap-bind! *ctrl-c-map* "c" 'whitespace-cleanup)
+
+    ;; Toggle electric pair
+    (keymap-bind! *ctrl-c-map* "Q" 'toggle-electric-pair)
+
+    ;; Previous/next buffer
+    (keymap-bind! *ctrl-x-map* "<left>" 'previous-buffer)
+    (keymap-bind! *ctrl-x-map* "<right>" 'next-buffer)
+
+    ;; Balance windows
+    (keymap-bind! *ctrl-x-map* "+" 'balance-windows)
+
+    ;; Move to window line
+    (keymap-bind! *global-keymap* "M-r" 'move-to-window-line)
+
+    ;; Kill buffer and window
+    (keymap-bind! *ctrl-x-4-map* "0" 'kill-buffer-and-window)
+
+    ;; Flush undo
+    (keymap-bind! *ctrl-c-map* "/" 'flush-undo)
+
+    ;; Upcase initials region
+    (keymap-bind! *ctrl-c-map* "U" 'upcase-initials-region)
+
+    ;; Untabify buffer
+    (keymap-bind! *ctrl-c-map* "_" 'untabify-buffer)
+
+    ;; Insert buffer name
+    (keymap-bind! *ctrl-c-map* "%" 'insert-buffer-name)
+
+    ;; Mark defun
+    (keymap-bind! *ctrl-c-map* "y" 'mark-defun)
+
+    ;; Insert pairs
+    (keymap-bind! *ctrl-c-map* "(" 'insert-parentheses)
+    (keymap-bind! *ctrl-c-map* "[" 'insert-pair-brackets)
+
+    ;; Describe char
+    (keymap-bind! *ctrl-c-map* "," 'describe-char)
+
+    ;; Find file at point
+    (keymap-bind! *ctrl-c-map* "o" 'find-file-at-point)
+
+    ;; Count chars region
+    (keymap-bind! *ctrl-c-map* "K" 'count-chars-region)
+
+    ;; Count words buffer
+    (keymap-bind! *ctrl-c-map* "+" 'count-words-buffer)
+
+    ;; Unfill paragraph
+    (keymap-bind! *ctrl-c-map* ";" 'unfill-paragraph)
+
+    ;; List registers
+    (keymap-bind! *ctrl-c-map* "@" 'list-registers)
+
+    ;; Show kill ring
+    (keymap-bind! *ctrl-c-map* "Y" 'show-kill-ring)
+
+    ;; Smart beginning of line
+    (keymap-bind! *ctrl-c-map* "`" 'smart-beginning-of-line)
+
+    ;; What buffer
+    (keymap-bind! *ctrl-c-map* "~" 'what-buffer)
+
+    ;; Narrowing indicator
+    (keymap-bind! *ctrl-c-map* ":" 'toggle-narrowing-indicator)
+
+    ;; Insert file name
+    (keymap-bind! *ctrl-c-map* "&" 'insert-file-name)
+
+    ;; S-expression navigation
+    (keymap-bind! *meta-g-map* "u" 'backward-up-list)
+    (keymap-bind! *meta-g-map* "d" 'forward-up-list)
+    (keymap-bind! *meta-g-map* "k" 'kill-sexp)
+    (keymap-bind! *meta-g-map* "f" 'forward-sexp)
+    (keymap-bind! *meta-g-map* "b" 'backward-sexp)