Last active
December 20, 2025 14:50
-
-
Save jargnar/e9267e0abcd9de8ca8a6b48d1f3e22eb to your computer and use it in GitHub Desktop.
.emacs.d/init.el
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| ;; -*- lexical-binding: t -*- | |
| ;;; ========================================================================== | |
| ;;; Theme and basic settings | |
| ;;; ========================================================================== | |
| (load-theme 'tsdh-dark t) | |
| (ido-mode 1) | |
| (ido-everywhere 1) | |
| (global-display-line-numbers-mode 1) | |
| ;;; ========================================================================== | |
| ;;; MELPA Package Management | |
| ;;; ========================================================================== | |
| (require 'package) | |
| (add-to-list 'package-archives '("melpa" . "https://melpa.org/packages/") t) | |
| (package-initialize) | |
| (custom-set-variables | |
| ;; custom-set-variables was added by Custom. | |
| ;; If you edit it by hand, you could mess it up, so be careful. | |
| ;; Your init file should contain only one such instance. | |
| ;; If there is more than one, they won't work right. | |
| '(package-selected-packages | |
| '(consult exec-path-from-shell helix magit multiple-cursors))) | |
| (custom-set-faces | |
| ;; custom-set-faces was added by Custom. | |
| ;; If you edit it by hand, you could mess it up, so be careful. | |
| ;; Your init file should contain only one such instance. | |
| ;; If there is more than one, they won't work right. | |
| ) | |
| ;;; ========================================================================== | |
| ;;; macOS Modifier Keys | |
| ;;; ========================================================================== | |
| (when (eq system-type 'darwin) | |
| (setq mac-command-modifier 'super) | |
| (setq mac-option-modifier 'meta)) | |
| ;;; ========================================================================== | |
| ;;; env and stuff | |
| ;;; ========================================================================== | |
| (when (memq window-system '(mac ns x)) | |
| (exec-path-from-shell-initialize)) | |
| ;;; ========================================================================== | |
| ;;; Helix Mode Configuration | |
| ;;; ========================================================================== | |
| (require 'multiple-cursors) | |
| (defun spc-leader--mirror-helix-to-super () | |
| "Copy Helix C-<key> bindings to s-<key> (Cmd on macOS). | |
| Must be called BEFORE purging C- bindings." | |
| (dolist (mapvar '(helix-normal-state-keymap | |
| helix-visual-state-keymap | |
| helix-select-state-keymap)) | |
| (when (boundp mapvar) | |
| (let ((keymap (symbol-value mapvar))) | |
| (when (keymapp keymap) | |
| (map-keymap | |
| (lambda (key binding) | |
| (when (and (integerp key) | |
| (<= 1 key 26) | |
| binding | |
| (not (eq binding 'undefined))) | |
| (let* ((base-char (+ key ?a -1)) | |
| (super-key (vector (+ base-char (ash 1 23))))) | |
| (define-key keymap super-key binding)))) | |
| keymap)))))) | |
| (defun spc-leader--purge-ctrl-bindings (keymap) | |
| "Remove all C-<letter> bindings from KEYMAP. | |
| This allows major mode C- keys to work instead of being | |
| intercepted by Helix." | |
| (when (keymapp keymap) | |
| (map-keymap | |
| (lambda (key _binding) | |
| (when (and (integerp key) (<= 1 key 26)) | |
| (define-key keymap (vector key) nil))) | |
| keymap) | |
| (define-key keymap (kbd "C-g") nil))) | |
| (defun spc-leader--purge-helix-bindings () | |
| "Purge all Ctrl and SPC bindings from Helix keymaps." | |
| (dolist (mapvar '(helix-mode-map | |
| helix-normal-state-keymap | |
| helix-visual-state-keymap | |
| helix-select-state-keymap)) | |
| (when (boundp mapvar) | |
| (spc-leader--purge-ctrl-bindings (symbol-value mapvar)))) | |
| ;; Unbind SPC so our leader mode takes over | |
| (when (boundp 'helix-normal-state-keymap) | |
| (define-key helix-normal-state-keymap (kbd "SPC") nil)) | |
| (when (boundp 'helix-visual-state-keymap) | |
| (define-key helix-visual-state-keymap (kbd "SPC") nil)) | |
| (when (boundp 'helix-select-state-keymap) | |
| (define-key helix-select-state-keymap (kbd "SPC") nil))) | |
| (defun spc-leader--setup-helix-bindings () | |
| "Mirror C- to Cmd, THEN purge C- and SPC so leader mode works. | |
| Order matters!" | |
| (spc-leader--mirror-helix-to-super) ; 1. Copy C-x → Cmd-x | |
| (spc-leader--purge-helix-bindings)) ; 2. Remove C-x and SPC | |
| (use-package helix | |
| :after multiple-cursors | |
| :config | |
| (helix-multiple-cursors-setup)) | |
| ;; Setup bindings AFTER helix is fully loaded | |
| (with-eval-after-load 'helix | |
| (spc-leader--setup-helix-bindings)) | |
| ;; Also setup when helix-mode activates (keymaps may be recreated) | |
| (add-hook 'helix-mode-hook #'spc-leader--setup-helix-bindings) | |
| ;;; Helix typable commands (must come after helix loads) | |
| (with-eval-after-load 'helix | |
| (helix-define-typable-command "q" #'kill-current-buffer) | |
| (helix-define-typable-command "quit" #'kill-current-buffer)) | |
| ;;; Activate helix-mode globally | |
| (helix-mode) | |
| ;;; ========================================================================== | |
| ;;; Disable Helix in Magit (SPC leader remains active) | |
| ;;; ========================================================================== | |
| (defvar my/helix-disabled-modes | |
| '(magit-mode) | |
| "Major modes where helix modal editing should be disabled.") | |
| (defun my/disable-helix-in-buffer () | |
| "Disable helix modal editing in current buffer." | |
| (when (fboundp 'helix-normal-mode) | |
| (helix-normal-mode -1))) | |
| (defun my/maybe-disable-helix () | |
| "Disable helix if current major mode is in exclusion list." | |
| (when (apply #'derived-mode-p my/helix-disabled-modes) | |
| (my/disable-helix-in-buffer))) | |
| (add-hook 'after-change-major-mode-hook #'my/maybe-disable-helix 90) | |
| ;;; ========================================================================== | |
| ;;; Dired Configuration | |
| ;;; ========================================================================== | |
| (with-eval-after-load "dired" | |
| (define-key dired-mode-map [mouse-2] 'dired-mouse-find-file)) | |
| ;;; ========================================================================== | |
| ;;; Windmove Navigation & Swapping | |
| ;;; ========================================================================== | |
| ;; Navigate between windows | |
| (global-set-key (kbd "s-<left>") #'windmove-left) | |
| (global-set-key (kbd "s-<right>") #'windmove-right) | |
| (global-set-key (kbd "s-<up>") #'windmove-up) | |
| (global-set-key (kbd "s-<down>") #'windmove-down) | |
| ;; Swap buffers between windows | |
| (global-set-key (kbd "s-S-<left>") #'windmove-swap-states-left) | |
| (global-set-key (kbd "s-S-<right>") #'windmove-swap-states-right) | |
| (global-set-key (kbd "s-S-<up>") #'windmove-swap-states-up) | |
| (global-set-key (kbd "s-S-<down>") #'windmove-swap-states-down) | |
| ;;; ========================================================================== | |
| ;;; SPC Leader — Spacemacs-style Bindings | |
| ;;; ========================================================================== | |
| ;;; | |
| ;;; SPC acts as a leader key (like Spacemacs/Doom) triggering a menu of | |
| ;;; commands. Uses a minor mode with `menu-item` filter to conditionally | |
| ;;; fall back to literal space in insert contexts. | |
| ;;; | |
| ;;; ========================================================================== | |
| ;;; Behavior Matrix | |
| ;;; ========================================================================== | |
| ;;; | |
| ;;; ┌─────────────────────────────────┬─────────────────────────────────────┐ | |
| ;;; │ Context │ SPC Behavior │ | |
| ;;; ├─────────────────────────────────┼─────────────────────────────────────┤ | |
| ;;; │ Helix normal mode │ Leader menu │ | |
| ;;; │ Helix visual/select mode │ Leader menu │ | |
| ;;; │ Helix insert mode │ Literal space (typing text) │ | |
| ;;; ├─────────────────────────────────┼─────────────────────────────────────┤ | |
| ;;; │ Org-mode (helix normal) │ Leader menu │ | |
| ;;; │ Org-mode (helix insert) │ Literal space │ | |
| ;;; ├─────────────────────────────────┼─────────────────────────────────────┤ | |
| ;;; │ Dired, Magit, *Help*, *Info* │ Leader menu │ | |
| ;;; │ Any special-mode derivative │ Leader menu │ | |
| ;;; ├─────────────────────────────────┼─────────────────────────────────────┤ | |
| ;;; │ Minibuffer (M-x, find-file) │ Literal space (typing input) │ | |
| ;;; │ Incremental search (C-s/C-r) │ Literal space (searching for space) │ | |
| ;;; │ Completion (ivy, vertico, etc) │ Literal space (via minibuffer) │ | |
| ;;; ├─────────────────────────────────┼─────────────────────────────────────┤ | |
| ;;; │ Terminal (term, vterm, eat) │ Literal space (shell input) │ | |
| ;;; │ Eshell │ Literal space (shell input) │ | |
| ;;; ├─────────────────────────────────┼─────────────────────────────────────┤ | |
| ;;; │ Anywhere with S-SPC │ Literal space (escape hatch) │ | |
| ;;; │ Anywhere with C-q SPC │ Literal space (quoted-insert) │ | |
| ;;; └─────────────────────────────────┴─────────────────────────────────────┘ | |
| ;;; | |
| ;;; ========================================================================== | |
| ;;; Key Bindings Quick Reference | |
| ;;; ========================================================================== | |
| ;;; | |
| ;;; ┌─────────────────────────────────┬─────────────────────────────────────┐ | |
| ;;; │ Keys │ Action │ | |
| ;;; ├─────────────────────────────────┼─────────────────────────────────────┤ | |
| ;;; │ SPC SPC │ M-x (execute-extended-command) │ | |
| ;;; │ SPC f f │ find-file │ | |
| ;;; │ SPC f s │ save-buffer │ | |
| ;;; │ SPC b b │ switch-to-buffer (consult) │ | |
| ;;; │ SPC b d │ kill-current-buffer │ | |
| ;;; │ SPC w v │ split-window-right │ | |
| ;;; │ SPC w s │ split-window-below │ | |
| ;;; │ SPC g g │ magit-status │ | |
| ;;; │ SPC s s │ consult-line │ | |
| ;;; │ SPC h k │ describe-key │ | |
| ;;; ├─────────────────────────────────┼─────────────────────────────────────┤ | |
| ;;; │ SPC x ... │ C-x prefix (escape hatch) │ | |
| ;;; │ SPC c ... │ C-c prefix (mode-specific) │ | |
| ;;; ├─────────────────────────────────┼─────────────────────────────────────┤ | |
| ;;; │ Cmd-<key> │ Helix's original C-<key> commands │ | |
| ;;; └─────────────────────────────────┴─────────────────────────────────────┘ | |
| ;;; | |
| ;;; ========================================================================== | |
| ;;; -------------------------------------------------------------------------- | |
| ;;; Customization | |
| ;;; -------------------------------------------------------------------------- | |
| (defgroup spc-leader nil | |
| "Spacebar as leader key — Spacemacs-style bindings." | |
| :group 'convenience | |
| :prefix "spc-leader-") | |
| (defcustom spc-leader-literal-predicates | |
| '(spc-leader--helix-insert-p | |
| spc-leader--minibuffer-p | |
| spc-leader--isearch-p | |
| spc-leader--terminal-p) | |
| "Predicates that determine when SPC should insert literally." | |
| :type '(repeat function) | |
| :group 'spc-leader) | |
| ;;; -------------------------------------------------------------------------- | |
| ;;; Predicate Functions — When Should SPC Be Literal? | |
| ;;; -------------------------------------------------------------------------- | |
| (defun spc-leader--helix-insert-p () | |
| "Return non-nil when in Helix insert mode." | |
| (or (bound-and-true-p helix-insert-mode) | |
| (and (boundp 'helix--current-state) | |
| (eq helix--current-state 'insert)))) | |
| (defun spc-leader--minibuffer-p () | |
| "Return non-nil when point is in the minibuffer." | |
| (minibufferp)) | |
| (defun spc-leader--isearch-p () | |
| "Return non-nil during incremental search." | |
| (bound-and-true-p isearch-mode)) | |
| (defun spc-leader--terminal-p () | |
| "Return non-nil in terminal emulator modes." | |
| (derived-mode-p 'term-mode 'vterm-mode 'eat-mode 'eshell-mode)) | |
| (defun spc-leader--literal-p () | |
| "Return non-nil if current context requires literal space." | |
| (seq-some #'funcall spc-leader-literal-predicates)) | |
| ;;; -------------------------------------------------------------------------- | |
| ;;; Leader Keymap | |
| ;;; -------------------------------------------------------------------------- | |
| (defvar spc-leader-map (make-sparse-keymap) | |
| "Leader keymap triggered by SPC.") | |
| ;; Give it a name for which-key | |
| (define-prefix-command 'spc-leader-map) | |
| ;; SPC SPC → M-x | |
| (define-key spc-leader-map (kbd "SPC") #'execute-extended-command) | |
| ;;; --- Files (f) --- | |
| (define-key spc-leader-map (kbd "f") (cons "file" (make-sparse-keymap))) | |
| (define-key spc-leader-map (kbd "f f") #'find-file) | |
| (define-key spc-leader-map (kbd "f s") #'save-buffer) | |
| (define-key spc-leader-map (kbd "f S") #'write-file) | |
| (define-key spc-leader-map (kbd "f r") #'recentf-open-files) | |
| (define-key spc-leader-map (kbd "f R") #'rename-file) | |
| (define-key spc-leader-map (kbd "f d") #'dired) | |
| (define-key spc-leader-map (kbd "f D") #'delete-file) | |
| (define-key spc-leader-map (kbd "f c") #'copy-file) | |
| (define-key spc-leader-map (kbd "f e") #'find-file-other-window) | |
| ;;; --- Buffers (b) --- | |
| (define-key spc-leader-map (kbd "b") (cons "buffer" (make-sparse-keymap))) | |
| (define-key spc-leader-map (kbd "b b") #'consult-buffer) | |
| (define-key spc-leader-map (kbd "b B") #'switch-to-buffer) | |
| (define-key spc-leader-map (kbd "b d") #'kill-current-buffer) | |
| (define-key spc-leader-map (kbd "b D") #'kill-buffer) | |
| (define-key spc-leader-map (kbd "b n") #'next-buffer) | |
| (define-key spc-leader-map (kbd "b p") #'previous-buffer) | |
| (define-key spc-leader-map (kbd "b r") #'revert-buffer) | |
| (define-key spc-leader-map (kbd "b l") #'ibuffer) | |
| (define-key spc-leader-map (kbd "b s") #'save-buffer) | |
| (define-key spc-leader-map (kbd "b S") #'save-some-buffers) | |
| ;;; --- Windows (w) --- | |
| (define-key spc-leader-map (kbd "w") (cons "window" (make-sparse-keymap))) | |
| (define-key spc-leader-map (kbd "w d") #'delete-window) | |
| (define-key spc-leader-map (kbd "w v") #'split-window-right) | |
| (define-key spc-leader-map (kbd "w s") #'split-window-below) | |
| (define-key spc-leader-map (kbd "w o") #'delete-other-windows) | |
| (define-key spc-leader-map (kbd "w w") #'other-window) | |
| (define-key spc-leader-map (kbd "w m") #'maximize-window) | |
| (define-key spc-leader-map (kbd "w =") #'balance-windows) | |
| (define-key spc-leader-map (kbd "w h") #'windmove-left) | |
| (define-key spc-leader-map (kbd "w l") #'windmove-right) | |
| (define-key spc-leader-map (kbd "w j") #'windmove-down) | |
| (define-key spc-leader-map (kbd "w k") #'windmove-up) | |
| ;;; --- Git (g) --- | |
| (define-key spc-leader-map (kbd "g") (cons "git" (make-sparse-keymap))) | |
| (define-key spc-leader-map (kbd "g g") #'magit-status) | |
| (define-key spc-leader-map (kbd "g b") #'magit-blame) | |
| (define-key spc-leader-map (kbd "g l") #'magit-log-current) | |
| (define-key spc-leader-map (kbd "g L") #'magit-log-buffer-file) | |
| (define-key spc-leader-map (kbd "g d") #'magit-diff) | |
| (define-key spc-leader-map (kbd "g f") #'magit-file-dispatch) | |
| (define-key spc-leader-map (kbd "g s") #'magit-stage-file) | |
| (define-key spc-leader-map (kbd "g u") #'magit-unstage-file) | |
| ;;; --- Search (s) --- | |
| (define-key spc-leader-map (kbd "s") (cons "search" (make-sparse-keymap))) | |
| (define-key spc-leader-map (kbd "s s") #'consult-line) | |
| (define-key spc-leader-map (kbd "s S") #'isearch-forward) | |
| (define-key spc-leader-map (kbd "s r") #'isearch-backward) | |
| (define-key spc-leader-map (kbd "s o") #'occur) | |
| (define-key spc-leader-map (kbd "s i") #'consult-imenu) | |
| (define-key spc-leader-map (kbd "s p") #'consult-ripgrep) | |
| (define-key spc-leader-map (kbd "s g") #'consult-grep) | |
| ;;; --- Help (h) --- | |
| (define-key spc-leader-map (kbd "h") (cons "help" (make-sparse-keymap))) | |
| (define-key spc-leader-map (kbd "h f") #'describe-function) | |
| (define-key spc-leader-map (kbd "h v") #'describe-variable) | |
| (define-key spc-leader-map (kbd "h k") #'describe-key) | |
| (define-key spc-leader-map (kbd "h m") #'describe-mode) | |
| (define-key spc-leader-map (kbd "h b") #'describe-bindings) | |
| (define-key spc-leader-map (kbd "h a") #'apropos) | |
| (define-key spc-leader-map (kbd "h i") #'info) | |
| (define-key spc-leader-map (kbd "h p") #'describe-package) | |
| ;;; --- Toggle (t) --- | |
| (define-key spc-leader-map (kbd "t") (cons "toggle" (make-sparse-keymap))) | |
| (define-key spc-leader-map (kbd "t l") #'display-line-numbers-mode) | |
| (define-key spc-leader-map (kbd "t w") #'whitespace-mode) | |
| (define-key spc-leader-map (kbd "t t") #'load-theme) | |
| (define-key spc-leader-map (kbd "t v") #'visual-line-mode) | |
| (define-key spc-leader-map (kbd "t h") #'hl-line-mode) | |
| (define-key spc-leader-map (kbd "t f") #'toggle-frame-fullscreen) | |
| ;;; --- Quit (q) --- | |
| (define-key spc-leader-map (kbd "q") (cons "quit" (make-sparse-keymap))) | |
| (define-key spc-leader-map (kbd "q q") #'save-buffers-kill-terminal) | |
| (define-key spc-leader-map (kbd "q Q") #'kill-emacs) | |
| (define-key spc-leader-map (kbd "q r") #'restart-emacs) | |
| ;;; --- Open (o) --- | |
| (define-key spc-leader-map (kbd "o") (cons "open" (make-sparse-keymap))) | |
| (define-key spc-leader-map (kbd "o t") #'eshell) | |
| (define-key spc-leader-map (kbd "o d") #'dired-jump) | |
| (define-key spc-leader-map (kbd "o m") #'man) | |
| ;;; --- Direct prefix access (escape hatch to C-x / C-c) --- | |
| (define-key spc-leader-map (kbd "x") ctl-x-map) | |
| (define-key spc-leader-map (kbd "c") mode-specific-map) | |
| ;;; -------------------------------------------------------------------------- | |
| ;;; Leader Minor Mode | |
| ;;; -------------------------------------------------------------------------- | |
| (defvar spc-leader-mode-map | |
| (let ((map (make-sparse-keymap))) | |
| (define-key map (kbd "SPC") | |
| `(menu-item "" spc-leader-map | |
| :filter ,(lambda (cmd) | |
| (unless (spc-leader--literal-p) | |
| cmd)))) | |
| map) | |
| "Keymap for leader mode with context-aware SPC.") | |
| (define-minor-mode spc-leader-mode | |
| "Global minor mode: SPC as leader key. | |
| In normal editing contexts, SPC activates the leader menu. | |
| In insert contexts (minibuffer, helix insert, terminals), SPC inserts space. | |
| Escape hatch: S-SPC always inserts literal space." | |
| :global t | |
| :lighter " ⌘" | |
| :keymap spc-leader-mode-map | |
| (if spc-leader-mode | |
| (message "Leader mode: SPC → leader menu (S-SPC for literal space)") | |
| (message "Leader mode disabled"))) | |
| ;;; -------------------------------------------------------------------------- | |
| ;;; Escape Hatches | |
| ;;; -------------------------------------------------------------------------- | |
| (defun spc-leader-insert-space () | |
| "Insert a literal space character." | |
| (interactive) | |
| (insert " ")) | |
| (global-set-key (kbd "S-SPC") #'spc-leader-insert-space) | |
| ;;; -------------------------------------------------------------------------- | |
| ;;; Activate! | |
| ;;; -------------------------------------------------------------------------- | |
| (spc-leader-mode 1) | |
| ;;; ========================================================================== | |
| ;;; End of init.el | |
| ;;; ========================================================================== |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment