Proxy Information
Original URL
gemini://starbreaker.smol.pub/my-emacs-configuration
Status Code
Success (20)
Meta
text/gemini # my emacs configuration I thought I'd test the ox-gemini package for Emacs by having it convert my configuration org file. :) => https://git.sr.ht/~starbreaker/emacs.d source repository As you can see below, the conversion isn't perfect. # GNU Emacs configuration Use `C-c C-v t' to generate the following files if you've cloned this repository and made changes: * README.md * Makefile * config.el * secrets.el When defining custom functions or variables for my `~/.emacs', I've been prefixing them with `emacs-init/' to keep them in a kind of namespace (since Emacs Lisp doesn't actually provide built-in namespacing). You're welcome to use this prefix yourself if using this config and improving on it, or use your own prefix. # README ``` # GNU Emacs Configuration I'm tired of my GNU Emacs configuration being a mess, so it's time to organize it. It's available under [GPL-3][1] if you want to use it yourself and you're worried about licensing. ## Installation This repository comes with a [makefile][2]. If you have GNU Make installed, you can just run `make install` in your terminal to build the config and install it if you've modified your copy. You can also run `make` to just generate the config. Otherwise, you can manually run the following commands in your terminal after moving to where you cloned this repository: ```bash mkdir -p ~/.emacs.d cp init.el ~/.emacs.d/ ``` ## Extending the Config Add source blocks as needed. Just copy and paste: ```org #+BEGIN_SRC emacs-lisp :tangle yes #+END_SRC ``` ## Credits I stole bits and pieces of my config from various sources, listed below: - [System Crafters][3] - [Howardism][4] - [Emacs Redux][5] [1]: ./LICENSE [2]: ./Makefile [3]: https://systemcrafters.cc [4]: https://howardism.org [5]: https://emacsredux.com/blog/2013/05/09/keep-backup-and-auto-save-files-out-of-the-way/ ``` # Makefile Run this in the repository's directory to install. ``` .DEFAULT: tangle DEST=~/.emacs tangle: config.org emacs -Q --batch --eval "(progn (require 'ob-tangle) (dolist (file command-line-args-left) (with-current-buffer (find-file-noselect file) (org-babel-tangle))))" config.org install: tangle install -m 644 config.el ${DEST} ``` # Garbage Collection Adjustments Let's adjust the garbage collection threshold, and have Emacs do garbage collection when it loses focus. ``` (setq gc-cons-threshold 100000000) (add-hook 'focus-out-hook 'garbage-collect) ``` # Package Initialization Let's get the package system set up first. ## Initialize Package Sources ``` (require 'package) (setq package-archives '(("melpa" . "https://melpa.org/packages/") ("org" . "https://orgmode.org/elpa/") ("elpa" . "https://elpa.gnu.org/packages/"))) ``` ## Initialize the Package Mangler ``` (package-initialize) ``` ## Update Installed Packages ``` (unless package-archive-contents (package-refresh-contents)) ``` ## Set up use-package I want to set up package using `use-package' and make sure it works even if I end up going back to BSD. use-package ``` (unless (package-installed-p 'use-package) (package-install 'use-package)) (require 'use-package) (setq use-package-always-ensure t) ``` Using `use-package-always-ensure' saves me some typing and guarantees consistency. # External Secret Storage Rather than put credentials, API keys, and location information here, I'm using a separate file called `secrets.el'. ``` (load "~/.emacs.d/secrets.el") ``` Incidentally, this is what `secrets.el' looks like: ``` (setq user-full-name "YOUR NAME" user-mail-address "YOUR EMAIL" erc-nick "YOUR IRC NICK" erc-password "YOUR IRC NICK PASSWORD" sunshine-location "CITY,STATE/PROVINCE,COUNTRY" sunshine-appid "YOUR OPEN WEATHER MAP API KEY") ``` # Basic/Built-in Settings These are settings that don't require external packages or Elisp functions. ## External Secret Storage Let's load credentials from a separate file. ## Default Font Families I'm going to define some font family variables so that I can set them once and use them wherever I need them. Gotta stay DRY, you know? ``` (defvar emacs-init/default-font "Fira Code Retina") (defvar emacs-init/default-variable-font "Noto Serif") ``` To install these fonts on a Debian-style distro, use the following commands. ``` sudo apt install fonts-firacode fonts-noto-hinted ``` ## Default Font Sizes These font-sizes made sense on my Thinkpad T60, but you may want to bump them up for a higher-resolution display. ``` (defvar emacs-init/default-font-size 120) (defvar emacs-init/default-variable-font-size 140) ``` ## Set Default, Fixed-Pitch, and Variable-Pitch Faces Now we'll use the variables I defined earlier to set my fonts. ``` (set-face-attribute 'default nil :font emacs-init/default-font :height emacs-init/default-font-size :weight 'regular) (set-face-attribute 'fixed-pitch nil :font emacs-init/default-font :height emacs-init/default-font-size :weight 'regular) (set-face-attribute 'variable-pitch nil :font emacs-init/default-variable-font :height emacs-init/default-variable-font-size :weight 'regular) ``` ## No Splash Screen I know I'm using Emacs. Just gimme a scratch buffer. ``` (setq inhibit-startup-message t) ``` ## Suppress Unnecessary UI Elements I don't want a scrollbar, a toolbar, or tooltips. ``` (scroll-bar-mode -1) (tool-bar-mode -1) (tooltip-mode -1) ``` The menu comes in handy on occasion, though, so I'll refrain from suppressing it for now. If you disagree, change the tangle property on the block below to 'yes'. ``` (menu-bar-mode -1) ``` ## Make ESC quit prompts In case I'm too drunk to remember to use C-g to back out of something—or have spent too long using vi. ``` (global-set-key (kbd "") 'keyboard-escape-quit) ``` ## Wider Fringes Let's have a little breathing room on the sides. There's no need for buffers to be flush with frame borders. ``` (set-fringe-mode 15) ``` ## Visual Bell If I screw up, I don't want to hear it. Just flash the screen. Not like I've got epilepsy. ``` (setq visible-bell t) ``` ## Unicode Settings I used this on OpenBSD to ensure that Emacs consistently used UTF-8. I don't think it does any harm to use it on GNU/Linux. ``` (prefer-coding-system 'utf-8) (set-default-coding-systems 'utf-8) (set-terminal-coding-system 'utf-8) (set-keyboard-coding-system 'utf-8) ``` ## Column Display in Modeline By default, the modeline only shows the current line. I want to see the current column, too. ``` (column-number-mode t) ``` ## File Size in Modeline Emacs doesn't display the file/buffer size in the modeline, either. Let's change that. ``` (size-indication-mode t) ``` ## Line Number Display I want to show line numbers on the sides when coding, but not in certain text and shell modes. ``` (global-display-line-numbers-mode t) (dolist (mode '(org-mode-hook markdown-mode-hook gemini-mode-hook term-mode-hook shell-mode-hook eshell-mode-hook eww-mode-hook elpher-mode-hook emms-mode-hook erc-mode-hook)) (add-hook mode (lambda () (display-line-numbers-mode 0)))) ``` ## Buffer Identification How do we tell buffers apart if they have the same name? Fortunately, uniquify comes with GNU Emacs by default and doesn't require a package. ``` (require 'uniquify) (setq uniquify-buffer-name-style 'forward) ``` ## Frame Title Based on Current Buffer I want the Emacs frame (window for all you normies) to reflect the filename of the current buffer. ``` (setq frame-title-format '((:eval (if (buffer-file-name) (abbreviate-file-name (buffer-file-name)) "%b")))) ``` ## Scroll Behavior Adjustments These settings seem to smooth out scrolling for me, but I could be wrong and might have [misread the manual]. Make adjustments as needed. ``` (setq scroll-margin 0 scroll-conservatively 100000 scroll-preserve-screen-position 1) ``` => https://www.gnu.org/software/emacs/manual/html_node/emacs/Auto-Scrolling.html misread the manual ## ERC (Emacs Relay Chat) I want to use Emacs as my IRC client. Yes, I know how crazy that sounds. ``` (require 'erc) ``` However, because Libera Chat uses SSL, we'll need TLS support. ``` (require 'tls) ``` ### Set up a keybinding to connect to Libera Chat I want to use `C-c e i' to start ERC and connect to Libera.Chat (Freenode's successor) ``` (global-set-key "\C-cel" (lambda () (interactive) (erc-tls :server "irc.libera.chat" :port "6697" :nick "starbreaker"))) ``` Don't forget to change the nick here. ### Automatically join certain channels on Libera Chat When I join irc.libera.chat, I want in on the following channels: * midnight-pub * gemini * callahans (if it got transferred from freenode) I'll also join these, just in case. * emacs * erc * debian ``` (setq erc-autojoin-channels-alist '(("libera.chat" "#gemini" "#midnight-pub" "#callahans" "#emacs" "#erc" "#debian"))) ``` ### Other Options Here are some quality-of-life settings I got out of the ERC manual. ``` (setq erc-rename-buffers t erc-interpret-mirc-color t) ``` ## Fun with Dired [Dired] is another sweet tool built into GNU Emacs. It's a file manager in your editor. First, let's use Dired-X when loading Dired to extend its capabilities. ``` (eval-after-load "dired" '(require 'dired-x)) ``` Next, let's tweak a few settings. I want dired to trash files by default, and put them in the standard trash location. I also want recursive copies and deletes. ``` (setq dired-recursive-deletes 'always dired-recursive-copies 'always dired-deletion-confirmer 'y-or-n-p dired-clean-up-buffers-too nil delete-by-moving-to-trash t trash-directory "~/.local/share/Trash/files/" dired-dwim-target t dired-listing-switches "-alv") ``` I'm going to bind a couple of keys to make Dired work with EMMS; I like to play entire albums by feeding EMMS a directory since I'm anal about keeping my music organized on disk. I also have an alternate keybinding to change to wdired; I prefer `C-c w' to the default `C-x C-q'. ``` (add-hook 'dired-mode-hook (lambda () (local-set-key "E" 'emms-play-dired) (local-set-key "A" 'emms-add-dired) (local-set-key (kbd "C-c w") 'wdired-change-to-wdired-mode))) ``` I only want to tangle the following when running OpenBSD. On most GNU/Linux distributions, the default ls from GNU coreutils is compatible with dired. If you're on a BSD whose ls doesn't provide GNU extensions, or you're using busybox as your shell/coreutils, your ls might not work right with dired. Installing GNU coreutils and enabling this setting should sort you out. ``` (setq insert-directory-program "/usr/local/bin/gls") ``` Just make sure you adjust the path as needed. => https://www.gnu.org/software/emacs/manual/html_node/emacs/Dired.html Dired ## Using gtkLP to provide a print dialog I sometimes like to print from Emacs, especially while writing, so my wife can read rough cuts without squinting at a screen. Having Emacs talk to gtklp allows me to take advantage of CUPS. ``` (setq lpr-command "/usr/bin/gtklp") (setq ps-lpr-command "/usr/bin/gtklp") ``` Since it's an external tool, install it through your package mangler. In my case that's either `sudo apt install gtklp' or `doas pkg_add -iv gtklp'. ## Putting backups and auto-saves in /tmp I don't like having to do `rm *~' to purge backup files, let alone `rm -rf *~', because if I'm drunk enough to forget that '~' at the end I'm stuck restoring from backups. Instead, let's put that stuff in /tmp where it belongs. ``` (setq backup-directory-alist `((".*" . ,temporary-file-directory)) auto-save-file-name-transforms `((".*" ,temporary-file-directory t))) ``` ## y/n instead of yes/no I'm lazy. I shouldn't have to type 'yes' at a prompt when 'y' will do. ``` (fset 'yes-or-no-p 'y-or-n-p) ``` ## Automatically reload buffer when file is changed on disk If a file I have open is changed on disk, I want the buffer automatically refreshed. Emacs calls this "reverting" a buffer, most likely for reasons that made sense when Emacs was an extension of TECO in the 1970s. ``` (global-auto-revert-mode t) ``` ## Indentation settings By default, I want to indent with spaces, with a tab width of 2. I should be able to override this using the editorconfig package if a given project has an .editorconfig file. Using hard tabs by default causes headaches when manually editing YAML and JSON files ``` (setq-default tab-width 2 indent-tabs-mode nil) ``` ## Kill the Current Buffer Here's a keybinding to get rid of the current buffer once I'm done with a file. ``` (global-set-key (kbd "C-c k") 'kill-this-buffer) ``` ## Print the Current Region and Buffer Here are keybindings to print the current region and buffer since Emacs doesn't provide one. This will convert the current region/buffer to monochrome PostScript and send it to CUPS via gtkLP. ``` (global-set-key (kbd "C-c p r") 'ps-print-region) (global-set-key (kbd "C-c p b") 'ps-print-buffer) ``` # Elisp Functions Emacs Lisp functions used later on get defined here. ## Get track info from file tags. ``` (defun emacs-init/emms-track-description (track) (let ((artist (emms-track-get track 'info-artist)) (year (emms-track-get track 'info-year)) (album (emms-track-get track 'info-album)) (tracknumber (emms-track-get track 'info-tracknumber)) (title (emms-track-get track 'info-title))) (cond ((or artist title) (concat (if (> (length artist) 0) artist "Unknown Artist") " - " (if (> (length year) 0) year "XXXX") " - " (if (> (length album) 0) album "Unknown Album") " - " (if (> (length tracknumber) 0) (format "%02d" (string-to-number tracknumber)) "XX") " - " (if (> (length title) 0) title "Unknown Title"))) (t (emms-track-simple-description track))))) ``` ## Make eww use elpher for gopher and gemini URLs When using eww, if I hit a gopher or gemini URL, I want eww to call elpher. We'll install elpher later. ``` (defun emacs-init/eww-browse-url (original url &optional new-window) "Handle gemini links." (cond ((string-match-p "\\`\\(gemini\\|gopher\\)://" url) (require 'elpher) (elpher-go url)) (t (funcall original url new-window)))) ``` ## Org Mode Functions These are some functions I cribbed from System Crafters. First is a basic setup function that enables `org-indent', `variable-pitch-mode', and `visual-line-mode'. It makes Org work more like a word processor. ``` (defun emacs-init/org-mode-setup () (org-indent-mode) (variable-pitch-mode 1) (visual-line-mode 1)) ``` Next, we need to set up fonts for Org mode. This function is more involved since we're using different font sizes for various heading levels, and also want to replace the hyphen used in lists with a bullet point. ``` (defun emacs-init/org-font-setup () (dolist (face '((org-level-1 . 1.5) (org-level-2 . 1.4) (org-level-3 . 1.3) (org-level-4 . 1.2) (org-level-5 . 1.1) (org-level-6 . 1.05))) (set-face-attribute (car face) nil :font emacs-init/default-variable-font :weight 'regular :height (cdr face))) (set-face-attribute 'org-block nil :foreground nil :inherit 'fixed-pitch) (set-face-attribute 'org-code nil :inherit '(shadow fixed-pitch)) (set-face-attribute 'org-table nil :inherit '(shadow fixed-pitch)) (set-face-attribute 'org-verbatim nil :inherit '(shadow fixed-pitch)) (set-face-attribute 'org-special-keyword nil :inherit '(font-lock-comment-face fixed-pitch)) (set-face-attribute 'org-meta-line nil :inherit '(font-lock-comment-face fixed-pitch)) (set-face-attribute 'org-checkbox nil :inherit 'fixed-pitch) (font-lock-add-keywords 'org-mode '(("^ *\\([-]\\) " (0 (prog1 () (compose-region (match-beginning 1) (match-end 1) "•"))))))) ``` ## Visual Fill Setup Let's set up visual fill and centering for text modes. This was originally just for org mode, but I bet it work work nicely when writing Gemini text or Markdown. I'll rename the function accordingly. ``` (defun emacs-init/visual-fill-setup () (setq visual-fill-column-width 80 visual-fill-column-center-text t) (visual-fill-column-mode 1)) ``` When we set up the `visual-fill-column' package, we'll add hooks that call this function for Org mode, Gemini mode, and Markdown mode. ## Elfeed Shortcuts These are shortcut functions I can use to jump around in Elfeed ``` (defun emacs-init/elfeed-show-all () (interactive) (bookmark-maybe-load-default-file) (bookmark-jump "elfeed-all")) (defun emacs-init/elfeed-show-emacs () (interactive) (bookmark-maybe-load-default-file) (bookmark-jump "elfeed-emacs")) (defun emacs-init/elfeed-show-misc () (interactive) (bookmark-maybe-load-default-file) (bookmark-jump "elfeed-misc")) (defun emacs-init/elfeed-show-debian () (interactive) (bookmark-maybe-load-default-file) (bookmark-jump "elfeed-debian")) ``` # Packages ## ORG MODE This is basically the killer app for a lot of GNU Emacs people. It's an outliner, a journaling app, a todo list, a more powerful markup language than Markdown, and a literate programming tool. It's what I'm using to generate this configuration. ``` (use-package org :hook (org-mode . emacs-init/org-mode-setup) :config (setq org-ellipsis " ▾") (emacs-init/org-font-setup)) ``` I also want to have prettier bullets in Org mode, so we'll use `org-bullets' ``` (use-package org-bullets :after org :hook (org-mode . org-bullets-mode) :custom (org-bullets-bullet-list '("◉" "○" "●" "○" "●" "○" "●"))) ``` ## Visual Fill Column Let's make Org and other text markup modes look a little nicer using `visual-fill-column'. ``` (use-package visual-fill-column :hook (org-mode . emacs-init/visual-fill-setup) :hook (markdown-mode . emacs-init/visual-fill-setup) :hook (gemini-mode . emacs-init/visual-fill-setup)) ``` ## Markdown When I want to edit Markdown directly, let's have the appropriate mode. `markdown-mode' will give me syntax highlighting, a handy menu, preview support, and works with `pandoc'. ``` (use-package markdown-mode :init (setq markdown-command "/usr/bin/pandoc") :mode (("README\\.md\\'" . gfm-mode) ("\\.md\\'" . markdown-mode) ("\\.markdown\\'" . markdown-mode))) ``` ## Gemini Text Since I've gotten into using Gemini protocol (and prefer it over the Web and HTML when I'm not getting paid to put up with webshit), I want support for writing Gemtext (Gemini markup) in Emacs. ``` (use-package gemini-mode) ``` Being able to export from org mode to gemini might be nice, too. ``` (use-package ox-gemini :after org :config (require 'ox-gemini)) ``` ## Command Log Mode If for some reason I want to be able to log commands in an Emacs session, this package will make it possible. ``` (use-package command-log-mode) ``` ## unfill: a nicer fill mode for hard-wrapping (or un-wrapping) text This has come in pretty handy. ``` (use-package unfill :ensure t :config (global-set-key (kbd "") 'toggle-fill-unfill)) ``` ## Async mode for Dired Let's extend Dired further to allow asynchronous operations (thus improving responsiveness). ``` (use-package async :diminish dired-async-mode :init (dired-async-mode 1)) ``` ## Elpher: Smol Net Browsing in Emacs The `elpher' package is a complement to the built-in `eww' tool; the latter handles web browsing in emacs, and the former also lets you view sites via the gopher and gemini protocols. We're going to install it here, and set up a hook that allows `eww' to call `elpher' as needed. ``` (use-package elpher :config (set browse-url-browser-function 'eww-browse-url) (advice-add 'eww-browse-url :around 'emacs-init/eww-browse-url)) ``` ## EMMS (Emacs Multimedia System) Let's use Emacs to rock out. We won't need a package since EMMS is included in GNU Emacs. We'll also configure EMMS to cache album covers embedded in tracks, and use Python's Tinytag library to get track metadata. ``` (use-package emms :config (require 'emms-setup) (require 'emms-info-metaflac) (require 'emms-info-mp3info) (require 'emms-info-ogginfo) (emms-all) (emms-default-players) (setq emms-source-file-default-directory "~/Music/") (setq emms-browser-covers 'emms-browser-cache-thumbnail-async) (setq emms-playlist-default-major-mode 'emms-playlist-mode) (setq emms-track-description-function 'emacs-init/emms-track-description) (add-to-list 'emms-info-functions 'emms-info-libtag) (add-to-list 'emms-info-functions 'emms-info-mp3info) (add-to-list 'emms-info-functions 'emms-info-ogginfo) (global-set-key (kbd "C-c e p") 'emms-playlist-mode-go) (global-set-key (kbd "C-c e r") 'emms-toggle-repeat-playlist) (global-set-key (kbd "C-c e s") 'emms-toggle-random-playlist)) ``` Tinytag is a Python package, so we'll need to install it. This is how I did it on Debian. ``` sudo apt install python3-pip pip install tinytag ``` ### EMMS Keybindings Here's a list of keybindings for EMMS, so I don't have to dig through the manual. Also, I've got custom bindings that aren't in the manual. 🐱 * #### Custom Bindings * Open the EMMS Playlist buffer. * Toggle *repeat* mode on current playlist * Toggle *shuffle* on current playlist * #### Default Bindings for EMMS Playlist buffer * next track * previous track * stop playback * pause playback (and unpause) * show track info in minibuffer * center current track * play track under cursor ## In case I find myself doing webshit again... I'm trying not to do webshit unless I'm getting paid (in which case I have other computers for that) but if I find myself messing with HTML and friends for a personal project I should probably have `web-mode' and `emmet-mode' handy. The latter makes typing out tags a /little/ less tedious. ``` (use-package web-mode :config (add-to-list 'auto-mode-alist '("\\.phtml\\'" . web-mode)) (add-to-list 'auto-mode-alist '("\\.shtml\\'" . web-mode)) (add-to-list 'auto-mode-alist '("\\.tpl\\.php\\'" . web-mode)) (add-to-list 'auto-mode-alist '("\\.[agj]sp\\'" . web-mode)) (add-to-list 'auto-mode-alist '("\\.as[cp]x\\'" . web-mode)) (add-to-list 'auto-mode-alist '("\\.erb\\'" . web-mode)) (add-to-list 'auto-mode-alist '("\\.mustache\\'" . web-mode)) (add-to-list 'auto-mode-alist '("\\.njk\\'" . web-mode)) (add-to-list 'auto-mode-alist '("\\.djhtml\\'" . web-mode))) ``` Now it's time to install `emmet-mode'... ``` (use-package emmet-mode :init (add-hook 'sgml-mode-hook 'emmet-mode) (add-hook 'html-mode-hook 'emmet-mode) (add-hook 'css-mode-hook 'emmet-mode)) ``` ## Elfeed: reading RSS/Atom feeds in Emacs I want to use Emacs as my feed reader, so we'll install `elfeed'. While installing, I'll map my shortcut functions to keys for convenience. As I add categories, I'll need new functions and mappings. I'll also pull `elfeed-org' because I want to store my feeds list in an org file. ``` (use-package elfeed-org :config (elfeed-org) (setq rmh-elfeed-org-files (list "/home/starbreaker/git/srht/elfeed-org/feed.org"))) ``` Since we're forcing elfeed to update during init, I want to make sure elfeed-org is set up first. We'll also have elfeed update every 8 hours. ``` (use-package elfeed :init (elfeed-update) :bind (:map elfeed-search-mode-map ("A" . emacs-init/elfeed-show-all) ("E" . emacs-init/elfeed-show-emacs) ("D" . emacs-init/elfeed-show-debian) ("M" . emacs-init/elfeed-show-misc)) :config (run-at-time nil (* 8 60 60) #'elfeed-update)) ``` ## Smart Parentheses When I open a set of parentheses, it would be handy to have the closed automatically. Yeah, I'm lazy. ``` (use-package smartparens :config (require 'smartparens-config) (show-paren-mode t)) ``` ## Rainbow Delimiters This should make it easier to spot matching parentheses and brackets. ``` (use-package rainbow-delimiters :hook (prog-mode . rainbow-delimiters-mode)) ``` ## Weather Forecasts With Sunshine I'm going to use Aaron Bieber's sunshine package to get weather when I don't feel like using eww to hit . :) ``` (use-package sunshine :config (setq sunshine-show-icons t) (global-set-key (kbd "C-c s f") 'sunshine-forecast)) ``` ## Improved Help Buffers with Helpful Using the `helpful' package should improve Emacs' help buffers by providing more contextual information. ``` (use-package helpful :custom (counsel-describe-function-function #'helpful-callable) (counsel-describe-variable-function #'helpful-variable) :bind ([remap describe-function] . counsel-describe-function) ([remap describe-command] . helpful-command) ([remap describe-variable] . counsel-describe-variable) ([remap describe-key] . helpful-key)) ``` ## Keybinding Completion with which-key Emacs has a shitload of keybindings, and I still don't have them all in my head. Maybe which-key can help? ``` (use-package which-key :init (which-key-mode) :diminish which-key-mode :config (setq which-key-idle-delay 0.3)) ``` ## Learning Emacs Keybindings with Guru Mode I still tend to use arrow keys in Emacs, so maybe having Guru Mode to nudge me will help me get better at Emacs. But I won't use it in text modes. ``` (use-package guru-mode :diminish guru-mode :config (add-hook 'prog-mode-hook 'guru-mode)) ``` If this annoys you, just disable tangling. ## Completion Setup If I want to use Ivy and Ivy-Rich, I need to start by installing Counsel. ``` (use-package counsel :bind (("M-x" . counsel-M-x) ("C-x b" . counsel-ibuffer) ("C-x C-f" . counsel-find-file) :map minibuffer-local-map ("C-r" . 'counsel-minibuffer-history))) ``` ## Basic Completion with Ivy The Ivy package provides "incremental vertical completion", and is a more convenient version of Emacs' default completion. It's also lighter than Helm. ``` (use-package ivy :diminish :bind (("C-s" . swiper) :map ivy-minibuffer-map ("TAB" . ivy-alt-done) ("C-l" . ivy-alt-done) ("C-j" . ivy-next-line) ("C-k" . ivy-previous-line) :map ivy-switch-buffer-map ("C-k" . ivy-previous-line) ("C-l" . ivy-done) ("C-d" . ivy-switch-buffer-kill) :map ivy-reverse-i-search-map ("C-k" . ivy-previous-line) ("C-d" . ivy-reverse-i-search-kill)) :config (ivy-mode 1)) ``` This config also replaces the default find bound to `C-s' with Ivy's "swiper". ## Beautifying Completions with Ivy-Rich Adding Ivy-Rich will make Ivy more comfortable to use. ``` (use-package ivy-rich :init (ivy-rich-mode 1) :config (setq ivy-format-function #'ivy-format-function-line) (setq ivy-rich-display-transformers-list (plist-put ivy-rich-display-transformers-list 'ivy-switch-buffer '(:columns ((ivy-rich-candidate (:width 40)) (ivy-rich-switch-buffer-indicators ( :width 4 :face error :align right)) (ivy-rich-switch-buffer-major-mode ( :width 12 :face warning)) (ivy-rich-switch-buffer-project ( :width 15 :face success)) (ivy-rich-switch-buffer-path ( :width (lambda (x) (ivy-rich-switch-buffer-shorten-path x (ivy-rich-minibuffer-width 0.3)))))) :predicate (lambda (cand) (if-let ((buffer (get-buffer cand))) ;; Don't mess with EXWM buffers (with-current-buffer buffer (not (derived-mode-p 'exwm-mode))))))))) ``` ## Ivy + EMMS? Using Ivy with EMMS might make it more pleasant to use, and might make a good alternative to grabbing albums with Dired. ``` (use-package ivy-emms :config (global-set-key (kbd "C-c e i") 'ivy-emms)) ``` ## All the Icons I need this for Doom Themes and the Doom Modeline. ``` (use-package all-the-icons) ``` When first using this config, remember to run `M-x all-the-icons-install-fonts'. Then everything will work properly the next time you start Emacs. ## All the Icons (Dired) Never mind pimping my ride. Let's pimp my Dired. ``` (use-package all-the-icons-dired :config (add-hook 'dired-mode-hook 'all-the-icons-dired-mode)) ``` ## All the Icons (Ivy-Rich) Let's add all-the-icons to Ivy and further enrich the experience. ``` (use-package all-the-icons-ivy-rich :config (all-the-icons-ivy-rich-mode 1)) ``` ## Doom Themes I don't want to use Doom Emacs, but I like the themes. ``` (use-package doom-themes :config (setq doom-themes-enable-bold t doom-themes-enable-italic t) (load-theme 'doom-tomorrow-night t) (doom-themes-visual-bell-config) (doom-themes-org-config)) ``` The config enables bold and italic fonts before loading the theme. It also sets up visual effects on errors and fixes org mode font rendering. The byte compiler will gripe about a bunch of stuff not being defined when first installing the packages, but the bytecomp warning only shows up once. ## Doom Modeline Let's have a more attractive modeline, shall we? It'll be cleaner and take advantage of the all-the-icons package. ``` (use-package doom-modeline :init (doom-modeline-mode 1) :custom ((doom-modeline-height 20))) ;; everything below here is generated by GNU Emacs... ``` That should be everything.
Capsule Response Time
204.372069 milliseconds
Gemini-to-HTML Time
0.009196 milliseconds

This content has been proxied by September (ba2dc).