lexical binding
;; init.el -*- lexical-binding: t; -*-
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)
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)))
- The path to the currently loaded
.emacs.d
directory. - Storage location for system’s installation of Emacs.
- Directory for non-volatile local storage, files that don’t change much, like server binaries, external dependencies or long-term shared data.
- Directory for volatile local storage, for files that change often, like cache files
- 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/"))
(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)))))
Use the develop branch of straight.el
on Radian’s develop branch.
(setq straight-repository-branch "develop")
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))))
Clear out recipe overrides (in case of re-init).
(setq straight-recipe-overrides nil)
(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))
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)
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)
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)
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))
Enables you to customise the mode names displayed in the mode line.
(use-package delight
:straight (:host github :repo "emacs-straight/delight")
:demand t)
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))
(straight-use-package
'(org :host github :repo "emacs-straight/org-mode" :local-repo "org"))
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)
Favor vertical splits over horizontal ones. Screens are usually wide.
(setq split-width-threshold 160
split-height-threshold nil)
Reduce the clutter in the fringes; reserve that space for more useful information.
(setq indicate-buffer-boundaries nil
indicate-empty-lines t)
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))
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)
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))
Make `mode-line-position’ show the column, not just the row.
(column-number-mode +1)
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 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))
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)
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)))
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")
(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)))
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))
(use-package hl-line
:init
(setq hl-line-sticky-flag nil)
(add-hook 'prog-mode-hook #'hl-line-mode))
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))
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"))
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))
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 things that look like domain names.
(setq ffap-machine-p-known 'reject)
(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")))
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)))
(use-package ledger-mode)
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)
(setq sentence-end-double-space nil
delete-trailing-lines nil
require-final-newline t
tabify-regexp "^\t* [ \t]+")
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)))
(setq-default word-wrap t
truncate-lines t
truncate-partial-width-windows nil
fill-column 80)
Favor hard-wrapping in text modes
(add-hook 'text-mode-hook #'auto-fill-mode)
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)
Enable mouse in terminal Emacs
(add-hook 'tty-setup-hook #'xterm-mouse-mode)
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))
Sane trackpad/mouse scroll settings in Mac.
(when is-mac
(setq mac-redisplay-dont-reset-vscroll t
mac-mouse-wheel-smooth-scroll nil))
More performant rapid scrolling over unfontified regions. May cause brief spells of inaccurate fontification immediately after scrolling.
(setq fast-but-imprecise-scrolling t)
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)
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))
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)))
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))
(use-package gcmh
:straight (:host gitlab :repo "koral/gcmh")
:demand t
:delight
:init
(gcmh-mode 1))
Maximum number of lines to keep in the message log buffer.
(setq message-log-max 8192)
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)
Emacs “updates” its ui more often than it needs to, so we slow it down slightly, from 0.5s:
(setq idle-update-delay 1)
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)
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 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)
Performance on Windows is considerably worse than elsewhere, especially if WSL is involved.
- Reduce the workload when doing file IO
- 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))
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))
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))
(use-feature emacs
:init
(setq-default tab-width 4
tab-always-indent t
indent-tabs-mode nil))
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))
Eliminate duplicates in the kill ring.
(setq kill-do-not-save-duplicates t)
Middle-click paste at point, not at click
(setq mouse-yank-at-point t)
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))
(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))
(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)))
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/")))
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 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))
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)))
(use-feature dired-aux
:config
(setq dired-isearch-filenames 'dwim
dired-create-destination-dirs 'ask))
(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)))
(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)))))
(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)))
(use-feature org
:init
(org-babel-do-load-languages
'org-babel-load-languages
'((ledger . t) ;this is the important one for this tutorial
)))