Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/meatcar/emacs.d
A "modern" emacs config
https://github.com/meatcar/emacs.d
emacs emacs-configuration evil-mode straight-el
Last synced: 3 months ago
JSON representation
A "modern" emacs config
- Host: GitHub
- URL: https://github.com/meatcar/emacs.d
- Owner: meatcar
- License: mit
- Created: 2020-08-27T03:00:24.000Z (over 4 years ago)
- Default Branch: master
- Last Pushed: 2023-12-20T19:04:40.000Z (about 1 year ago)
- Last Synced: 2024-04-15T02:55:00.935Z (10 months ago)
- Topics: emacs, emacs-configuration, evil-mode, straight-el
- Homepage:
- Size: 325 KB
- Stars: 29
- Watchers: 3
- Forks: 6
- Open Issues: 0
-
Metadata Files:
- Readme: README.org
- License: LICENSE
Awesome Lists containing this project
README
#+STARTUP: fold
#+babel: :cache yes
#+PROPERTY: header-args :results silent :tangle init.el* The Bestest Emacs
Inspired by Spacemacs and Doom Emacs. Most of the "aesthetic" parts of those distributions are available as plugins, so gluing together your own configuration isn't too hard.
Featuring:
- [[https://github.com/raxod502/straight.el][straight.el]] for package management
- maximal [[https://github.com/jwiegley/use-package][use-package]] for package configuration
- maximal [[https://github.com/emacs-evil/evil][EVIL]] for vim comfort* Goals
** Multi-platform
Be multi-platform, as I jump between Linux, Windows, and WSL** Consistency and Modernity
Be as idiomatic as possible. Parts of this config have been copied and pasted from other places, but are rewritten/updated if needed to stay consistent and easy to read.Every feature provided by ~use-package~ is used over calling elisp functions. That means ~:custom~ is preferred over ~setq~, ~:hook~ over ~add-hook~, etc. where possible.
** Minimal Customization, Maximal Reuse
Minimal customization of packages we use, unless they misbehave. Try to document and rationalize any setting set thats not part of the package's setup instructions.Try to avoid "Not Invented Here" syndrome, use an existing package to do something instead of rolling our own.
* Startup
Emacs startup times can be painful, if left uncontrolled. With a "basic" config like this one still resulting in multi-second startup times, its a frequent topic of debate. Distributions like =doom-emacs= use fast startup times as one of the main selling points. Let's try to pull in all the wisdom on how to keep our config simple yet fast.
** Early Init
:properties:
:header-args+: :tangle "./early-init.el"
:end:In Emacs 27+, package initialization occurs before ~user-init-file~ is loaded, but after ~early-init-file~. We handle package initialization, so we must prevent Emacs from doing it early!
#+begin_src emacs-lisp
;;; -*- lexical-binding: t; -*-
#+end_src*** Defer Compliations
#+begin_src emacs-lisp
(defvar comp-deferred-compliation)
(setq comp-deferred-compilation t)
#+end_src*** Low-haniging Speedup Fruits
#+begin_src emacs-lisp
(setq package-enable-at-startup nil);; Resizing the Emacs frame can be a terribly expensive part of changing the
;; font. By inhibiting this, we easily halve startup times with fonts that are
;; larger than the system default.
(setq frame-inhibit-implied-resize t)
#+end_src*** Hide bars
Prevent the glimpse of un-styled Emacs by disabling these UI elements early.#+begin_src emacs-lisp
(menu-bar-mode -1)
(unless (and (display-graphic-p) (eq system-type 'darwin))
(push '(menu-bar-lines . 0) default-frame-alist))
(push '(tool-bar-lines . 0) default-frame-alist)
(push '(vertical-scroll-bars) default-frame-alist)
#+end_src*** Reduce GC
Following [[https://github.com/hlissner/doom-emacs/blob/develop/docs/faq.org#how-does-doom-start-up-so-quickly][Doom-Emacs FAQ]], we max the garbage collection threshold on startup, and reset it to the original value after.#+begin_src emacs-lisp
;; max memory available for gc on startup
(defvar me/gc-cons-threshold 16777216)
(setq gc-cons-threshold most-positive-fixnum
gc-cons-percentage 0.6)
(add-hook 'emacs-startup-hook
(lambda ()
(setq gc-cons-threshold me/gc-cons-threshold
gc-cons-percentage 0.1)));; max memory available for gc when opening minibuffer
(defun me/defer-garbage-collection-h ()
(setq gc-cons-threshold most-positive-fixnum))(defun me/restore-garbage-collection-h ()
;; Defer it so that commands launched immediately after will enjoy the
;; benefits.
(run-at-time
1 nil (lambda () (setq gc-cons-threshold me/gc-cons-threshold))))(add-hook 'minibuffer-setup-hook #'me/defer-garbage-collection-h)
(add-hook 'minibuffer-exit-hook #'me/restore-garbage-collection-h)
(setq garbage-collection-messages t)
#+end_src*** Temporarily avoid special handling of files
We also set the ~file-name-handler-alist~ to an empty list, and reset it after Emacs has finished initializing.
#+begin_src emacs-lisp
(defvar me/-file-name-handler-alist file-name-handler-alist)
(setq file-name-handler-alist nil)
(add-hook 'emacs-startup-hook
(lambda ()
(setq file-name-handler-alist me/-file-name-handler-alist)))
#+end_src*** Disable =site-run-file=
#+begin_src emacs-lisp
(setq site-run-file nil)
#+end_src*** Don't compact font caches
#+begin_src emacs-lisp
(setq inhibit-compacting-font-caches t)
#+end_src*** Improve I/O
Optimizations for improving I/O performance. Increase max bytes read from a sub-process in a single op (Emacs 27+)#+begin_src emacs-lisp
(when (boundp 'read-process-output-max)
;; 1MB in bytes, default 4096 bytes
(setq read-process-output-max 1048576))
#+end_src*** Straight.el
[[https://github.com/raxod502/straight.el][straight.el]] is used to download packages for us from all over the web. It stores them all in their respective git folders in =.emacs.d/straight=, which makes debugging, and contributing fixes back upstream as easy as possible.First, we configure some settings for =staight.el= to better integrate with =use-package=. [[https://github.com/jwiegley/use-package][use-package]] is a nice and consistent way to declare packages and their respective configs.
#+begin_src emacs-lisp
(setq straight-use-package-by-default t
use-package-always-defer t
straight-cache-autoloads t
straight-vc-git-default-clone-depth 1
straight-check-for-modifications '(find-when-checking)
package-enable-at-startup nil
vc-follow-symlinks t)
#+end_srcThen, we want to enable debugging whenever we encounter an error.
#+begin_src emacs-lisp
(setq debug-on-error t)
#+end_srcNow, let's fetch =straight.el=.
#+begin_src emacs-lisp
(defvar bootstrap-version)
(let ((bootstrap-file
(expand-file-name "straight/repos/straight.el/bootstrap.el" user-emacs-directory))
(bootstrap-version 5))
(unless (file-exists-p bootstrap-file)
(with-current-buffer
(url-retrieve-synchronously
"https://raw.githubusercontent.com/raxod502/straight.el/develop/install.el"
'silent 'inhibit-cookies)
(goto-char (point-max))
(eval-print-last-sexp)))
(load bootstrap-file nil 'nomessage))
(setq vc-follow-symlinks 'ask) ; restore default
#+end_srcLet's load an optional package which gives us some convenience functions, like ~straight-x-clean-unused-repo~ to remove any packages we don't have configured anymore.
#+begin_src emacs-lisp
(require 'straight-x)
#+end_srcNow, let's install =use-package=.
#+begin_src emacs-lisp
(straight-use-package 'use-package)
#+end_src*** Benchmarking
We use [[https://github.com/jschaf/esup][esup]] and [[https://github.com/dholm/benchmark-init-el][benchmark-init-el]] to keep tabs on our startup speed.#+begin_src emacs-lisp
(use-package esup
:demand t
:commands esup)(use-package benchmark-init
:demand t
:straight (:host github :repo "kekeimiku/benchmark-init-el")
:hook (after-init . benchmark-init/deactivate))
#+end_srcAlso let's print a message to the =*messages*= buffer with the total startup time.
#+begin_src emacs-lisp
(add-hook
'emacs-startup-hook
(lambda ()
(message "Emacs ready in %s with %d garbage collections."
(format
"%.2f seconds"
(float-time
(time-subtract after-init-time before-init-time)))
gcs-done)))
#+end_src*** Use the garbage collector magic hack
#+begin_src emacs-lisp
(use-package gcmh
:demand t
:config
(gcmh-mode 1))
#+end_src*** End early-init.el
#+begin_src emacs-lisp
(provide 'early-init)
#+end_src* General Emacs settings
** Lexical Binding
Make elisp in this file behave like we expect these days. Everyone has this set, but no one explains why.In non-elisp speak, it adds proper scoping and "closure" behaviour to variables.[[https://www.emacswiki.org/emacs/DynamicBindingVsLexicalBinding][This Emacswiki article explains it well.]]
#+begin_src emacs-lisp :comments no
;;; config.el -*- lexical-binding: t ; eval: (view-mode -1) -*-
#+end_srcEnable =view-mode=, which both makes the file read-only (as a reminder
that =init.el= is an auto-generated file, not supposed to be edited),
and provides some convenient key bindings for browsing through the
file.** Constants
Let's define some constants we use throughout our config.#+begin_src emacs-lisp
;; environment
(defconst *is-windows* (eq system-type 'windows-nt))
(defconst *is-unix* (not *is-windows*));; fonts
(defconst *mono-font-family*
(if *is-windows* "JetBrainsMono NF" "GoMono Nerd Font"))
(defconst *mono-font-height*
(if *is-windows* 90 90))
(defconst *serif-font-family*
(if *is-windows* "Georgia" "IBM Plex Serif"))
(defconst *serif-font-height*
(if *is-windows* 110 110))
(defconst *project-dir* (expand-file-name "~/git"))
#+end_src** Make Emacs Sensible
Essentially what [[https://github.com/tpope/vim-sensible][vim-sensible]] does, but we use [[https://git.sr.ht/~technomancy/better-defaults][better-defaults]] in emacs. But it doesn't do everything, so we need to help it out.#+BEGIN_SRC emacs-lisp
(use-package better-defaults
:straight (better-defaults :type git :host nil :repo "https://git.sr.ht/~technomancy/better-defaults")
:demand t)(setq default-directory "~/"
;; always follow symlinks when opening files
vc-follow-symlinks t
;; overwrite text when selected, like we expect.
delete-seleciton-mode t
;; quiet startup
inhibit-startup-message t
initial-scratch-message nil
;; hopefully all themes we install are safe
custom-safe-themes t
;; simple lock/backup file management
create-lockfiles nil
backup-by-copying t
delete-old-versions t
;; when quiting emacs, just kill processes
confirm-kill-processes nil
;; ask if local variables are safe once.
enable-local-variables t
;; life is too short to type yes or no
use-short-answers t;; clean up dired buffers
dired-kill-when-opening-new-dired-buffer t);; use human-readable sizes in dired
(setq-default dired-listing-switches "-alh");; always highlight code
(global-font-lock-mode 1)
;; refresh a buffer if changed on disk
(global-auto-revert-mode 1);; save window layout & buffers
;; (setq desktop-restore-eager 5)
;; (desktop-save-mode 1)
#+END_SRC** UTF-8 by Default
Emacs is very conservative about assuming encoding. Everything is utf-8 these days, lets have that as the default.#+begin_src emacs-lisp
(prefer-coding-system 'utf-8)
(set-default-coding-systems 'utf-8)
(set-terminal-coding-system 'utf-8)
(set-keyboard-coding-system 'utf-8)
(set-selection-coding-system 'utf-8)
(set-file-name-coding-system 'utf-8)
(set-clipboard-coding-system 'utf-8)
(if *is-windows*
(set-w32-system-coding-system 'utf-8))
(set-buffer-file-coding-system 'utf-8)
#+end_src** No Littering
[[https://github.com/emacscollective/no-littering][no-littering]] teaches Emacs to not leave it's files everywhere, and just keep them neatly in =.emacs.d= where they don't bother anyone.We also set ~custom-file~ to be within one of these new nice directories, so Emacs doesn't keep chaging =init.el= and messing with our git workflow.
#+begin_src emacs-lisp
(use-package no-littering
:demand t
:config
(setq
auto-save-file-name-transforms
`((".*" ,(no-littering-expand-var-file-name "auto-save/") t)))
(setq custom-file (no-littering-expand-etc-file-name "custom.el"))
(when (file-exists-p custom-file)
(load custom-file)))
#+end_src** Which-key
[[https://github.com/justbur/emacs-which-key][which-key]] pops up a nice window whenever we hesitate about a keyboard shortcut, and shows all the possible keys we can press. Popularized by Spacemacs and Doom-Emacs, we can now configure absurd key combinations, forget about them, and then be delighted to discover them again!#+begin_src emacs-lisp
(use-package which-key
:demand t
:after evil
:custom
(which-key-allow-evil-operators t)
(which-key-show-remaining-keys t)
(which-key-sort-order 'which-key-prefix-then-key-order)
:config
(which-key-mode 1)
(which-key-setup-minibuffer)
(set-face-attribute
'which-key-local-map-description-face nil :weight 'bold))
#+end_src** Evil
[[https://github.com/emacs-evil/evil][EVIL]] is vim emulation in Emacs. There are a number of other evil packages which add vim-like bindings to various modes.#+BEGIN_SRC emacs-lisp
(use-package undo-tree
:demand t
:config
(global-undo-tree-mode))
(use-package evil
:demand t
:after undo-tree
:init
(setq evil-want-integration t
evil-want-keybinding nil
evil-want-C-u-scroll t
evil-want-Y-yank-to-eol t
evil-split-window-below t
evil-vsplit-window-right t
evil-respect-visual-line-mode t
evil-undo-system 'undo-tree)
:config
(evil-mode 1))
(use-package evil-collection
:demand t
:after evil
:config
(evil-collection-init))
(use-package evil-commentary
:demand t
:after evil
:config
(evil-commentary-mode 1))
(use-package evil-surround
:demand t
:after evil
:config
(global-evil-surround-mode 1))
(use-package evil-org
:demand t
:after evil org
:hook (org-mode . evil-org-mode)
:config
(add-hook 'evil-org-mode-hook 'evil-org-set-key-theme)
(require 'evil-org-agenda)
(evil-org-agenda-set-keys))
#+END_SRC** General.el
[[https://github.com/noctuid/general.el][general.el]] is a wrapper around Emacs key-binding mechanisms to make them easier to use. It integrates with use-package, evil, and which-key.We will define two "leader maps", similar to vim's == and == that we will use to bind global and major-mode-specific keybindings. This is how we're kind of like
#+begin_src emacs-lisp
(use-package general
:demand t
:config
(general-evil-setup t)
(general-create-definer leader-def
:states '(normal motion emacs)
:keymaps 'override
:prefix "SPC"
:non-normal-prefix "C-SPC")
(leader-def
"" '(:ignore t :wk "leader")
"f" '(:ignore t :wk "file")
"c" '(:ignore t :wk "checks")
"t" '(:ignore t :wk "toggle")
"b" '(:ignore t :wk "buffer")
"bd" 'kill-this-buffer
"bn" 'next-buffer
"bp" 'previous-buffer
"bx" 'kill-buffer-and-window
"s" '(:ignore t :wk "straight")
"sf" 'straight-x-fetch-all
"sp" 'straight-x-pull-all
"sr" 'straight-remove-unused-repos
"ss" 'straight-get-recipe)(general-create-definer localleader-def
:states '(normal motion emacs)
:keymaps 'override
:prefix "SPC m"
:non-normal-prefix "C-SPC m")
(localleader-def "" '(:ignore t :wk "mode")))
#+end_src** Fancy Compilation
#+begin_src elisp
(add-hook 'compilation-filter-hook 'ansi-color-compilation-filter)
#+end_src* Interface
A good-looking tool is a pleasure to work with. Here, we try to tweak all the dials Emacs gives us to make it pretty and =A E S T H E T I C=.** Aesthetics
#+begin_src emacs-lisp
(setq ring-bell-function 'ignore ; no bell
;; better scrolling
scroll-conservatively 101
scroll-preserve-screen-position 1
mouse-wheel-follow-mouse t
pixel-scroll-precision-use-momentum t)
(setq-default line-spacing 1);; highlight the current line
(global-hl-line-mode t);; Add padding inside buffer windows
(setq-default left-margin-width 2
right-margin-width 2)
(set-window-buffer nil (current-buffer)) ; Use them now.;; Add padding inside frames (windows)
(add-to-list 'default-frame-alist '(internal-border-width . 8))
(set-frame-parameter nil 'internal-border-width 8) ; Use them now;; fix color display when loading emacs in terminal
(defun enable-256color-term ()
(interactive)
(load-library "term/xterm")
(terminal-init-xterm))(unless (display-graphic-p)
(if (string-suffix-p "256color" (getenv "TERM"))
(enable-256color-term)))
#+end_src** Themes
We will load all the themes. We need to ~:defer~ them, to prevent each theme getting loaded upon init, and flashing emacs and conflicting with each other.#+begin_src emacs-lisp
(use-package leuven-theme
:defer t)(use-package vivid-theme
:straight (:host github :repo "websymphony/vivid-theme")
:defer t)(use-package doom-themes
:defer t
:config
(doom-themes-visual-bell-config)
(doom-themes-treemacs-config)
(doom-themes-org-config)
(doom-themes-set-faces nil
;; extending faces breaks orgmode collapsing for now
'(org-block-begin-line :extend nil)
'(org-block-end-line :extend nil)
;; different sized headings are nice.
'(outline-1 :height 1.3)
'(outline-2 :height 1.1)
'(outline-3 :height 1.0)))(use-package modus-themes
:defer t
:custom
(modus-themes-italic-constructs t)
(modus-themes-intense-markup t)
(modus-themes-mode-line '(borderless moody))
(modus-themes-tabs-accented t)
(modus-themes-completions
'((matches . (extrabold background intense))
(selection . (semibold accented intense))
(popup . (accented))
(t . (extrabold intense))))
(modus-themes-org-blocks 'tinted-background)
(modus-themes-mixed-fonts t)
(modus-themes-headings
'((1 . (rainbow))
(2 . (rainbow))
(3 . (rainbow))
(t . (monochrome)))))(defun me/init-theme ()
(load-theme 'modus-operandi t))(add-hook 'emacs-startup-hook #'me/init-theme)
#+end_src** Fonts
The [[https://github.com/rolandwalker/unicode-fonts][unicode-fonts]] package helps Emacs use the full range of unicode characters provided by most fonts.We set a regular font and a ~variable-pitch~ one, the latter is used by ~mixed-pitch-mode~ to render regular text with a proportional font.
#+begin_src emacs-lisp
(use-package persistent-soft
:demand t)
(use-package unicode-fonts
:demand t
:after persistent-soft
:config
(unicode-fonts-setup)
(custom-set-faces
`(default ((t (:family ,*mono-font-family*
:height ,*mono-font-height*))))
`(variable-pitch ((t (:family ,*serif-font-family*
:height ,*serif-font-height*))))))
#+end_src** All The Icons
[[https://github.com/domtronn/all-the-icons.el/][all-the-icons]] allows emacs to show pretty icons anywhere we want.We pair it with [[https://github.com/jtbm37/all-the-icons-dired][all-the-icons-dired]] to show them in =dired=, [[https://github.com/Alexander-Miller/treemacs/blob/master/src/extra/treemacs-all-the-icons.el][treemacs-all-the-icons]] to show them in =treemacs=, and [[https://github.com/iyefrat/all-the-icons-completion][all-the-icons-completion]] for completion sources.
#+begin_src emacs-lisp
(use-package all-the-icons
:demand t)
(use-package all-the-icons-dired
:defer 1
:after all-the-icons
:hook (dired-mode . all-the-icons-dired-mode))
(use-package treemacs-all-the-icons
:defer 1
:after all-the-icons treemacs
:config
(treemacs-load-theme "all-the-icons"))
(use-package all-the-icons-completion
:defer 1
:after all-the-icons
:config
(add-hook 'marginalia-mode-hook
#'all-the-icons-completion-marginalia-setup)
(all-the-icons-completion-mode 1))
#+end_src** Dashboard
[[https://github.com/emacs-dashboard/emacs-dashboard][emacs-dashboard]] adds a nice startup screen, showing recent files, projectes, etc.#+begin_src emacs-lisp
(use-package dashboard
:demand t
:after all-the-icons projectile
:if (< (length command-line-args) 2)
:custom
;; show in `emacsclient -c`
(initial-buffer-choice #'(lambda () (get-buffer-create "*dashboard*")))
(dashboard-startup-banner 'logo)
(dashboard-set-heading-icons t)
(dashboard-set-file-icons t)
(dashboard-center-content t)
(dashboard-items '((recents . 10)
(projects . 5)
(bookmarks . 5)))
:config
(dashboard-setup-startup-hook))
#+end_src** Mode Line
[[https://github.com/seagle0128/doom-modeline][doom-modeline]] provides a clean and simple modeline (bottom bar) for each buffer. We pair it with the [[https://github.com/tarsius/minions][minions]] minor mode to collect all minor modes into a single menu. [[https://github.com/emacsorphanage/anzu][anzu]] is used to show the number of matches when we search in a file.#+begin_src emacs-lisp
(use-package anzu
:defer 1
:after isearch
:config
(global-anzu-mode 1))(use-package minions
:defer 1
:config
(minions-mode 1))(use-package doom-modeline
:demand t
:custom
(inhibit-compacting-font-caches t)
(doom-modeline-height 28)
;; 1 minor mode will be shown thanks to minions
(doom-modeline-minor-modes t)
(doom-modeline-hud t)
:config
(doom-modeline-mode 1))
#+end_src** Tabs
[[https://github.com/ema2159/centaur-tabs][centaur-tabs]] add tabs to the top of the window for emacs. It might sound crazy, but they are useful to keep an eye on which buffers you have open, especially when you jump between projects.Out of the box they come configured ok, but not perfect. We configure the tabs to group by project, and hide/show them for more buffers.
#+begin_src emacs-lisp
(use-package centaur-tabs
:disabled t
:defer 1
:after all-the-icons
:general
(:states 'normal
"gt" 'centaur-tabs-forward
"gT" 'centaur-tabs-backward)
(leader-def
"tg" 'centaur-tabs-toggle-groups)
:hook
(dashboard-mode . centaur-tabs-local-mode)
(term-mode . centaur-tabs-local-mode)
(calendar-mode . centaur-tabs-local-mode)
(org-agenda-mode . centaur-tabs-local-mode)
(helpful-mode . centaur-tabs-local-mode)
:init
(setq centaur-tabs-enable-key-bindings t)
:custom
(centaur-tabs-style "bar")
(centaur-tabs-set-icons t)
(centaur-tabs-set-modified-marker t)
(centaur-tabs-height 28)
(centaur-tabs-gray-out-icons 'buffer)
(centaur-tabs-modified-marker "")
(uniquify-separator "/")
(uniquify-buffer-name-style 'forward)
:config
(centaur-tabs-headline-match)
(centaur-tabs-enable-buffer-reordering)
(centaur-tabs-mode t)
(centaur-tabs-change-fonts *mono-font-family* *mono-font-height*)(defun me/after-theme (&rest _args)
(centaur-tabs-init-tabsets-store)
(centaur-tabs-display-update)
(centaur-tabs-headline-match))
(advice-add 'enable-theme :after #'me/after-theme)(defun centaur-tabs-buffer-groups ()
"`centaur-tabs-buffer-groups' control buffers' group rules.Group centaur-tabs with mode if buffer is derived from `eshell-mode' `emacs-lisp-mode' `dired-mode' `org-mode' `magit-mode'.
All buffer name start with * will group to \"Emacs\".
Other buffer group by `centaur-tabs-get-group-name' with project name."
(list
(cond
;; ((not (eq (file-remote-p (buffer-file-name)) nil))
;; "Remote")
((or (string-equal "*" (substring (buffer-name) 0 1))
(memq major-mode '(magit-process-mode
magit-status-mode
magit-diff-mode
magit-log-mode
magit-file-mode
magit-blob-mode
magit-blame-mode)))
"Emacs")
((derived-mode-p 'dired-mode)
"Dired")
((memq major-mode '(helpful-mode
help-mode))
"Help")
((memq major-mode '(org-agenda-clockreport-mode
org-agenda-mode
org-beamer-mode
org-src-mode
org-indent-mode
org-bullets-mode
org-cdlatex-mode
org-agenda-log-mode
diary-mode))
"OrgMode")
(t
(or (concat "Project: " (projectile-project-name))
(centaur-tabs-get-group-name (current-buffer))))))))
#+end_src** Fast Scroll
Always redraw immediately when scrolling, more responsive and doesn't hang! Sourced from http://emacs.stackexchange.com/a/31427/2418#+begin_src emacs-lisp
(setq fast-but-imprecise-scrolling t
jit-lock-defer-time 0)
#+end_src[[https://github.com/ahungry/fast-scroll][fast-scroll]] "works by temporarily disabling font-lock and switching to a barebones mode-line, until you stop scrolling (at which point it re-enables)". It only does this when scrolling super fast, to keep everything responsive.
#+begin_src emacs-lisp
(use-package fast-scroll
:defer 1
:hook
(fast-scroll-start . (lambda () (flycheck-mode -1)))
(fast-scroll-end . (lambda () (flycheck-mode 1)))
:config
(fast-scroll-config)
(fast-scroll-mode 1))
#+end_src** Wrap Long Lines
[[https://github.com/joostkremers/visual-fill-column][visual-fill-column]] wraps lines at ~fill-column~, and makes it easier to read long lines of code. It is preferred over the built-in ~visual-line-mode~ because it doesn't break words.#+begin_src emacs-lisp
(use-package visual-fill-column
:defer 1
:hook (org-src . visual-fill-column-mode)
:custom
(visual-line-fringe-indicators
'(left-curly-arrow right-curly-arrow))
(split-window-preferred-function
'visual-fill-column-split-window-sensibly)
:config
(advice-add 'text-scale-adjust
:after #'visual-fill-column-adjust)
(global-visual-fill-column-mode 1)
(global-visual-line-mode 1))
#+end_src** Mixed Pitch Mode
[[https://gitlab.com/jabranham/mixed-pitch][mixed-pitch]] allows us to use proportional fonts to display text that isn't code, and make files more readable.#+begin_src emacs-lisp
(use-package mixed-pitch
:after all-the-icons
:defer 1
:commands mixed-pitch-mode
:custom
(mixed-pitch-set-height t))
;; :hook (text-mode . mixed-pitch-mode))
#+end_src** Ligatures
#+begin_src emacs-lisp
(use-package ligature
:straight (:host github :repo "mickeynp/ligature.el")
:defer 1
:config
(ligature-set-ligatures 't '("www"))
(ligature-set-ligatures
'prog-mode
'("-->" "//" "/**" "/*" "*/" "