Skip to content

Instantly share code, notes, and snippets.

@reflechant
Last active February 12, 2026 10:38
Show Gist options
  • Select an option

  • Save reflechant/c900eb968fc75a16a676428f29ed2138 to your computer and use it in GitHub Desktop.

Select an option

Save reflechant/c900eb968fc75a16a676428f29ed2138 to your computer and use it in GitHub Desktop.
new Emacs config
;;; init.el --- Personal Emacs config -*- lexical-binding: t; -*-
;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Package Management ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;
(require 'package)
(add-to-list 'package-archives '("melpa" . "https://melpa.org/packages/") t)
;; use-package is built-in in Emacs 30 but :ensure needs this module
(require 'use-package-ensure)
(setq use-package-always-ensure t)
;; Keep Custom's auto-generated stuff out of init.el
(setq custom-file (expand-file-name "custom.el" user-emacs-directory))
;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Sane Defaults ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;
(setopt use-short-answers t) ; y/n instead of yes/no
(setq inhibit-startup-message t) ; skip splash screen
(setq column-number-mode t) ; show column in modeline
;; Fill column indicator at 80 chars
(setopt display-fill-column-indicator-column 80)
(global-display-fill-column-indicator-mode t)
;; Line numbers in code
(add-hook 'prog-mode-hook #'display-line-numbers-mode)
;; Remember cursor position in files
(save-place-mode 1)
;; Remember recent files
(recentf-mode 1)
(setq recentf-max-saved-items 50)
;; Remember minibuffer history (Vertico sorts by this)
(savehist-mode 1)
;; Auto-pair brackets (disabled in paredit buffers below)
(electric-pair-mode t)
;; Smooth pixel scrolling
(pixel-scroll-precision-mode t)
;; Store backups in a dedicated directory
(setq backup-directory-alist
`(("." . ,(expand-file-name "backups" user-emacs-directory))))
;; Hide commands in M-x that don't apply to current mode
(setq read-extended-command-predicate #'command-completion-default-include-p)
;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Evil Mode + Leader ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Vim emulation — C-z toggles back to Emacs keybindings anytime
(use-package evil
:init
(setq evil-want-integration t)
(setq evil-want-keybinding nil) ; let evil-collection handle non-core modes
(setq evil-want-C-u-scroll t) ; C-u scrolls up like vim (use universal-argument via SPC u)
(setq evil-undo-system 'undo-redo) ; Emacs 28+ built-in undo-redo
:config
(evil-mode 1))
;; Evil bindings for 150+ Emacs packages (magit, dired, org, etc.)
(use-package evil-collection
:after evil
:config
(evil-collection-init))
;; gc to comment/uncomment (works on lines and selections)
(use-package evil-nerd-commenter
:after evil
:bind ("M-;" . evilnc-comment-or-uncomment-lines))
;; Leader key system — press SPC in normal mode to see all commands
(use-package general
:after evil
:config
(general-create-definer my-leader-def
:keymaps '(normal visual emacs)
:prefix "SPC"
:global-prefix "C-SPC") ; C-SPC works in insert/emacs state too
(my-leader-def
"" '(nil :which-key "leader")
"SPC" '(execute-extended-command :which-key "M-x")
"u" '(universal-argument :which-key "universal arg")
"TAB" '(evil-switch-to-windows-last-buffer :which-key "last buffer")
"!" '(shell-command :which-key "shell command")
"/" '(consult-ripgrep :which-key "ripgrep")
";" '(eval-expression :which-key "eval expression")
"'" '(eshell :which-key "eshell")
;; Files
"f" '(:ignore t :which-key "file")
"f f" '(find-file :which-key "find file")
"f r" '(consult-recent-file :which-key "recent files")
"f s" '(save-buffer :which-key "save")
"f S" '(write-file :which-key "save as")
"f R" '(rename-visited-file :which-key "rename current file")
;; Buffers
"b" '(:ignore t :which-key "buffer")
"b b" '(consult-buffer :which-key "switch buffer")
"b d" '(kill-current-buffer :which-key "kill buffer")
"b l" '(ibuffer :which-key "list buffers")
"b n" '(next-buffer :which-key "next buffer")
"b p" '(previous-buffer :which-key "previous buffer")
"b r" '(revert-buffer-quick :which-key "revert buffer")
"b s" '(scratch-buffer :which-key "scratch buffer")
"b m" '(bookmark-set :which-key "set bookmark")
"b M" '(consult-bookmark :which-key "jump to bookmark")
;; Project (built-in project.el)
"p" '(:ignore t :which-key "project")
"p f" '(project-find-file :which-key "find file in project")
"p p" '(project-switch-project :which-key "switch project")
"p s" '(project-find-regexp :which-key "grep in project")
"p b" '(consult-project-buffer :which-key "project buffers")
"p c" '(project-compile :which-key "compile")
"p e" '(project-eshell :which-key "eshell in project root")
"p d" '(project-dired :which-key "dired in project root")
"p k" '(project-kill-buffers :which-key "kill project buffers")
"p r" '(project-query-replace-regexp :which-key "replace in project")
;; Search
"s" '(:ignore t :which-key "search")
"s s" '(consult-line :which-key "search in buffer")
"s S" '(isearch-forward :which-key "isearch forward")
"s r" '(consult-ripgrep :which-key "ripgrep from here")
"s f" '(consult-find :which-key "find file by name")
"s i" '(consult-imenu :which-key "imenu symbols")
"s I" '(consult-imenu-multi :which-key "imenu all buffers")
"s l" '(consult-line-multi :which-key "search all open buffers")
"s o" '(consult-outline :which-key "outline headings")
"s R" '(query-replace :which-key "search & replace in buffer")
;; Code / LSP
"c" '(:ignore t :which-key "code")
"c a" '(eglot-code-actions :which-key "code actions")
"c r" '(eglot-rename :which-key "rename symbol")
"c f" '(apheleia-format-buffer :which-key "format buffer")
"c d" '(xref-find-definitions :which-key "go to definition")
"c D" '(xref-find-references :which-key "find references")
"c e" '(consult-flymake :which-key "list diagnostics")
"c j" '(flymake-goto-next-error :which-key "next error")
"c k" '(flymake-goto-prev-error :which-key "prev error")
"c o" '(eglot-code-action-organize-imports :which-key "organize imports")
"c x" '(eglot-code-action-quickfix :which-key "quickfix")
"c h" '(eldoc :which-key "docs at point")
;; Git
"g" '(:ignore t :which-key "git")
"g g" '(magit-status :which-key "status")
"g b" '(magit-blame :which-key "blame")
"g l" '(magit-log-current :which-key "log current branch")
"g L" '(magit-log-all :which-key "log all branches")
"g d" '(diff-hl-show-hunk :which-key "show hunk diff")
"g r" '(diff-hl-revert-hunk :which-key "revert hunk")
"g n" '(diff-hl-next-hunk :which-key "next changed hunk")
"g p" '(diff-hl-previous-hunk :which-key "prev changed hunk")
"g f" '(magit-file-dispatch :which-key "file actions")
"g s" '(magit-stage-file :which-key "stage current file")
;; Window management
"w" '(:ignore t :which-key "window")
"w v" '(split-window-right :which-key "split vertical")
"w s" '(split-window-below :which-key "split horizontal")
"w d" '(delete-window :which-key "close window")
"w w" '(other-window :which-key "other window")
"w m" '(delete-other-windows :which-key "maximize")
"w =" '(balance-windows :which-key "balance windows")
"w r" '(evil-window-rotate-downwards :which-key "rotate windows")
"w h" '(evil-window-left :which-key "go left")
"w j" '(evil-window-down :which-key "go down")
"w k" '(evil-window-up :which-key "go up")
"w l" '(evil-window-right :which-key "go right")
;; Toggles
"t" '(:ignore t :which-key "toggle")
"t t" '(treemacs :which-key "file tree")
"t d" '(my/load-dark-theme :which-key "dark theme")
"t l" '(my/load-light-theme :which-key "light theme")
"t T" '(consult-theme :which-key "browse themes")
"t n" '(display-line-numbers-mode :which-key "line numbers")
"t w" '(whitespace-mode :which-key "whitespace")
"t f" '(display-fill-column-indicator-mode :which-key "fill column")
"t v" '(visual-line-mode :which-key "word wrap")
;; Help
"h" '(:ignore t :which-key "help")
"h k" '(describe-key :which-key "describe key")
"h f" '(describe-function :which-key "describe function")
"h v" '(describe-variable :which-key "describe variable")
"h m" '(describe-mode :which-key "describe mode")
"h p" '(describe-package :which-key "describe package")
"h i" '(info :which-key "info manual")
"h a" '(apropos :which-key "search all help")
"h b" '(embark-bindings :which-key "all keybindings")
;; Org
"o" '(:ignore t :which-key "org")
"o a" '(org-agenda :which-key "agenda")
"o c" '(org-capture :which-key "capture")
"o l" '(org-store-link :which-key "store link")
"o t" '(org-todo-list :which-key "global todo list")
;; Evaluate elisp
"e" '(:ignore t :which-key "eval")
"e b" '(eval-buffer :which-key "eval buffer")
"e r" '(eval-region :which-key "eval region")
"e e" '(eval-last-sexp :which-key "eval last sexp")
;; Quit
"q" '(:ignore t :which-key "quit")
"q q" '(save-buffers-kill-terminal :which-key "quit emacs")
"q r" '(restart-emacs :which-key "restart emacs")
;; Packages
"P" '(:ignore t :which-key "packages")
"P r" '(package-refresh-contents :which-key "refresh archives")
"P u" '(package-upgrade-all :which-key "upgrade all")
"P l" '(package-list-packages :which-key "list packages")))
;; Show available keys after pressing a prefix
(use-package which-key
:diminish
:config
(which-key-mode))
(use-package diminish)
;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Appearance ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Font
(set-face-attribute 'default nil :family "Fira Code" :height 120)
;; Dark theme (Spacemacs-like)
(use-package doom-themes
:config
(load-theme 'doom-one t)
(doom-themes-visual-bell-config)
(doom-themes-treemacs-config)
(doom-themes-org-config))
;; Light themes for daytime
(use-package ef-themes
:defer t)
;; Quick theme switching
(defun my/load-dark-theme ()
"Switch to dark theme."
(interactive)
(mapc #'disable-theme custom-enabled-themes)
(load-theme 'doom-one t))
(defun my/load-light-theme ()
"Switch to light theme."
(interactive)
(mapc #'disable-theme custom-enabled-themes)
(load-theme 'ef-light t))
;; Icons (run M-x nerd-icons-install-fonts on first launch)
(use-package nerd-icons)
;; Modeline
(use-package doom-modeline
:init (doom-modeline-mode 1)
:custom
(doom-modeline-height 35))
;; Font ligatures (Fira Code)
(use-package ligature
:config
(ligature-set-ligatures
'prog-mode
'("www" "**" "***" "**/" "*>" "*/" "\\\\" "\\\\\\"
"{-" "::" ":::" ":=" "!!" "!=" "!==" "-}" "----" "-->" "->" "->>"
"-<" "-<<" "-~" "#{" "#[" "##" "###" "####" "#(" "#?" "#_" "#_("
".-" ".=" ".." "..<" "..." "?=" "??" ";;" "/*" "/**"
"/=" "/==" "/>" "//" "///" "&&" "||" "||=" "|=" "|>" "^=" "$>"
"++" "+++" "+>" "=:=" "==" "===" "==>" "=>" "=>>" "<="
"=<<" "=/=" ">-" ">=" ">=>" ">>" ">>-" ">>=" ">>>" "<*"
"<*>" "<|" "<|>" "<$" "<$>" "<!--" "<-" "<--" "<->" "<+"
"<+>" "<=" "<==" "<=>" "<=<" "<>" "<<" "<<-" "<<=" "<<<"
"<~" "<~~" "</" "</>" "~@" "~-" "~>" "~~" "~~>" "%%"))
(global-ligature-mode t))
;; Colorful parentheses
(use-package rainbow-delimiters
:hook (prog-mode . rainbow-delimiters-mode))
;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Completion Framework ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Vertical completion UI
(use-package vertico
:custom
(vertico-count 20)
(vertico-resize t)
:config
(vertico-mode))
;; Fuzzy/orderless matching
(use-package orderless
:custom
(completion-styles '(orderless basic))
(completion-category-overrides '((file (styles basic partial-completion)))))
;; Enhanced commands (search, buffer switch, etc.)
(use-package consult
:bind (("C-x b" . consult-buffer)
("M-y" . consult-yank-pop)
("M-g g" . consult-goto-line)
("M-g M-g" . consult-goto-line)
("M-g i" . consult-imenu))
:hook (completion-list-mode . consult-preview-at-point-mode)
:init
(setq xref-show-xrefs-function #'consult-xref
xref-show-definitions-function #'consult-xref)
:config
(consult-customize
consult-theme :preview-key '(:debounce 0.2 any)
consult-ripgrep consult-git-grep consult-grep consult-bookmark
consult-recent-file consult-xref
consult--source-bookmark consult--source-file-register
consult--source-recent-file consult--source-project-recent-file
:preview-key '(:debounce 0.4 any))
(setq consult-narrow-key "<"))
;; Annotations in minibuffer completions
(use-package marginalia
:init (marginalia-mode))
;; Context-dependent actions on targets
(use-package embark
:bind (("C-." . embark-act)
("C-h B" . embark-bindings))
:init
(setq prefix-help-command #'embark-prefix-help-command)
:config
(add-to-list 'display-buffer-alist
'("\\`\\*Embark Collect \\(Live\\|Completions\\)\\*"
nil
(window-parameters (mode-line-format . none)))))
(use-package embark-consult
:after (embark consult)
:hook (embark-collect-mode . consult-preview-at-point-mode))
;; Inline completion popup (replaces company-mode)
(use-package corfu
:custom
(corfu-auto t) ; show completions automatically
(corfu-auto-delay 0.1)
(corfu-cycle t) ; cycle through candidates
:init
(global-corfu-mode))
;; Extra completion sources for corfu
(use-package cape
:init
(add-hook 'completion-at-point-functions #'cape-dabbrev)
(add-hook 'completion-at-point-functions #'cape-file))
;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Development Tools ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Tree-sitter grammar management
(use-package treesit-auto
:custom
(treesit-auto-install 'prompt)
:config
(treesit-auto-add-to-auto-mode-alist 'all)
(global-treesit-auto-mode))
;; LSP via built-in eglot
(use-package eglot
:hook ((go-ts-mode rust-mode rust-ts-mode python-ts-mode python-mode
js-ts-mode typescript-ts-mode zig-mode) . eglot-ensure)
:config
(setq eglot-autoshutdown t)) ; shut down server when last buffer is closed
;; Format on save with external formatters
(use-package apheleia
:diminish
:config
(apheleia-global-mode t))
;; Git porcelain
(use-package magit
:defer t)
;; Git gutter indicators
(use-package diff-hl
:config
(global-diff-hl-mode)
(add-hook 'magit-pre-refresh-hook 'diff-hl-magit-pre-refresh)
(add-hook 'magit-post-refresh-hook 'diff-hl-magit-post-refresh))
;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Clojure + CIDER ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;
(use-package clojure-mode
:mode (("\\.clj\\'" . clojure-mode)
("\\.edn\\'" . clojure-mode)
("\\.cljs\\'" . clojurescript-mode)
("\\.cljc\\'" . clojurec-mode)))
(use-package cider
:defer t
:diminish subword-mode
:custom
(cider-repl-pop-to-buffer-on-connect t)
(cider-show-error-buffer t)
(cider-auto-select-error-buffer t))
(use-package clj-deps-new
:defer t)
;; Structural editing for Lisps — paredit handles parens, so disable electric-pair
(use-package paredit
:hook ((clojure-mode . paredit-mode)
(clojurescript-mode . paredit-mode)
(clojurec-mode . paredit-mode)
(cider-repl-mode . paredit-mode)
(emacs-lisp-mode . paredit-mode)
(lisp-interaction-mode . paredit-mode))
:config
(add-hook 'paredit-mode-hook
(lambda () (electric-pair-local-mode -1))))
;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Languages ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Rust
(use-package rust-mode
:defer t)
;; Zig
(use-package zig-mode
:defer t)
;; Racket
(use-package racket-mode
:defer t)
(use-package geiser-racket
:defer t)
;; Web (HTML, JSX, TSX)
(use-package web-mode
:mode ("\\.html\\'" "\\.jsx\\'" "\\.tsx\\'"))
;; YAML
(use-package yaml-mode
:defer t)
;; Markdown
(use-package markdown-mode
:mode ("\\.md\\'" ("README\\.md\\'" . gfm-mode))
:custom
(markdown-command "multimarkdown"))
;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Org Mode ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;
(use-package org
:ensure nil ; built-in
:custom
(org-directory "~/org")
(org-agenda-files '("~/org"))
(org-startup-indented t)
(org-hide-emphasis-markers t)
(org-return-follows-link t)
:config
(setq org-capture-templates
'(("t" "Todo" entry (file+headline "~/org/inbox.org" "Tasks")
"* TODO %?\n %i\n %a")
("n" "Note" entry (file+headline "~/org/inbox.org" "Notes")
"* %?\n %i\n %a"))))
;; Pretty org headers, bullets, tables
(use-package org-modern
:hook (org-mode . org-modern-mode))
;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; File Tree ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;
(use-package treemacs
:defer t
:config
(treemacs-follow-mode t)
(treemacs-filewatch-mode t))
(use-package treemacs-magit
:after (treemacs magit))
(use-package treemacs-nerd-icons
:after treemacs
:config
(treemacs-load-theme "nerd-icons"))
;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Load custom.el ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;
(when (file-exists-p custom-file)
(load custom-file))
;;; init.el ends here
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment