Skip to content

Latest commit

 

History

History
1006 lines (970 loc) · 34.7 KB

init.org

File metadata and controls

1006 lines (970 loc) · 34.7 KB

Emacs init.el Configuration File

Initialization

Header

lexical binding

;; init.el -*- lexical-binding: t; -*-

File name handler

This is consulted on every require, load and various path/io functions. to get a minor speed up by nooping this. Restore file-name-handler-alist later, because it is needed for handling encrypted or compressed files, among other things.

(defvar initial-file-name-handler-alist file-name-handler-alist)

(setq file-name-handler-alist nil)

(defun reset-file-handler-alist-h ()
  (setq file-name-handler-alist initial-file-name-handler-alist))
(add-hook 'emacs-startup-hook #'reset-file-handler-alist-h)

Definition

Operating System

Determine what operating system are emacs on.

(defconst is-mac     (eq system-type 'darwin))
(defconst is-linux   (eq system-type 'gnu/linux))
(defconst is-windows (memq system-type '(cygwin windows-nt ms-dos)))

Directories

  1. The path to the currently loaded .emacs.d directory.
  2. Storage location for system’s installation of Emacs.
  3. Directory for non-volatile local storage, files that don’t change much, like server binaries, external dependencies or long-term shared data.
  4. Directory for volatile local storage, for files that change often, like cache files
  5. Directory for local installation packages
(defconst emacs-dir
  (eval-when-compile (file-truename user-emacs-directory)))

(defconst local-dir (concat emacs-dir "local/"))
(defconst etc-dir (concat local-dir "etc/"))
(defconst cache-dir (concat local-dir "cache/"))
(defconst site-lisp-dir (concat local-dir "site-lisp/"))

Exec Path

(when is-windows
  (let (
        (path-list
         [
          "C:/Windows/system32"
          "C:/Windows"
          "C:/Windows/System32/Wbem"
          "C:/Windows/System32/WindowsPowerShell/v1.0"
          "C:/msys64/mingw64/bin"
          "C:/Python38/Scripts/"
          "C:/Python38/"
          "C:/Program Files/Git/cmd"
          "C:/emacs-28/bin"
          "C:/ProgramData/chocolatey/bin"
          ]))

    (setenv "PATH" (mapconcat 'identity path-list ";"))
    (setq exec-path (append path-list (list "." exec-directory)))))

Package Management

develop branch

Use the develop branch of straight.el on Radian’s develop branch.

(setq straight-repository-branch "develop")

detect package modifications

If watchexec and Python are installed, use file watchers to detect package modifications. This saves time at startup. Otherwise, use the ever-reliable find(1).

(if is-windows
    (setq straight-check-for-modifications 'live)
  (if (and (executable-find "watchexec")
	   (executable-find "python3"))
    (setq straight-check-for-modifications '(watch-files find-when-checking))
  (setq straight-check-for-modifications
	  '(find-at-startup find-when-checking))))

package recipe

Clear out recipe overrides (in case of re-init).

(setq straight-recipe-overrides nil)

bootstrap straight.el

(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))

use-package

Package use-package provides a handy macro by the same name which is essentially a wrapper around with-eval-after-load with a lot of handy syntactic sugar and useful features.

(straight-use-package 'use-package)

use-package by default

When configuring a feature with use-package, also tell straight.el to install a package of the same name, unless otherwise specified using the :straight keyword.

(setq straight-use-package-by-default t)

lazy loading

Tell use-package to always load features lazily unless told otherwise. It’s nicer to have this kind of thing be deterministic: if :demand is present, the loading is eager; otherwise, the loading is lazy. See https://github.com/jwiegley/use-package#notes-about-lazy-loading.

(setq use-package-always-defer t)

use-feature

Like use-package, but with straight-use-package-by-default disabled. NAME and ARGS are as in use-package.

(defmacro use-feature (name &rest args)
  (declare (indent defun))
  `(use-package ,name
     :straight nil
     ,@args))

delight

Enables you to customise the mode names displayed in the mode line.

(use-package delight
  :straight (:host github :repo "emacs-straight/delight")
  :demand t)

straight.el configuration

Feature straight-x from package straight provides experimental/unstable extensions to straight.el which are not yet ready for official inclusion. Add an autoload for this extremely useful command.

(use-feature straight-x
  :commands (straight-x-fetch-all))

Prevent Emacs-provided Org from being loaded

(straight-use-package
 '(org :host github :repo "emacs-straight/org-mode" :local-repo "org"))

Environment

Frame

resize pixelwise

Don’t resize windows & frames in steps, it’s prohibitive to prevent the user from resizing it to exact dimensions, and looks weird.

 (setq window-resize-pixelwise t
	frame-resize-pixelwise t)

vertical split

Favor vertical splits over horizontal ones. Screens are usually wide.

 (setq split-width-threshold 160
	split-height-threshold nil)

Fringes

Reduce the clutter in the fringes; reserve that space for more useful information.

(setq indicate-buffer-boundaries nil
      indicate-empty-lines t)

Windows

Winner

Feature `winner’ provides an undo/redo stack for window configurations, with undo and redo being C-c left and C-c right, respectively. (Actually “redo” doesn’t revert a single undo, but rather a whole sequence of them.) For instance, you can use C-x 1 to focus on a particular window, then return to your previous layout with C-c left.

(use-feature winner
  :demand t
  :config
  (winner-mode +1))

Window Divider

The native border “consumes” a pixel of the fringe on righter-most splits, window-divider does not.

(setq window-divider-default-places t
      window-divider-default-bottom-width 1
      window-divider-default-right-width 1)
(add-hook 'window-setup-hook #'window-divider-mode)

Mode Line

buffer name

Make the buffer name unique if more than one buffer have the same name. Do not beep or blink

(use-feature uniquify
  :demand t
  :init
  (setq uniquify-buffer-name-style 'forward))

Column number

Make `mode-line-position’ show the column, not just the row.

(column-number-mode +1)

Minibuffer

Minibuffer

Allow for minibuffer-ception. Sometimes we need another minibuffer command while we’re in the minibuffer. Expand the minibuffer to fit multi-line text displayed in the echo-area. But don’t let the minibuffer grow beyond this size Try really hard to keep the cursor from getting stuck in the read-only prompt portion of the minibuffer.

(setq enable-recursive-minibuffers t
      resize-mini-windows 'grow-only
      max-mini-window-height 0.15
      minibuffer-prompt-properties
      '(read-only t intangible t cursor-intangible t face minibuffer-prompt))
(add-hook 'minibuffer-setup-hook #'cursor-intangible-mode)

SaveHist

Savehist mode saves your minibuffer histories, optionally save other histories and other variables (see option savehist-additional-variables). for instance save search strings, search-ring regexp-search-ring. save only specific histories, not all minibuffer histories, savehist-save-minibuffer-history. save only on kill savehist-autosave-interval nil.

(use-feature savehist
  :demand t
  :init
  (setq savehist-file (concat cache-dir "savehist")
        savehist-save-minibuffer-history t
        savehist-autosave-interval nil
        savehist-additional-variables '(kill-ring search-ring regexp-search-ring))
  :config
  (savehist-mode +1))

Faces and UI

GUI

Suppress GUI features.

(setq use-file-dialog nil
      use-dialog-box nil
      inhibit-splash-screen t
      initial-scratch-message nil
      initial-major-mode 'fundamental-mode)
(fset #'display-startup-echo-area-message #'ignore)

Tooltip

Don’t display floating tooltips, display their contents in the echo-area.

(use-feature tooltip
  :init
  (when (bound-and-true-p tooltip-mode)
    (tooltip-mode -1))
  (when is-linux
    (setq x-gtk-use-system-tooltips nil)))

Font

x-underline-at desent-line Draw the underline at the the descent line underline-minimum-offset 1 between baseline and underline. Set the default font and font size. Using set-face-attribute does not have an effect. Use the same font for fixed-pitch text as the rest of Emacs.

(setq x-underline-at-descent-line t
      underline-minimum-offset 1)
(set-face-attribute
 'default (selected-frame) :font
   "-*-Consolas-medium-normal-normal-*-14-*-*-*-m-0-iso10646-1")

Theme

(use-package emacs-color-theme-solarized
  :straight (:host github :repo "sellout/emacs-color-theme-solarized")
  :init
  (setq solarized-termcolor 256
        solarized-broken-srgb t
        solarized-contrast 'normal)

  (defun solarized-light ()
      (load-theme 'solarized t)
      (set-frame-parameter nil 'background-mode 'light)
      (enable-theme 'solarized))

  (defun solarized-dark ()
      (load-theme 'solarized t)
      (set-frame-parameter nil 'background-mode 'dark)
      (enable-theme 'solarized))

  (defun solarized-switch ()
      (interactive)
      (if (string= (frame-parameter nil 'background-mode) 'light)
          (solarized-dark)
        (solarized-light)))

  (solarized-light)
  :bind* (("C-c <f6>" . #'solarized-switch)))

Cursor

Don’t blink the cursor. Don’t stretch the cursor to fit wide characters.

(use-feature emacs
  :init
  (setq cursor-type 'box
        cursor-in-non-selected-windows 'hollow
        visible-cursor nil
        x-stretch-cursor nil)
  :config
  (blink-cursor-mode -1))

Highlight

(use-package hl-line
  :init
  (setq hl-line-sticky-flag nil)
  (add-hook 'prog-mode-hook #'hl-line-mode))

Parenthesis

Highlight matching parentheses when the point is on them. Don’t blink the paren matching the one at point.

(use-feature paren
  :init
  (setq show-paren-style 'parenthesis
        show-paren-when-point-in-periphery t
        show-paren-when-point-inside-paren t
        blink-matching-paren nil)
  (show-paren-mode 1))

Communication

Security

Emacs is a huge security vulnerability, what with all the dependencies it pulls in from all corners of the globe. Let’s at least try to be more discerning.

 (setq gnutls-verify-error (getenv "INSECURE")
	tls-checktrust gnutls-verify-error
	tls-program '("gnutls-cli --x509cafile %t -p %p %h"
		      ;; compatibility fallbacks
		      "gnutls-cli -p %p %h"
		      "openssl s_client -connect %h:%p -no_ssl2 -no_ssl3 -ign_eof"))

Emacs stores authinfo in HOME and in plaintext. This file usually stores usernames, passwords, and other such treasures for the aspiring malicious third party.

(setq auth-sources (list (expand-file-name "authinfo.gpg" etc-dir)
			   "~/.authinfo.gpg"))

gnutls

Feature gnutls provides support for SSL/TLS connections, using the GnuTLS. use-package does eval-when-compile for us normally. gnutls-verify-error Do not allow insecure TLS connections. Bump the required security level for TLS to an acceptably modern value.

(with-eval-after-load 'gnutls
  (eval-when-compile
    (require 'gnutls))
  (setq gnutls-verify-error t)
  (setq gnutls-min-prime-bits 3072))

url-http

Feature url-http is a library for making HTTP requests. (with-eval-after-load ‘url-http (eval-when-compile (require ‘url-http))

(radian-defadvice radian–no-query-on-http-kill (buffer) :filter-return #’url-http “Disable query-on-exit for all network connections. This prevents Emacs shutdown from being interrupted just because there is a pending network request.” (prog1 buffer (set-process-query-on-exit-flag (get-buffer-process buffer) nil))))

Don’t ping

Don’t ping things that look like domain names.

(setq ffap-machine-p-known 'reject)

Applications

Transient

(use-package transient
  :config
  (setq transient-levels-file  (concat etc-dir "transient/levels")
        transient-values-file  (concat etc-dir "transient/values")
        transient-history-file (concat etc-dir "transient/history")))

Magit

Package magit provides a full graphical interface for Git within Emacs. C-x g display information about the current Git repository,

(use-package magit
  :bind (("C-x g" . #'magit-status)
         ("C-x M-g" . #'magit-dispatch)
         ("C-c M-g" . #'magit-file-dispatch)))

Ledger

(use-package ledger-mode)

Convenience

Line Numbers

Explicitly define a width to reduce computation Show absolute line numbers for narrowed regions makes it easier to tell the buffer is narrowed, and where you are, exactly. Enable line numbers in most text-editing modes. avoid global-display-line-numbers-mode because there are many special and temporary modes where we don’t need/want them.

(setq-default display-line-numbers-width 2
              display-line-numbers-widen t)

(add-hook 'prog-mode-hook #'display-line-numbers-mode)

;; (defun switch-relative-absolute-linum ()
;;   (interactive)
;;   (if (string= (bound-and-true-p display-line-numbers) 'relative)
;;       (display-line-numbers 'relative)
;;     (display-line-numbers 1)))

;; (global-set-key (kbd "C-c <f7>") 'switch-relative-absolute-linum)

Whitespace

(setq sentence-end-double-space nil
      delete-trailing-lines nil
      require-final-newline t
      tabify-regexp "^\t* [ \t]+")

Windmove

Feature `windmove’ provides keybindings S-left, S-right, S-up, and S-down to move between windows. This is much more convenient and efficient than using the default binding, C-x o, to cycle through all of them in an essentially unpredictable order.

(use-feature windmove
  :demand t
  :config
  (windmove-default-keybindings)

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

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

Word Wrapping

wrapping

(setq-default word-wrap t
              truncate-lines t
              truncate-partial-width-windows nil
              fill-column 80)

text mode

Favor hard-wrapping in text modes

(add-hook 'text-mode-hook #'auto-fill-mode)

Case-insensitive

if the first case-sensitive search through the alist fails to find a matching major mode, a second case-insensitive search is ignore.

(setq auto-mode-case-fold nil)

Scrolling

mouse in terminal

Enable mouse in terminal Emacs

(add-hook 'tty-setup-hook #'xterm-mouse-mode)

adjust scrolling

Emacs spends too much effort recentering the screen if you scroll the cursor more than N lines past window edges (where N is the settings of `scroll-conservatively’). This is especially slow in larger files during large-scale scrolling commands. If kept over 100, the window is never automatically recentered. Reduce cursor lag by a tiny bit by not auto-adjusting `window-vscroll’ for tall lines. mouse don’t accelerate scrolling except using shift.

(setq hscroll-margin 2
      hscroll-step 1
      scroll-conservatively 101
      scroll-margin 0
      scroll-preserve-screen-position t
      auto-window-vscroll nil)

(use-feature mwheel
  :init
  (setq  mouse-wheel-scroll-amount '(1 ((shift) . 5) ((control)))
         mouse-wheel-progressive-speed nil))

Mac trackpad

Sane trackpad/mouse scroll settings in Mac.

(when is-mac
  (setq mac-redisplay-dont-reset-vscroll t
	  mac-mouse-wheel-smooth-scroll nil))

rapid scrolling

More performant rapid scrolling over unfontified regions. May cause brief spells of inaccurate fontification immediately after scrolling.

(setq fast-but-imprecise-scrolling t)

Apropos

If the variable apropos-do-all is non-nil, most apropos commands behave as if they had been given a prefix argument. There is one exception: apropos-variable without a prefix argument will always search for all variables, no matter what the value of apropos-do-all is.

(setq apropos-do-all t)

Feedback

Make simple title bar. Show current key-sequence in minibuffer immediately (<1 second). Follow symlinks when opening files, from the file’s true directory. Disable the warning “same file” and redirect to the existing buffer. Turn off the alarm bell, flash the frame instead. Enable all disabled commands. Confirmation prompt when quiting Emacs. Typing y/n rather than yes/no.

(use-package emacs
  :init
  (setq frame-title-format '("%b %& GNU Emacs")
        echo-keystrokes 1e-6
        find-file-visit-truename t
        vc-follow-symlinks t
        find-file-suppress-same-file-warnings t
        ring-bell-function #'ignore
        visible-bell t
        disabled-command-function nil
        confirm-kill-emacs #'y-or-n-p)
  (fset #'yes-or-no-p #'y-or-n-p))

Ibuffer

Feature ibuffer provides a more modern replacement for the list-buffers command.

(use-feature ibuffer
  :config
  (setq ibuffer-expert t
        ibuffer-use-other-window nil
        ibuffer-show-empty-filter-groups nil
        ibuffer-saved-filter-groups
        '(("Main"
           ("Directories" (mode . dired-mode))
           ("Org" (mode . org-mode))
           ("Programming" (mode . prog-mode))
           ("Markdown" (mode . markdown-mode))
           ("Magit" (or
                    (mode . magit-blame-mode)
                    (mode . magit-cherry-mode)
                    (mode . magit-diff-mode)
                    (mode . magit-log-mode)
                    (mode . magit-process-mode)
                    (mode . magit-status-mode)))
           ("Emacs" (or
                    (name . "^\\*Help\\*$")
                    (name . "^\\*Custom.*")
                    (name . "^\\*Org Agenda\\*$")
                    (name . "^\\*info\\*$")
                    (name . "^\\*scratch\\*$")
                    (name . "^\\*Backtrace\\*$")
                    (name . "^\\*Completions\\*$")
                    (name . "^\\*straight-process\\*$")
                    (name . "^\\*Messages\\*$"))))))
  :hook
  (ibuffer-mode . hl-line-mode)
  (ibuffer-mode . (lambda ()
                    (ibuffer-switch-to-saved-filter-groups "Main")))
  :bind
  (([remap list-buffers] . #'ibuffer)))

Data

Saveplace

Feature `saveplace’ provides a minor mode for remembering the location of point in each file you visit, and returning it there when you find the file again.

(use-feature saveplace
  :demand t
  :init
  (setq save-place-file (concat cache-dir "saveplace")
        save-place-limit 100)
  :config
  (save-place-mode +1))

Development

GCMH

(use-package gcmh
  :straight (:host gitlab :repo "koral/gcmh")
  :demand t
  :delight
  :init
  (gcmh-mode 1))

Log Message

Maximum number of lines to keep in the message log buffer.

(setq message-log-max 8192)

Legacy System

Disable warnings from legacy advice system. They aren’t useful, and we can’t often do anything about them besides changing packages upstream

(setq ad-redefinition-action 'accept)

Delay UI update

Emacs “updates” its ui more often than it needs to, so we slow it down slightly, from 0.5s:

(setq idle-update-delay 1)

Optimizations

bidirectional rendering

Disable bidirectional text rendering for a modest performance boost. this renders Emacs unable to detect/display right-to-left languages

(setq-default bidi-display-reordering 'left-to-right
              bidi-paragraph-direction 'left-to-right)

rendering/line scan

Reduce rendering/line scan work for Emacs by not rendering cursors or regions in non-focused windows.

(setq-default cursor-in-non-selected-windows nil)
(setq highlight-nonselected-windows nil)

resizing emacs frame

Resizing the Emacs frame can be a terribly expensive part of changing the font. By inhibiting this, we halve startup times, particularly when we use fonts that are larger than the system default (which would resize the frame).

(setq frame-inhibit-implied-resize t)

Windows performance

Performance on Windows is considerably worse than elsewhere, especially if WSL is involved.

  1. Reduce the workload when doing file IO
  2. Font compacting can be terribly expensive, especially for rendering icon

fonts on Windows. Whether it has a noteable affect on Linux and Mac hasn’t been determined.

(when is-windows
  (setq w32-get-true-file-attributes nil)
  (setq inhibit-compacting-font-caches t))

command line options

Remove command line options that aren’t relevant to our current OS; means slightly less to process at startup.

(unless is-mac   (setq command-line-ns-option-alist nil))
(unless is-linux (setq command-line-x-option-alist nil))

Editing

UTF-8

UTF-8 as the default coding system, Except for the clipboard on Windows, where its contents could be in an encoding that’s wider than utf-8, let Emacs/the OS decide what encoding to use.

(when (fboundp 'set-charset-priority)
  (set-charset-priority 'unicode))
(prefer-coding-system 'utf-8)
(setq locale-coding-system 'utf-8)

(unless is-windows
  (setq selection-coding-system 'utf-8))

Tabs and Indentation

(use-feature emacs
  :init
  (setq-default tab-width 4
                tab-always-indent t
                indent-tabs-mode nil))

Delete selection

Feature delsel provides an alternative behavior for certain actions when you have a selection active. Namely: if you start typing when you have something selected, then the selection will be deleted; and if you press DEL while you have something selected, it will be deleted rather than killed. (Otherwise, in both cases the selection is deselected and the normal function of the key is performed.)

(use-feature delsel
  :demand t
  :config
  (delete-selection-mode +1))

Clipboard/kill-ring

duplicate

Eliminate duplicates in the kill ring.

(setq kill-do-not-save-duplicates t)

middle mouse paste

Middle-click paste at point, not at click

(setq mouse-yank-at-point t)

Find

Feature `isearch’ provides a basic and fast mechanism for jumping forward or backward to occurrences of a given search string. Eliminate the 0.25s idle delay for isearch highlighting, as in my opinion it usually produces a rather disjointed and distracting UX.

(use-feature isearch
  :config
  (setq lazy-highlight-initial-delay 0))

Dabbrev

(use-feature dabbrev
  :commands (dabbrev-expand dabbrev-completion)
  :config
  (setq dabbrev-abbrev-char-regexp "\\sw\\|\\s_")
  (setq dabbrev-abbrev-skip-leading-regexp "\\$\\|\\*\\|/\\|=")
  (setq dabbrev-backward-only nil)
  (setq dabbrev-case-distinction nil)
  (setq dabbrev-case-fold-search t)
  (setq dabbrev-case-replace nil)
  (setq dabbrev-check-other-buffers t)
  (setq dabbrev-eliminate-newlines nil)
  (setq dabbrev-upcase-means-case-search t))

Hippie Expand

(use-feature hippie-exp
  :config
  (defvar he-search-loc-backward (make-marker))
  (defvar he-search-loc-forward (make-marker))

  (defun he--closest-in-this-buffer (old beg-function search-function)
    (let (expansion)
      (unless old
        (he-init-string (funcall beg-function) (point))
        (set-marker he-search-loc-backward he-string-beg)
        (set-marker he-search-loc-forward he-string-end))

      (if (not (equal he-search-string ""))
          (save-excursion
            (save-restriction
              (if hippie-expand-no-restriction
                  (widen))

              (let (forward-point
                    backward-point
                    forward-distance
                    backward-distance
                    forward-expansion
                    backward-expansion
                    chosen)

                ;; search backward
                (goto-char he-search-loc-backward)
                (setq expansion (funcall search-function he-search-string t))

                (when expansion
                  (setq backward-expansion expansion)
                  (setq backward-point (point))
                  (setq backward-distance (- he-string-beg backward-point)))

                ;; search forward
                (goto-char he-search-loc-forward)
                (setq expansion (funcall search-function he-search-string))

                (when expansion
                  (setq forward-expansion expansion)
                  (setq forward-point (point))
                  (setq forward-distance (- forward-point he-string-beg)))

                ;; choose depending on distance
                (setq chosen (cond
                              ((and forward-point backward-point)
                               (if (< forward-distance backward-distance) :forward :backward))

                              (forward-point :forward)
                              (backward-point :backward)))

                (when (equal chosen :forward)
                  (setq expansion forward-expansion)
                  (set-marker he-search-loc-forward forward-point))

                (when (equal chosen :backward)
                  (setq expansion backward-expansion)
                  (set-marker he-search-loc-backward backward-point))

                ))))

      (if (not expansion)
          (progn
            (if old (he-reset-string))
            nil)
        (progn
          (he-substitute-string expansion t)
          t))))

  (defun try-expand-dabbrev-closest-first (old)
    "Try to expand word \"dynamically\", searching the current buffer.
  The argument OLD has to be nil the first call of this function, and t
  for subsequent calls (for further possible expansions of the same
  string).  It returns t if a new expansion is found, nil otherwise."
    (he--closest-in-this-buffer old #'he-dabbrev-beg #'he-dabbrev-search))

  (setq hippie-expand-try-functions-list
        '(try-expand-dabbrev-closest-first
          try-complete-file-name
          try-expand-dabbrev-all-buffers
          try-expand-dabbrev-from-kill
          try-expand-all-abbrevs
          try-complete-lisp-symbol-partially
          try-complete-lisp-symbol))
  :bind
  (([remap dabbrev-expand] . #'hippie-expand)))

External

Files

Back Up

Don’t autosave files or create lock/history/backup files. But have a place to store them. Don’t litter emacs directory

(use-feature emacs
  :init
  (setq auto-save-default nil
        create-lockfiles nil
        make-backup-files nil
        auto-save-list-file-name           (concat cache-dir "autosave")
        backup-directory-alist             `(("." . ,(concat cache-dir "backup/")))
        abbrev-file-name                   (concat local-dir "abbrev.el")
        async-byte-compile-log-file        (concat etc-dir "async-bytecomp.log")
        bookmark-default-file              (concat etc-dir "bookmarks")
        custom-file                        (concat local-dir "custom.el")
        custom-theme-directory             (concat local-dir "themes/")
        desktop-dirname                    (concat etc-dir "desktop")
        desktop-base-file-name             "autosave"
        desktop-base-lock-name             "autosave-lock"
        pcache-directory                   (concat cache-dir "pcache/")
        request-storage-directory          (concat cache-dir "request")
        server-auth-dir                    (concat cache-dir "server/")
        shared-game-score-directory        (concat etc-dir "shared-game-score/")
        tramp-auto-save-directory          (concat cache-dir "tramp-auto-save/")
        tramp-backup-directory-alist backup-directory-alist
        tramp-persistency-file-name        (concat cache-dir "tramp-persistency.el")
        url-cache-directory                (concat cache-dir "url/")
        url-configuration-directory        (concat etc-dir "url/")
        gamegrid-user-score-file-directory (concat etc-dir "games/")))

Auto Revert

Turn the delay on auto-reloading from 5 seconds down to 1 second. We have to do this before turning on `auto-revert-mode’ for the change to take effect. (Note that if we set this variable using `customize-set-variable’, all it does is toggle the mode off and on again to make the change take effect, so that way is dumb.)

Auto-revert all buffers, not only file-visiting buffers. The docstring warns about potential performance problems but this should not be an issue since we only revert visible buffers.

Since we automatically revert all visible buffers after one second, there’s no point in asking the user whether or not they want to do it when they find a file. This disables that prompt.

(use-feature autorevert
  :defer 2
  :delight
  :config
  (setq auto-revert-interval 1)
  (global-auto-revert-mode +1)
  (setq global-auto-revert-non-file-buffers t)
  (setq revert-without-query '(".*")))

Recentf

Recentf is a minor mode that builds a list of recently opened files. This list is is automatically saved across sessions on exiting Emacs you can then access this list through a command or the menu.

(use-feature recentf
  :demand t
  :init
  (setq recentf-save-file (concat cache-dir "recentf")
        recentf-auto-cleanup 'never
        recentf-max-menu-items 10
        recentf-max-saved-items 100)
  :config
  (recentf-mode 1))

Directory Editor

Dired

Feature dired provides a simplistic filesystem manager in Emacs. Automatically revert Dired buffers on revisiting their directory. Dired copies/delete directories recursively. always means to copy/delete recursively without asking. top means to ask for each directory at top level. If there is a Dired buffer displayed in some window, see its current directory, instead of this Dired buffer’s current directory. Details such as file ownership and permissions are hidden from view, by default. Highlight the current line in Dired.

(use-feature dired
  :config
  (setq dired-auto-revert-buffer t
        dired-recursive-copies 'top
        dired-recursive-deletes 'top
        delete-by-moving-to-trash t
        dired-listing-switches "-alh"
        dired-dwim-target t)
  :hook ((dired-mode . dired-hide-details-mode)
         (dired-mode . hl-line-mode)))

Dired-aux

(use-feature dired-aux
  :config
  (setq dired-isearch-filenames 'dwim
        dired-create-destination-dirs 'ask))

Wdired

(use-feature wdired
  :after dired
  :commands wdired-change-to-wdired-mode
  :config
  (setq wdired-allow-to-change-permissions t
        wdired-create-parent-directories t)

  (defun dired-back-to-start-of-files ()
    (interactive)
    (backward-char (- (current-column) 2)))

  :bind (:map wdired-mode-map
              ([remap move-beginning-of-line] . #'dired-back-to-start-of-files)))

Dired-x

(use-feature dired-x
  :after dired
  :config
  (when-let (cmd (cond (is-mac "open")
                       (is-linux "xdg-open")
                       (is-windows "start")))
    (setq dired-guess-shell-alist-user
          `(("\\.\\(?:docx\\|pdf\\|djvu\\|eps\\)\\'" ,cmd)
            ("\\.\\(?:jpe?g\\|png\\|gif\\|xpm\\)\\'" ,cmd)
            ("\\.\\(?:xcf\\)\\'" ,cmd)
            ("\\.csv\\'" ,cmd)
            ("\\.tex\\'" ,cmd)
            ("\\.\\(?:mp4\\|mkv\\|avi\\|flv\\|rm\\|rmvb\\|ogv\\)\\(?:\\.part\\)?\\'" ,cmd)
            ("\\.\\(?:mp3\\|flac\\)\\'" ,cmd)
            ("\\.html?\\'" ,cmd)
            ("\\.md\\'" ,cmd)))))

Icomplete

(use-feature icomplete
  :init
  (fido-mode 1)
  :config
   (defun fido-recentf ()
    (interactive)
    (let ((files (mapcar 'abbreviate-file-name recentf-list)))
      (find-file
       (completing-read "Recent File: " files nil t)
       )))
  :bind
  (([remap find-file-read-only] . #'fido-recentf)))

Help

Programming

Text

Organization

Org

(use-feature org
  :init
  (org-babel-do-load-languages
   'org-babel-load-languages
   '((ledger . t) ;this is the important one for this tutorial
     )))

Local