emacs/init.el

2137 lines
74 KiB
EmacsLisp
Raw Normal View History

;;; init.el -*- lexical-binding: t; coding: utf-8-unix -*-
2021-02-26 17:31:50 +00:00
;; Author: Case Duckworth <acdw@acdw.net>
2021-03-01 05:58:57 +00:00
;; Created: Sometime during Covid-19, 2020
2021-02-26 17:31:50 +00:00
;; Keywords: configuration
2021-03-08 04:14:38 +00:00
;; URL: https://tildegit.org/acdw/emacs
2021-04-06 23:30:49 +00:00
;; Bankruptcy: 7
2021-03-16 16:16:21 +00:00
2021-03-01 05:58:57 +00:00
;; This file is NOT part of GNU Emacs.
2021-03-16 16:16:21 +00:00
;;; License:
2021-03-01 05:58:57 +00:00
;; Everyone is permitted to do whatever with this software, without
;; limitation. This software comes without any warranty whatsoever,
;; but with two pieces of advice:
;; - Don't hurt yourself.
;; - Make good choices.
2021-03-16 16:16:21 +00:00
;;; Code:
2021-04-06 22:59:45 +00:00
;;; Setup
;;;; `setup'
2021-08-16 02:10:13 +00:00
(straight-use-package '(setup :host nil :repo "https://git.sr.ht/~pkal/setup"))
(require 'setup)
(setup setup
2021-08-31 03:17:09 +00:00
;; Install a package using `straight-use-package'
(setup-define :straight
(lambda (recipe)
`(straight-use-package ',recipe))
2021-08-31 03:17:09 +00:00
:documentation
"Install RECIPE with `straight-use-package'.
This macro can be used as HEAD, and will replace itself with the
first RECIPE's package."
:repeatable t
:shorthand (lambda (sexp)
(let ((recipe (cadr sexp)))
(if (consp recipe)
(car recipe)
2021-08-31 03:17:09 +00:00
recipe))))
;; Install a package with straight, but only under a condition
(setup-define :straight-if
(lambda (recipe condition)
`(if ,condition
(straight-use-package ',recipe)
,(setup-quit)))
:documentation
"Install RECIPE with `straight-use-package' when CONDITION is met.
If CONDITION is false, stop evaluating the body. This macro can
be used as HEAD, and will replace itself with the RECIPE's
package. This macro is not repeatable."
:repeatable nil
:shorthand (lambda (sexp)
(let ((recipe (cadr sexp)))
(if (consp recipe) (car recipe) recipe)))))
;;;; `no-littering'
2021-04-06 22:59:45 +00:00
(setup (:straight no-littering)
(:option no-littering-etc-directory (acdw/dir)
no-littering-var-directory (acdw/dir))
(require 'no-littering))
;;;; My packages
(when-let ((default-directory
2021-04-20 04:46:24 +00:00
(expand-file-name-exists-p "pkg/" user-emacs-directory)))
(normal-top-level-add-subdirs-to-load-path))
;;;; Private stuff
2021-06-07 04:26:28 +00:00
(acdw/require-private)
2021-08-12 03:03:54 +00:00
;;;; Compatibility with older versions
(require 'acdw-compat)
;;;; Lisp
(require 'acdw-lisp)
;;; Basics
;; NOTE that some of the names in `setup' forms are arbitrary.
(setup acdw
2021-04-06 22:59:45 +00:00
(:option user-full-name "Case Duckworth"
user-mail-address "acdw@acdw.net"))
2021-05-29 03:42:14 +00:00
(setup (:require auth-source)
(:option auth-sources '("~/.authinfo" "~/.authinfo.gpg")))
(setup autorevert
2021-08-19 23:15:37 +00:00
(:option global-auto-revert-non-file-buffers t)
(global-auto-revert-mode +1))
(setup browse-url
(require 'acdw-browse-url)
2021-05-21 13:34:52 +00:00
(setq-default browse-url-secondary-browser-function
(if (executable-find "firefox") ; prefer Firefox
#'browse-url-firefox
#'browse-url-default-browser)
browse-url-new-window-flag nil ; for eww
browse-url-firefox-arguments '("--new-tab") ; for firefox
2021-05-21 13:34:52 +00:00
browse-url-firefox-new-window-is-tab t)
(acdw/browse-url-set-handlers
2021-08-29 04:09:15 +00:00
(list
(cons (rx (seq "." (or "jpeg" "jpg" ; images
"png")
eos))
(lambda (&rest args)
(apply (if (executable-find "feh")
#'browse-url-feh
#'eww-browse-url)
args)))
(cons (rx (or "youtube.com" ; videos
"youtu.be"
(seq "." (or "mp4"
"gif")
eos)))
(lambda (&rest args)
(apply (if (executable-find "mpv")
#'browse-url-mpv
browse-url-secondary-browser-function)
args)))
(cons (rx (or "google.com" ; websites that don't work with eww
"reddit.com"
"twitter.com"))
browse-url-secondary-browser-function)
(cons "." ; everything else
#'eww-browse-url)))
;; Buttonize gemini:// links.
(acdw/add-button-url-regexp-protocol "gemini"))
(setup buffers
2021-05-05 17:33:20 +00:00
(:global "C-x k" acdw/kill-a-buffer))
2021-07-01 00:34:06 +00:00
(setup calendar
(:option calendar-week-start-day 1 ; Monday
))
(setup completion
(:option completion-ignore-case t
read-buffer-completion-ignore-case t
2021-08-10 04:14:01 +00:00
completion-styles '(substring partial-completion)
completion-category-defaults nil
completion-category-overrides
'((file (styles . (partial-completion)))))
(:global "M-/" hippie-expand))
2021-04-06 22:59:45 +00:00
(setup cursor
(:option cursor-type 'bar
cursor-in-non-selected-windows 'hollow
blink-cursor-blinks 1)
(blink-cursor-mode +1))
2021-04-06 22:59:45 +00:00
(setup cus-edit
2021-08-22 20:04:48 +00:00
(:option custom-file null-device ; don't store customizations
custom-magic-show nil
custom-magic-show-button t
custom-raised-buttons nil
custom-unlispify-tag-names nil
custom-variable-default-form 'lisp)
;; `Custom-mode-hook' fires /before/ the widgets are built, so I have to
;; install advice after the widgets are made.
(advice-add
'custom-buffer-create :after
(defun custom-buffer@expand-widgets (&rest _)
"Expand descriptions and values of variables in `Custom-mode' buffers."
(interactive)
;; "More/Hide" widgets (thanks alphapapa!)
(widget-map-buttons (lambda (widget _)
(pcase (widget-get widget :off)
("More" (widget-apply-action widget)))
nil))
;; "Show Value" widgets (the little triangles)
(widget-map-buttons (lambda (widget _)
(pcase (widget-get widget :off)
("Show Value" (widget-apply-action widget)))
nil))))
(add-hook ; thanks u/oantolin!
'Custom-mode-hook
(defun custom-mode@imenu ()
"Build `imenu' for `Custom-mode'."
(setq imenu-generic-expression
'(("Faces" "^\\(?:Show\\|Hide\\) \\(.*\\) face: \\[sample\\]" 1)
("Variables" "^\\(?:Show Value\\|Hide\\) \\([^:\n]*\\)" 1))))))
(setup debugger
2021-08-30 13:51:21 +00:00
(:hook visual-line-mode))
(setup dired
(setq-default dired-recursive-copies 'always
dired-recursive-deletes 'always
delete-by-moving-to-trash t
dired-listing-switches "-Al"
ls-lisp-dirs-first t
dired-ls-F-marks-symlinks t
dired-no-confirm '(byte-compile
chgrp chmod chown copy
hardlink load move
shell touch symlink)
dired-dwim-target t)
2021-08-26 04:04:42 +00:00
(:hook dired-hide-details-mode
hl-line-mode)
(:global "C-x C-j" dired-jump)
2021-04-06 22:59:45 +00:00
(acdw/system
(:work (:straight w32-browser)
(autoload 'dired-w32-browser "w32-browser")
(:bind "RET" dired-w32-browser))
(:home (:straight dired-open)
(require 'dired-open)
2021-08-26 04:04:42 +00:00
(:bind "RET" dired-find-alternate-file)))
(with-eval-after-load 'dired
(require 'dired-x)
(:straight dired-subtree)
(:bind "i" dired-subtree-toggle
"TAB" dired-subtree-cycle)
2021-08-26 04:04:42 +00:00
(:straight dired-collapse)
(:hook dired-collapse-mode)
2021-08-26 04:04:42 +00:00
(:straight dired-git-info)
(:bind ")" dired-git-info-mode)
2021-08-26 04:04:42 +00:00
(:straight trashed)
(:option trashed-action-confirmer #'y-or-n-p)))
2021-08-25 22:38:32 +00:00
(setup disabled
;; While this stuff is defined in novice.el, I'm using 'disabled' as the name
;; for easy finding.
;; Enable all disabled commands.
;; This is an option, but I'm going to try /enabling/ just the ones that I
;; use instead.
;; (mapatoms (lambda (symbol)
;; (when (get symbol 'disabled)
;; (put symbol 'disabled nil))))
;; Enable /some/ disabled commands
(dolist (enable-sym '(narrow-to-region
dired-find-alternate-file
narrow-to-page))
(put enable-sym 'disabled nil))
2021-08-25 22:38:32 +00:00
;; Now, disable symbols as I wish.
(dolist (disable-sym '(view-hello-file
suspend-frame
scroll-left
scroll-right
comment-set-column
set-fill-column))
(put disable-sym 'disabled t))
2021-08-25 22:38:32 +00:00
;; And set the disabled function to something better than the default.
;; Now, I can run any disabled command, but I have to use M-x to do it.
2021-08-25 22:38:32 +00:00
(setq disabled-command-function
(defun acdw/disabled-command-function (&optional cmd keys)
(let ((cmd (or cmd this-command))
(keys (or keys (this-command-keys))))
;; this logic stolen from original `disabled-command-function'
(if (or (eq (aref keys 0) (if (stringp keys)
(aref "\M-x" 0)
?\M-x))
(and (>= (length keys) 2)
(eq (aref keys 0) meta-prefix-char)
(eq (aref keys 1) ?x)))
;; it's been run as an M-x command, we want to do it
(call-interactively cmd)
;; else, tell the user it's disabled.
(message (substitute-command-keys
(concat "Command `%s' has been disabled. "
"Run with \\[execute-extended-command]."))
cmd))))))
2021-08-25 22:38:32 +00:00
(setup ediff
(:option ediff-window-setup-function 'ediff-setup-windows-plain
ediff-split-window-function 'split-window-horizontally))
(setup eldoc
(:option eldoc-idle-delay 0.1
eldoc-echo-area-use-multiline-p nil))
(setup elisp-mode
(:option eval-expression-print-length nil
eval-expression-print-level nil
lisp-indent-function #'lisp-indent-function)
2021-04-06 22:59:45 +00:00
(add-hook 'emacs-lisp-mode-hook #'checkdoc-minor-mode)
2021-05-29 01:45:53 +00:00
(add-hook 'emacs-lisp-mode-hook
(defun emacs-lisp@enforce-lexical-binding ()
2021-08-31 04:39:21 +00:00
(setq-local lexical-binding t)))
2021-04-06 22:59:45 +00:00
2021-05-29 03:42:24 +00:00
(add-hook 'emacs-lisp-mode-hook
(defun emacs-lisp@imenu-add-setup ()
(add-to-list 'imenu-generic-expression
'("Setup"
"\\(^\\s-*(setup +(?\\)\\(\\_<.+\\_>\\)" 2))))
;; Emulate slime's eval binds
(:with-map emacs-lisp-mode-map
(:bind "C-c C-c" eval-defun
"C-c C-k" acdw/eval-region-or-buffer
"C-c C-z" ielm))
(add-hook 'emacs-lisp-mode-hook #'turn-on-eldoc-mode)
(add-hook 'ielm-mode-hook #'turn-on-eldoc-mode)
(setup (:straight macrostep)
(define-key emacs-lisp-mode-map (kbd "C-c e") #'macrostep-expand))
(setup (:straight eros)
(:hook-into emacs-lisp-mode))
;; Add advice to pulse evaluated regions
(define-advice eval-region (:around (fn start end &rest args) pulse-region)
(pulse-momentary-highlight-region start end)
2021-08-23 22:29:40 +00:00
(apply fn start end args))
(setup (:straight elisp-slime-nav)
(:hook-into emacs-lisp-mode
ielm-mode)))
(setup encoding
(:option locale-coding-system 'utf-8-unix
2021-04-06 22:59:45 +00:00
coding-system-for-read 'utf-8-unix
coding-system-for-write 'utf-8-unix
buffer-file-coding-system 'utf-8-unix
default-process-coding-system '(utf-8-unix . utf-8-unix)
x-select-request-type '(UTF8_STRING
COMPOUND_TEXT
TEXT
STRING))
(set-charset-priority 'unicode)
(set-language-environment "UTF-8")
(prefer-coding-system 'utf-8-unix)
(set-default-coding-systems 'utf-8-unix)
(set-terminal-coding-system 'utf-8-unix)
(set-keyboard-coding-system 'utf-8-unix)
(acdw/system
(:work (set-clipboard-coding-system 'utf-16-le)
(set-selection-coding-system 'utf-16-le))
(_ (set-selection-coding-system 'utf-8)
(set-clipboard-coding-system 'utf-8))))
(setup erc
(:require acdw-erc)
(:also-load erc-autoaway
2021-05-30 04:18:27 +00:00
erc-track
erc-goodies)
2021-05-26 20:10:07 +00:00
(:option
erc-auto-discard-away t
2021-08-29 04:08:17 +00:00
erc-auto-set-away t
2021-05-26 20:10:07 +00:00
erc-autoaway-idle-seconds 600
erc-autoaway-message "BRB (autoaway: %i seconds)"
erc-button-url-regexp browse-url-button-regexp
erc-common-server-suffixes '(("tilde.chat\\'" . "~")
("libera.chat\\'" . "LC"))
erc-default-server "irc.tilde.chat"
2021-06-07 04:28:25 +00:00
erc-fill-function #'erc-fill-static
erc-fill-static-center 14
2021-07-23 02:15:12 +00:00
erc-format-nick-function #'erc-format-truncate-@nick
2021-05-26 20:10:07 +00:00
erc-header-line-face-method #'erc/update-header-line-show-disconnected
2021-08-29 04:08:17 +00:00
erc-hide-list '("NICK" "MODE" "JOIN" "PART" "QUIT" "AWAY")
2021-05-30 04:18:27 +00:00
erc-interpret-controls-p t
2021-05-26 20:10:07 +00:00
erc-interpret-mirc-color t
2021-06-07 04:28:25 +00:00
erc-join-buffer 'bury
2021-05-26 20:10:07 +00:00
erc-kill-buffer-on-part t
erc-kill-queries-on-quit t
erc-kill-server-buffer-on-quit t
erc-nick "acdw"
2021-08-07 20:06:19 +00:00
erc-nick-truncate (- erc-fill-static-center 1)
2021-08-27 23:01:23 +00:00
erc-pcomplete-nick-postfix ":"
2021-08-16 02:10:48 +00:00
erc-prompt #'acdw-erc/prompt
2021-07-23 02:15:12 +00:00
erc-prompt-for-password nil ; use ~/.authinfo
2021-08-07 02:26:14 +00:00
erc-rename-buffers t
erc-server erc-default-server
2021-06-07 19:09:48 +00:00
erc/servers
(when (boundp 'erc-autojoin-channels-alist)
(mapcar #'car erc-autojoin-channels-alist))
2021-05-26 20:10:07 +00:00
erc-server-coding-system '(utf-8 . utf-8)
2021-08-18 23:21:22 +00:00
erc-timestamp-intangible t
2021-07-13 23:53:07 +00:00
erc-track-exclude-types (append erc-hide-list
2021-08-29 04:08:17 +00:00
'("AWAY" ; for some reason this triggers
; track anyway... so it's in
; `erc-hide-list'
"353" "324" "329" "332" "333" "477"))
2021-06-07 04:28:25 +00:00
erc-track-exclude-server-buffer t
erc-track-position-in-mode-line 'before-modes
2021-07-23 02:15:12 +00:00
erc-track-visibility nil ; only the selected frame
2021-06-07 04:28:25 +00:00
)
;; Thanks bpalmer!
(advice-add 'show-paren-function :around
(defun show-paren@skip-in-erc (f &rest r)
"Skip `show-paren-mode' in `erc-mode'."
(unless (derived-mode-p 'erc-mode)
(apply f r))))
2021-08-16 02:26:39 +00:00
(add-hook 'kill-emacs-hook #'erc/disconnect)
(add-hook 'erc-mode-hook
(defun erc-mode@setup ()
(setq-local scroll-margin 0)))
(:hook erc-autoaway-mode
2021-08-12 03:04:22 +00:00
erc-track-mode
erc-truncate-mode)
2021-05-29 03:42:53 +00:00
2021-08-25 01:18:14 +00:00
;; disable ERC tracking when working ... BE PRODUCTIVE!
(add-hook 'org-clock-in-hook #'erc-track-disable)
(add-hook 'org-clock-out-hook #'erc-track-enable)
2021-08-07 02:26:14 +00:00
(:bind "C-c C-b" acdw-erc/erc-switch-to-buffer
"C-c C-c" nil ; def: `erc-toggle-interpret-controls'
)
2021-06-10 02:48:31 +00:00
(with-eval-after-load 'erc
2021-08-09 03:48:50 +00:00
(when (acdw/system :work)
;; IDK why, but on 28 this bit doesn't work -- which is at home.
(setup (:straight erc-hl-nicks)
(:option (append erc-modules) 'hl-nicks
erc-hl-nicks-minimum-contrast-ratio 4.5
erc-hl-nicks-color-contrast-strategy '(invert contrast))
(:hook-into erc-mode)
;; Refresh nick colors after changing modus theme
;; Ideally, there'd be a hook for /any/ time we changed theme... but
;; whatever.
(add-hook 'modus-themes-after-load-theme-hook
#'erc-hl-nicks-refresh-colors)))
2021-06-10 02:48:31 +00:00
2021-07-14 21:58:58 +00:00
;; (setup (:straight erc-image)
;; (:option (append erc-modules) 'image
;; erc-image-inline-rescale 300))
2021-08-12 13:42:12 +00:00
;; Rewrite `erc-quit/part-reason-default'
(defun erc-quit/part-reason-default ()
"Default quit/part message."
(format "\C-iSee You, Space Cowpokes. . .\C-i"))
2021-06-10 02:48:31 +00:00
2021-07-03 02:45:37 +00:00
(erc-update-modules)))
(setup eshell
(:also-load acdw-eshell
em-smart)
(:option eshell-aliases-file (acdw/dir "eshell/aliases" t)
eshell-directory-name (acdw/dir "eshell/" t)
eshell-kill-on-exit nil
eshell-review-quick-commands nil
eshell-smart-space-goes-to-end t
eshell-where-to-jump 'begin)
(:global "C-c s" eshell-pop-or-quit)
(defun eshell-mode@setup ()
"Set up `eshell' for use.
Most customizations must go in this function since `eshell' loads
like a dumbass."
;; Define keys
(dolist (spec '(("C-d" . eshell-quit-or-delete-char)))
2021-08-25 01:15:53 +00:00
(define-key eshell-mode-map (kbd (car spec)) (cdr spec)))
2021-08-12 03:04:22 +00:00
;; Fix modeline
(when (boundp 'simple-modeline--mode-line)
2021-08-12 03:04:22 +00:00
(setq mode-line-format '(:eval simple-modeline--mode-line)))
2021-08-25 01:16:11 +00:00
;; Make navigating amongst prompts easier
(setq-local outline-regexp eshell-prompt-regexp
page-delimiter eshell-prompt-regexp))
2021-08-09 03:45:50 +00:00
(defun eshell-buffer-name ()
(rename-buffer (concat "*eshell*<" (eshell/pwd) ">") t))
(add-hook 'eshell-directory-change-hook #'eshell-buffer-name)
(add-hook 'eshell-prompt-load-hook #'eshell-buffer-name)
(:hook eshell-mode@setup
eshell-arg-hist-mode))
(setup eww
2021-05-20 03:00:59 +00:00
(:option eww-search-prefix "https://duckduckgo.com/html?q="
url-privacy-level '(email agent cookies lastloc))
(:hook acdw/reading-mode))
(setup files
(:option
auto-save-file-name-transforms `((".*" ,(acdw/dir "auto-save/" t) t))
auto-save-list-file-prefix (acdw/dir "auto-save-list/.saves-" t)
auto-save-interval 60
auto-save-timeout 60
auto-save-visited-interval auto-save-timeout
backup-by-copying t
backup-directory-alist `((".*" . ,(acdw/dir "backup/" t)))
delete-old-versions t
mode-require-final-newline 'visit-save
tramp-backup-directory-alist backup-directory-alist
vc-make-backup-files t
version-control t)
(:global "C-c i" acdw/find-emacs-dotfiles)
(auto-save-visited-mode +1)
2021-05-05 04:25:35 +00:00
(add-hook 'unfocused-hook
(defun unfocused@save-buffers ()
(save-some-buffers t))))
2021-08-23 22:29:40 +00:00
(setup flyspell
(add-hook 'text-mode-hook #'flyspell-mode))
(setup (:straight flyspell-correct)
(add-hook 'flyspell-mode-hook
(defun flyspell-mode@flyspell-correct ()
(dolist (keybind '(("C-;" . flyspell-correct-wrapper)
("C-," . nil)
("C-." . nil)
("C-M-i" . nil)))
(define-key flyspell-mode-map
(kbd (car keybind)) (cdr keybind))))))
(setup frames
2021-05-29 01:50:58 +00:00
(:option frame-title-format '("%b@"
(:eval
(or (file-remote-p default-directory 'host)
system-name))
" %+%* GNU Emacs"
2021-05-29 01:50:58 +00:00
(:eval (when (frame-parameter nil 'client)
" Client")))
window-resize-pixelwise t)
2021-05-05 04:25:35 +00:00
(add-hook 'unfocused-hook #'garbage-collect))
2021-04-06 22:59:45 +00:00
(setup gnus
2021-05-05 22:56:31 +00:00
(:option gnus-home-directory (acdw/dir "gnus" t)
gnus-directory (acdw/dir "News" t)
gnus-init-file (expand-file-name "gnus.el" user-emacs-directory))
2021-06-02 03:29:47 +00:00
(:global "C-c n" gnus))
2021-06-10 02:48:42 +00:00
(setup goto-addr
2021-08-31 04:39:21 +00:00
(add-hook 'after-change-major-mode-hook #'goto-address-mode))
2021-06-10 02:48:42 +00:00
2021-05-05 17:33:20 +00:00
(setup ibuffer
2021-08-25 02:24:43 +00:00
(:also-load ibuf-ext)
2021-05-05 17:33:20 +00:00
(:option ibuffer-saved-filter-groups
'(("default"
("dired" (mode . dired-mode))
2021-05-27 13:13:14 +00:00
("customize" (mode . Custom-mode))
2021-05-05 17:33:20 +00:00
("emacs" (or (name . "^\\*scratch\\*$")
(name . "^\\*Messages\\*$")
2021-05-27 13:13:14 +00:00
(name . "^\\*Warnings\\*$")
(name . "^\\*straight-process\\*$")
(name . "^\\*Calendar\\*$")))
("git" (or (name . "^\*magit")
(name . "^\magit")))
2021-05-05 17:33:20 +00:00
("help" (or (mode . help-mode)
(mode . Info-mode)
(mode . helpful-mode)))
("messaging" (or (mode . message-mode)
(mode . bbdb-mode)
(mode . mail-mode)
(mode . gnus-group-mode)
(mode . gnus-summary-mode)
(mode . gnus-article-mode)
(name . "^\\.bbdb$")
(name . "^\\.newsrc-dribble")
(mode . erc-mode)))
("shell" (or (mode . eshell-mode)
(mode . shell-mode)
(mode . vterm-mode)))
("web" (or (mode . elpher-mode)
(mode . gemini-mode)
(mode . eww-mode))))))
2021-05-05 17:33:20 +00:00
(global-set-key (kbd "C-x C-b") #'ibuffer)
2021-08-25 02:24:43 +00:00
(add-hook 'ibuffer-mode-hook
2021-08-20 13:29:40 +00:00
(defun ibuffer@filter-to-default ()
(ibuffer-switch-to-saved-filter-groups "default")))
(:option ibuffer-show-empty-filter-groups nil
ibuffer-expert t))
2021-05-05 17:33:20 +00:00
(setup imenu
(:option imenu-auto-rescan t))
2021-04-06 22:59:45 +00:00
(setup Info
2021-05-25 17:28:32 +00:00
(:hook variable-pitch-mode
acdw/reading-mode))
(setup isearch
(:option search-default-mode t))
(setup lines
(:option fill-column 79
word-wrap t
truncate-lines nil)
2021-04-21 16:50:18 +00:00
(global-display-fill-column-indicator-mode +1)
(global-so-long-mode +1)
(add-hook 'visual-line-mode-hook
(defun acdw/disable-fill-column-indicator ()
(display-fill-column-indicator-mode
(if visual-line-mode -1 +1))))
2021-04-22 17:53:19 +00:00
2021-04-21 16:50:18 +00:00
;; `acdw/kill-line-and-join-advice' cribs from `crux-kill-and-join-forward'.
;; I can't simply advise `kill-line' with an override from crux because crux
;; itself calls `kill-line', leading to a infinite nesting situation.
(define-advice kill-line (:around (fn &rest args) join-killed-line)
(if (and (eolp)
(not (bolp)))
(delete-indentation 1)
(apply fn args))))
2021-04-06 22:59:45 +00:00
(setup minibuffer
2021-08-26 21:03:50 +00:00
(:option enable-recursive-minibuffers t
file-name-shadow-properties '(invisible t intangible t)
2021-08-26 21:03:50 +00:00
minibuffer-eldef-shorten-default t
minibuffer-prompt-properties
'(read-only t cursor-intangible t face minibuffer-prompt)
2021-08-10 04:14:14 +00:00
read-answer-short t
read-extended-command-predicate ; used on >28
#'command-completion-default-include-p)
2021-04-06 22:59:45 +00:00
2021-08-10 04:14:14 +00:00
(add-hook 'minibuffer-setup-hook #'cursor-intangible-mode)
(add-hook 'minibuffer-setup-hook #'acdw/gc-disable)
(add-hook 'minibuffer-exit-hook #'acdw/gc-enable)
(minibuffer-depth-indicate-mode +1)
(file-name-shadow-mode +1)
(minibuffer-electric-default-mode +1)
(fset 'yes-or-no-p #'y-or-n-p))
2021-04-06 22:59:45 +00:00
(setup page
(:option page-delimiter
(rx bol (or "\f" ";;;")
(not (any "#")) (* not-newline) "\n"
(* (* blank) (opt ";" (* not-newline)) "\n")))
(defun recenter-to-top (&rest _)
"Recenter the cursor to the top of the window."
(when (called-interactively-p 'any)
(recenter (if (or (null scroll-margin)
(zerop scroll-margin))
3
scroll-margin))))
(:advise forward-page :after #'recenter-to-top
backward-page :after #'recenter-to-top)
;; I'm not sure where this is in /my/ version of Emacs
(defvar page-navigation-repeat-map
(let ((map (make-sparse-keymap)))
(define-key map "]" #'forward-page)
(define-key map "[" #'backward-page)
map)
"Keymap to repeat page navigation key sequences. Used in `repeat-mode'.")
(put 'forward-page 'repeat-map 'page-navigation-repeat-map)
(put 'backward-page 'repeat-map 'page-navigation-repeat-map))
2021-04-06 22:59:45 +00:00
(setup prog
(:option smie-indent-basic tab-width)
(add-hook 'prog-mode-hook
(defun prog-mode@auto-fill ()
(setq-local comment-auto-fill-only-comments t)
;; (advice-add 'do-auto-fill :after
;; (defun auto-fill@set-comment-column (&rest _)
;; (save-excursion
;; (when (or (looking-back comment-start-skip)
;; (progn (backward-word)
;; (looking-back
;; comment-start-skip)))
;; (comment-set-column t)))))
;; If the above advice is enabled, the below advice also needs to
;; be set to make `comment-dwim' work... I think.
;; (advice-add 'comment-dwim :before
;; (defun comment-dwim@set-comment-column (&rest _)
;; (setq comment-column 0)))
(turn-on-auto-fill)))
2021-04-06 22:59:45 +00:00
(:option show-paren-delay 0
show-paren-style 'mixed
show-paren-when-point-inside-paren t
show-paren-when-point-in-periphery t)
(defun flymake-mode-except ()
"Turn on flymake mode, except in some modes."
(let ((no-flymake-modes '(emacs-lisp-mode)))
(unless (or (member major-mode no-flymake-modes)
(apply #'derived-mode-p no-flymake-modes))
(flymake-mode-on))))
2021-04-06 22:59:45 +00:00
(:hook show-paren-mode
electric-pair-local-mode
flymake-mode-except
acdw/setup-fringes)
2021-04-06 22:59:45 +00:00
(add-hook 'after-save-hook
#'executable-make-buffer-file-executable-if-script-p))
(setup re-builder
(require 'acdw-re)
(advice-add 're-builder :before #'acdw/re-builder-save-state)
2021-04-06 22:59:45 +00:00
2021-05-05 04:45:30 +00:00
(add-hook 'reb-mode-hook #'paredit-mode)
(:global "<f2>" re-builder)
(dolist (map '(reb-mode-map reb-lisp-mode-map))
(let ((setup-map map))
(:bind "RET" reb-replace-regexp
"M-n" reb-next-match
"M-p" reb-prev-match
2021-08-07 20:13:10 +00:00
"C-g" reb-quit
"C-c C-k" reb-quit))))
(setup (:require recentf)
2021-04-06 22:59:45 +00:00
(:option recentf-save-file (acdw/dir "recentf.el")
2021-03-30 04:21:58 +00:00
recentf-max-menu-items 100
recentf-max-saved-items nil
2021-05-12 21:41:58 +00:00
recentf-auto-cleanup 'mode
2021-04-06 22:59:45 +00:00
(append recentf-exclude) (acdw/dir))
2021-05-12 21:41:58 +00:00
(advice-add 'dired-rename-file :after #'rjs/recentf-rename-notify)
(recentf-mode +1))
2021-03-09 04:40:23 +00:00
2021-05-29 01:51:07 +00:00
(setup repeat
2021-08-25 04:01:20 +00:00
;; new for Emacs 28!
2021-05-29 01:51:07 +00:00
(:only-if (fboundp #'repeat-mode))
2021-08-25 04:01:20 +00:00
(:option repeat-exit-key "g"
repeat-exit-timeout 5)
2021-05-29 01:51:07 +00:00
(repeat-mode +1))
(setup (:require savehist)
(:option history-length t
2021-03-30 04:21:58 +00:00
history-delete-duplicates t
2021-05-12 21:42:36 +00:00
savehist-autosave-interval 60
2021-04-06 22:59:45 +00:00
savehist-file (acdw/dir "savehist.el"))
2021-05-12 21:42:36 +00:00
(dolist (var '(extended-command-history
global-mark-ring
kill-ring
regexp-search-ring
search-ring
2021-05-12 21:42:36 +00:00
mark-ring))
(add-to-list 'savehist-additional-variables var))
2021-04-06 22:59:45 +00:00
(savehist-mode +1))
2021-04-01 21:35:26 +00:00
(setup saveplace
(:option save-place-file (acdw/dir "places.el")
save-place-forget-unreadable-files (acdw/system :home))
(save-place-mode +1))
2021-04-07 05:14:08 +00:00
(setup scratch
(:option inhibit-startup-screen t
initial-buffer-choice t
2021-09-01 22:57:12 +00:00
initial-scratch-message ""
;; (concat ";; Howdy, "
;; (nth 0 (split-string
;; user-full-name))
;; "! "
;; "Welcome to GNU Emacs.\n\n")
initial-major-mode 'emacs-lisp-mode)
(add-hook 'kill-buffer-query-functions
(defun kill-buffer-query@immortal-scratch ()
(if (eq (current-buffer) (get-buffer "*scratch*"))
(progn (bury-buffer)
nil)
t))))
(setup scrolling
(:option auto-window-vscroll nil
fast-but-imprecise-scrolling t
2021-08-25 22:38:45 +00:00
scroll-margin 3
scroll-conservatively 101
scroll-preserve-screen-position 1))
2021-04-03 14:45:59 +00:00
(setup selection
(:option save-interprogram-paste-before-kill t
yank-pop-change-selection t
x-select-enable-clipboard t
x-select-enable-primary t
mouse-drag-copy-region t
kill-do-not-save-duplicates t)
2021-04-03 14:45:59 +00:00
(delete-selection-mode +1))
(setup (:require server)
(unless (server-running-p)
(server-start)))
(setup sh-mode
(:option sh-basic-offset tab-width
sh-indent-after-case 0
sh-indent-for-case-alt '+
sh-indent-for-case-label 0)
(:local-set indent-tabs-mode t)
(when (executable-find "shfmt")
(with-eval-after-load 'apheleia
(:option (append apheleia-formatters) '(shfmt . ("shfmt"))
(append apheleia-mode-alist) '(sh-mode . shfmt))))
(when (executable-find "shellcheck")
(:straight flymake-shellcheck)
(:hook flymake-mode
flymake-shellcheck-load)))
(setup shell-command
(:option shell-command-switch (acdw/system
;; I should be testing on some variable
(:home "-csi")
(:work "-c"))
shell-command-prompt-show-cwd t
shell-command-default-error-buffer "*shell-command-errors*"))
(setup shr
(:option shr-width fill-column
shr-max-width fill-column
shr-max-image-proportion 0.6
shr-image-animate t
2021-05-20 03:00:59 +00:00
shr-discard-aria-hidden t
shr-folding-mode t))
(setup text
(:hook turn-on-auto-fill
acdw/setup-fringes))
(setup uniquify
(:option uniquify-buffer-name-style 'forward
uniquify-separator path-separator
uniquify-after-kill-buffer-p t
uniquify-ignore-buffers-re "^\\*"))
2021-04-03 14:45:59 +00:00
(setup variable-pitch-mode
2021-08-23 22:29:40 +00:00
;; I might want to change this to `buffer-face-mode-hook'...
(advice-add 'variable-pitch-mode :after
(defun variable-pitch-mode@setup (&rest _)
"Set up `variable-pitch-mode' with my customizations."
(display-fill-column-indicator-mode (if buffer-face-mode
-1
+1)))))
(setup view
(:option view-read-only t)
(defun acdw/read-view-mode ()
(acdw/reading-mode (if view-mode +1 -1)))
(:hook acdw/read-view-mode))
2021-04-18 04:02:11 +00:00
(setup whitespace
(:option whitespace-style
'(empty indentation space-before-tab space-after-tab)
indent-tabs-mode nil
tab-width 4
backward-delete-char-untabify-method 'hungry)
2021-05-05 17:34:44 +00:00
(:global "M-SPC" cycle-spacing))
2021-04-03 14:45:59 +00:00
(setup windows
(require 'acdw-bell)
(:option use-dialog-box nil
use-file-dialog nil
tab-bar-show 1
visible-bell nil
ring-bell-function (lambda ()
(acdw-bell/flash-mode-line
(acdw/system :home)))
recenter-positions '(top middle bottom))
2021-08-25 04:01:20 +00:00
(tooltip-mode -1))
(setup winner
;; see https://lists.gnu.org/archive/html/emacs-devel/2021-08/msg00888.html
(:global "C-x 4 C-/" winner-undo
"C-x 4 /" winner-undo
"C-x 4 C-?" winner-redo
"C-x 4 ?" winner-redo)
;; add `winner-undo' and `winner-redo' to `repeat-mode'
(when (fboundp 'repeat-mode)
(defvar winner-mode-repeat-map
(let ((map (make-sparse-keymap)))
(define-key map "/" #'winner-undo)
(define-key map "?" #'winner-redo)
map)
"Keymap to repeat `winner-mode' sequences. Used in `repeat-mode'.")
(put 'winner-undo 'repeat-map 'winner-mode-repeat-map)
(put 'winner-redo 'repeat-map 'winner-mode-repeat-map))
(winner-mode +1))
2021-04-03 14:45:59 +00:00
2021-08-25 04:01:20 +00:00
(setup windmove
(:option windmove-wrap-around t)
(:global
;; moving
"C-x 4 <left>" windmove-left
"C-x 4 <right>" windmove-right
"C-x 4 <up>" windmove-up
"C-x 4 <down>" windmove-down
;; swapping
"C-x 4 S-<left>" windmove-swap-states-left
"C-x 4 S-<right>" windmove-swap-states-right
"C-x 4 S-<up>" windmove-swap-states-up
"C-x 4 S-<down>" windmove-swap-states-down)
(when (fboundp 'repeat-mode)
(defvar windmove-repeat-map
(let ((map (make-sparse-keymap)))
;; moving
(define-key map [left] #'windmove-left)
(define-key map [right] #'windmove-right)
(define-key map [up] #'windmove-up)
(define-key map [down] #'windmove-down)
;; swapping
(define-key map [S-left] #'windmove-swap-states-left)
(define-key map [S-right] #'windmove-swap-states-right)
(define-key map [S-up] #'windmove-swap-states-up)
(define-key map [S-down] #'windmove-swap-states-down)
map)
"Keymap to repeat various `windmove' sequences. Used in `repeat-mode'.")
(dolist (sym '(windmove-left
windmove-right
windmove-up
windmove-down
windmove-swap-states-left
windmove-swap-states-right
windmove-swap-states-up
windmove-swap-states-down))
(put sym 'repeat-map 'windmove-repeat-map))))
(setup w32
(:option w32-allow-system-shell t
w32-pass-lwindow-to-system nil
w32-lwindow-modifier 'super
w32-pass-rwindow-to-system nil
w32-rwindow-modifier 'super
w32-pass-apps-to-system nil
w32-apps-modifier 'hyper))
2021-04-19 13:24:46 +00:00
2021-05-04 22:27:09 +00:00
;;; "Et cetera" settings
;; This should stay as /minimal/ as possible. Anything that can go somewhere
;; else /should/ go there.
(setup emacs
(:option
attempt-orderly-shutdown-on-fatal-signal nil
attempt-stack-overflow-recovery nil
echo-keystrokes 0.01
find-function-C-source-directory (acdw/find-emacs-source)
kill-read-only-ok t
load-prefer-newer t
native-comp-async-report-warnings-errors nil
2021-08-30 13:51:46 +00:00
set-mark-command-repeat-pop t)
2021-04-03 14:45:59 +00:00
2021-08-18 23:21:31 +00:00
(when (fboundp 'command-completion-default-include-p)
(setq read-extended-command-predicate
#'command-completion-default-include-p))
2021-09-01 13:37:17 +00:00
(defvar case-map (make-sparse-keymap)
"A keymap for setting case in various ways.")
(global-set-key (kbd "C-c c") case-map)
(:global "M-=" count-words
2021-05-12 21:42:18 +00:00
"C-w" kill-region-or-backward-word
2021-09-01 13:37:17 +00:00
"C-c c c" capitalize-dwim
"C-c c t" titlecase-dwim
"C-c c u" upcase-dwim
"C-c c l" downcase-dwim
2021-08-30 13:51:21 +00:00
"C-c d" acdw/insert-iso-date
"M-`" nil)
;; toggle bindings
(defvar toggle-map (make-sparse-keymap)
"A keymap for toggling!")
(global-set-key (kbd "C-c t") toggle-map)
(:with-map toggle-map
(:bind "c" column-number-mode
"l" display-line-numbers-mode
"d" toggle-debug-on-error))
(defalias 'forward-word-with-case 'forward-word
"Alias for `forward-word' for use in `case-repeat-map'.")
(defalias 'backward-word-with-case 'backward-word
"Alias for `backward-word for use in `case-repeat-map'.")
2021-08-30 13:51:21 +00:00
2021-09-01 13:37:17 +00:00
;; XXX: this isn't repeating correctly ...
(defvar case-repeat-map
(let ((map (make-sparse-keymap)))
(define-key map "c" #'capitalize-word)
(define-key map "u" #'upcase-word)
(define-key map "l" #'downcase-word)
;; movement
(define-key map "f" #'forward-word-with-case)
(define-key map "b" #'backward-word-with-case)
map)
"A map to repeat word-casing commands. For use with `repeat-mode'.")
2021-08-30 13:51:21 +00:00
(dolist (command '(capitalize-word
capitalize-dwim
upcase-word
upcase-dwim
downcase-word
downcase-dwim
forward-word-with-case
backward-word-with-case))
(put command 'repeat-map 'case-repeat-map)))
2021-04-03 14:45:59 +00:00
;;; Packages
2021-08-10 13:30:17 +00:00
(setup (:straight (0x0 :host gitlab
:repo "willvaughn/emacs-0x0"))
(:option 0x0-default-server 'ttm))
(setup (:straight (apheleia :host github
:repo "raxod502/apheleia"))
(apheleia-global-mode +1)
2021-03-31 17:46:14 +00:00
;; Use a dumb formatter on modes that `apheleia' doesn't work for.
(add-hook 'before-save-hook
(defun before-save@dumb-auto-format ()
(setq stupid-modes '(makefile-mode
org-mode))
;; If there's no apheleia formatter for the mode, just indent the
;; buffer.
(unless (or (apply #'derived-mode-p stupid-modes)
(and (fboundp 'apheleia--get-formatter-command)
(apheleia--get-formatter-command)))
(indent-region (point-min) (point-max))))))
2021-08-31 03:18:13 +00:00
(setup (:straight-if affe
2021-09-01 13:42:07 +00:00
(and (or (executable-find "fd")
(executable-find "find"))
(executable-find "rg")))
2021-08-31 03:18:13 +00:00
;; Keys are bound in `acdw/sensible-grep' and `acdw/sensible-find'
(defun affe-orderless-regexp-compiler (input _type)
(setq input (orderless-pattern-compiler input))
(cons input (lambda (str) (orderless--highlight input str))))
(:option affe-regexp-compiler #'affe-orderless-regexp-compiler))
(setup (:straight async)
(autoload 'dired-async-mode "dired-async.el" nil t)
(dired-async-mode +1)
(add-hook 'dired-mode
(defun dired@disable-dired-async-mode-line ()
(autoload 'dired-async--modeline-mode "dired-async.el" nil t)
(dired-async--modeline-mode -1))))
(setup (:straight alert)
(:option alert-default-style (acdw/system
(:home 'libnotify)
(_ 'message))))
2021-03-31 17:46:14 +00:00
(setup (:straight avy)
(:global "C-'" avy-goto-char-timer
"M-g f" avy-goto-line
"M-g w" avy-goto-word-1
"C-c C-j" avy-resume)
(with-eval-after-load "isearch"
(define-key isearch-mode-map (kbd "C-'") #'avy-isearch)))
2021-03-31 17:46:14 +00:00
(setup (:straight (beginend))
(beginend-global-mode +1))
2021-08-29 04:08:17 +00:00
(setup (:straight circe)
(require 'circe)
(require 'acdw-irc)
(setq acdw-irc/post-my-nick "-> ")
(setq circe-default-nick "acdw"
circe-default-part-message "See You, Space Cowpokes . . ."
2021-08-29 04:08:17 +00:00
circe-highlight-nick-type 'all
circe-network-options
(("Libera Chat"
:channels ("#emacs" "#systemcrafters" "##webpals")
:sasl-username "acdw"
:sasl-password ,(acdw/fetch-password :host "libera.chat"))
("Tilde Chat"
:channels ("#meta" "#bread" "#dadjokes" "#team")
:host "irc.tilde.chat" :port 6697 :use-tls t
:sasl-username "acdw"
:sasl-password ,(acdw/fetch-password :host "tilde.chat"))
("Casa"
:channels ("#basement")
:host "m455.casa" :port 6697 :use-tls t
:sasl-username "acdw"
:sasl-password ,(acdw/fetch-password :host "m455.casa")))
2021-08-29 04:08:17 +00:00
circe-reduce-lurker-spam t
circe-server-auto-join-default-type :after-auth)
(defun irc ()
"Connect to IRC."
(interactive)
(dolist (network (mapcar #'car circe-network-options))
(circe-maybe-connect network)))
(defun circe-network-connected-p (network)
"Return non-nil if there's any Circe server-buffer whose
`circe-server-netwok' is NETWORK."
(catch 'return
(dolist (buffer (circe-server-buffers))
(with-current-buffer buffer
(if (string= network circe-server-network)
(throw 'return t))))))
(defun circe-maybe-connect (network)
"Connect to NETWORK, but ask user for confirmation if it's
already been connected to."
(interactive "sNetwork: ")
(if (or (not (circe-network-connected-p network))
(y-or-n-p (format "Already connected to %s, reconnect?" network)))
(circe network)))
2021-08-29 04:08:17 +00:00
(add-hook 'circe-chat-mode-hook
(defun circe-chat@setup ()
(lui-set-prompt
(concat (propertize (acdw-irc/margin-format (buffer-name)
""
">")
'face 'circe-prompt-face
'read-only t 'intangible t
'cursor-intangible t)
" "))
(enable-circe-color-nicks)
(enable-circe-display-images)
(enable-circe-new-day-notifier)))
2021-09-01 23:13:04 +00:00
(add-hook 'modus-themes-after-load-theme-hook
#'circe-nick-color-reset)
2021-08-29 15:37:02 +00:00
(let ((len (number-to-string (- acdw-irc/left-margin 1
(+ (length acdw-irc/pre-nick)
(length acdw-irc/post-nick)))))
(my-len (number-to-string (- acdw-irc/left-margin 1
(+ (length acdw-irc/pre-my-nick)
(length acdw-irc/post-my-nick))))))
(setq circe-format-say (concat acdw-irc/pre-nick
"{nick:" len "." len "s} "
acdw-irc/post-nick
"{body}")
circe-format-self-say (concat acdw-irc/pre-my-nick
"{nick:" my-len "." my-len "s} "
acdw-irc/post-my-nick
"{body}")
circe-format-action (concat "*"
(repeat-string
(- acdw-irc/left-margin 3)
" ")
"* {nick} {body}")
circe-format-self-action (concat "-*"
(repeat-string
(- acdw-irc/left-margin 4)
" ")
"* {nick} {body}")
lui-fill-type (concat
(repeat-string (- acdw-irc/left-margin 2)
" ")
" ")))
2021-08-29 04:08:17 +00:00
(setq lui-time-stamp-position 'right-margin
lui-time-stamp-format "%H:%M")
(add-hook 'lui-mode-hook
(defun lui-mode@setup ()
2021-08-29 15:37:02 +00:00
(setq-local fringes-outside-margins t
lui-track-bar-behavior 'before-switch-to-buffer
right-margin-width 5
scroll-margin 0
word-wrap t
wrap-prefix (repeat-string
2021-09-01 23:13:04 +00:00
acdw-irc/left-margin " "))
2021-08-31 03:17:59 +00:00
;; (enable-lui-track-bar)
)))
2021-08-29 04:08:17 +00:00
2021-04-16 04:23:50 +00:00
(setup (:straight (consult
:host github
:repo "minad/consult"))
(require 'acdw-consult)
(setq consult--regexp-compiler #'consult--orderless-regexp-compiler)
2021-04-01 21:39:46 +00:00
;; Bindings
(:global
2021-04-01 21:39:46 +00:00
;; C-c bindings (`mode-specific-map')
;; I don't use any of these right now.
;; "C-c h" consult-history
;; "C-c m" consult-mode-command
;; "C-c b" consult-bookmark
;; "C-c k" consult-kmacro
2021-04-01 21:39:46 +00:00
;; C-x bindings (`ctl-x-map')
"C-x M-:" consult-complex-command
"C-x b" consult-buffer
"C-x 4 b" consult-buffer-other-window
"C-x 5 b" consult-buffer-other-frame
;; Custom M-# bindings for fast register access
"M-#" consult-register-load
"M-'" consult-register-store
"C-M-#" consult-register
;; M-g bindings (`goto-map')
"M-g e" consult-compile-error
"M-g g" consult-goto-line
"M-g M-g" consult-goto-line
"M-g o" consult-outline
"M-g m" consult-mark
"M-g k" consult-global-mark
"M-g i" consult-imenu
"M-g I" consult-project-imenu
;; M-s bindings (`search-map')
"M-s g" acdw-consult/sensible-grep
"M-s f" acdw-consult/sensible-find
2021-04-01 21:39:46 +00:00
"M-s l" consult-line
"M-s m" consult-multi-occur
"M-s k" consult-keep-lines
"M-s u" consult-focus-lines
;; Other bindings
"M-y" consult-yank-pop
"<help> a" consult-apropos
;; Isearch integration
"M-s e" consult-isearch)
(:with-map isearch-mode-map
(:bind "M-e" consult-isearch
"M-s e" consult-isearch
"M-s l" consult-line))
2021-08-20 12:57:35 +00:00
;; see https://github.com/oantolin/completing-history
(defmacro consult-history-to-modes (map-hook-alist)
(let (defuns)
(dolist (map-hook map-hook-alist)
(let ((map-name (symbol-name (car map-hook)))
(key-defs `(progn (define-key
,(car map-hook)
(kbd "M-r")
(function consult-history))
(define-key ,(car map-hook)
(kbd "M-s") nil))))
(push (if (cdr map-hook)
`(add-hook ',(cdr map-hook)
(defun
,(intern (concat map-name
"@consult-history-bind"))
nil
,(concat
"Bind `consult-history' to M-r in "
map-name ".\n"
"Defined by `consult-history-to-modes'.")
,key-defs))
key-defs)
defuns)))
`(progn ,@ (nreverse defuns))))
(consult-history-to-modes ((minibuffer-local-map . nil)
(shell-mode-map . shell-mode-hook)
(term-mode-map . term-mode-hook)
(term-raw-map . term-mode-hook)
(comint-mode-map . comint-mode-hook)
(sly-mrepl-mode-map . sly-mrepl-hook)))
2021-04-01 21:39:46 +00:00
;; Registers
(autoload 'consult-register-preview "consult")
(:option register-preview-delay 0
2021-04-01 21:39:46 +00:00
register-preview-function #'consult-register-format)
(:advise register-preview :override #'consult-register-window)
;; Xref
(:option xref-show-xrefs-function #'consult-xref
xref-show-definitions-function #'consult-xref)
;; Projects
2021-04-20 21:25:31 +00:00
(:option consult-project-root-function #'vc-root-dir)
;; Competion-at-point (complete-region)
(:option completion-in-region-function #'acdw-consult/complete-in-region
completion-cycle-threshold 3
2021-08-10 04:14:01 +00:00
tab-always-indent 'complete)
;; Completing-read-multple
(if (fboundp #'consult-completing-read-multiple)
(:advise completing-read-multple
:override #'consult-completing-read-multiple)
2021-08-12 19:20:48 +00:00
;; else
2021-08-10 04:14:01 +00:00
(defun crm-indicator (args)
(cons (concat "[CRM] " (car args)) (cdr args)))
(:advise completing-read-multiple
:filter-args #'crm-indicator))
(with-eval-after-loads (vertico consult)
(when (boundp 'consult-crm-map)
(define-key consult-crm-map "\r" #'+vertico-crm-exit)
(define-key consult-crm-map "\t" #'vertico-exit)
(defun +vertico-crm-exit ()
(interactive)
(run-at-time 0 nil #'vertico-exit)
(funcall #'vertico-exit)))))
(setup (:straight crux)
2021-08-25 04:01:20 +00:00
(:global "C-x o" acdw/other-window-or-switch-buffer
"C-o" crux-smart-open-line
"M-o" crux-smart-open-line-above
"C-M-\\" crux-cleanup-buffer-or-region
2021-08-12 01:25:40 +00:00
"C-x 4 t" crux-transpose-windows)
2021-08-25 04:01:20 +00:00
(when (fboundp 'repeat-mode)
2021-08-25 22:39:55 +00:00
(unless (boundp 'other-window-repeat-map)
(defvar other-window-repeat-map (make-sparse-keymap)
"A map for repeating `other-window' keys."))
2021-08-25 04:01:20 +00:00
(define-key other-window-repeat-map "o"
#'acdw/other-window-or-switch-buffer)
(define-key other-window-repeat-map "O"
(defun acdw/other-window-or-switch-buffer-backward ()
(interactive)
(setq repeat-map 'other-window-repeat-map)
(acdw/other-window-or-switch-buffer -1)))
(put 'acdw/other-window-or-switch-buffer
'repeat-map 'other-window-repeat-map))
2021-08-12 01:25:40 +00:00
(crux-reopen-as-root-mode +1))
;; requires extension:
;; https://addons.mozilla.org/en-US/firefox/addon/edit-with-emacs1/
(setup (:straight edit-server)
(when (and (daemonp)
(require 'edit-server nil :noerror))
(edit-server-start)
2021-08-29 15:37:15 +00:00
(advice-add 'edit-server-make-frame :before
(defun edit-server@set-a-variable (&rest _)
2021-09-01 23:14:15 +00:00
(setq-local edit-server-frame-p t)))))
(setup (:straight (electric-cursor
:host github
:repo "duckwork/electric-cursor"))
(electric-cursor-mode +1))
2021-09-01 22:15:20 +00:00
(setup (:straight elfeed
elfeed-protocol)
(:option elfeed-use-curl t
elfeed-feeds `(("fever+https://acdw@mf.acdw.net"
:api-url "https://mf.acdw.net/fever/"
:password ,(acdw/fetch-password
:host "mf.acdw.net"))))
(elfeed-protocol-enable)
(add-hook 'elfeed-show-mode-hook
(defun elfeed-show@setup ()
(olivetti-mode +1)))
;; see https://irreal.org/blog/?p=8885
)
(setup (:straight (elpher :host nil
:repo "git://thelambdalab.xyz/elpher.git"))
(:option elpher-ipv4-always t
elpher-certificate-directory (acdw/dir "elpher/")
elpher-gemini-max-fill-width fill-column)
(:bind "n" elpher-next-link
"p" elpher-prev-link
"o" elpher-follow-current-link
"G" elpher-go-current)
(:hook acdw/reading-mode)
(autoload 'elpher-bookmarks "elpher" nil t)
(autoload 'elpher-go "elpher" nil t)
;; Make `eww' gemini/gopher aware. From Emacswiki.
(define-advice eww-browse-url (:around (fn url &rest args) gemini-elpher)
(cond ((string-match-p "\\`\\(gemini\\|gopher\\)://" url)
(require 'elpher)
(elpher-go url))
(t (apply fn url args))))
(:when-loaded
(setup (:straight (gemini-write
:host nil
:repo "https://alexschroeder.ch/cgit/gemini-write"
:branch "main"))
(require 'gemini-write))))
(setup (:straight embark)
2021-08-12 03:06:26 +00:00
(:global "C-." embark-act)
(:option prefix-help-command #'embark-prefix-help-command
(append display-buffer-alist)
'("\\`\\*Embark Collect \\(Live\\|Completions\\)\\*"
nil
2021-08-10 04:36:58 +00:00
(window-parameters (mode-line-format . none)))
embark-prompter #'embark-keymap-prompter
embark-verbose-indicator-display-action
2021-08-10 04:46:48 +00:00
'(display-buffer-at-bottom (window-height . fit-window-to-buffer)))
2021-08-10 04:41:26 +00:00
(setq embark-action-indicator
(lambda (map _target)
(which-key--show-keymap "Embark" map nil nil 'no-paging)
#'which-key--hide-popup-ignore-command)
embark-become-indicator embark-action-indicator)
(with-eval-after-loads (embark consult)
(setup (:straight embark-consult)
(add-hook 'embark-collect-mode-hook
#'consult-preview-at-point-mode))))
2021-05-29 01:51:21 +00:00
(setup (:straight epithet)
(add-hook 'Info-selection-hook #'epithet-rename-buffer)
(add-hook 'eww-after-render-hook #'epithet-rename-buffer)
(add-hook 'help-mode-hook #'epithet-rename-buffer)
(add-hook 'occur-mode-hook #'epithet-rename-buffer))
2021-08-31 03:17:09 +00:00
(setup (:straight-if eradio
(executable-find "mpv"))
2021-05-30 04:18:35 +00:00
(:option
eradio-player '("mpv" "--no-video" "--no-terminal")
2021-06-07 19:09:48 +00:00
eradio-channels `(("KLSU" .
"http://130.39.238.143:8010/stream.mp3")
("Soma FM Synphaera" .
"https://somafm.com/synphaera256.pls")
("SomaFM BAGel Radio" .
"https://somafm.com/bagel.pls")
("SomaFM Boot Liquor" .
"https://somafm.com/bootliquor320.pls")
("SomaFM Deep Space One" .
"https://somafm.com/deepspaceone.pls")
("SomaFM Fluid" .
"https://somafm.com/fluid.pls")
("SomaFM Underground 80s" .
"https://somafm.com/u80s256.pls")
("WBRH: Jazz & More" .
"http://wbrh.streamguys1.com/wbrh-mp3")
("KBRH Blues & Rhythm Hits" .
"http://wbrh.streamguys1.com/kbrh-mp3")
2021-06-07 19:09:48 +00:00
("WRKF HD-2" .
,(concat "https://playerservices.streamtheworld.com/"
"api/livestream-redirect/WRKFHD2.mp3"))
("WRKF: NPR for the Capital Region" .
2021-06-07 19:09:48 +00:00
,(concat "https://playerservices.streamtheworld.com/"
"api/livestream-redirect/WRKFFM.mp3"))
2021-08-10 13:30:28 +00:00
("BadRadio: 24/7 PHONK" .
"https://s2.radio.co/s2b2b68744/listen")
2021-06-07 19:09:48 +00:00
("tilderadio" .
2021-07-01 00:33:51 +00:00
"https://radio.tildeverse.org/radio/8000/radio.ogg")
("vantaradio" .
"https://vantaa.black/radio")))
2021-06-07 19:09:48 +00:00
(:global "C-c r r" eradio-play ; mnemonic: radio
"C-c r s" eradio-stop ; mnemonic: stop
"C-c r p" eradio-toggle ; mnemonic: play/pause
))
2021-05-30 04:18:35 +00:00
(setup (:straight expand-region)
(defun acdw/set-mark-or-expand-region (arg)
"Set mark at point and activate, jump to mark, or expand region.
See `set-mark-command' and `expand-region'.
With no prefix argument, either run `set-mark-command' on first
invocation and `er/expand-region' on each successive invocation.
With any prefix argument
(e.g., \\[universal-argument] \\[set-mark-command]), act as with
`set-mark-command' (i.e., pop the mark). Don't care about
successive invocations."
(interactive "P")
(cond
((or arg
(and set-mark-command-repeat-pop
(eq last-command 'pop-to-mark-command)))
(setq this-command 'set-mark-command)
(set-mark-command arg))
((eq last-command 'acdw/set-mark-or-expand-region)
(er/expand-region 1))
(t (set-mark-command arg))))
(:global "C-=" er/expand-region
"C-SPC" acdw/set-mark-or-expand-region))
2021-08-31 03:17:09 +00:00
(setup (:straight-if fennel-mode
(executable-find "fennel"))
(autoload 'fennel-repl "fennel-mode" nil t)
(add-to-list 'auto-mode-alist '("\\.fnl\\'" . fennel-mode)))
2021-08-20 12:57:35 +00:00
(setup (:straight gcmh)
(:option gcmh-idle-delay 'auto)
(gcmh-mode +1))
(setup (:straight-if geiser
(progn
2021-08-31 04:47:02 +00:00
(defvar acdw/schemes
(let (schemes) ; these binaries should be checked...
(dolist (scheme '(("scheme" . geiser-chez) ; chez
("petite" . geiser-chez) ; petite
("csi" . geiser-chez) ; chicken
("gsi" . geiser-gambit) ; gambit
("gosh" . geiser-gauche) ; gauche
("guile" . geiser-guile)
("kawa" . geiser-kawa)
("mit-scheme" . geiser-mit)
("racket" . geiser-racket)
("stklos" . geiser-stklos)))
(when-let (binary (executable-find (car scheme)))
(push binary schemes)
;; and install the proper helper package
(straight-use-package (cdr scheme))))
(nreverse schemes)))
acdw/schemes)))
(setup (:straight (gemini-mode
:host nil
:repo "https://git.carcosa.net/jmcbray/gemini.el.git"))
(add-to-list 'auto-mode-alist '("\\.\\(gemini\\|gmi\\)\\'" . gemini-mode))
2021-05-22 21:42:05 +00:00
(:hook turn-off-auto-fill))
(setup gforth
(when (locate-library "gforth")
(autoload 'forth-mode "gforth")
(add-to-list 'auto-mode-alist '("\\.fs\\'" . forth-mode))
(autoload 'forth-block-mode "gforth")
(add-to-list 'auto-mode-alist '("\\.fb\\'" . forth-block-mode))))
(setup (:straight helpful)
(:option helpful-max-buffers 5
;; helpful-switch-buffer-function #'pop-to-buffer
;; helpful-switch-buffer-function
;; (lambda (buf)
;; (pop-to-buffer buf
;; '((display-buffer-reuse-mode-window
;; display-buffer-pop-up-window)
;; (mode . helpful-mode))
;; :norecord))
)
(:global "<help> f" helpful-callable
"<help> v" helpful-variable
"<help> k" helpful-key
"<help> o" helpful-symbol
"C-c C-d" helpful-at-point)
;; (with-eval-after-load 'helpful
;; (define-key helpful-mode-map "q"
;; (defun helpful-mode|quit ()
;; (interactive)
;; (bury-buffer)
;; (unless (window-parameter (frame-selected-window) 'no-other-window)
;; (delete-window)))))
)
2021-05-30 04:18:42 +00:00
(setup (:straight iscroll)
(:hook-into text-mode))
(setup (:straight lacarte)
(:global "<f10>" lacarte-execute-menu-command))
2021-08-31 03:17:09 +00:00
(setup (:straight-if ledger-mode
(executable-find "ledger")))
2021-05-02 19:15:10 +00:00
2021-09-01 22:58:08 +00:00
(setup (:straight link-hint)
;; Browse web URLs with a browser with a prefix argument.
(dolist (type '(gnus-w3m-image-url
gnus-w3m-url
markdown-link
mu4e-attachment
mu4e-url
notmuch-hello
nov-link
org-link
shr-url
text-url
w3m-link
w3m-message-link))
(link-hint-define-type type
:open-secondary browse-url-secondary-browser-function))
(defun acdw/link-hint-open-link (arg)
"Open a link using `link-hint-open-link', but like `browse-url-at-point'.
That is, a prefix argument (\\[universal-argument]) will open the
browser defined in `browse-url-secondary-browser-function'."
(interactive "P")
(avy-with link-hint-open-link
(link-hint--one (if arg :open-secondary :open))))
(:global "C-c C-o" acdw/link-hint-open-link
"C-c o" acdw/link-hint-open-link))
(setup (:straight lua-mode)
(add-to-list 'auto-mode-alist '("\\.lua\\'" . lua-mode)))
(setup (:straight magit)
(:global "C-c g" magit-status)
(defun magit-display-buffer-same-window (buffer)
"Display BUFFER in the selected window like God intended."
(display-buffer buffer '(display-buffer-same-window)))
(:option magit-display-buffer-function #'magit-display-buffer-same-window
magit-popup-display-buffer-action '((display-buffer-same-window))
magit-refresh-status-buffer nil))
(setup (:straight marginalia)
2021-03-30 04:21:58 +00:00
(:option marginalia-annotators '(marginalia-annotators-heavy
marginalia-annotators-light))
(marginalia-mode +1))
(setup (:straight (mastodon
:host github
:repo "mooseyboots/mastodon.el"))
2021-08-14 23:00:02 +00:00
(:straight request)
(:option mastodon-instance-url "https://writing.exchange"
mastodon-auth-source-file (car auth-sources)
2021-08-30 13:51:46 +00:00
mastodon-client--token-file (acdw/dir "mastodon.plstore"))
(:hook hl-line-mode
olivetti-mode))
(setup (:straight (modus-themes
:host gitlab
:repo "protesilaos/modus-themes"))
2021-03-30 04:21:58 +00:00
(:option modus-themes-slanted-constructs t
modus-themes-bold-constructs t
modus-themes-region 'bg-only
modus-themes-org-blocks 'grayscale
modus-themes-headings '((1 . section)
(t . no-color))
modus-themes-mode-line nil)
(acdw/sunrise-sunset #'modus-themes-load-operandi
#'modus-themes-load-vivendi))
2021-08-29 15:37:28 +00:00
(setup (:straight markdown-mode))
(setup (:straight mwim)
(:global "C-a" mwim-beginning
"C-e" mwim-end))
(setup (:straight nov)
(:option nov-text-width fill-column)
(add-to-list 'auto-mode-alist '("\\.epub\\'" . nov-mode)))
2021-05-05 04:25:42 +00:00
(setup (:straight package-lint))
(setup (:straight package-lint-flymake))
(setup (:straight olivetti)
(:option olivetti-body-width (+ fill-column 4)
olivetti-minimum-body-width fill-column)
(add-hook 'olivetti-mode-hook
(defun acdw/olivetti-mode-hook ()
(if olivetti-mode
(setq-local indicate-empty-lines nil
indicate-buffer-boundaries nil)
(acdw/setup-fringes)))))
2021-04-01 21:35:26 +00:00
(setup (:straight (orderless
:host github
:repo "oantolin/orderless"))
(require 'orderless)
2021-08-12 03:06:46 +00:00
(:option (append completion-styles) 'orderless
orderless-component-separator #'orderless-escapable-split-on-space
orderless-style-dispatchers '(acdw/orderless-dispatch))
(defun fix-dollar (args)
(if (string-suffix-p "$" (car args))
(list (concat (substring (car args) 0 -1) "[\x100000-\x10FFFD]*$"))
args))
(advice-add #'orderless-regexp :filter-args #'fix-dollar)
(defun acdw/orderless-dispatch (pattern _index _total)
"My custom dispatcher for `orderless'."
(cond
;; Ensure that $ works with Consult commands, which add disambiguation
;; suffixes -- see `fix-dollar'
((string-suffix-p "$" pattern)
`(orderless-regexp . ,(concat (substring pattern 0 -1)
"[\x100000-\x10FFFD]*$")))
;; File extensions
((string-match-p "\\`\\.." pattern)
`(orderless-regexp . ,(concat "\\." (substring pattern 1)
"[\x100000-\x10FFFD]*$")))
;; Ignore single !
((string= "!" pattern)
`(orderless-literal . ""))
;; Character folding
((string-prefix-p "%" pattern)
`(char-fold-to-regexp . ,(substring pattern 1)))
((string-suffix-p "%" pattern)
`(char-fold-to-regexp . ,(substring pattern 0 -1)))
;; Without literal
((string-prefix-p "!" pattern)
`(orderless-without-literal . ,(substring pattern 1)))
((string-suffix-p "!" pattern)
`(orderless-without-literal . ,(substring pattern 0 -1)))
;; Initialism matching
((string-prefix-p "`" pattern)
`(orderless-initialism . ,(substring pattern 1)))
((string-suffix-p "`" pattern)
`(orderless-initialism . ,(substring pattern 0 -1)))
;; Literal matching
((string-prefix-p "=" pattern)
`(orderless-literal . ,(substring pattern 1)))
((string-suffix-p "=" pattern)
`(orderless-literal . ,(substring pattern 0 -1)))
;; Flex matching
((string-prefix-p "~" pattern)
`(orderless-flex . ,(substring pattern 1)))
((string-suffix-p "~" pattern)
`(orderless-flex . ,(substring pattern 0 -1))))))
(setup (:straight org
org-contrib)
(require 'acdw-org) ; so I don't clutter up init.el
2021-08-16 02:10:48 +00:00
(:option
org-adapt-indentation nil
2021-08-23 22:29:40 +00:00
org-agenda-files nil ; only until I set this up
2021-08-16 02:10:48 +00:00
org-catch-invisible-edits 'smart
org-clock-clocked-in-display 'mode-line
org-clock-string-limit 7 ; gives time and not title
org-confirm-babel-evaluate nil
org-directory "~/org"
org-ellipsis ""
org-export-coding-system 'utf-8-unix
org-export-headline-levels 8
org-export-with-section-numbers nil
org-export-with-smart-quotes t
org-export-with-sub-superscripts t
org-export-with-toc nil
org-fontify-done-headline t
org-fontify-quote-and-verse-blocks t
org-fontify-whole-heading-line t
org-hide-emphasis-markers t
org-html-coding-system 'utf-8-unix
org-image-actual-width '(300)
org-imenu-depth 3
org-outline-path-complete-in-steps nil
org-pretty-entities t
org-refile-use-outline-path 'file
org-special-ctrl-a/e t
org-special-ctrl-k t
org-src-fontify-natively t
org-src-tab-acts-natively t
org-src-window-setup 'current-window
org-startup-truncated nil
org-startup-with-inline-images t
org-tags-column 0 ; (- 0 fill-column -3)
)
(:bind "RET" acdw-org/return-dwim
2021-06-02 03:30:05 +00:00
"<S-return>" acdw-org/org-table-copy-down
"M-SPC M-SPC" insert-zero-width-space
"C-c C-l" org-insert-link-dwim
"M-w" acdw/copy-region-plain
"C-c C-n" acdw/org-next-heading-widen
"C-c C-p" acdw/org-previous-heading-widen)
2021-06-02 03:30:05 +00:00
(with-eval-after-load 'org-export
(add-to-list 'org-export-filter-final-output-functions
#'org-export-remove-zero-width-spaces))
(defun acdw/org-fix-lines-before-save ()
(add-hook 'before-save-hook #'acdw-org/fix-blank-lines-in-buffer 0 :local))
(:hook variable-pitch-mode
2021-08-27 23:01:38 +00:00
olivetti-mode
acdw/org-fix-lines-before-save)
(advice-add 'org-delete-backward-char
2021-08-16 02:10:48 +00:00
:override #'acdw-org/delete-backward-char)
(add-hook 'org-mode-hook
(defun org-mode@wc-stupid ()
(unless (and wc-mode
2021-08-17 22:26:53 +00:00
(> 0 (+ (or wc-orig-words 0)
(or wc-words-delta 0)))))
(setq-local
wc-count-words-function
(lambda (start end) "Count words stupidly with a limit."
(acdw-org/count-words-stupidly start
end
2021-08-17 22:26:53 +00:00
999)))))
2021-08-16 02:10:48 +00:00
(setup (:straight org-appear)
(:hook-into org-mode)))
2021-04-03 14:47:58 +00:00
(setup (:straight page-break-lines)
(global-page-break-lines-mode +1))
(setup (:straight paredit)
2021-04-25 04:23:15 +00:00
;; I don't use paredit-splice-sexp much, and it stomps on isearch.
(:unbind "M-s")
2021-08-30 21:37:02 +00:00
(defun paredit@setup ()
2021-04-25 04:23:15 +00:00
"Correct weirdnesses and set up paredit mode."
2021-08-30 21:37:02 +00:00
(:with-map lisp-mode-shared-map
(:bind "DEL" paredit-backward-delete
"C-M-;" comment-or-uncomment-sexp
"C-<backspace>" paredit-backward-kill-word))
(paredit-mode +1))
2021-04-25 04:23:15 +00:00
(dolist (mode lispy-modes)
2021-04-25 04:23:15 +00:00
(add-hook (intern (concat (symbol-name mode) "-hook"))
2021-08-30 21:37:02 +00:00
#'paredit@setup))
2021-04-06 22:59:45 +00:00
(require 'eldoc)
2021-04-06 22:59:45 +00:00
(eldoc-add-command 'paredit-backward-delete 'paredit-close-round))
(setup (:straight paren-face)
(dolist (mode lispy-modes)
(add-hook (intern (concat (symbol-name mode) "-hook")) #'paren-face-mode)))
2021-08-30 13:51:54 +00:00
(setup (:straight persistent-scratch)
(:option persistent-scratch-backup-directory (acdw/dir "scratch" t)
2021-08-31 03:18:45 +00:00
persistent-scratch-keep-n-newest-backups 12)
(persistent-scratch-setup-default)
(mapc (lambda (buf)
(with-current-buffer buf
(when (funcall persistent-scratch-scratch-buffer-p-function)
(persistent-scratch-mode +1))))
(buffer-list)))
2021-08-30 13:51:54 +00:00
(setup (:straight restart-emacs)
2021-05-04 02:31:29 +00:00
(defun emacs-upgrade (&optional update-packages)
"Pull config, upgrade packages, restart Emacs."
2021-05-04 02:31:29 +00:00
(interactive "P")
(when update-packages
(straight-pull-all))
(emacs-git-pull-config)
(restart-emacs)))
2021-04-09 17:50:11 +00:00
(setup (:straight simple-modeline)
(setup (:straight minions))
(require 'acdw-modeline)
(:option
simple-modeline-segments '(;; left
(acdw-modeline/modified
acdw-modeline/buffer-name
acdw-modeline/vc-branch
2021-08-10 19:47:00 +00:00
acdw-modeline/position)
;; right
(simple-modeline-segment-misc-info
acdw-modeline/track
acdw-modeline/wc
acdw-modeline/text-scale
simple-modeline-segment-process
acdw-modeline/god-mode-indicator
acdw-modeline/winum
acdw-modeline/minions
2021-08-07 21:59:56 +00:00
acdw-modeline/narrowed
2021-08-28 05:23:56 +00:00
acdw-modeline/major-mode)))
;; I've put in a pull request to add the (- 0 right-margin) bit here.
(advice-add 'simple-modeline--format :override
(defun simple-modeline@format (lefts rights)
(let* ((left (simple-modeline--format-segments lefts))
(right (simple-modeline--format-segments rights))
(reserve (length right)))
(concat
left
(propertize " "
'display `((space :align-to
(- right
(- 0 right-margin)
,reserve)))
'face '(:inherit simple-modeline-space))
right))))
(simple-modeline-mode +1))
2021-04-03 14:47:19 +00:00
2021-08-31 03:17:09 +00:00
(setup (:straight-if sly
(progn (defvar acdw/lisp-bin
(or (executable-find "sbcl")
(executable-find "clisp")
""))
(executable-find acdw/lisp-bin)))
(:option inferior-lisp-program acdw/lisp-bin
sly-kill-without-query-p t)
(:also-load sly-autoloads)
(setup (:straight clhs))
(:with-feature sly-mrepl
(dolist (key '("RET" "<return>"))
(:bind key sly-mrepl-return-at-end))
(:bind "C-c C-c" sly-mrepl-return))
(defun sly-mrepl-return-at-end ()
(interactive)
(if (<= (point-max) (point))
(sly-mrepl-return)
(if (bound-and-true-p paredit-mode)
(paredit-newline)
(electric-newline-and-maybe-indent)))))
2021-06-03 04:38:30 +00:00
(setup (:straight ssh-config-mode)
(dolist (spec '(("/\\.ssh/config\\'" . ssh-config-mode)
("/sshd?_config\\'" . ssh-config-mode)
("/knownhosts\\'" . ssh-known-hosts-mode)
("/authorized_keys2?\\'" . ssh-authorized-keys-mode)))
(add-to-list 'auto-mode-alist spec))
(add-hook 'ssh-config-mode-hook #'turn-on-font-lock))
2021-08-23 22:29:40 +00:00
(setup (:straight (topsy
:host github
:repo "alphapapa/topsy.el"))
(:hook-into prog-mode))
(setup (:straight typo)
2021-08-31 03:18:45 +00:00
;; Enable C-c 8 map in all buffers
(typo-global-mode +1)
(add-hook 'text-mode-hook
(defun text-mode@typo-unless ()
2021-08-30 21:37:34 +00:00
"Start `typo-mode' UNLESS the buffer matches a predicate."
;; I implement this instead of using
;; `typo-disable-electricity-functions' because the latter checks
;; on every pertinent keypress. I know I want /no/ typo-ing in
;; these certain buffers, so I won't even turn on the mode.
2021-08-31 03:18:45 +00:00
(unless (or ; predicates here
(string-match-p "COMMIT_EDITMSG"
(or (buffer-name) "")))
2021-08-31 03:18:45 +00:00
(typo-mode +1))))
(with-eval-after-load 'typo
;; jlf & cvandusen on #emacs make a great point: (RIGHT SINGLE QUOTATION
;; MARK) is /not/ an apostrophe. Making it curly is a typographical
;; consideration, not an input consideration. (I suppose you could make
;; the argument that all of these are typographical considerations, but
;; .. bleh.)
(define-typo-cycle typo-cycle-apostrophe
"Cycle through apostrophe-like graphemes.
If used with a numeric prefix argument N, N apostrophes will be inserted."
("'" "" "" ""))
(define-typo-cycle typo-cycle-backtick
"Cycle through backtick and left single quotation mark.
If used with a numeric prefix argument N, N backticks will be inserted."
("`" ""))
(:bind "'" typo-cycle-apostrophe
"`" typo-cycle-backtick)
))
(setup (:straight undo-fu)
(:global "C-/" undo-fu-only-undo
"C-?" undo-fu-only-redo))
2021-04-03 14:48:05 +00:00
(setup (:straight undo-fu-session)
(:option undo-fu-session-incompatible-files '("/COMMIT_EDITMSG\\'"
"/git-rebase-todo\\'")
undo-fu-session-directory (acdw/dir "undo/" t)
undo-fu-session-compression (acdw/system :home))
(global-undo-fu-session-mode +1))
(setup (:straight unfill))
2021-05-05 04:25:35 +00:00
(setup (:straight (unfocused
:host github
:repo "duckwork/unfocused"))
(unfocused-mode +1))
(setup (:straight (vertico
:host github
2021-08-10 04:14:25 +00:00
:repo "minad/vertico"
:files ("*" "extensions/*"
(:exclude ".git"))))
2021-08-07 02:26:37 +00:00
(:option resize-mini-windows 'grow-only
vertico-count-format nil
vertico-cycle t)
2021-08-20 12:57:35 +00:00
(defun up-directory (arg)
"Move up a directory (delete backwards to /)."
(interactive "p")
(if (string-match-p "/." (minibuffer-contents))
(zap-up-to-char (- arg) ?/)
(backward-kill-word arg)))
2021-08-20 13:29:40 +00:00
(with-eval-after-load 'vertico
(define-key vertico-map (kbd "<C-backspace>") #'up-directory))
2021-08-20 12:57:35 +00:00
(if (boundp 'comp-deferred-compilation-deny-list)
(add-to-list 'comp-deferred-compilation-deny-list "vertico"))
2021-08-10 04:14:25 +00:00
(vertico-mode +1)
;; Extensions!
(:also-load vertico-mouse)
(vertico-mouse-mode +1)
;; Prefix the current candidate with "> ". From Vertico wiki.
(defun vertico-format@add-arrow (orig cand prefix suffix index _start)
(setq cand (funcall orig cand prefix suffix index _start))
(concat
(if (= vertico--index index)
(propertize "> " 'face 'vertico-current)
" ")
cand))
(advice-add #'vertico--format-candidate :around #'vertico-format@add-arrow))
(setup (:straight wc-mode) ; TODO: move some of this stuff around
(:option wc-modeline-format "[%tww]"
2021-08-16 14:13:14 +00:00
wc-idle-wait 2)
2021-05-27 13:13:08 +00:00
(:hook-into text-mode)
(defun acdw-modeline/wc ()
"Display current `wc-buffer-stats'."
(when (bound-and-true-p wc-mode)
2021-08-13 02:05:48 +00:00
(or wc-buffer-stats "[w]"))))
2021-05-27 13:13:08 +00:00
(setup (:straight web-mode)
2021-03-30 04:21:58 +00:00
(:option css-level-offset 2
js-indent-level 2
sgml-indent-offset 2)
(dolist (ext '("\\.\\(p\\|dj\\)?html\\'"
"\\.html?\\'"
"\\.\\(tpl\\.\\)?php\\'"
"\\.[agj]sp\\'"
"\\.as[cp]x\\'"
"\\.erb\\'"
"\\.mustache\\'"))
(add-to-list 'auto-mode-alist `(,ext . web-mode))))
2021-03-11 18:16:50 +00:00
(setup (:straight which-key)
(:option which-key-show-early-on-C-h t
which-key-idle-delay 1
2021-05-05 17:34:21 +00:00
which-key-idle-secondary-delay 0.5)
2021-05-05 00:58:30 +00:00
(which-key-setup-side-window-right-bottom)
(which-key-mode +1))
2021-04-10 22:30:58 +00:00
2021-05-05 17:34:44 +00:00
(setup (:straight whitespace-cleanup-mode)
(global-whitespace-cleanup-mode +1))
(setup (:straight winum)
(:option winum-scope 'frame-local
winum-auto-setup-mode-line nil
2021-05-22 21:41:42 +00:00
winum-ignored-buffers '(" *which-key*")
winum-format " %s")
(when-unfocused winum-map-keys
(defvar winum--keys-mapped nil
"Whether `winum' keys have been mapped already.")
(when (and (not winum--keys-mapped)
(display-graphic-p))
(:with-map winum-keymap
(:bind "M-0" winum-select-window-0-or-10
"M-1" winum-select-window-1
"M-2" winum-select-window-2
"M-3" winum-select-window-3
"M-4" winum-select-window-4
"M-5" winum-select-window-5
"M-6" winum-select-window-6
"M-7" winum-select-window-7
"M-8" winum-select-window-8
"M-9" winum-select-window-9))
(setq winum--keys-mapped t)))
(winum-mode +1))
2021-05-26 12:32:36 +00:00
(setup (:straight xr))
(setup (:straight zzz-to-char)
(defun acdw/zzz-up-to-char (prefix)
"Call `zzz-up-to-char', unless issued a PREFIX, in which case
call `zzz-to-char'."
(interactive "P")
(if prefix
(call-interactively #'zzz-to-char)
(call-interactively #'zzz-up-to-char)))
(:global "M-z" acdw/zzz-up-to-char))
;;; System-dependent
;;;; Home
(when (acdw/system :home)
(setup (:straight exec-path-from-shell)
(when (daemonp)
(exec-path-from-shell-initialize)))
(setup (:straight pkgbuild-mode))
(setup (:straight (pdf-tools
:host github
:repo "vedang/pdf-tools"))
2021-05-30 04:18:46 +00:00
(add-to-list 'auto-mode-alist '("\\.pdf\\'" . pdf-view-mode))
(pdf-loader-install))
(setup (:straight systemd))
2021-08-27 01:05:02 +00:00
(setup (:straight vterm))
(add-hook 'after-make-frame-functions
(defun after-make-frame@maximize (frame)
2021-08-29 15:37:15 +00:00
(unless (bound-and-true-p edit-server-frame-p)
(toggle-frame-maximized frame)))))
2021-06-07 19:09:48 +00:00
;;;; Work
(when (acdw/system :work)
(setup (:straight ahk-mode)))
2021-07-14 21:59:13 +00:00
;;; init.el ends here