Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/jtdowney/emacs.d
my emacs.d
https://github.com/jtdowney/emacs.d
Last synced: about 2 months ago
JSON representation
my emacs.d
- Host: GitHub
- URL: https://github.com/jtdowney/emacs.d
- Owner: jtdowney
- Created: 2018-10-11T00:55:07.000Z (over 6 years ago)
- Default Branch: main
- Last Pushed: 2024-02-23T23:11:33.000Z (11 months ago)
- Last Synced: 2024-10-16T14:59:38.309Z (3 months ago)
- Language: Emacs Lisp
- Homepage:
- Size: 149 KB
- Stars: 0
- Watchers: 2
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: readme.org
Awesome Lists containing this project
README
#+Title: Emacs configuration
#+STARTUP: show3levels
#+PROPERTY: header-args:emacs-lisp :comments link* early-init.el and init.el
** early-init.el
#+BEGIN_SRC emacs-lisp :tangle early-init.el
;;; early-init.el --- Early Init File -*- lexical-binding: t; no-byte-compile: t -*-;; Defer garbage collection further back in the startup process
(setq gc-cons-threshold most-positive-fixnum
gc-cons-percentage 0.6);; In Emacs 27+, package initialization occurs before `user-init-file' is
;; loaded, but after `early-init-file'. Doom handles package initialization, so
;; we must prevent Emacs from doing it early!
(setq package-enable-at-startup nil)
;; Do not allow loading from the package cache (same reason).
(setq package-quickstart nil);; Prevent the glimpse of un-styled Emacs by disabling these UI elements early.
(push '(menu-bar-lines . 0) default-frame-alist)
(push '(tool-bar-lines . 0) default-frame-alist)
(push '(vertical-scroll-bars) default-frame-alist);; Resizing the Emacs frame can be a terribly expensive part of changing the
;; font. By inhibiting this, we easily halve startup times with fonts that are
;; larger than the system default.
(setq frame-inhibit-implied-resize t);; Disable GUI elements
(menu-bar-mode -1)
(tool-bar-mode -1)
(scroll-bar-mode -1)
(setq inhibit-splash-screen t)
(setq use-file-dialog nil);; Prevent unwanted runtime builds in gccemacs (native-comp); packages are
;; compiled ahead-of-time when they are installed and site files are compiled
;; when gccemacs is installed.
(setq comp-deferred-compilation nil);; Mitigate https://debbugs.gnu.org/cgi/bugreport.cgi?bug=57849
(when (eq system-type 'darwin)
(setq native-comp-driver-options '("-Wl,-w")))
#+END_SRC** init.el: startup optimization
#+BEGIN_SRC emacs-lisp :tangle init.el
;;; init.el --- Personal configuration file -*- lexical-binding: t; no-byte-compile: t; -*-;; `file-name-handler-alist' is consulted on every `require', `load' and various
;; path/io functions. You get a minor speed up by nooping this. However, this
;; may cause problems on builds of Emacs where its site lisp files aren't
;; byte-compiled and we're forced to load the *.el.gz files (e.g. on Alpine)
(unless (daemonp)
(defvar doom--initial-file-name-handler-alist file-name-handler-alist)
(setq file-name-handler-alist nil)
;; Restore `file-name-handler-alist' later, because it is needed for handling
;; encrypted or compressed files, among other things.
(defun doom-reset-file-handler-alist-h ()
;; Re-add rather than `setq', because changes to `file-name-handler-alist'
;; since startup ought to be preserved.
(dolist (handler file-name-handler-alist)
(add-to-list 'doom--initial-file-name-handler-alist handler))
(setq file-name-handler-alist doom--initial-file-name-handler-alist))
(add-hook 'emacs-startup-hook #'doom-reset-file-handler-alist-h)
(add-hook 'after-init-hook (lambda ()
;; restore after startup
(setq gc-cons-threshold 16777216
gc-cons-percentage 0.1))));; Ensure Doom is running out of this file's directory
(setq user-emacs-directory (file-truename (file-name-directory load-file-name)))
#+END_SRC** init.el: load modules
#+BEGIN_SRC emacs-lisp :tangle init.el
(add-to-list 'load-path (expand-file-name "lisp" user-emacs-directory))(let ((file-name-handler-alist nil)
(gc-cons-threshold 100000000))
(load "init-core")
(load "init-keybindings")
(load "init-evil")
(load "init-ui")
(load "init-window")
(load "init-navigation")
(load "init-completion")
(load "init-search")
(load "init-org")
(load "init-writing")
(load "init-prog")
(load "init-apps")
)
#+END_SRC** init.el: measure startup
#+begin_src emacs-lisp :tangle init.el
(add-hook 'emacs-startup-hook
(lambda ()
(message "Emacs started in %s with %d garbage collections."
(format "%.3f seconds"
(float-time
(time-subtract after-init-time before-init-time)))
gcs-done)))
#+end_src* Package manager
:PROPERTIES:
:header-args: :tangle lisp/init-core.el
:END:** bootstrap straight and straight-use-package
#+BEGIN_SRC emacs-lisp
(setq straight-use-package-by-default t)
(setq straight-vc-git-default-clone-depth 1)
(setq straight-recipes-gnu-elpa-use-mirror t)
(setq straight-check-for-modifications nil)(defvar bootstrap-version)
(let ((bootstrap-file
(expand-file-name "straight/repos/straight.el/bootstrap.el" user-emacs-directory))
(bootstrap-version 6))
(unless (file-exists-p bootstrap-file)
(with-current-buffer
(url-retrieve-synchronously
"https://raw.githubusercontent.com/radian-software/straight.el/develop/install.el"
'silent 'inhibit-cookies)
(goto-char (point-max))
(eval-print-last-sexp)))
(load bootstrap-file nil 'nomessage))(straight-use-package 'use-package)
(setq comp-deferred-compilation-black-list nil)
#+END_SRC** Enable use-package statistics
#+BEGIN_SRC emacs-lisp
(setq use-package-compute-statistics t)
#+END_SRC* Core
:PROPERTIES:
:header-args: :tangle lisp/init-core.el
:END:** Sane defaults
#+BEGIN_SRC emacs-lisp
(use-package emacs
:custom
(user-full-name "John Downey")
(user-mail-address "[email protected]")(inhibit-startup-screen t)
(initial-scratch-message nil)
(initial-major-mode 'text-mode)(sentence-end-double-space nil)
(ring-bell-function 'ignore)
(ad-redefinition-action 'accept)
(frame-resize-pixelwise t)
(vc-follow-symlinks t)(custom-file (make-temp-file ""))
(make-backup-files nil)
(auto-save-default nil)
(create-lockfiles nil)(byte-compile-warnings '(not free-vars unresolved noruntime lexical make-local))
(native-comp-async-report-warnings-errors nil)(column-number-mode t)
(tab-always-indent 'complete)
:init
(defalias 'yes-or-no-p 'y-or-n-p);; default to utf-8 for all the things
(set-charset-priority 'unicode)
(setq locale-coding-system 'utf-8
coding-system-for-read 'utf-8
coding-system-for-write 'utf-8)
(set-terminal-coding-system 'utf-8)
(set-keyboard-coding-system 'utf-8)
(set-selection-coding-system 'utf-8)
(prefer-coding-system 'utf-8)
(setq default-process-coding-system '(utf-8-unix . utf-8-unix))(delete-selection-mode 1)
(global-set-key (kbd "") 'keyboard-escape-quit)
(winner-mode 1)
(show-paren-mode 1)
(display-time-mode -1)(setq-default indent-tabs-mode nil))
#+END_SRC** On hooks
#+begin_src emacs-lisp
(use-package on
:demand
:straight (:host github :repo "ajgrf/on.el"))
#+end_src** Private configuration
#+begin_src emacs-lisp
(add-hook
'after-init-hook
(lambda ()
(let ((private-file (concat user-emacs-directory "private.el")))
(when (file-exists-p private-file)
(load-file private-file)))))
#+end_src** Zoom
#+BEGIN_SRC emacs-lisp
(global-set-key (kbd "C-=") 'text-scale-increase)
(global-set-key (kbd "C--") 'text-scale-decrease)
#+END_SRC** macOS
#+BEGIN_SRC emacs-lisp
(use-package emacs
:init
(when (eq system-type 'darwin)
(setq mac-command-modifier 'super) ; command as super
(setq mac-option-modifier 'meta) ; alt as meta
(setq mac-control-modifier 'control));; when on emacs-mac
(when (fboundp 'mac-auto-operator-composition-mode)
(mac-auto-operator-composition-mode) ;; enables font ligatures
(global-set-key [(s c)] 'kill-ring-save)
(global-set-key [(s v)] 'yank)
(global-set-key [(s x)] 'kill-region)
(global-set-key [(s q)] 'kill-emacs)))
#+END_SRC** Garbage collector magic hack
#+BEGIN_SRC emacs-lisp
(use-package gcmh
:config
(gcmh-mode 1))
#+END_SRC** Helpful
#+begin_src emacs-lisp
(use-package helpful
:bind
([remap describe-function] . helpful-function)
([remap describe-command] . helpful-command)
([remap describe-variable] . helpful-variable)
([remap describe-key] . helpful-key))
#+end_src** Save recent files
#+begin_src emacs-lisp
(use-package recentf
:straight (:type built-in)
:hook
(after-init . recentf-mode)
:custom
(recentf-exclude `(,(expand-file-name "straight/build/" user-emacs-directory)
,(expand-file-name "eln-cache/" user-emacs-directory)
,(expand-file-name "etc/" user-emacs-directory)
,(expand-file-name "var/" user-emacs-directory))))
#+end_src** Highlight trailing whitespace
#+begin_src emacs-lisp
(dolist (hook '(prog-mode-hook text-mode-hook))
(add-hook hook (lambda ())
(setq-local show-trailing-whitespace t)))
#+end_src** Undo
#+begin_src emacs-lisp
(use-package undo-fu)
#+end_src** Tramp
#+begin_src emacs-lisp
(use-package tramp
:defer 1
:straight (:type built-in)
:config
(setq vc-ignore-dir-regexp (format "\\(%s\\)\\|\\(%s\\)"
vc-ignore-dir-regexp
tramp-file-name-regexp)
tramp-default-method "ssh"
tramp-auto-save-directory (expand-file-name "tramp-auto-save" user-emacs-directory)
tramp-persistency-file-name (expand-file-name "tramp-connection-history" user-emacs-directory)
tramp-use-ssh-controlmaster-options nil
remote-file-name-inhibit-cache nil
tramp-ssh-controlmaster-options (concat
"-o ControlPath=/tmp/ssh-tramp-%%r@%%h:%%p "
"-o ControlMaster=auto -o ControlPersist=yes")))(use-package tramp-container
:defer 2
:straight (:type built-in))
#+end_src* Keybindings
:PROPERTIES:
:header-args: :tangle lisp/init-keybindings.el
:END:** General
#+begin_src emacs-lisp
(defun jtd/find-file-in-emacs ()
"Find files in the emacs configuration directory"
(interactive)
(ido-find-file-in-dir user-emacs-directory))(defun jtd/switch-to-scratch-buffer ()
"Switch to the scratch buffer"
(interactive)
(switch-to-buffer "*scratch*"))(defun jtd/copy-buffer ()
"Copy the entire buffer"
(interactive)
(mark-whole-buffer)
(kill-ring-save 0 0 t))(defun jtd/kill-other-buffers ()
"Kill all buffers but the current one. Don't mess with special buffers."
(interactive)
(dolist (buffer (buffer-list))
(unless (or (eql buffer (current-buffer)) (not (buffer-file-name buffer)))
(kill-buffer buffer))))(use-package general
:config
(general-evil-setup)(general-create-definer jtd/leader-key
:keymaps 'override
:states '(normal visual)
:prefix "SPC"
:global-prefix "C-SPC")
(general-create-definer jtd/local-leader-key
:states '(normal visual motion)
:prefix ","
:global-prefix "C-,")(general-def '(normal insert visual emacs) "C-@" (general-simulate-key "C-SPC"))
(jtd/leader-key
":" 'execute-extended-command
"a" '(:ignore t :wk "apps")
"b" '(:ignore t :wk "buffer")
"bk" 'kill-buffer-and-window
"bK" 'jtd/kill-other-buffers
"bs" 'jtd/switch-to-scratch-buffer
"bY" 'jtd/copy-buffer
"f" '(:ignore t :wk "file")
"ff" '(find-file :wk "find file")
"fe" '(jtd/find-file-in-emacs :wk "find file in emacs.d")
"g" '(:ignore t :wk "git")
"h" '(:ignore t :wk "help")
"ha" 'apropos-command
"hf" 'helpful-function
"hk" 'helpful-key
"hm" 'helpful-macro
"ho" 'helpful-symbol
"hv" 'helpful-variable
"hx" 'helpful-command
"s" '(:ignore t :wk "search")
"sj" '(imenu :wk "jump")
"t" '(:ignore t :wk "tabs")
"T" '(:ignore t :wk "toggle")
"w" '(:ignore t :wk "window"))(general-define-key
:definer 'minor-mode
:states '(normal motion)
:keymaps 'outline-minor-mode
"]h" 'outline-next-visible-heading
"[h" 'outline-prev-visible-heading))
#+end_src** Which key
#+begin_src emacs-lisp
(use-package which-key
:hook (on-first-input . which-key-mode)
:custom
(which-key-idle-delay 1))
#+end_src** Hydra
#+begin_src emacs-lisp
(use-package hydra)
#+end_src* Evil
:PROPERTIES:
:header-args: :tangle lisp/init-evil.el
:END:** evil mode
#+BEGIN_SRC emacs-lisp
(use-package evil
:general
(jtd/leader-key
"wv" 'evil-window-vsplit
"ws" 'evil-window-split)
(general-imap "C-g" 'evil-normal-state)
:custom
((evil-want-integration t)
(evil-want-keybinding nil)
(evil-want-abbrev-expand-on-insert-exit nil)
(evil-respect-visual-line-mode t)
(evil-want-C-i-jump nil)
(evil-want-C-d-scroll t)
(evil-want-C-u-scroll t)
(evil-want-C-w-delete nil)
(evil-want-Y-yank-to-eol t)
(evil-undo-system 'undo-fu)
(evil-search-module 'evil-search-module 'evil-search) ;; enables gn
(evil-split-window-below t)
(evil-vsplit-window-right t)
(evil-auto-indent t)
(evil-want-C-w-in-emacs-state t))
:init
(evil-mode 1)
(evil-set-initial-state 'messages-buffer-mode 'normal)
(evil-set-initial-state 'dashboard-mode 'normal))
#+END_SRC** evil-collection
#+BEGIN_SRC emacs-lisp
(use-package evil-collection
:after evil
:config
(evil-collection-init))
#+END_SRC** Surround
#+begin_src emacs-lisp
(use-package evil-surround
:after evil
:hook
(on-first-input . global-evil-surround-mode))
#+end_src** Preview registers
#+begin_src emacs-lisp
(use-package evil-owl
:hook
(on-first-input . evil-owl-mode)
:custom
(evil-owl-max-string-length 500)
(evil-owl-display-method 'window))
#+end_src* UI
:PROPERTIES:
:header-args: :tangle lisp/init-ui.el
:END:** Theme
#+BEGIN_SRC emacs-lisp
(load-theme 'modus-vivendi t)
#+END_SRC** Font
#+begin_src emacs-lisp
(set-face-attribute 'default nil :font "Berkeley Mono" :height 160)
(set-face-attribute 'variable-pitch nil :font "Fira Sans" :height 160)
#+end_src** Highlight current line
#+begin_src emacs-lisp
(global-hl-line-mode 1)
#+end_src** Highlight indentation guides
#+begin_src emacs-lisp
(use-package highlight-indent-guides
:hook (prog-mode . highlight-indent-guides-mode)
:custom
(highlight-indent-guides-method 'character)
(highlight-indent-guides-responsive 'top))
#+end_src** Doom modeline
#+BEGIN_SRC emacs-lisp
(use-package doom-modeline
:hook
(on-init-ui . doom-modeline-mode)
:custom
(doom-modeline-buffer-encoding nil)
(doom-modeline-env-enable-python nil)
(doom-modeline-height 15))
#+END_SRC** All the icons
#+begin_src emacs-lisp
(use-package all-the-icons)
#+end_src** Icons in the terminal
#+begin_src emacs-lisp
(use-package icons-in-terminal
:straight (:host github :repo "seagle0128/icons-in-terminal.el")
:if (not (display-graphic-p))
:config
(defalias #'all-the-icons-insert #'icons-in-terminal-insert)
(defalias #'all-the-icons-insert-faicon #'icons-in-terminal-insert-faicon)
(defalias #'all-the-icons-insert-fileicon #'icons-in-terminal-insert-fileicon)
(defalias #'all-the-icons-insert-material #'icons-in-terminal-insert-material)
(defalias #'all-the-icons-insert-octicon #'icons-in-terminal-insert-octicon)
(defalias #'all-the-icons-insert-wicon #'icons-in-terminal-insert-wicon)
(defalias #'all-the-icons-icon-for-dir #'icons-in-terminal-icon-for-dir)
(defalias #'all-the-icons-icon-for-file #'icons-in-terminal-icon-for-file)
(defalias #'all-the-icons-icon-for-mode #'icons-in-terminal-icon-for-mode)
(defalias #'all-the-icons-icon-for-url #'icons-in-terminal-icon-for-url)
(defalias #'all-the-icons-icon-family #'icons-in-terminal-icon-family)
(defalias #'all-the-icons-icon-family-for-buffer #'icons-in-terminal-icon-family-for-buffer)
(defalias #'all-the-icons-icon-family-for-file #'icons-in-terminal-icon-family-for-file)
(defalias #'all-the-icons-icon-family-for-mode #'icons-in-terminal-icon-family-for-mode)
(defalias #'all-the-icons-icon-for-buffer #'icons-in-terminal-icon-for-buffer)
(defalias #'all-the-icons-faicon #'icons-in-terminal-faicon)
(defalias #'all-the-icons-octicon #'icons-in-terminal-octicon)
(defalias #'all-the-icons-fileicon #'icons-in-terminal-fileicon)
(defalias #'all-the-icons-material #'icons-in-terminal-material)
(defalias #'all-the-icons-wicon #'icons-in-terminal-wicon)
(defalias 'all-the-icons-default-adjust 'icons-in-terminal-default-adjust)
(defalias 'all-the-icons-color-icons 'icons-in-terminal-color-icons)
(defalias 'all-the-icons-scale-factor 'icons-in-terminal-scale-factor)
(defalias 'all-the-icons-icon-alist 'icons-in-terminal-icon-alist)
(defalias 'all-the-icons-dir-icon-alist 'icons-in-terminal-dir-icon-alist)
(defalias 'all-the-icons-weather-icon-alist 'icons-in-terminal-weather-icon-alist))
#+end_src** Ligatures
#+begin_src emacs-lisp
(use-package ligature
:straight (:host github :repo "mickeynp/ligature.el")
:hook (prog-mode . ligature-mode)
:config
(ligature-set-ligatures 't '("www" "ff" "fi" "ffi"))
(ligature-set-ligatures 'prog-mode '("|||>" "<|||" "<==>" "" "---" "-<<"
"<~~" "<~>" "<*>" "<||" "<|>" "<$>" "<==" "<=>" "<=<" "<->"
"<--" "<-<" "<<=" "<<-" "<<<" "<+>" ">" "###" "#_(" "..<"
"..." "+++" "/==" "///" "_|_" "www" "&&" "^=" "~~" "~@" "~="
"~>" "~-" "**" "*>" "*/" "||" "|}" "|]" "|=" "|>" "|-" "{|"
"[|" "]#" "::" ":=" ":>" ":<" "$>" "==" "=>" "!=" "!!" ">:"
">=" ">>" ">-" "-~" "-|" "->" "--" "-<" "<~" "<*" "<|" "<:"
"<$" "<=" "<>" "<-" "<<" "<+" "" "#{" "#[" "#:" "#=" "#!"
"##" "#(" "#?" "#_" "%%" ".=" ".-" ".." ".?" "+>" "++" "?:"
"?=" "?." "??" ";;" "/*" "/=" "/>" "//" "__" "~~" "(*" "*)"
"\\\\" "://")))
#+end_src** Pretty symbols
#+begin_src emacs-lisp
(global-prettify-symbols-mode 1)
#+end_src** Hide modeline
#+begin_src emacs-lisp
(use-package hide-mode-line
:commands hide-mode-line)
#+end_src** Show end of file
#+begin_src emacs-lisp
(use-package vi-tilde-fringe
:if (display-graphic-p)
:hook (prog-mode . vi-tilde-fringe-mode))
#+end_src** Emoji
#+begin_src emacs-lisp
(use-package emojify
:hook
(on-init-ui . global-emojify-mode)
:config
(delete 'mu4e-headers-mode emojify-inhibit-major-modes))
#+end_src** Fill column indicator
#+begin_src emacs-lisp
(use-package display-fill-column-indicator
:straight (:type built-in)
:hook
(prog-mode . display-fill-column-indicator-mode)
:custom
(fill-column 120))
#+end_src** Dashboard
#+begin_src emacs-lisp
(use-package dashboard
:demand t
:custom
(dashboard-projects-backend 'project-el)
(dashboard-set-heading-icons t)
(dashboard-set-file-icons t)
(dashboard-banner-logo-title nil)
(dashboard-set-footer nil)
(dashboard-items '((recents . 5)
(projects . 5)))
:config
(dashboard-setup-startup-hook))
#+end_src* Window management
:PROPERTIES:
:header-args: :tangle lisp/init-window.el
:END:** Disable built in
#+begin_src emacs-lisp
(tab-bar-mode -1)
(tab-line-mode -1)(global-unset-key (kbd "C-"))
#+end_src** Golden ratio
#+begin_src emacs-lisp
(use-package golden-ratio
:hook
(on-first-buffer . golden-ratio-mode)
:custom
(golden-ratio-exclude-modes '(treemacs-mode imenu-list-major-mode))
(golden-ratio-extra-commands
'(windmove-left
windmove-right
windmove-down
windmove-up
evil-window-left
evil-window-right
evil-window-up
evil-window-down
buf-move-left
buf-move-right
buf-move-up
buf-move-down
window-number-select
select-window
select-window-1
select-window-2
select-window-3
select-window-4
select-window-5
select-window-6
select-window-7
select-window-8
select-window-9)))
#+end_src** Transpose frame
#+begin_src emacs-lisp
(use-package transpose-frame
:general
(jtd/leader-key
"wt" '(transpose-frame :wk "transpose")
"wf" '(rotate-frame :wk "flip")))
#+end_src** Perspective
#+begin_src emacs-lisp
(use-package perspective
:demand
:after consult
:custom
(persp-state-default-file (expand-file-name ".persp" user-emacs-directory))
(persp-mode-prefix-key (kbd "C-c M-p"))
:general
(jtd/leader-key
"TAB" '(:ignore true :wk "tab")
"TAB TAB" 'persp-switch
"TAB `" 'persp-switch-last
"TAB d" 'persp-kill
"TAB h" 'persp-prev
"TAB l" 'persp-next
"TAB x" '((lambda () (interactive) (persp-kill (persp-current-name))) :wk "kill current")
"TAB X" '((lambda () (interactive) (persp-kill (persp-names))) :wk "kill all"))
:init
:config
(persp-mode)
(consult-customize consult--source-buffer :hidden t :default nil)
(add-to-list 'consult-buffer-sources persp-consult-source)
(add-hook 'kill-emacs-hook #'persp-state-save))
#+end_src* Navigation
:PROPERTIES:
:header-args: :tangle lisp/init-navigation.el
:END:** Ranger
#+begin_src emacs-lisp
(use-package ranger
:custom
(ranger-key "zp")
:general
(jtd/leader-key
"ar" 'ranger))
#+end_src** dired
#+begin_src emacs-lisp
(use-package dired
:straight (:type built-in)
:general
(jtd/leader-key
"ad" 'dired)
(general-nmap
"-" 'dired-jump)
(general-nmap dired-mode-map
"c" 'find-file)
:config
(require 'dired-x))
#+end_src** Treemacs
#+begin_src emacs-lisp
(use-package treemacs
:custom
((treemacs-project-follow-mode t)
(treemacs-follow-mode t)
(treemacs-filewatch-mode t))
:general
(jtd/leader-key
"fd" 'treemacs-find-file
"ft" 'treemacs))(use-package treemacs-evil
:after (treemacs evil))(use-package treemacs-icons-dired
:hook (dired-mode . treemacs-icons-dired-enable-once))(use-package treemacs-magit
:after (treemacs magit))
#+end_src* Completion
:PROPERTIES:
:header-args: :tangle lisp/init-completion.el
:END:** Ignore case
#+begin_src emacs-lisp
(setq read-buffer-completion-ignore-case t
read-file-name-completion-ignore-case t
completion-ignore-case t)
#+end_src** Vertico
#+begin_src emacs-lisp
(use-package vertico
:demand t
:straight (:files (:defaults "extensions/*"))
:bind (:map vertico-map
("C-j" . vertico-next)
("C-k" . vertico-previous)
("C-l" . vertico-insert)
:map minibuffer-local-map
("M-h" . backward-kill-word))
:custom
(vertico-cycle t)
:config
(vertico-mode 1)
(advice-add #'vertico--format-candidate :around
(lambda (orig cand prefix suffix index _start)
(setq cand (funcall orig cand prefix suffix index _start))
(concat
(if (= vertico--index index)
(propertize "» " 'face 'vertico-current)
" ")
cand))))(use-package vertico-directory
:demand t
:after vertico
:straight nil
:bind (:map vertico-map
("RET" . vertico-directory-enter)
("DEL" . vertico-directory-delete-char)
("M-DEL" . vertico-directory-delete-word))
:hook (rfn-eshadow-update-overlay . vertico-directory-tidy))
#+end_src** Save history
#+begin_src emacs-lisp
(use-package savehist
:demand t
:after vertico
:hook
(on-first-input . savehist-mode))
#+end_src** Consult
#+begin_src emacs-lisp
(use-package consult
:general
(jtd/leader-key
"bb" 'consult-buffer
"fr" 'consult-recent-file
"pb" 'consult-project-buffer
"so" 'consult-outline
"si" 'consult-isearch
"sr" 'consult-ripgrep
"ss" 'consult-line)
:init
(setq xref-show-xrefs-function #'consult-xref
xref-show-definitions-function #'consult-xref)
:config
(setq consult-project-root-function #'project-root))
#+end_src** Embark
#+begin_src emacs-lisp
(use-package embark
:bind
(("C-." . embark-act)
("C-;" . embark-dwim)
("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)
:demand t
:hook
(embark-collect-mode . consult-preview-at-point-mode))
#+end_src** Marginalia
#+begin_src emacs-lisp
(use-package marginalia
:after vertico
:hook
(on-first-input . marginalia-mode))
#+end_src** Better search matching
#+begin_src emacs-lisp
(use-package fussy
:demand t
:after vertico
:config
(push 'fussy completion-styles)
(setq completion-category-defaults nil
completion-category-overrides nil))(use-package orderless
:demand t
:after fussy
:commands orderless-filter
:init
(setq fussy-filter-fn 'fussy-filter-orderless))
#+end_src** Corfu
#+begin_src emacs-lisp
(use-package corfu
:hook ((prog-mode . corfu-mode)
(org-mode . corfu-mode))
:bind
(:map corfu-map
("C-j" . corfu-next)
("C-k" . corfu-previous))
:general
(evil-insert-state-map "C-k" nil)
:custom
(corfu-auto nil)
(corfu-cycle t)
(corfu-min-width 80)
(corfu-max-width corfu-min-width)
(corfu-preselect-first t)
:init
(defun corfu-enable-always-in-minibuffer ()
"Enable Corfu in the minibuffer if Vertico/Mct are not active."
(unless (or (bound-and-true-p mct--active) ; Useful if I ever use MCT
(bound-and-true-p vertico--input))
(setq-local corfu-auto nil) ; Ensure auto completion is disabled
(corfu-mode 1)))
(add-hook 'minibuffer-setup-hook #'corfu-enable-always-in-minibuffer 1))(use-package corfu-terminal
:if (not (display-graphic-p))
:config
(corfu-terminal-mode +1))(use-package cape
:init
;; Add `completion-at-point-functions', used by `completion-at-point'.
;; (add-to-list 'completion-at-point-functions #'cape-dabbrev)
(add-to-list 'completion-at-point-functions #'cape-file)
;;(add-to-list 'completion-at-point-functions #'cape-history)
;;(add-to-list 'completion-at-point-functions #'cape-keyword)
;;(add-to-list 'completion-at-point-functions #'cape-tex)
;;(add-to-list 'completion-at-point-functions #'cape-sgml)
;;(add-to-list 'completion-at-point-functions #'cape-rfc1345)
;;(add-to-list 'completion-at-point-functions #'cape-abbrev)
;;(add-to-list 'completion-at-point-functions #'cape-ispell)
;;(add-to-list 'completion-at-point-functions #'cape-dict)
;;(add-to-list 'completion-at-point-functions #'cape-symbol)
;;(add-to-list 'completion-at-point-functions #'cape-line)
)
#+end_src** Kind icon
#+begin_src emacs-lisp
(use-package kind-icon
:demand t
:after corfu
:custom
(kind-icon-default-face 'corfu-default)
:config
(add-to-list 'corfu-margin-formatters #'kind-icon-margin-formatter))
#+end_src* Search
:PROPERTIES:
:header-args: :tangle lisp/init-search.el
:END:** Avy
#+begin_src emacs-lisp
(use-package avy
:general
(jtd/leader-key
"SPC" 'evil-avy-goto-subword-1
"j" '(:ignore t :wk "jump")
"jJ" 'evil-avy-goto-char-2
"jj" 'evil-avy-goto-char
"jl" 'evil-avy-goto-line
"jw" 'evil-avy-goto-subword-1))
#+end_src* Org
:PROPERTIES:
:header-args: :tangle lisp/init-org.el
:END:** Org mode
#+begin_src emacs-lisp
(use-package org
:defer t
:hook
(org-mode . variable-pitch-mode)
(org-mode . visual-line-mode)
:general
(jtd/leader-key
"o" '(:ignore t :wk "org")
"oa" 'org-agenda-list
"oc" 'org-capture
"om" 'org-tags-view
"oo" 'org-agenda
"ot" 'org-todo-list)
:custom
(org-startup-indented t)
(org-agenda-files '("~/org/inbox.org"
"~/org/projects.org"
"~/org/tickler.org"))
(org-refile-targets '(("~/org/projects.org" :maxlevel . 3)
("~/org/someday.org" :level . 1)
("~/org/tickler.org" :maxlevel . 2)))
(org-todo-keywords '((sequence "TODO(t)" "WAITING(w)" "|" "DONE(d)" "CANCELLED(c)")))
:config
(jtd/local-leader-key :keymaps 'org-mode-map
"!" 'org-time-stamp-inactive
"'" 'org-edit-special
"*" 'org-ctrl-c-star
"," 'org-ctrl-c-ctrl-c
"-" 'org-ctrl-c-minus
"." 'org-time-stamp
"/" 'org-sparse-tree
":" 'org-set-tags
"A" 'org-archive-subtree
"D" 'org-insert-drawer
"H" 'org-shiftleft
"I" 'org-clock-in
"J" 'org-shiftdown
"K" 'org-shiftup
"L" 'org-shiftright
"N" 'widen
"O" 'org-clock-out
"P" 'org-set-property
"R" 'org-refile
"Sh" 'org-promote-subtree
"Sj" 'org-move-subtree-down
"Sk" 'org-move-subtree-up
"Sl" 'org-demote-subtree
"T" 'org-show-todo-tree
"^" 'org-sort
"a" 'org-agenda
"b" 'org-tree-to-indirect-buffer
"c" 'org-capture
"d" 'org-deadline
"e" 'org-export-dispatch
"f" 'org-set-effort
"hI" 'org-insert-heading
"hi" 'org-insert-heading-after-current
"hs" 'org-insert-subheading
"ia" 'org-attach
"if" 'org-footnote-new
"il" 'org-insert-link
"l" 'org-open-at-point
"n" 'org-narrow-to-subtree
"q" 'org-clock-cancel
"s" 'org-schedule
"tE" 'org-table-export
"tH" 'org-table-move-column-left
"tI" 'org-table-import
"tJ" 'org-table-move-row-down
"tK" 'org-table-move-row-up
"tL" 'org-table-move-column-right
"tN" 'org-table-create-with-table.el
"ta" 'org-table-align
"tb" 'org-table-blank-field
"tc" 'org-table-convert
"tdc" 'org-table-delete-column
"tdr" 'org-table-kill-row
"te" 'org-table-eval-formula
"th" 'org-table-previous-field
"tiH" 'org-table-hline-and-move
"tic" 'org-table-insert-column
"tih" 'org-table-insert-hline
"tir" 'org-table-insert-row
"tj" 'org-table-next-row
"tl" 'org-table-next-field
"tn" 'org-table-create
"tr" 'org-table-recalculate
"ts" 'org-table-sort-lines
"ttf" 'org-table-toggle-formula-debugger
"tto" 'org-table-toggle-coordinate-overlays
"tw" 'org-table-wrap-region
"RET" 'org-ctrl-c-ret)
(jtd/local-leader-key
:definer 'minor-mode
:keymaps 'org-src-mode
"c" 'org-edit-src-exit
"a" 'org-edit-src-abort
"k" 'org-edit-src-abort)
(setq org-capture-templates
`(("b" "Books")
("bf" "Finished book" table-line
(file+headline ,(concat org-directory "/books.org") "Finished")
"| %^{Title} | %^{Author} | %u |")
("br" "Book to read" entry
(file+headline ,(concat org-directory "/books.org") "To Read")
"* %i%?\n")
("g" "GTD")
("gt" "Todo [inbox]" entry
(file+headline ,(concat org-directory "/inbox.org") "Tasks")
"* TODO %i%?")
("gT" "Tickler" entry
(file+headline ,(concat org-directory "/tickler.org") "Tickler")
"* %i%? \n %U")
("i" "Ideas")
("ib" "Blog idea" entry
(file ,(concat org-directory "/blog-ideas.org"))
"* %?\n")
)))
#+end_src** Evil integration
#+begin_src emacs-lisp
(use-package evil-org
:hook (org-mode . evil-org-mode)
:config
(require 'evil-org-agenda)
(evil-org-agenda-set-keys)
(evil-org-set-key-theme '(textobjects
insert
navigation
additional
shift
todo
heading)))
#+end_src** Structure templates
#+begin_src emacs-lisp
(use-package org-tempo
:after org
:straight nil
:config
(add-to-list 'org-structure-template-alist '("el" . "src emacs-lisp"))
(add-to-list 'org-structure-template-alist '("py" . "src python"))
(add-to-list 'org-structure-template-alist '("sh" . "src shell")))
#+end_src** Modern
#+begin_src emacs-lisp
(use-package org-modern
:hook
(org-mode . org-modern-mode))
#+end_src* Writing
:PROPERTIES:
:header-args: :tangle lisp/init-writing.el
:END:** Writeroom
#+begin_src emacs-lisp
(use-package writeroom-mode
:general
(jtd/leader-key "Tw" 'writeroom-mode))
#+end_src** Darkroom
#+begin_src emacs-lisp
(use-package darkroom
:general
(jtd/leader-key "Td" 'darkroom-tentative-mode))
#+end_src** Spelling
#+begin_src emacs-lisp
(use-package flyspell
:hook
(text-mode . flyspell-mode)
(prog-mode . flyspell-prog-mode)
:custom
(ispell-program-name "aspell"))(use-package flyspell-correct
:after flyspell
:bind (:map flyspell-mode-map
("C-;" . flyspell-correct-wrapper)))
#+end_src* Programming
:PROPERTIES:
:header-args: :tangle lisp/init-prog.el
:END:** Line numbers
#+begin_src emacs-lisp
(add-hook 'prog-mode-hook #'display-line-numbers-mode)
(add-hook 'conf-mode-hook #'display-line-numbers-mode)
#+end_src** Version control
*** magit
#+begin_src emacs-lisp
(use-package magit
:general
(jtd/leader-key
"gb" 'magit-blame
"gl" 'magit-log
"gg" 'magit-status
"gG" 'magit-status-here))
#+end_src*** Time machine
#+begin_src emacs-lisp
(use-package git-timemachine
:straight (:package "git-timemachine"
:type git
:host nil
:repo "https://codeberg.org/pidu/git-timemachine.git")
:hook
(git-time-machine-mode . evil-normalize-keymaps)
:custom
(git-timemachine-show-minibuffer-details t)
:general
(jtd/leader-key
"gt" 'git-timemachine)
(git-timemachine-mode-map
"C-k" 'git-timemachine-show-previous-revision
"C-j" 'git-timemachine-show-next-revision
"q" 'git-timemachine-quit))
#+end_src*** Highlight uncommitted changes
#+begin_src emacs-lisp
(use-package diff-hl
:hook
((prog-mode text-mode vc-dir-mode) . diff-hl-mode)
(magit-pre-refresh . diff-hl-magit-pre-refresh)
(magit-post-refresh . diff-hl-magit-post-refresh))
#+end_src*** smerge
#+begin_src emacs-lisp
(use-package smerge-mode
:straight (:type built-in)
:after hydra
:general
(jtd/leader-key "gm" 'smerge-hydra/body)
:hook
(magit-diff-visit-file . (lambda ()
(when smerge-mode
(smerge-hydra/body))))
:init
(defhydra smerge-hydra (:hint nil
:pre (smerge-mode 1)
:post (smerge-auto-leave))
"
╭────────┐
Movement Keep Diff Other │ smerge │
╭─────────────────────────────────────────────────┴────────╯
^_g_^ [_b_] base [_<_] upper/base [_C_] Combine
^_C-k_^ [_u_] upper [_=_] upper/lower [_r_] resolve
^_k_ ↑^ [_l_] lower [_>_] base/lower [_R_] remove
^_j_ ↓^ [_a_] all [_H_] hightlight
^_C-j_^ [_RET_] current [_E_] ediff ╭──────────
^_G_^ │ [_q_] quit"
("g" (progn (goto-char (point-min)) (smerge-next)))
("G" (progn (goto-char (point-max)) (smerge-prev)))
("C-j" smerge-next)
("C-k" smerge-prev)
("j" next-line)
("k" previous-line)
("b" smerge-keep-base)
("u" smerge-keep-upper)
("l" smerge-keep-lower)
("a" smerge-keep-all)
("RET" smerge-keep-current)
("\C-m" smerge-keep-current)
("<" smerge-diff-base-upper)
("=" smerge-diff-upper-lower)
(">" smerge-diff-base-lower)
("H" smerge-refine)
("E" smerge-ediff)
("C" smerge-combine-with-next)
("r" smerge-resolve)
("R" smerge-kill-current)
("q" nil :color blue)))
#+end_src** Project management
#+begin_src emacs-lisp
(use-package project
:straight (:type built-in)
:general
(jtd/leader-key
"p" '(:ignore t :wk "project")
"pD" 'project-dired
"pf" 'project-find-file
"pk" 'project-kill-buffers
"pp" 'project-switch-project))
#+end_src** Comments
#+begin_src emacs-lisp
(use-package evil-commentary
:hook (prog-mode . evil-commentary-mode))
#+end_src** Treat _ as part of a word like vim
#+begin_src emacs-lisp
(add-hook 'prog-mode-hook (lambda () (modify-syntax-entry ?_ "w")))
#+end_src** Delete trailing white space
#+begin_src emacs-lisp
(add-hook 'before-save-hook
(lambda ()
(when (derived-mode-p 'prog-mode)
(whitespace-cleanup))))
#+end_src** Terminal emulation
#+begin_src emacs-lisp
(use-package vterm
:general
(jtd/leader-key
"'" 'vterm))(use-package vterm-toggle
:general
(jtd/leader-key
"`" 'vterm-toggle-cd))
#+end_src** Completion
#+begin_src emacs-lisp
(use-package company
:hook (prog-mode . company-mode)
:custom
(company-minimum-prefix-length 1))
#+end_src** Snippets
#+begin_src emacs-lisp
(use-package yasnippet
:config
(yas-global-mode 1))(use-package yasnippet-snippets
:after yasnippet)(use-package company-yasnippet
:straight (:type built-in))
#+end_src** Formatting
#+begin_src emacs-lisp
(use-package apheleia
:commands apheleia-mode)
#+end_src** Tree sitter
#+begin_src emacs-lisp
(use-package tree-sitter
:hook
(on-first-buffer . global-tree-sitter-mode)
(tree-sitter-after-on . tree-sitter-hl-mode))(use-package tree-sitter-langs
:defer 1)
#+end_src** Rainbow Delimiters
#+begin_src emacs-lisp
(use-package rainbow-delimiters
:hook (prog-mode . rainbow-delimiters-mode))
#+end_src** Smartparens
#+begin_src emacs-lisp
(use-package smartparens
:hook (prog-mode . smartparens-mode))
#+end_src** Copilot
#+begin_src emacs-lisp
(use-package copilot
:straight (:host github :repo "zerolfx/copilot.el"
:files ("dist" "*.el"))
:general
(jtd/leader-key
"c" '(:ignore t :wk "copilot")
"cx" 'copilot-clear-overlay
"cc" 'copilot-complete)
(copilot-completion-map
"TAB" 'copilot-accept-completion)
:init
(with-eval-after-load 'company
;; disable inline previews
(delq 'company-preview-if-just-one-frontend company-frontends)))
#+end_src** Docker
#+begin_src emacs-lisp
(use-package dockerfile-mode
:defer t)
#+end_src** Lisps
*** Lispy
#+begin_src emacs-lisp
(use-package lispy
:hook (emacs-lisp-mode . lispy-mode))
#+end_src*** Lispyville
#+begin_src emacs-lisp
(use-package lispyville
:hook (lispy-mode . lispyville-mode)
:config
(lispyville-set-key-theme '((operators normal)
c-w
(prettify insert)
(atom-movement t)
slurp/barf-lispy
additional
additional-insert)))
#+end_src** Eglot
#+begin_src emacs-lisp
(defun jtd/eglot-cap-config ()
(setq-local completion-at-point-functions
(list (cape-super-capf
#'eglot-completion-at-point
(cape-company-to-capf #'company-yasnippet)))))(use-package eglot
:defer 2
:hook
(before-save . eglot-format-buffer)
(eglot-managed-mode . jtd/eglot-cap-config)
:custom
(eglot-confirm-server-initiated-edits nil)
:general
(jtd/local-leader-key eglot-mode-map
"l" '(:ignore t :wk "lsp")
"la" 'eglot-code-actions
"lf" 'eglot-format
"lh" 'eldoc
"lr" 'eglot-rename))
#+end_src** Breadcrumb
#+begin_src emacs-lisp
(cl-defgeneric project-name (project)
"A human-readable name for the project.
Nominally unique, but not enforced."
(file-name-base (directory-file-name (project-root project))))(use-package breadcrumb
:straight (:repo "joaotavora/breadcrumb"
:host github))
#+end_src** Rust
#+begin_src emacs-lisp
(use-package rustic
:hook
(rustic-mode . eglot-ensure)
:custom
(rustic-lsp-client 'eglot)
:general
(jtd/local-leader-key
:keymaps 'rustic-mode-map
"=" 'rustic-cargo-fmt
"c" '(:ignore t :wk "cargo")
"cC" 'rustic-cargo-clippy
"ca" 'rustic-cargo-add
"cb" 'rustic-cargo-build
"cc" 'rustic-cargo-check
"cd" 'rustic-cargo-doc
"cf" 'rustic-cargo-clippy-fix
"co" 'rustic-cargo-outdated
"cu" 'rustic-cargo-upgrade
"cx" 'rustic-cargo-run
"t" '(:ignore t :wk "test")
"ta" 'rustic-cargo-test
"tt" 'rustic-cargo-current-test))
#+end_src** Elixir
#+begin_src emacs-lisp
(use-package elixir-mode
:after eglot
:hook
(elixir-mode . eglot-ensure)
:config
(add-to-list 'eglot-server-programs '(elixir-mode "~/.emacs.d/elixir-ls/release/language_server.sh")))(defun jtd/elixir-format-on-save ()
(add-hook 'before-save-hook 'elixir-format nil t))(use-package elixir-format
:after elixir-mode
:straight nil
:hook
(elixir-mode . jtd/elixir-format-on-save))
#+end_src** YAML
#+begin_src emacs-lisp
(use-package yaml-mode
:hook
(yaml-mode . display-line-numbers-mode)
:commands yaml-mode)
#+end_src* Apps
:PROPERTIES:
:header-args: :tangle lisp/init-apps.el
:END:** Notes
#+begin_src emacs-lisp
(use-package deft
:general
(jtd/leader-key
"n" '(:ignore t :wk "notes")
"nf" 'deft-find-file
"nv" 'deft)
(jtd/local-leader-key :keymaps 'deft-mode-map
"c" 'deft-filter-clear
"d" 'deft-delete-file
"i" 'deft-toggle-incremental-search
"n" 'deft-new-file
"r" 'deft-rename-file)
:config
(evil-set-initial-state 'deft-mode 'insert)(setq deft-default-extension "org"
deft-directory "~/notes"
deft-use-filename-as-title nil
deft-use-filter-string-for-filename t))
#+end_src*** mu4e
#+begin_src emacs-lisp
(use-package mu4e
:straight nil
:custom
(mu4e-attachment-dir (expand-file-name "~/Downloads"))
(mu4e-headers-fields '((:human-date . 12)
(:flags . 6)
(:from . 22)
(:subject)))
:general
(jtd/leader-key
"am" 'mu4e))
#+end_src*** org-msg
#+begin_src emacs-lisp
(use-package org-msg
:after mu4e)
#+end_src** RSS
#+begin_src emacs-lisp
(use-package elfeed
:custom
(elfeed-sort-order 'ascending)
:general
(jtd/leader-key
"af" 'elfeed))(use-package elfeed-protocol
:after elfeed
:config
(elfeed-protocol-enable))
#+end_src** IRC
#+begin_src emacs-lisp
(use-package circe
:custom
(circe-reduce-lurker-spam t)
:general
(jtd/leader-key
"ac" 'circe)
:config
(enable-circe-color-nicks))
#+end_src** OpenAI
*** ChatGPT
#+begin_src emacs-lisp
(use-package chatgpt-shell
:straight (:host github :repo "xenodium/chatgpt-shell")
:custom
(chatgpt-shell-openai-key
(lambda ()
(auth-source-pick-first-password :host "api.openai.com")))
:commands chatgpt-shell)
#+end_src*** Dall-E
#+begin_src emacs-lisp
(use-package dall-e-shell
:straight (:host github :repo "xenodium/chatgpt-shell")
:custom
(dall-e-shell-openai-key
(lambda ()
(auth-source-pick-first-password :host "api.openai.com")))
:commands dall-e-shell)
#+end_src