An emacs configuration for both GUI and terminal. Instructions on setting up emacsclient for the terminal config can be found here.
- Initial Setup
- Common Functions
- Common General Configuration
- Common Packages
- GUI Config
- Terminal Config
Before opening emacs with this configuration there are a few set up tasks that need to be performed:
- Install nerd-fonts: https://github.com/rainstormstudio/nerd-icons.el
- Create the following directories in
./emacs.d
org-directory
org-directory/denote
backups
- Configure environment variables: https://github.com/amodelbello/dot-env.el example
.env
file: .env.example
These are functions needed by both configurations during initial startup.
(defun amo/load-straight (&optional base-dir)
(defvar bootstrap-version)
(let* ((base-dir (or base-dir user-emacs-directory))
(bootstrap-file
(expand-file-name
(concat user-emacs-directory "straight/repos/straight.el/bootstrap.el") base-dir))
(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)
(straight-use-package 'org))
(defun amo/load-customize (&optional base-dir)
(defvar custom-file)
(let* ((base-dir (or base-dir user-emacs-directory)))
(setq custom-file (concat base-dir "customize.el"))
(unless (file-exists-p custom-file)
(write-region "" "" custom-file))
(load custom-file)))
(defun amo/load-config-file (config-file)
(org-babel-load-file (expand-file-name (concat user-emacs-directory config-file))))
(use-package emacs
:config
;; Use C-h for delete-backward-char
(global-set-key (kbd "C-h") 'delete-backward-char)
;; Set custom prefix key ("C-z")
(define-prefix-command 'z-map)
(global-set-key (kbd "C-z") 'z-map)
(global-display-line-numbers-mode 0)
(fset 'yes-or-no-p 'y-or-n-p)
(recentf-mode 1)
(savehist-mode 1)
(whitespace-mode -1)
(delete-selection-mode 1)
(blink-cursor-mode 0)
(electric-pair-mode 1)
(visual-line-mode 1)
(put 'narrow-to-region 'disabled nil)
(setq save-interprogram-paste-before-kill t
vc-follow-symlinks nil
require-final-newline t
enable-recursive-minibuffers t
ispell-program-name (dot-env-get 'ISPELL_PATH "/usr/bin/ispell"))
(setq-default indent-tabs-mode nil
global-tab-line-mode nil
tab-line-mode nil
tab-bar-mode nil
line-spacing 0.3
fill-column 100
sentence-end-double-space nil
whitespace-line-column 110)
;; Blink modeline instead of ring bell
(setq ring-bell-function
(lambda ()
(let ((orig-fg (face-foreground 'mode-line)))
(set-face-foreground 'mode-line "Magenta")
(run-with-idle-timer 0.1 nil
(lambda (fg) (set-face-foreground 'mode-line fg))
orig-fg))))
;; Un-highlight region after mark jump
(defun amo/exchange-point-and-mark ()
"Deactivates mark after exchanging point and mark"
(interactive)
(exchange-point-and-mark)
(deactivate-mark))
;; Transpose chars and words backwards
(defun amo/transpose-chars-backwards ()
"Just like transpose-chars but goes the other way"
(interactive)
(transpose-chars -1))
(defun amo/transpose-words-backwards ()
"Just like transpose-words but goes the other way"
(interactive)
(transpose-words -1))
;; Move char after point to end of next word
(defun amo/transpose-char-to-end-of-next-word ()
"Move char at point to the end of the next word.
Use case is to push closing parentheses out to contain subsequent characters
when a function is typed and the closing parenthesis is automatically added.
Skips over periods, quotes, and closing parentheses."
(interactive)
;; helpers
(defun amo/should-move-forward-one-char (c)
(or
(char-equal (following-char) ?\")
(char-equal (following-char) ?\))))
(defun amo/should-move-forward-one-word (c)
(char-equal (following-char) ?.))
(defun amo/should-move (c)
(or
(amo/should-move-forward-one-char c)
(amo/should-move-forward-one-word c)))
(forward-char)
(let ((start (point))
(end nil))
(save-excursion
(forward-word)
(while (amo/should-move (following-char))
(if (amo/should-move-forward-one-char (following-char))
(forward-char)
(forward-word)))
(setq end (point)))
(transpose-subr 'forward-char (- end start)))
(backward-char))
;; Move lines up and down
(defmacro amo/save-column (&rest body)
`(let ((column (current-column)))
(unwind-protect
(progn ,@body)
(move-to-column column))))
(put 'save-column 'lisp-indent-function 0)
(defun amo/move-line-up ()
(interactive)
(amo/save-column
(transpose-lines 1)
(forward-line -2)))
(defun amo/move-line-down ()
(interactive)
(amo/save-column
(forward-line 1)
(transpose-lines 1)
(forward-line -1)))
;; Toggle capitalization of character at point
(defun amo/toggle-capitalization ()
"Toggle the capitalization of the character at point."
(interactive)
(let ((char (char-after)))
(cond ((eq char (upcase char)) (progn (amo/downcase-char 1) (forward-char)))
((eq char (downcase char)) (progn (upcase-char 1) (forward-char)))
(t (message "No character at point.")))))
(defun amo/downcase-char (arg)
"Lowercasify ARG chars starting from point. Point doesn't move."
(interactive "p")
(save-excursion
(downcase-region (point) (progn (forward-char arg) (point)))))
(defun amo/toggle-line-numbers ()
"Toggle the display of line numbers"
(interactive)
(if (eq nil global-display-line-numbers-mode)
(global-display-line-numbers-mode 1)
(global-display-line-numbers-mode 0)))
:bind (("C-z l" . amo/toggle-line-numbers)
("M-'" . end-of-visual-line)
("C-x C-x" . amo/exchange-point-and-mark)
("C-S-t" . amo/transpose-chars-backwards)
("M-T" . amo/transpose-words-backwards)
("C-S-f" . amo/transpose-char-to-end-of-next-word)
("M-z" . zap-up-to-char)))
(add-hook 'before-save-hook 'amo/whitespace-cleanup)
(add-hook 'text-mode-hook 'flyspell-mode)
(add-hook 'prog-mode-hook (lambda () (flyspell-mode -1)))
(use-package dired
:config (setq dired-kill-when-opening-new-dired-buffer t
dired-listing-switches "-al")
;; from https://www.emacswiki.org/emacs/DiredSortDirectoriesFirst
(defun mydired-sort ()
"Sort dired listings with directories first."
(save-excursion
(let (buffer-read-only)
(forward-line 2) ;; beyond dir. header
(sort-regexp-fields t "^.*$" "[ ]*." (point) (point-max)))
(set-buffer-modified-p nil)))
(defadvice dired-readin
(after dired-after-updating-hook first () activate)
"Sort dired listings with directories first before adding marks."
(mydired-sort))
:hook ((dired-mode . dired-hide-details-mode))
:bind (:map dired-mode-map
("C-o" . nil)))
;; Copy whole line to kill ring when no active region
(defadvice kill-ring-save (before slick-copy activate compile)
"When called interactively with no active region, copy a single line instead."
(interactive
(if mark-active
(list (region-beginning) (region-end))
(message "Copied line")
(list (line-beginning-position) (line-beginning-position 2)))))
- Repo: https://github.com/minad/vertico
- Description: Performant and minimalistic vertical completion UI based on the default completion system.
(use-package vertico
:straight (:files (:defaults "extensions/*"))
:bind (:map vertico-map
("C-j" . vertico-directory-enter)
("DEL" . vertico-directory-delete-char)
("M-DEL" . vertico-directory-delete-word))
:hook (rfn-eshadow-update-overlay . vertico-directory-tidy)
:init
(vertico-mode))
- Repo: https://github.com/oantolin/embark
- Description: Emacs Mini-Buffer Actions Rooted in Keymaps
(use-package embark
:straight t
:bind (("C-." . embark-act)
("C-S-h B" . embark-bindings)
:map flyspell-mode-map
("C-." . nil))
:init
(setq prefix-help-command #'embark-prefix-help-command)
(add-hook 'eldoc-documentation-functions #'embark-eldoc-first-target)
:config
(add-to-list 'display-buffer-alist
'("\\`\\*Embark Collect \\(Live\\|Completions\\)\\*"
nil
(window-parameters (mode-line-format . none))))
(defun embark-which-key-indicator ()
"An embark indicator that displays keymaps using which-key.
The which-key help message will show the type and value of the
current target followed by an ellipsis if there are further
targets."
(lambda (&optional keymap targets prefix)
(if (null keymap)
(which-key--hide-popup-ignore-command)
(which-key--show-keymap
(if (eq (plist-get (car targets) :type) 'embark-become)
"Become"
(format "Act on %s '%s'%s"
(plist-get (car targets) :type)
(embark--truncate-target (plist-get (car targets) :target))
(if (cdr targets) "…" "")))
(if prefix
(pcase (lookup-key keymap prefix 'accept-default)
((and (pred keymapp) km) km)
(_ (key-binding prefix 'accept-default)))
keymap)
nil nil t (lambda (binding)
(not (string-suffix-p "-argument" (cdr binding))))))))
(setq embark-indicators
'(embark-which-key-indicator
embark-highlight-indicator
embark-isearch-highlight-indicator))
(defun embark-hide-which-key-indicator (fn &rest args)
"Hide the which-key indicator immediately when using the completing-read prompter."
(which-key--hide-popup-ignore-command)
(let ((embark-indicators
(remq #'embark-which-key-indicator embark-indicators)))
(apply fn args)))
(advice-add #'embark-completing-read-prompter
:around #'embark-hide-which-key-indicator))
(use-package embark-consult
:straight t
:hook
(embark-collect-mode . consult-preview-at-point-mode))
- Repo: https://github.com/minad/marginalia
- Description: Enable rich annotations in the minibuffer
(use-package marginalia
:straight t
:init
(marginalia-mode))
- Repo: https://github.com/minad/consult
- Description: Search and navigation commands based on the Emacs completion function completing-read
;; Example configuration for Consult
(use-package consult
:straight t
;; Replace bindings. Lazily loaded due by `use-package'.
:bind (("C-s" . consult-line)
("C-c m" . consult-man)
("C-c i" . consult-info)
([remap Info-search] . consult-info)
("C-x b" . consult-buffer)
("C-x 4 b" . consult-buffer-other-window)
("C-x r b" . consult-bookmark)
("s-r" . consult-recent-file)
("M-y" . consult-yank-pop)
("M-g g" . consult-goto-line)
("M-g o" . consult-outline)
("M-g m" . consult-mark)
("M-g k" . consult-global-mark)
("M-g i" . consult-imenu)
("M-g I" . consult-imenu-multi)
("M-s d" . consult-find)
("M-s D" . consult-locate)
("M-s g" . consult-grep)
("M-s G" . consult-git-grep)
("M-s r" . consult-ripgrep)
("M-s e" . consult-isearch-history))
;; Enable automatic preview at point in the *Completions* buffer. This is
;; relevant when you use the default completion UI.
:hook (completion-list-mode . consult-preview-at-point-mode)
;; The :init configuration is always executed (Not lazy)
:init
;; Optionally configure the register formatting. This improves the register
;; preview for `consult-register', `consult-register-load',
;; `consult-register-store' and the Emacs built-ins.
(setq register-preview-delay 0.5
register-preview-function #'consult-register-format)
;; Optionally tweak the register preview window.
;; This adds thin lines, sorting and hides the mode line of the window.
(advice-add #'register-preview :override #'consult-register-window)
;; Use Consult to select xref locations with preview
(setq xref-show-xrefs-function #'consult-xref
xref-show-definitions-function #'consult-xref)
;; Configure other variables and modes in the :config section,
;; after lazily loading the package.
: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 "M-."
:preview-key '(:debounce 0.4 any)))
- Repo: https://github.com/oantolin/orderless
- Description: Emacs completion style that matches multiple regexps in any order
(use-package orderless
:straight t
:config
(setq completion-styles '(orderless basic)
completion-category-overrides '((file (styles basic partial-completion)))))
- Repo: https://github.com/justbur/emacs-which-key
- Description: Emacs package that displays available keybindings in popup
(use-package which-key
:straight t
:config
(which-key-mode))
- Repo: https://github.com/abo-abo/ace-window
- Description: Quickly switch windows in Emacs
(use-package ace-window
:straight t
:bind
(("C-o" . ace-window)
("C-x o" . ace-window))
:config
(setq aw-scope 'frame
aw-dispatch-always nil
aw-keys '(?j ?k ?d ?s ?a ?g ?h ?k ?l)))
- Repo: https://github.com/Malabarba/aggressive-indent-mode
- Description: Emacs minor mode that keeps your code always indented
(use-package aggressive-indent
:straight t
:config
(global-aggressive-indent-mode 1)
(add-to-list 'aggressive-indent-excluded-modes 'html-mode)
(add-to-list 'aggressive-indent-excluded-modes 'python-ts-mode))
- Repo: https://github.com/abo-abo/avy
- Description: Jumping to visible text using a char-based decision tree
(use-package avy
:straight t
:bind (("C-;" . avy-goto-char-2)
:map org-mode-map
("C-'" . nil)
:map flyspell-mode-map
("C-;" . nil)))
- Repo: https://github.com/bbatsov/crux
- Docs: https://emacsredux.com/blog/2016/01/30/crux
- Description: A Collection of Ridiculously Useful eXtensions for Emacs
(use-package crux
:straight t
:bind
(("s-o" . crux-smart-open-line-above)
("M-o" . crux-smart-open-line)
("C-c D" . crux-delete-file-and-buffer)
("C-c d" . crux-duplicate-current-line-or-region)
("C-c M-d" . crux-duplicate-and-comment-current-line-or-region)
("C-c r" . crux-rename-file-and-buffer)
("s-j" . crux-top-join-line)
("s-k" . crux-kill-whole-line)
("<C-backspace>" . crux-kill-line-backwards)))
- Repo: https://github.com/radian-software/el-patch
- Description: ✨ Future-proof your Emacs Lisp customizations!
(use-package el-patch
:straight t)
- Repo: https://github.com/magnars/expand-region.el
- Description: Emacs extension to increase selected region by semantic units.
(use-package expand-region
:straight t
:bind (("C-=" . er/expand-region)
("C--" . er/contract-region)))
- Repo: https://codeberg.org/ideasman42/emacs-idle-highlight-mode
- Description: Simple symbol highlighting package for Emacs
(use-package idle-highlight-mode
:straight t
:config
(setq idle-highlight-idle-time 0.2
idle-highlight-exclude-point t)
:hook
((prog-mode text-mode) . idle-highlight-mode))
- Repo: https://github.com/lewang/jump-char
- Description: Navigation by character occurrence
(use-package jump-char
:straight (:host github :repo "lewang/jump-char"
:branch "master")
:bind (("M-n" . jump-char-forward)
("M-N" . jump-char-backward)))
- Repo: https://github.com/tarsius/minions
- Description: A minor-mode menu for the mode line
(use-package minions
:straight t
:config
(minions-mode 1))
-
Description: Emacs: moves current line or lines surrounding region up or down.
(use-package move-lines :straight (:host github :repo "targzeta/move-lines" :branch "master") :config (global-set-key (kbd "M-<down>") 'move-lines-down)) (global-set-key (kbd "M-<up>") 'move-lines-up)
- Repo: https://github.com/emacsmirror/paredit/blob/master/paredit.el
- Docs: https://www.emacswiki.org/emacs/ParEdit, https://wikemacs.org/wiki/Paredit-mode
- Description: A minor mode for performing structured editing of S-expression data
(use-package paredit
:straight t
:hook
((lisp-mode . paredit-mode)
(emacs-lisp-mode . paredit-mode)
(clojure-mode . paredit-mode)
(clojurescript-mode . paredit-mode)
(clojurec-mode . paredit-mode)
(cider-repl-mode . paredit-mode)))
- Repo: https://github.com/apchamberlain/undo-tree.el
- Docs: https://www.emacswiki.org/emacs/UndoTree
- Description: Visualize Emacs undo information as a graphical tree and navigate to previous states
(use-package undo-tree
:straight t
:config
(global-undo-tree-mode)
(setq undo-tree-history-directory-alist `((".*" . ,temporary-file-directory))
undo-tree-enable-undo-in-region t
undo-tree-auto-save-history t)
:diminish
(undo-tree-mode))
- Repo: https://github.com/rainstormstudio/nerd-icons.el
- Description: A library for easily using Nerd Font icons inside Emacs
(use-package nerd-icons
:straight t)
- Repo: https://github.com/rainstormstudio/nerd-icons-dired
- Description: Use nerd-icons for Dired
(use-package nerd-icons-dired
:straight t
:hook
(dired-mode . nerd-icons-dired-mode))
- Repo: https://github.com/rainstormstudio/nerd-icons-completion
- Description: Icons for candidates in minibuffer
(use-package nerd-icons-completion
:straight t
:after marginalia
:hook ((marginalia-mode . nerd-icons-completion-marginalia-setup))
:init
(nerd-icons-completion-mode 1))
- Repo: https://github.com/jdtsmith/kind-icon
- Description: Completion kind text/icon prefix labelling for emacs in-region completion
(use-package kind-icon
:straight t
:after corfu
:custom
(kind-icon-default-face 'corfu-default) ; to compute blended backgrounds correctly
:config
(add-to-list 'corfu-margin-formatters #'kind-icon-margin-formatter))
Configuration and packages specific to GUI
(setq ediff-split-window-function 'split-window-horizontally)
(setq ediff-window-setup-function 'ediff-setup-windows-plain)
;; Maximize frames when created
(add-to-list 'default-frame-alist '(fullscreen . maximized))
;; Use C-H for help prefix
(global-set-key (kbd "C-S-h") 'help-command)
(set-frame-font amo/font nil t)
(set-face-attribute 'fixed-pitch nil :font amo/font)
(set-face-attribute 'variable-pitch nil :font amo/font)
(set-face-attribute 'default nil :height amo/base-font-size)
(desktop-save-mode 1)
(global-hl-line-mode t)
(menu-bar-mode (string-to-number (dot-env-get 'MENU_BAR_MODE "1")))
(setq warning-minimum-level :error
default-directory (dot-env-get 'DEFAULT_DIRECTORY "~/")
scroll-step 1
;; split-width-threshold 120
;; split-height-threshold 160
compilation-window-height 24
frame-inhibit-implied-resize t
recentf-max-menu-items 25
recentf-max-saved-items 25
inferior-lisp-program "/usr/local/bin/sbcl"
font-latex-fontify-script nil
auto-save-default nil
create-lockfiles nil
delete-by-moving-to-trash t
comment-column 64
;; Change mode based on file extension
auto-mode-alist (append '(("\\.cl$" . lisp-mode)
("\\.mod$" . go-mod-ts-mode))
auto-mode-alist))
(setq-default org-catch-invisible-edits 'show)
;; Save backups to a central location
(let ((backup-directory (dot-env-get 'BACKUP_DIRECTORY "~/.emacs.d/backups/")))
(setq backup-directory-alist `(("." . ,backup-directory))
make-backup-files t
delete-old-versions -1
version-control t
vc-make-backup-files t
indent-tabs-mode nil))
;; Open settings.org (this file)
(defun amo/open-settings-file ()
"Open settings.org"
(interactive)
(find-file (concat user-emacs-directory "gui/settings.org")))
;; Open common settings.org
(defun amo/open-common-settings-file ()
"Open common/settings.org"
(interactive)
(find-file (concat user-emacs-directory "common/settings.org")))
;; Reload config
(defun amo/reload-config ()
"Reload configuration"
(interactive)
(load-file (concat user-emacs-directory "init.el")))
;; Delete desktop files and restart emacs
(defun amo/delete-emacs-desktop-files-restart ()
"Delete saved desktop, then restart emacs"
(interactive)
(setq desktop-save-mode nil)
(delete-file (concat user-emacs-directory ".emacs.desktop"))
(delete-file (concat user-emacs-directory ".emacs.desktop.lock"))
(restart-emacs))
;; Move point to other window immediately after split
(defun amo/split-window-below ()
"Create a new window below and move point to new window."
(interactive)
(split-window-below)
(other-window 1))
(defun amo/split-window-horizontally()
"Create a new window to the right and move point to new window."
(interactive)
(split-window-horizontally)
(other-window 1))
(defun amo/open-notes-directory ()
"Open notes directory"
(interactive)
(find-file org-directory))
(defun amo/open-denote-directory ()
"Open denote directory"
(interactive)
(find-file (concat org-directory "/denote")))
;; Custom prefix C-z
(global-set-key (kbd "C-z s") 'amo/open-settings-file)
(global-set-key (kbd "C-z C-z s") 'amo/open-common-settings-file)
(global-set-key (kbd "C-z r") 'amo/reload-config)
(global-set-key (kbd "C-z C-z r") 'restart-emacs)
(global-set-key (kbd "C-z C-z C-z r") 'amo/delete-emacs-desktop-files-restart)
(global-set-key (kbd "C-z t") 'customize-themes)
(global-set-key (kbd "C-z e") 'eshell)
(global-set-key (kbd "C-z n") 'amo/open-notes-directory)
(global-set-key (kbd "C-z d") 'amo/open-denote-directory)
;; Other bindings
(global-set-key (kbd "C-x 2") 'amo/split-window-below)
(global-set-key (kbd "C-x 3") 'amo/split-window-horizontally)
(global-set-key (kbd "M-<down>") 'amo/move-line-down)
(global-set-key (kbd "M-<up>") 'amo/move-line-up)
(global-set-key (kbd "C-'") 'amo/toggle-capitalization)
(global-set-key (kbd "C-s-p") 'scroll-down-line)
(global-set-key (kbd "C-s-n") 'scroll-up-line)
(global-set-key (kbd "C-x K") 'kill-buffer-and-window)
(global-set-key (kbd "M-SPC") 'cycle-spacing)
;; Don't auto-complete when we are debugging
(defun amo/comint-mode-actions ()
(setq-local corfu-auto nil) [])
;; Cleanup whitespace
(defun amo/whitespace-cleanup ()
(whitespace-cleanup)
(delete-trailing-whitespace))
(add-hook 'comint-mode-hook 'amo/comint-mode-actions)
(add-hook 'focus-out-hook 'garbage-collect)
(use-package ibuffer
:bind (:map ibuffer-mode-map
("C-o" . nil)))
-
treesit-auto
- Repo: https://github.com/renzmann/treesit-auto
- Description: Automatic installation, usage, and fallback for tree-sitter major modes in Emacs
(use-package treesit-auto :straight t :custom (treesit-auto-install 'prompt) :config (treesit-auto-add-to-auto-mode-alist 'all) (global-treesit-auto-mode))
-
Eglot
- Repo: https://github.com/joaotavora/eglot
- Description: A client for Language Server Protocol servers
(defun amo/eglot-format-on-save () (when (bound-and-true-p eglot--managed-mode) (eglot-format))) (use-package eglot :straight t :defer t :hook ((after-save . amo/eglot-format-on-save) (python-ts-mode . eglot-ensure) (bash-ts-mode . eglot-ensure) (json-ts-mode . eglot-ensure) (go-ts-mode . eglot-ensure) (haskell-mode . eglot-ensure) (rust-ts-mode . eglot-ensure) (c++-ts-mode . eglot-ensure)) :bind (:map eglot-mode-map ("<C-return>" . xref-find-references) ("C-c e f n" . flymake-goto-next-error) ("C-c e f p" . flymake-goto-prev-error) ("C-c e r" . eglot-rename) ("C-c e a" . eglot-code-actions) ("C-c e w r" . eglot-reconnect)))
-
Dape
- Repo: https://github.com/svaante/dape
- Description: Debug Adapter Protocol for Emacs
(use-package dape :straight t :config (setq dape-buffer-window-arrangement 'right) (setq dape-cwd-fn 'projectile-project-root))
-
Golang
-
go-ts-mode
(use-package go-ts-mode :hook (go-ts-mode . (lambda () (setq-local tab-width 4 electric-indent-inhibit t) (aggressive-indent-mode -1))))
-
-
Haskell
-
haskell-mode
- Repo: https://github.com/haskell/haskell-mode
- Description: Emacs mode for Haskell
(use-package haskell-mode :straight t :config (setq haskell-interactive-popup-errors nil) :hook (haskell-mode . (lambda () (interactive-haskell-mode t))))
-
-
Python
-
interpreter
(when (executable-find "ipython") (setq python-shell-interpreter "ipython"))
-
conda
- Repo: https://github.com/necaris/conda.el
- Description: Emacs helper library (and minor mode) to work with conda environments
(use-package conda :straight t :init (setq conda-anaconda-home (expand-file-name "~/opt/miniconda3") conda-env-home-directory (expand-file-name "~/opt/miniconda3") conda-env-autoactivate-mode t) (add-hook 'find-file-hook (lambda () (when (bound-and-true-p conda-project-env-path) (conda-env-activate-for-buffer)))) (setq-default mode-line-format (cons '(:exec conda-env-current-name) mode-line-format)))
-
pyvenv
- Repo: https://github.com/jorgenschaefer/pyvenv
- Description: Python virtual environment interface for Emacs
(use-package pyvenv :straight t :diminish :config (setq pyvenv-mode-line-indicator '(pyvenv-virtual-env-name ("[venv:" pyvenv-virtual-env-name "] "))) (pyvenv-mode +1))
-
-
Docker
-
dockerfile-mode
(use-package dockerfile-mode :straight t)
-
docker-compose-mode
(use-package docker-compose-mode :straight t)
-
-
Jinja2
- Repo: https://github.com/paradoxxxzero/jinja2-mode
- Description: Jinja2 mode for emacs
(use-package jinja2-mode :straight t)
-
SuperCollider
- Repo: https://github.com/supercollider/scel
- Description: Supercollider emacs package
(when (executable-find "sclang") (require 'sclang))
- Repo: https://github.com/magit/magit
- Docs: https://magit.vc/
- Description: It's Magit! A Git Porcelain inside Emacs.
(use-package magit
:straight t
:bind
(("C-x g" . magit)))
- Repo: https://github.com/alphapapa/magit-todos
- Description: Show source files' TODOs (and FIXMEs, etc) in Magit status buffer
(use-package magit-todos
:straight t
:hook ((magit-mode . magit-todos-mode)))
- Repo: https://github.com/emacsorphanage/git-messenger
- Description: Emacs Port of git-messenger.vim
(use-package git-messenger
:straight t
:config (setq git-messenger:show-detail t
git-messenger:use-magit-popup t)
:bind ("C-x m" . git-messenger:popup-message))
- Repo: https://github.com/emacsmirror/git-timemachine
- Description: Walk through git revisions of a file
(use-package git-timemachine
:straight t)
- Repo: https://github.com/dgutov/diff-hl
- Description: Emacs package for highlighting uncommitted changes
(use-package diff-hl
:straight t
:config
(global-diff-hl-mode)
:hook
((dired-mode . diff-hl-dired-mode)
(magit-pre-refresh . diff-hl-magit-pre-refresh)
(magit-post-refresh . diff-hl-magit-post-refresh))
:bind
(("C-c e C-n" . diff-hl-show-hunk-next)
("C-c e C-p" . diff-hl-show-hunk-previous)))
- Repo: https://github.com/emacsmirror/consult-projectile
- Description: Consult integration for projectile
(use-package consult-projectile
:straight t
:config
(define-key projectile-command-map (kbd "h") #'consult-projectile)
(define-key projectile-command-map (kbd "f") #'consult-projectile-find-file)
(define-key projectile-command-map (kbd "d") #'consult-projectile-find-dir)
(define-key projectile-command-map (kbd "p") #'consult-projectile-switch-project)
(define-key projectile-command-map (kbd "b") #'consult-projectile-switch-to-buffer))
-
Description: Jump to workspace symbols with eglot and consult
(use-package consult-eglot :straight t)
- Repo: https://github.com/minad/corfu
- Description: corfu.el - COmpletion in Region FUnction
(use-package corfu
:straight (:files (:defaults "extensions/*"))
:init
(global-corfu-mode)
(corfu-popupinfo-mode 1)
(corfu-echo-mode 1)
:custom (setq corfu-quit-at-boundary t)
:config (setq corfu-auto t
corfu-auto-prefix 1
corfu-quit-no-match t
corfu-popupinfo-delay '(1.0 . 0.5)))
;; A few more useful configurations...
;; TAB cycle if there are only few candidates
(setq completion-cycle-threshold 3)
;; Enable indentation+completion using the TAB key.
;; `completion-at-point' is often bound to M-TAB.
(setq tab-always-indent 'complete)
- Docs: https://orgmode.org/
- Description: A GNU Emacs major mode for keeping notes, authoring documents, computational notebooks, literate programming, maintaining to-do lists, planning projects, and more — in a fast and effective plain text system.
(use-package org
:config
(setq org-directory (dot-env-get 'ORG_DIRECTORY
(concat user-emacs-directory "org-directory"))
org-agenda-files (directory-files-recursively org-directory "\\.org$")
org-notes-file (concat org-directory "/notes.org")
org-lists-file (concat org-directory "/lists.org")
org-archive-location (concat org-directory "/_archive/%s_archive::")
org-yank-folded-subtrees nil)
(defun amo/org-mode-hook ()
(org-indent-mode 1)
(visual-line-mode 1))
(defun amo/org-mode-agenda-hook ()
"For some reason the org-agenda-files var is never set"
(setq org-agenda-files (directory-files-recursively org-directory "\\.org$")))
(advice-add
'org-agenda
:before
(lambda (&rest r) (amo/org-mode-agenda-hook)))
:hook
(org-mode . amo/org-mode-hook)
:bind
(("C-c c" . org-capture)
("C-c a" . org-agenda)
("C-c h" . consult-org-heading))
:custom
(setq org-use-tag-inheritance t)
(org-hide-emphasis-markers t)
(org-list-demote-modify-bullet
'(("-" . "+") ("+" . "*") ("*" . "-")))
(org-list-allow-alphabetical t)
(org-M-RET-may-split-line '((default . nil)))
(org-capture-templates
'(("n"
"Note"
entry
(file org-notes-file)
"** %?\n%T\n%i\n" :empty-lines-after 1 :prepend t)
("t"
"Todo"
checkitem
(file+headline org-notes-file "General Todos")
"[ ] %T %?\n%i\n" :empty-lines-after 1)
("e"
"Emacs Idea"
checkitem
(file+headline org-lists-file "Emacs Ideas")
"[ ] %?" :prepend t)
("k"
"Keyboard Idea"
checkitem
(file+headline org-lists-file "Keyboard Ideas")
"[ ] %?" :prepend t)
("r"
"Interesting Albums"
item
(file+headline org-lists-file "Interesting Albums")
"%?"))))
(use-package ox-gfm
:straight t
:config
(eval-after-load "org"
'(require 'ox-gfm nil t)))
-
Description: 🦄 Modern Org Style
(use-package org-modern :straight t :config (with-eval-after-load 'org (global-org-modern-mode)))
- Repo: https://github.com/lukhas/buffer-move
- Description: Easily swap buffers
(use-package buffer-move
:straight t
:bind
(("<C-S-up>" . buf-move-up)
("<C-S-down>" . buf-move-down)
("<C-S-left>" . buf-move-left)
("<C-S-right>" . buf-move-right)
:map org-mode-map
("<C-S-up>" . buf-move-up)
("<C-S-down>" . buf-move-down)
("<C-S-left>" . buf-move-left)
("<C-S-right>" . buf-move-right)))
-
Description: Casual Suite - An umbrella package to support a single install point for all Casual porcelains.
(use-package casual-suite :straight t :bind ( ("C-," . casual-avy-tmenu) :map Calc-mode-map ("C-i" . casual-calc-tmenu) :map Info-mode-map ("C-i" . casual-info-tmenu) :map dired-mode-map ("C-i" . casual-dired-tmenu) :map isearch-mode-map ("<f2>" . casual-isearch-tmenu)))
- Repo: https://github.com/protesilaos/denote
- Docs: https://protesilaos.com/emacs/denote
- Description: Simple notes for Emacs with an efficient file-naming scheme
(use-package denote
:straight t
:after org
:config
(setq denote-directory (dot-env-get 'DENOTE_DIRECTORY (concat org-directory "/denote"))
denote-date-prompt-use-org-read-date t
denote-known-keywords nil
denote-allow-multi-word-keywords t)
:hook ((dired-mode . denote-dired-mode))
:bind (("C-c n n" . denote)
("C-c n N" . denote-type)
("C-c n d" . denote-date)
("C-c n z" . denote-signature)
("C-c n s" . denote-subdirectory)
("C-c n t" . denote-template)
("C-c n i" . denote-link)
("C-c n I" . denote-add-links)
("C-c n b" . denote-backlinks)
("C-c n f f" . denote-find-link)
("C-c n f b" . denote-find-backlink)
("C-c n k a" . denote-keywords-add)
("C-c n k k" . denote-keywords-remove)
("C-c n r" . denote-rename-file)
("C-c n R" . denote-rename-file-using-front-matter)
:map dired-mode-map
("C-c C-d C-i . denote-link-dired-marked-notes")
("C-c C-d C-r . denote-dired-rename-marked-files")
("C-c C-d C-R . denote-dired-rename-marked-files-using-front-matter")))
- Repo: https://github.com/purcell/exec-path-from-shell
- Description: Make Emacs use the $PATH set up by the user's shell
(when (memq window-system '(mac ns x)) ;; Linux
(use-package exec-path-from-shell
:straight t
:config
(exec-path-from-shell-initialize)))
- Repo: https://depp.brause.cc/eyebrowse/
- Description: A simple-minded way of managing window configs in Emacs
(use-package eyebrowse
:straight t
:config
(setq eyebrowse-new-workspace (lambda () (dashboard-open)))
(eyebrowse-mode))
- Repo: https://github.com/LionyxML/flymake-margin
- Description: A package to provide flymake into the margin world
(use-package flymake-margin
:straight (margin :type git
:host github
:repo "LionyxML/flymake-margin"
:files ("*.el"))
:after flymake
:config
(flymake-margin-mode t))
- Repo: https://github.com/karthink/gptel
- Description: A no-frills ChatGPT client for Emacs
(use-package gptel
:straight t
:config
(setq gptel-api-key (dot-env-get 'GPTEL_API_KEY)
gptel-default-mode #'org-mode)
:bind (("C-c g" . gptel)))
- Repo: https://github.com/Wilfred/helpful
- Description: A better Emacs help buffer
(use-package helpful
:straight t
:bind (("C-S-h f" . helpful-callable)
("C-S-h v" . helpful-variable)
("C-S-h o" . helpful-symbol)
("C-S-h k" . helpful-key)
("C-S-h x" . helpful-command)
("C-S-h d" . helpful-at-point)
("C-S-h F" . helpful-function)))
- Repo: https://github.com/purcell/ibuffer-projectile
- Description: Group buffers in Emacs ibuffer-mode by their projectile root directory
(use-package ibuffer-projectile
:straight t
:after projectile
:config (setq ibuffer-show-empty-filter-groups nil)
:hook ((ibuffer . (lambda ()
(ibuffer-projectile-set-filter-groups)
(unless (eq ibuffer-sorting-mode 'alphabetic)
(ibuffer-do-sort-by-alphabetic))))
(ibuffer-mode . (lambda ()
(ibuffer-auto-mode 1)
(ibuffer-switch-to-saved-filter-groups "default"))))
:bind (("C-x C-b" . ibuffer)))
- Repo: https://github.com/jrblevin/markdown-mode
- Description: Emacs Markdown Mode
(use-package markdown-mode
:straight t
:mode ("README\\.md\\'" . gfm-mode)
:init (setq markdown-command "multimarkdown"))
- Repo: https://github.com/purcell/package-lint
- Description: A linting library for elisp package metadata
(use-package package-lint
:straight t)
- Repo: https://github.com/karthink/popper
- Description: Emacs minor-mode to summon and dismiss buffers easily
(use-package popper
:straight t
:bind (("s-3" . popper-toggle)
("s-4" . popper-cycle)
("s-5" . popper-toggle-type))
:init
(setq popper-reference-buffers
'("\\*format-all-errors\\*"
"\\*cider-error\\*"
"\\*cider-scratch\\*"
"\\*Messages\\*"
"\\*helpful"
"\\*Warnings\\*"
"\\*Compile-Log\\*"
"\\*Completions\\*"
"\\*Backtrace\\*"
"\\*TeX Help\\*"
"Output\\*$"
"\\*Async Shell Command\\*"
"\\*eldoc\\*"
"^pop-"
help-mode
compilation-mode)
popper-mode-line ""
;; Make popper buffers 1/2 window height
popper-window-height (lambda (win)
(fit-window-to-buffer
win
(floor (frame-height) 2))))
(popper-mode +1)
(popper-echo-mode +1)
(defun amo/add-popper-status-to-modeline ()
"If buffer is a popper-type buffer, display POP in the modeline,
in a doom-modeline friendly way"
(if (popper-display-control-p (buffer-name))
(add-to-list 'mode-line-misc-info "POP")
(setq mode-line-misc-info (remove "POP" mode-line-misc-info))))
(add-hook 'buffer-list-update-hook 'amo/add-popper-status-to-modeline))
- Repo: https://github.com/bbatsov/projectile
- Docs: https://docs.projectile.mx/projectile/index.html
- Description: Project navigation and management library for Emacs
(use-package projectile
:straight t
:config
(projectile-global-mode)
(setq projectile-indexing-method 'alien
projectile-ignored-projects '("~/"))
:bind (("s-p" . projectile-command-map)
("C-c p" . projectile-command-map)))
(use-package ess
:straight t)
- Repo: https://github.com/Fanael/rainbow-delimiters
- Description: A "rainbow parentheses"-like mode which highlights delimiters
(use-package rainbow-delimiters
:straight t
:hook (prog-mode . rainbow-delimiters-mode))
- Docs: https://www.emacswiki.org/emacs/TransposeFrame
- Description: Interactive functions to transpose window arrangement in current frame
(use-package transpose-frame
:straight t
:bind (("C->" . transpose-frame)))
- Repo: https://github.com/joaotavora/yasnippet
- Description: A template system for Emacs
(use-package yasnippet
:straight t
:hook ((python-ts-mode . (lambda () (yas-activate-extra-mode 'python-mode))))
:config
(yas-global-mode)
(setq yas-snippet-dirs
'("~/.emacs.d/snippets")) ;TODO: Don't hardcode
(use-package yasnippet-snippets
:straight t))
- Repo: https://github.com/emacs-dashboard/emacs-dashboard
- Description: An extensible emacs dashboard
(use-package dashboard
:straight t
:after nerd-icons
:config
(setq dashboard-center-content t
dashboard-banner-logo-title "No! The beard stays. You go."
dashboard-startup-banner 'logo
dashboard-projects-backend 'projectile
dashboard-items '((projects . 10)
(recents . 10)
(bookmarks . 10))
dashboard-display-icons-p t
dashboard-icon-type 'nerd-icons
dashboard-set-file-icons t
dashboard-set-footer nil
dashboard-footer-messages '(""))
(dashboard-open))
- Repo: https://github.com/seagle0128/doom-modeline
- Description: A fancy and fast mode-line inspired by minimalism design
(straight-use-package '(f :type git :host github :repo "rejeep/f.el"))
(use-package doom-modeline
:straight t
:after f
:init (doom-modeline-mode 1)
:config
(setq doom-modeline-minor-modes t
doom-modeline-vcs-max-length 40
doom-modeline-buffer-encoding t))
- Repo: https://github.com/protesilaos/ef-themes
- Description: Colourful and legible themes for GNU Emacs
(use-package ef-themes
:straight t)
- Repo: https://github.com/protesilaos/modus-themes
- Description: Highly accessible themes for GNU Emacs
(use-package modus-themes
:straight t)
- Repo: https://github.com/LuigiPiucco/nerd-icons-corfu
- Description: Icons for corfu via nerd-icons
(use-package nerd-icons-corfu
:straight t)
- Repo: https://github.com/gekoke/magit-file-icons
- Description: File icons for Magit
(use-package magit-file-icons
;; :straight (margin :type git
;; :host github
;; :repo "gekoke/magit-file-icons"
;; :files ("*.el"))
:straight t
:init
(magit-file-icons-mode 1)
:custom
;; These are the default values:
(magit-file-icons-enable-diff-file-section-icons t)
(magit-file-icons-enable-untracked-icons t)
(magit-file-icons-enable-diffstat-icons t))
Configuration and packages specific to terminal
(use-package emacs
:config
(setq-default left-margin-width 1 right-margin-width 1)
(set-window-margins nil 1)
(setq inhibit-startup-screen t
x-select-enable-clipboard t
auto-save-default nil
make-backup-files nil
create-lockfiles nil)
(add-hook 'before-save-hook 'whitespace-cleanup)
(tool-bar-mode -1)
(menu-bar-mode -1)
(defun amo/modus-themes-toggle (&optional ignore-if-set)
"Toggle modus theme, sets to vivendi if unset"
(interactive)
(if (string-match "modus" (symbol-name (car custom-enabled-themes)))
(when (not ignore-if-set)
(modus-themes-toggle))
(load-theme 'modus-vivendi)))
(amo/modus-themes-toggle t)
(defun amo/open-settings-file ()
"Open settings.el"
(interactive)
(find-file "~/.emacs.d/terminal/settings.org"))
;; Reload config
(defun amo/reload-config ()
"Reload configuration"
(interactive)
;; (dot-env-load)
(load-file "~/.emacs.d/terminal/init.el"))
:bind (("C-z s" . amo/open-settings-file)
("C-z r" . amo/reload-config)
("C-z t" . amo/modus-themes-toggle)))
-
company
- Repo: https://github.com/company-mode/company-mode
- Docs: https://company-mode.github.io/
- Description: Modular in-buffer completion framework for Emacs
corfu-terminal doesn't seem to work for some reason. Company is just fine though.
(use-package company :straight t :config (global-company-mode))
(defun amo/define-escape-sequences-and-bindings ()
(interactive)
(progn
(let ((map (if (boundp 'input-decode-map)
input-decode-map
function-key-map)))
;; C-=
(define-key map "\e[1;P9" (kbd "H-a"))
(global-set-key (kbd "H-a") 'er/expand-region)
;; C--
(define-key map "\e[1;P10" (kbd "H-b"))
(global-set-key (kbd "H-b") 'er/contract-region) ;; FIXME - maps to undo for some reason
;; C-;
(define-key map "\e[1;P11" (kbd "H-c"))
(global-set-key (kbd "H-c") 'avy-goto-char-2)
(global-set-key (kbd "C-x H-c") 'comment-line)
;; s-o
(define-key map "\e[1;P12" (kbd "H-d"))
(global-set-key (kbd "H-d") 'crux-smart-open-line-above)
;; s-j
(define-key map "\e[1;P13" (kbd "H-e"))
(global-set-key (kbd "H-e") 'crux-top-join-line)
;; s-k
(define-key map "\e[1;P14" (kbd "H-f"))
(global-set-key (kbd "H-f") 'crux-kill-whole-line)
;; C-s-p
(define-key map "\e[1;P15" (kbd "H-g"))
(global-set-key (kbd "H-g") 'scroll-down-line)
;; C-s-n
(define-key map "\e[1;P16" (kbd "H-h"))
(global-set-key (kbd "H-h") 'scroll-up-line)
;; C-S-h
(define-key map "\e[1;P17" (kbd "H-i"))
(global-set-key (kbd "H-i") 'help-command)
;; M-S<down>
(define-key map "\e[1;P18" (kbd "H-j"))
(global-set-key (kbd "H-j") 'amo/move-line-down)
;; M-S-<up>
(define-key map "\e[1;P19" (kbd "H-k"))
(global-set-key (kbd "H-k") 'amo/move-line-up)
;; C-'
(define-key map "\e[1;P20" (kbd "H-l"))
(global-set-key (kbd "H-l") 'amo/toggle-capitalization)
;; C-.
(define-key map "\e[1;P21" (kbd "H-m"))
(global-set-key (kbd "H-m") 'embark-act)
;; s-r
(define-key map "\e[1;P22" (kbd "H-n"))
(global-set-key (kbd "H-n") 'consult-recent-file)
;; Additional available keybindings
(define-key map "\e[1;P23" (kbd "H-o"))
(define-key map "\e[1;P24" (kbd "H-p"))
(define-key map "\e[1;P25" (kbd "H-q"))
(define-key map "\e[1;P26" (kbd "H-r"))
(define-key map "\e[1;P27" (kbd "H-s"))
(define-key map "\e[1;P28" (kbd "H-t"))
(define-key map "\e[1;P29" (kbd "H-u"))
(define-key map "\e[1;P30" (kbd "H-v"))
(define-key map "\e[1;P31" (kbd "H-w"))
(define-key map "\e[1;P32" (kbd "H-x"))
(define-key map "\e[1;P33" (kbd "H-y"))
(define-key map "\e[1;P34" (kbd "H-z"))
(define-key map "\e[1;P35" (kbd "H-0"))
(define-key map "\e[1;P36" (kbd "H-1"))
(define-key map "\e[1;P37" (kbd "H-2"))
(define-key map "\e[1;P38" (kbd "H-3"))
(define-key map "\e[1;P39" (kbd "H-4"))
(define-key map "\e[1;P40" (kbd "H-5"))
(define-key map "\e[1;P41" (kbd "H-6"))
(define-key map "\e[1;P42" (kbd "H-7"))
(define-key map "\e[1;P43" (kbd "H-8"))
(define-key map "\e[1;P44" (kbd "H-9"))
(define-key map "\e[1;P45" (kbd "H-<f1>"))
(define-key map "\e[1;P46" (kbd "H-<f2>"))
(define-key map "\e[1;P47" (kbd "H-<f3>"))
(define-key map "\e[1;P48" (kbd "H-<f4>"))
(define-key map "\e[1;P49" (kbd "H-<f5>"))
(define-key map "\e[1;P50" (kbd "H-<f6>"))
(define-key map "\e[1;P51" (kbd "H-<f7>"))
(define-key map "\e[1;P52" (kbd "H-<f8>"))
(define-key map "\e[1;P53" (kbd "H-<f9>"))
(define-key map "\e[1;P54" (kbd "H-<f10>"))
(define-key map "\e[1;P55" (kbd "H-<f11>"))
(define-key map "\e[1;P56" (kbd "H-<f12>")))))
(add-hook 'server-after-make-frame-hook 'amo/define-escape-sequences-and-bindings)
(amo/define-escape-sequences-and-bindings)