Skip to content

shanemcd/.emacs.d

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

78 Commits
 
 
 
 
 
 

Repository files navigation

My Emacs Configuration

Hello. This is my Emacs configuration. It’s both documentation and code in one place, a paradigm referred to as Literate programming.

How it works

When Emacs starts it runs the code in init.el. Rather than storing the configuration here directly, we have this line:

(org-babel-load-file "~/.emacs.d/readme.org")

That then loads this file, which will tangle and then evaluate every emacs-lisp code block in here, unless it is explicitly marked with :tangle no, as is true with the example above.

Note that evaluating this file with org-babel-load-file will result in some variables being set unless we set the variable below. Instead of cluttering up this file, we will write the generated code to a new file that can be easily ignored:

(setq custom-file "~/.emacs.d/generated.el")

Set up a package management system

Bootstrap use-package

(require 'package)

(add-to-list 'package-archives
    '("MELPA" .
      "http://melpa.org/packages/"))

(setq package-enable-at-startup nil)

(eval-when-compile
  (require 'use-package))

(setq use-package-always-ensure t)

(setq quelpa-update-melpa-p nil)
(use-package quelpa)
(use-package quelpa-use-package)

Make a frame if we’re running daemonized

Note that I set EMACS_SERVER_AUTH_KEY and launch emacs via launchctl. Since I currently only run emacs as a daemon on macOS I do not have any conditional logic here.

(defun open-initial-frame-when-daemonized ()
  (when (daemonp)
    (setq server-use-tcp t)
    (setq server-auth-key (getenv "EMACS_SERVER_AUTH_KEY"))
    (setq server-port 52698)

    (server-start)

    (make-frame '((display . "mac"))))) ;; Adjust "mac" if needed, depending on your display configuration

;; Run the function after the daemon starts
(add-hook 'after-init-hook 'open-initial-frame-when-daemonized)

Why am I doing this?

My workflow is built around the assumption that the code I am working on may or may not be local to the machine I am working on.

For cases where I need to work remotely, I use tramp. This mostly works fine, but there are times where I am SSH’d into a remote machine where my code is hosted via a terminal, and I would like a way to open a file or directory in Emacs without having to switch contexts to copy / paste a path between the applications.

By starting the server below listening via TCP, we are able to open reverse emacsclient connections back to ourselves using this ZSH function:

#!/bin/env zsh
function re {
    # Get the number of arguments
    local num_args=$#

    # If no arguments are provided, exit the function
    if [ $num_args -eq 0 ]; then
        echo "🤖 re (remote? reverse? emacsclient) 🤖"
        echo "Usage: re [emacsclient options] <path>"
        return 1
    fi

    # Extract the last argument as the path
    local tramppath="$1"

    # Check if a valid path was provided (should be the first arg)
    if [ -z "$tramppath" ]; then
        echo "Error: No path provided."
        return 1
    fi

    # Run the emacsclient command with -cn option and --server-file and /sshx options
    emacsclient -cn --server-file ~/server /sshx:$(hostname):$tramppath
}

Other stuff that should run early

delight

https://elpa.gnu.org/packages/delight.html

This package makes the mode line less noisy by allowing us to hide certain minor modes. We’ll call this early so we can use as-needed, by using the delight keyword when calling use-package.

(use-package delight)

Install some packages

Text and programming modes

python-mode

(setq python-shell-interpreter "/Users/shanemcd/.pyenv/shims/python"
      flycheck-python-pycompile-executable "/Users/shanemcd/.pyenv/shims/python"
      python-shell-exec-path "/Users/shanemcd/.pyenv/shims/python")

markdown-mode

(use-package markdown-mode
  :config
  (setq markdown-fontify-code-blocks-natively t))

show-paren-mode

(show-paren-mode)

yaml-mode

(use-package yaml-mode
  :config
  (setq yaml-indent-offset 2))

(defun my/yaml-outline-setup ()
  "Configure outline-minor-mode for YAML to fold both keys and list items."
  ;; Match lines like:
  ;;   topKey:
  ;;   - listItem:
  ;;   - listItem
  (setq-local outline-regexp "^\\([[:space:]]*\\(-\\|\\w\\)\\)")
  (outline-minor-mode 1))

(add-hook 'yaml-mode-hook #'my/yaml-outline-setup)

groovy-mode

(use-package groovy-mode
  :config
  (setq groovy-indent-offset 2))

swift

(use-package swift-mode)
(use-package ob-swift)

go

(use-package go-mode
  :config
  (add-hook 'go-mode-hook
            (lambda ()
              (setq indent-tabs-mode 1)
              (setq tab-width 8))))
(use-package ob-go)

dockerfile-mode

(use-package dockerfile-mode)

ob-mermaid

(use-package ob-mermaid)

Org Mode

org-mode

(use-package org
  :mode ("\\.org\\'" . org-mode)
  :bind (("C-c l" . org-store-link)
         ("C-c c" . org-capture)
         ("C-c C-w" . org-refile))
  :config
  (require 'org-tempo)
  (setq org-directory "~/org")
  (setq org-agenda-skip-unavailable-files t)
  (setq org-agenda-files (directory-files-recursively "~/org/" "\\.org$"))
  (setq org-use-speed-commands t)
  (setq org-startup-with-inline-images t)
  (setq org-capture-templates '(
                                ("t" "TODO" entry (file+headline "~/org/incoming.org" "TODOs") "** TODO %?\n  %i\n  %a")
                                ("e" "Log entry" entry (file+headline "~/org/log.org" "Log") "** %?\n  %i\n  %a")
                                ("p" "Private note" entry (file+headline "~/org/journal.org" "Notes") "** %?\n  %i\n  %a")
                                ))

  (setq org-refile-targets '((org-agenda-files :maxlevel . 3)))
  (setq org-imenu-depth 3)
  (org-babel-do-load-languages
   'org-babel-load-languages
   '((shell      . t)
     (emacs-lisp . t)
     (js         . t)
     (ruby       . t)
     (swift      . t)
     (mermaid . t)
     (python     . t)))
  (setq org-babel-python-command "python3")
  (setq org-startup-folded t)
  (setq org-odt-preferred-output-format "docx")
  (setq org-src-fontify-natively t
        org-src-window-setup 'current-window
        org-src-strip-leading-and-trailing-blank-lines t
        org-src-preserve-indentation t
        org-hide-emphasis-markers t
        org-src-tab-acts-natively t))

(use-package org-appear
  :after org
  :hook (org-mode . org-appear-mode)
  :config
  (setq org-appear-autolinks t))

(defun my/org-roam-capture-finished ()
  "Function to run after an Org-roam capture is finalized."
  (setq org-agenda-files (directory-files-recursively "~/org/" "\\.org$")))

(use-package org-roam
  :after org
  :config
  (setq org-roam-directory (file-truename "~/org/roam"))
  (org-roam-db-autosync-mode)
  (setq org-roam-node-display-template "${title:*} ${tags:20}")
  (add-hook 'org-capture-after-finalize-hook 'my/org-roam-capture-finished)
  :bind (("C-c r b" . org-roam-buffer-toggle)
         ("C-c r f" . org-roam-node-find)))

(use-package org-modern
  :after org
  :hook (org-mode . global-org-modern-mode))

ox-gfm

https://github.com/larstvei/ox-gfm

(use-package ox-gfm)

Terminal Emulation

vterm

(use-package vterm
  ;; :config
  ;; (setq vterm-tramp-shells '(("sshx" "/bin/zsh")))

)

eat

(quelpa '(eat :fetcher git
              :url "https://codeberg.org/akib/emacs-eat"
              :files ("*.el" ("term" "term/*.el") "*.texi"
                      "*.ti" ("terminfo/e" "terminfo/e/*")
                      ("terminfo/65" "terminfo/65/*")
                      ("integration" "integration/*")
                      (:exclude ".dir-locals.el" "*-tests.el"))))

Interface Customizations

Smooth scrolling

(use-package ultra-scroll
  ;:vc (:url "https://github.com/jdtsmith/ultra-scroll") ; if desired (emacs>=v30)
  :init
  (setq scroll-conservatively 3 ; or whatever value you prefer, since v0.4
        scroll-margin 0)        ; important: scroll-margin>0 not yet supported
  :config
  (ultra-scroll-mode 1))

Columns

(setq-default fill-column 80)

Disable Native UI Controls

(tool-bar-mode -1)
(menu-bar-mode -1)
(scroll-bar-mode -1)

Font

https://github.com/tonsky/FiraCode

;; Set Iosevka SS05 Expanded using XLFD names for each OS
(set-frame-font
 (cond
  ((eq system-type 'darwin)
   "-*-Iosevka SS05-medium-normal-expanded-*-16-*-*-*-m-0-iso10646-1")
  ((eq system-type 'gnu/linux)
   "-UKWN-Iosevka SS05-medium-normal-expanded-*-16-*-*-*-d-0-iso10646-1"))
 t t)

Hide Splash Screen

(setq inhibit-splash-screen t)

Show column number in modeline

(setq column-number-mode t)

Show Line Numbers

;; (global-display-line-numbers-mode)

Theme

(use-package base16-theme)

Auto Dark Mode

Automatically switch between light and dark themes based on system appearance.

(use-package auto-dark
  :custom
  (auto-dark-themes '((base16-tomorrow-night) (base16-tomorrow)))
  :init
  (auto-dark-mode))

Wind Move

https://www.emacswiki.org/emacs/WindMove

(when (fboundp 'windmove-default-keybindings)
  (windmove-default-keybindings))

Enable clicking in the fringe to toggle bookmarks

(defun my-toggle-emacs-bookmark (event)
  "Toggle an Emacs bookmark at the line clicked."
  (interactive "e")
  (let* ((pos (posn-point (event-start event)))
         (line (line-number-at-pos pos))
         (bookmark-name (format "Line %d in %s" line (buffer-name))))
    (save-excursion
      (goto-char pos)
      (if (bookmark-get-bookmark bookmark-name t)
          (progn
            (bookmark-delete bookmark-name)
            (message "Deleted bookmark: %s" bookmark-name))
        (bookmark-set bookmark-name)
        (message "Set bookmark: %s" bookmark-name)))))

(global-set-key [left-fringe mouse-1] #'my-toggle-emacs-bookmark)

Increase spacing / padding of windows and frames

(use-package spacious-padding
  :config
  (spacious-padding-mode))

Start maximized

(toggle-frame-maximized)

Writing environment

(use-package olivetti)

Whitespace

(setq-default indent-tabs-mode nil tab-width 4)

(use-package sh-script
  :mode "\\.sh\\'"
  :config (setq sh-indentation 4 sh-basic-offset 4))

Require newlines at end of files

(setq require-final-newline t)

LLM

ellama

(use-package ellama
  :bind ("C-c e" . ellama-transient-main-menu)
  :init
  (require 'llm-ollama)
  (setopt ellama-provider
	  (make-llm-ollama
       :host "tot"
       :port 11434
       :chat-model "granite3.2:8b"
	   :embedding-model "granite3.2:8b")))

claude

(quelpa '(claudemacs :fetcher github :repo "cpoile/claudemacs"))

To be filed or tossed away at some point…

browse-at-remote

(use-package browse-at-remote
  :commands browse-at-remote
  :bind ("C-c g g" . browse-at-remote))

company

(use-package company
  :delight
  :config
  (setq company-minimum-prefix-length 1)
  (global-company-mode t)
  (setq company-global-modes '(not org-mode)))

dired

  • Set up key binding for dired-jump.
    • If you enter a file from dired and press this shortcut, you will pop back into the dired buffer
  • Only show filenames in dired by default, hiding the permissions and other details. Press ( to show details.
(global-set-key (kbd "C-x C-j") 'dired-jump)
(add-hook 'dired-mode-hook 'dired-hide-details-mode)
;(use-package dired-single)
(require 'dired-x)
(add-hook 'dired-mode-hook 'dired-omit-mode)
(setq-default dired-omit-files-p t) ; Buffer-local variable
(setq dired-omit-files (concat dired-omit-files "\\|^\\..+$"))
dired-subtree
(use-package dired-subtree
  :after dired
  :config
  (bind-key "<tab>" #'dired-subtree-toggle dired-mode-map)
  (bind-key "<backtab>" #'dired-subtree-cycle dired-mode-map)
  (setq dired-subtree-use-backgrounds nil))

drag-stuff

(use-package drag-stuff
  :config
  (drag-stuff-define-keys))

dumb-jump

(use-package dumb-jump
  :config
  ;(setq dumb-jump-selector 'helm)
  (add-hook 'xref-backend-functions #'dumb-jump-xref-activate))

fill-column-indicator

(use-package fill-column-indicator
  :config
  (setq-default fci-rule-column 80)
  (setq fci-rule-color (face-attribute 'highlight :background)))

flycheck

(use-package flycheck
  :delight
  :config
  (global-flycheck-mode))

flyspell

I unbind flyspell-mode-map because I use C-. for embark-act.

(use-package flyspell
  :delight
  :config
  (define-key flyspell-mode-map (kbd "C-.") nil)
  (add-hook 'prog-mode-hook 'flyspell-prog-mode)
  (add-hook 'text-mode-hook 'flyspell-mode)
  (add-hook 'markdown-mode-hook 'flyspell-mode))

htmlize

(use-package htmlize
  :commands (htmlize-buffer
	     htmlize-file
	     htmlize-many-files
	     htmlize-many-files-dired
	     htmlize-region))

imenu-list

(use-package imenu-list
  :bind
  (("C-." . imenu-list-smart-toggle))
  :config
  (setq imenu-list-focus-after-activation t))

tramp

(use-package tramp
  :defer t
  :config
  (setopt tramp-remote-path '(tramp-own-remote-path))
  (setq tramp-histfile-override nil))

magit

(use-package magit
  :bind ("C-x g" . magit)
  :commands magit-project-status)

(use-package project
  :bind
  (:map project-prefix-map
        ("m" . magit-project-status))
  :config
  (add-to-list 'project-switch-commands '(magit-project-status "Magit") t))

mwim

“Move where I mean” - C-a takes you to the first character on the line.

(use-package mwim
  :config
  (global-set-key (kbd "C-a") 'mwim-beginning)
  (global-set-key (kbd "C-e") 'mwim-end))

nerd-icons

(use-package nerd-icons)

(use-package nerd-icons-dired
  :delight
  :hook
  (dired-mode . nerd-icons-dired-mode))

rainbow-delimeters

(use-package rainbow-delimiters
  :config
  (add-hook 'prog-mode-hook #'rainbow-delimiters-mode))

reveal-in-osx-finder

(use-package reveal-in-osx-finder)

vundo

(use-package vundo
  :commands (vundo)
  :config
  (setq vundo-compact-display t))

ws-butler

(use-package ws-butler
  :delight
  :config
  (ws-butler-global-mode t))

wttrin

(use-package wttrin
  :config
  (setq wttrin-default-cities '("New York NY" "Winchester VA" "Durham NC" "Kaohsiung City")))

ztree

(use-package ztree)

yassnippet

(use-package yasnippet
  :commands yas-minor-mode
  :hook (go-mode . yas-minor-mode))

winum

(use-package winum
  :config
  (winum-mode)
  :bind
      (("M-0" . 'winum-select-window-0-or-10)
       ("M-1" . 'winum-select-window-1)
       ("M-2" . 'winum-select-window-2)
       ("M-3" . 'winum-select-window-3)
       ("M-4" . 'winum-select-window-4)
       ("M-5" . 'winum-select-window-5)
       ("M-6" . 'winum-select-window-6)
       ("M-7" . 'winum-select-window-7)
       ("M-8" . 'winum-select-window-8))
  )

pandoc-mode

(use-package pandoc-mode
  :config
  (add-hook 'markdown-mode-hook 'pandoc-mode))

marp-mode

;; (use-package marp-mode
;;   :quelpa (marp-mode :fetcher github :repo "shanemcd/marp-mode")
;;   :hook (markdown-mode . marp-mode))

(use-package marp-mode
  :load-path "/var/home/shanemcd/github/shanemcd/marp-mode"
  :hook (markdown-mode . marp-mode))

hide-mode-line

(use-package hide-mode-line)
(setq backup-directory-alist `(("." . "~/.emacs.bak")))

(setenv "PINENTRY_USER_DATA" "USE_CURSES=0")

Set up the PATH

(use-package exec-path-from-shell
  :config
  (setq exec-path-from-shell-arguments '("-li"))
  (setenv "SHELL" "/bin/zsh")
  (exec-path-from-shell-initialize)
  (dolist (var '("GOPATH"
                 "PATH"
                 "LC_ALL"
                 "LANG"
                 "LC_TYPE"
                 "SSH_AGENT_PID"
                 "SSH_AUTH_SOCK"
                 "SHELL"
                 "CLAUDE_CODE_USE_VERTEX"
                 "CLOUD_ML_REGION"
                 "ANTHROPIC_VERTEX_PROJECT_ID"
                 "ANTHROPIC_MODEL"
                 "ANTHROPIC_DEFAULT_HAIKU_MODEL"))
    (exec-path-from-shell-copy-env var)))

Proving ground

Trying to piece together a more modern completion system

marginalia

;; Enable rich annotations using the Marginalia package
(use-package marginalia
  ;; Bind `marginalia-cycle' locally in the minibuffer.  To make the binding
  ;; available in the *Completions* buffer, add it to the
  ;; `completion-list-mode-map'.
  :bind (:map minibuffer-local-map
         ("M-A" . marginalia-cycle))

  ;; The :init section is always executed.
  :init

  ;; Marginalia must be activated in the :init section of use-package such that
  ;; the mode gets enabled right away. Note that this forces loading the
  ;; package.
  (marginalia-mode))
(use-package embark
  :ensure t

  :bind
  (("C-." . embark-act)         ;; pick some comfortable binding
   ("C-;" . embark-dwim)        ;; good alternative: M-.
   ("C-h B" . embark-bindings)) ;; alternative for `describe-bindings'

  :init

  ;; Optionally replace the key help with a completing-read interface
  (setq prefix-help-command #'embark-prefix-help-command)

  ;; Show the Embark target at point via Eldoc. You may adjust the
  ;; Eldoc strategy, if you want to see the documentation from
  ;; multiple providers. Beware that using this can be a little
  ;; jarring since the message shown in the minibuffer can be more
  ;; than one line, causing the modeline to move up and down:

  ;; (add-hook 'eldoc-documentation-functions #'embark-eldoc-first-target)
  ;; (setq eldoc-documentation-strategy #'eldoc-documentation-compose-eagerly)

  :config

  ;; Hide the mode line of the Embark live/completions buffers
  (add-to-list 'display-buffer-alist
               '("\\`\\*Embark Collect \\(Live\\|Completions\\)\\*"
                 nil
                 (window-parameters (mode-line-format . none)))))

consult

;; Example configuration for Consult
(use-package consult
  ;; Replace bindings. Lazily loaded by `use-package'.
  :bind (;; C-c bindings in `mode-specific-map'
         ("C-c M-x" . consult-mode-command)
         ("C-c h" . consult-history)
         ("C-c k" . consult-kmacro)
         ("C-c m" . consult-man)
         ("C-c i" . consult-info)
         ([remap Info-search] . consult-info)
         ;; C-x bindings in `ctl-x-map'
         ("C-x M-:" . consult-complex-command)     ;; orig. repeat-complex-command
         ("C-x b" . consult-buffer)                ;; orig. switch-to-buffer
         ("C-x 4 b" . consult-buffer-other-window) ;; orig. switch-to-buffer-other-window
         ("C-x 5 b" . consult-buffer-other-frame)  ;; orig. switch-to-buffer-other-frame
         ("C-x t b" . consult-buffer-other-tab)    ;; orig. switch-to-buffer-other-tab
         ("C-x r b" . consult-bookmark)            ;; orig. bookmark-jump
         ("C-x p b" . consult-project-buffer)      ;; orig. project-switch-to-buffer
         ;; Custom M-# bindings for fast register access
         ("M-#" . consult-register-load)
         ("M-'" . consult-register-store)          ;; orig. abbrev-prefix-mark (unrelated)
         ("C-M-#" . consult-register)
         ;; Other custom bindings
         ("M-y" . consult-yank-pop)                ;; orig. yank-pop
         ;; M-g bindings in `goto-map'
         ("M-g e" . consult-compile-error)
         ("M-g f" . consult-flymake)               ;; Alternative: consult-flycheck
         ("M-g g" . consult-goto-line)             ;; orig. goto-line
         ("M-g M-g" . consult-goto-line)           ;; orig. goto-line
         ("M-g o" . consult-outline)               ;; Alternative: consult-org-heading
         ("M-g m" . consult-mark)
         ("M-g k" . consult-global-mark)
         ("M-g i" . consult-imenu)
         ("M-g I" . consult-imenu-multi)
         ;; M-s bindings in `search-map'
         ("M-s d" . consult-find)                  ;; Alternative: consult-fd
         ("M-s c" . consult-locate)
         ("M-s g" . consult-grep)
         ("M-s G" . consult-git-grep)
         ("M-s r" . consult-ripgrep)
         ("M-s l" . consult-line)
         ("M-s L" . consult-line-multi)
         ("M-s k" . consult-keep-lines)
         ("M-s u" . consult-focus-lines)
         ;; Isearch integration
         ("M-s e" . consult-isearch-history)
         :map isearch-mode-map
         ("M-e" . consult-isearch-history)         ;; orig. isearch-edit-string
         ("M-s e" . consult-isearch-history)       ;; orig. isearch-edit-string
         ("M-s l" . consult-line)                  ;; needed by consult-line to detect isearch
         ("M-s L" . consult-line-multi)            ;; needed by consult-line to detect isearch
         ;; Minibuffer history
         :map minibuffer-local-map
         ("M-s" . consult-history)                 ;; orig. next-matching-history-element
         ("M-r" . consult-history))                ;; orig. previous-matching-history-element

  ;; 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

  ;; Tweak the register preview for `consult-register-load',
  ;; `consult-register-store' and the built-in commands.  This improves the
  ;; register formatting, adds thin separator lines, register sorting and hides
  ;; the window mode line.
  (advice-add #'register-preview :override #'consult-register-window)
  (setq register-preview-delay 0.5)

  ;; 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

  ;; Optionally configure preview. The default value
  ;; is 'any, such that any key triggers the preview.
  ;; (setq consult-preview-key 'any)
  ;; (setq consult-preview-key "M-.")
  ;; (setq consult-preview-key '("S-<down>" "S-<up>"))
  ;; For some commands and buffer sources it is useful to configure the
  ;; :preview-key on a per-command basis using the `consult-customize' macro.
  (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))

  ;; Optionally configure the narrowing key.
  ;; Both < and C-+ work reasonably well.
  (setq consult-narrow-key "<") ;; "C-+"

  ;; Optionally make narrowing help available in the minibuffer.
  ;; You may want to use `embark-prefix-help-command' or which-key instead.
  ;; (keymap-set consult-narrow-map (concat consult-narrow-key " ?") #'consult-narrow-help)
)

(use-package consult-eglot
  :after eglot)

embark

;; Pulls in embark as a dependency
(use-package embark-consult
  :ensure t ; only need to install it, embark loads it after consult if found
  :hook
  (embark-collect-mode . consult-preview-at-point-mode))

vertico

(use-package vertico
  :custom
  (vertico-resize t) ;; Grow and shrink the Vertico minibuffer
  (vertico-cycle t) ;; Enable cycling for `vertico-next/previous'
  :init
  (vertico-mode))

(use-package vertico-directory
  :ensure f
  :bind (:map vertico-map
              ("C-l" . vertico-directory-up)
              ("RET" . vertico-directory-enter)
              ("DEL" . vertico-directory-delete-char)))

savehist

;; Persist history over Emacs restarts. Vertico sorts by history position.
(use-package savehist
  :init
  (savehist-mode))

emacs

;; A few more useful configurations...
(use-package emacs
  :custom
  ;; Hide commands in M-x which do not work in the current mode.  Vertico
  ;; commands are hidden in normal buffers. This setting is useful beyond
  ;; Vertico.
  (read-extended-command-predicate #'command-completion-default-include-p)
  :init
  ;; Add prompt indicator to `completing-read-multiple'.
  ;; We display [CRM<separator>], e.g., [CRM,] if the separator is a comma.
  (defun crm-indicator (args)
    (cons (format "[CRM%s] %s"
                  (replace-regexp-in-string
                   "\\`\\[.*?]\\*\\|\\[.*?]\\*\\'" ""
                   crm-separator)
                  (car args))
          (cdr args)))
  (advice-add #'completing-read-multiple :filter-args #'crm-indicator))

orderless

;; Optionally use the `orderless' completion style.
(use-package orderless
  :custom
  ;; Configure a custom style dispatcher (see the Consult wiki)
  ;; (orderless-style-dispatchers '(+orderless-consult-dispatch orderless-affix-dispatch))
  ;; (orderless-component-separator #'orderless-escapable-split-on-space)
  (completion-styles '(orderless ))
  (completion-category-defaults nil)
  (completion-category-overrides '((file (styles partial-completion)))))

wgrep

(use-package wgrep)

eglot

(use-package eglot)

(use-package dape
  :after eglot
  :config
  ;; Turn on global bindings for setting breakpoints with mouse
  (dape-breakpoint-global-mode)
  (setq dape-inlay-hints t))

smart-mode-line

(use-package smart-mode-line
  :init
  (sml/setup))

Misc

sudo-edit

(use-package sudo-edit)

Miscellaneous configuration

Swap super and meta keys on macOS

This makes it consistent with Linux.

(when (eq system-type 'darwin)
  (setq mac-command-modifier 'meta)
  (setq mac-option-modifier 'super)
  (setq mac-control-modifier 'control))

Kill all buffers except the current one

Pulled from https://www.emacswiki.org/emacs/KillingBuffers#h5o-2

(defun kill-other-buffers ()
  "Kill all other buffers."
  (interactive)
  (mapc 'kill-buffer (delq (current-buffer) (buffer-list))))

Increase resolution of rendered PDFs

(setq doc-view-resolution 300)

Custom font utilities

(defun preview-font ()
  "Interactively preview available fonts."
  (interactive)
  (let ((font (completing-read "Preview font: " (font-family-list))))
    (set-frame-font font t t)))

(defun preview-font-full ()
  "Preview full font faces including variants."
  (interactive)
  (let* ((fonts (delete-dups (sort (x-list-fonts "*" nil) #'string<)))
         (font (completing-read "Preview font face: " fonts)))
    (set-frame-font font t t)))

(defun print-current-font ()
  "Print the current frame font in the minibuffer and echo area."
  (interactive)
  (message "Current font: %s" (frame-parameter nil 'font)))

Ensure HOME is not a symlink

On Fedora Kinoite and other Atomic Desktops, /home is symlinked to /var/home. This causes issues with breakpoints not working in certain debuggers.

(when-let ((real-home (file-truename (getenv "HOME"))))
  (when (not (string= (getenv "HOME") real-home))
    (setenv "HOME" real-home)))

About

My emacs config

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors