Switch to using `setup.el' for customizations
setup (https://git.sr.ht/~zge/setup) does everything I tried to do with `acdw/pkg', et al., but better.
This commit is contained in:
parent
2fdfc43684
commit
1dd6b9c0ee
|
@ -27,32 +27,21 @@
|
|||
;;; Speed up init
|
||||
;; see doom-emacs, et al.
|
||||
|
||||
(defconst gc-cons-threshold-basis (* 800 1000)
|
||||
"The basis value for `gc-cons-threshold' to return to after a jump.
|
||||
800 KB is Emacs's default `gc-cons-threshold'.")
|
||||
|
||||
(defconst gc-cons-percentage-basis 0.1
|
||||
"The basis value for `gc-cons-percentage' to return to after init.
|
||||
0.1 is Emacs's default `gc-cons-percentage'.")
|
||||
|
||||
(defvar orig-file-name-handler-alist file-name-handler-alist
|
||||
"The original value of `file-name-handler-alist' will be restored
|
||||
after init.")
|
||||
|
||||
(setq gc-cons-threshold most-positive-fixnum
|
||||
gc-cons-percentage 0.6
|
||||
file-name-handler-alist nil)
|
||||
(setq file-name-handler-alist nil)
|
||||
(acdw/gc-disable)
|
||||
|
||||
(add-hook 'after-init-hook
|
||||
(defun hook--post-init-reset ()
|
||||
"Reset `gc-cons-threshold', `gc-cons-percentage', and
|
||||
`file-name-handler-alist' to their defaults after init."
|
||||
(setq gc-cons-threshold gc-cons-threshold-basis
|
||||
gc-cons-percentage gc-cons-percentage-basis)
|
||||
(acdw/gc-enable)
|
||||
(dolist (handler file-name-handler-alist)
|
||||
(add-to-list 'orig-file-name-handler-alist handler))
|
||||
(setq file-name-handler-alist orig-file-name-handler-alist))
|
||||
|
||||
(add-hook 'after-init-hook #'hook--post-init-reset)
|
||||
(setq file-name-handler-alist orig-file-name-handler-alist)))
|
||||
|
||||
;;; Frame settings
|
||||
|
||||
|
@ -104,13 +93,11 @@
|
|||
(setenv "PATH" (mapconcat #'identity exec-path path-separator))
|
||||
|
||||
;; 2. Set `package' and `straight' variables.
|
||||
(setq package-enable-at-startup nil ; not sure if strictly
|
||||
; necessary
|
||||
package-quickstart nil ; ditto
|
||||
(setq package-enable-at-startup nil
|
||||
package-quickstart nil
|
||||
straight-host-usernames '((github . "duckwork")
|
||||
(gitlab . "acdw"))
|
||||
straight-base-dir acdw/dir ; don't clutter ~/.emacs.d
|
||||
)
|
||||
straight-base-dir acdw/dir)
|
||||
|
||||
;; 3. Bootstrap `straight'.
|
||||
(defvar bootstrap-version)
|
||||
|
|
885
init.el
885
init.el
|
@ -3,7 +3,7 @@
|
|||
;; Created: Sometime during Covid-19, 2020
|
||||
;; Keywords: configuration
|
||||
;; URL: https://tildegit.org/acdw/emacs
|
||||
;; Bankruptcy: 5d
|
||||
;; Bankruptcy: 6
|
||||
|
||||
;; This file is NOT part of GNU Emacs.
|
||||
|
||||
|
@ -16,54 +16,113 @@
|
|||
|
||||
;;; Code:
|
||||
|
||||
;;; `setup' -- configuration macro
|
||||
(straight-use-package '(setup :host nil
|
||||
:repo "https://git.sr.ht/~zge/setup"))
|
||||
(require 'setup)
|
||||
|
||||
;; shorthand for `customize-set-variable' (via setup)
|
||||
(defmacro setc (&rest args)
|
||||
"Customize user options using ARGS like `setq'."
|
||||
(declare (debug setq))
|
||||
`(setup (:option ,@args)))
|
||||
|
||||
;; Install packages with `straight-use-package'
|
||||
(setup-define :straight
|
||||
(lambda (recipe)
|
||||
`(straight-use-package ',recipe))
|
||||
:documentation "Install RECIPE with `straight-use-package'."
|
||||
:repeatable t
|
||||
:shorthand (lambda (sexp)
|
||||
(let ((recipe (cadr sexp)))
|
||||
(if (consp recipe)
|
||||
(car recipe)
|
||||
recipe))))
|
||||
|
||||
;; Bind keys to `acdw/map'
|
||||
(setup-define :acdw/map
|
||||
(lambda (key command)
|
||||
`(define-key acdw/map
|
||||
,(if (stringp key) (kbd key) key)
|
||||
#',command))
|
||||
:documentation "Bind KEY to COMMAND in `acdw/map'."
|
||||
:debug '(form sexp)
|
||||
:repeatable t)
|
||||
|
||||
;; Bind keys to `acdw/leader'
|
||||
(setup-define :acdw/leader
|
||||
(lambda (key command)
|
||||
`(define-key acdw/leader
|
||||
,(if (stringp key) (kbd key) key)
|
||||
#',command))
|
||||
:documentation "Bind KEY to COMMAND in `acdw/leader' map."
|
||||
:debug '(form sexp)
|
||||
:repeatable t)
|
||||
|
||||
;; Bind keys, and autoload the functions they're bound to.
|
||||
(setup-define :bind-autoload
|
||||
(lambda (key command)
|
||||
`(progn
|
||||
(autoload #',command (symbol-name setup-name))
|
||||
(define-key (symbol-value setup-map)
|
||||
,(if (stringp key) (kbd key) key)
|
||||
#',command)))
|
||||
:documentation "Bind KEY to COMMAND, and autload COMMAND from FEATURE."
|
||||
:debug '(form sexp)
|
||||
:repeatable t)
|
||||
|
||||
;;; About me
|
||||
(acdw/set
|
||||
'((user-full-name "Case Duckworth")
|
||||
(user-mail-address "acdw@acdw.net")
|
||||
(calendar-location-name "Baton Rouge, LA")
|
||||
(calendar-latitude 30.4)
|
||||
(calendar-longitude -91.1)
|
||||
(calendar-date-style iso)))
|
||||
(setc user-full-name "Case Duckworth"
|
||||
user-mail-address "acdw@acdw.net"
|
||||
calendar-location-name "Baton Rouge, LA"
|
||||
calendar-latitude 30.4
|
||||
calendar-longitude -91.1)
|
||||
|
||||
;;; Good defaults
|
||||
|
||||
;; Lines
|
||||
(acdw/set '((fill-column 80)))
|
||||
(global-display-fill-column-indicator-mode +1)
|
||||
(setc fill-column 80
|
||||
word-wrap t
|
||||
truncate-lines nil)
|
||||
(add-hook 'text-mode-hook #'turn-on-auto-fill)
|
||||
(add-hook 'prog-mode-hook #'turn-on-auto-fill)
|
||||
(global-display-fill-column-indicator-mode +1)
|
||||
(global-so-long-mode +1)
|
||||
|
||||
;; I don't want `visual-line-mode', because I really only want to wrap and
|
||||
;; truncate lines. Believe me, I know what I'm doing.
|
||||
(acdw/set '((word-wrap t)
|
||||
(truncate-lines nil)))
|
||||
|
||||
;; Whitespace
|
||||
(acdw/set '((whitespace-style
|
||||
(empty indentation space-before-tab space-after-tab))
|
||||
(indent-tabs-mode nil "We've lost this battle...")
|
||||
(tab-width 4)))
|
||||
(setc whitespace-style
|
||||
'(empty indentation space-before-tab space-after-tab)
|
||||
indent-tabs-mode nil
|
||||
tab-width 4
|
||||
smie-indent-basic tab-width)
|
||||
(add-hook 'before-save-hook #'whitespace-cleanup)
|
||||
|
||||
;; Pairs
|
||||
(add-hook 'prog-mode-hook #'electric-pair-local-mode)
|
||||
(acdw/set '((show-paren-delay 0)
|
||||
(show-paren-style mixed)
|
||||
(show-paren-when-point-inside-paren t)
|
||||
(show-paren-when-point-in-periphery t)))
|
||||
(setc show-paren-delay 0
|
||||
show-paren-style 'mixed
|
||||
show-paren-when-point-inside-paren t
|
||||
show-paren-when-point-in-periphery t)
|
||||
(show-paren-mode +1)
|
||||
(add-hook 'prog-mode-hook #'electric-pair-local-mode)
|
||||
|
||||
;; Killing & Yanking
|
||||
;; Killing and yanking
|
||||
(setc 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)
|
||||
(delete-selection-mode +1)
|
||||
(acdw/set '((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)))
|
||||
|
||||
;; Encoding
|
||||
(setc local-coding-system 'utf-8-unix
|
||||
coding-system-for-read 'utf-8-unix
|
||||
coding-system-for-write 'utf-8-unix
|
||||
buffer-file-coding-system 'utf-8-unix
|
||||
org-export-coding-system 'utf-8-unix
|
||||
org-html-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)
|
||||
|
@ -71,453 +130,387 @@
|
|||
(set-terminal-coding-system 'utf-8-unix)
|
||||
(set-keyboard-coding-system 'utf-8-unix)
|
||||
(set-selection-coding-system 'utf-8-unix)
|
||||
(acdw/set '((locale-coding-system utf-8-unix)
|
||||
(coding-system-for-read utf-8-unix)
|
||||
(coding-system-for-write utf-8-unix)
|
||||
(buffer-file-coding-system utf-8-unix)
|
||||
(org-export-coding-system utf-8-unix)
|
||||
(org-html-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))))
|
||||
|
||||
;; Unique buffer names
|
||||
(when (require 'uniquify)
|
||||
(acdw/set '((uniquify-buffer-name-style forward)
|
||||
(uniquify-separator "/")
|
||||
(uniquify-after-kill-buffer-p t)
|
||||
(uniquify-ignore-buffers-re "^\\*"))))
|
||||
;; Uniquify
|
||||
(setup (:require uniquify)
|
||||
(:option uniquify-buffer-name-style 'forward
|
||||
uniquify-separator path-separator
|
||||
uniquify-after-kill-buffer-p t
|
||||
uniquify-ignore-buffers-re "^\\*"))
|
||||
|
||||
;; Backups
|
||||
(acdw/set `((backup-by-copying t)
|
||||
(delete-old-versions -1)
|
||||
(version-control t)
|
||||
(vc-make-backup-files t)
|
||||
(backup-directory-alist ((".*" . ,(acdw/in-dir "backup/" t))))))
|
||||
;; Autosaves
|
||||
(acdw/set `((auto-save-file-name-transforms
|
||||
((".*" ,(acdw/in-dir "auto-save/" t) t)))
|
||||
(auto-save-list-file-prefix
|
||||
,(acdw/in-dir "auto-save-list/.saves-" t))))
|
||||
;; Files
|
||||
(setc backup-directory-alist `((".*" . ,(acdw/in-dir "backup/" t)))
|
||||
tramp-backup-directory-alist backup-directory-alist
|
||||
auto-save-file-name-transforms `((".*" ,(acdw/in-dir "auto-save/" t) t))
|
||||
auto-save-list-file-prefix (acdw/in-dir "auto-save-list/.saves-" t)
|
||||
backup-by-copying t
|
||||
delete-old-versions t
|
||||
version-control t
|
||||
vc-make-backup-files t)
|
||||
(auto-save-visited-mode +1)
|
||||
|
||||
(add-function :after after-focus-change-function
|
||||
(defun hook--auto-save-when-unfocused ()
|
||||
"Save all buffers when out of focus."
|
||||
(acdw/when-unfocused #'save-some-buffers t))
|
||||
(add-function :after after-focus-change-function
|
||||
#'hook--auto-save-when-unfocused)
|
||||
(acdw/when-unfocused #'save-some-buffers t)))
|
||||
|
||||
;; Auto-revert
|
||||
(when (require 'autorevert)
|
||||
(setup (:require autorevert)
|
||||
(global-auto-revert-mode +1))
|
||||
;; Save place
|
||||
(when (require 'saveplace)
|
||||
(acdw/set
|
||||
`((save-place-file ,(acdw/in-dir "places.el"))
|
||||
(save-place-forget-unreadable-files ,(eq acdw/system :home))))
|
||||
|
||||
(setup (:require saveplace)
|
||||
(:option save-place-file (acdw/in-dir "places.el")
|
||||
save-place-forget-unreadable-files (eq acdw/system :home))
|
||||
(save-place-mode +1))
|
||||
;; Recent files
|
||||
(when (require 'recentf)
|
||||
(acdw/set
|
||||
`((recentf-save-file ,(acdw/in-dir "recentf.el"))
|
||||
(recentf-max-menu-items 100)
|
||||
(recentf-max-saved-items nil)
|
||||
(recentf-auto-cleanup 60 "Cleanup the recentf list when idle for 60s.")))
|
||||
(add-to-list 'recentf-exclude acdw/dir)
|
||||
|
||||
(setup (:require recentf)
|
||||
(:option recentf-save-file (acdw/in-dir "recentf.el")
|
||||
recentf-max-menu-items 100
|
||||
recentf-max-saved-items nil
|
||||
recentf-auto-cleanup 60
|
||||
(append recentf-exclude) acdw/dir)
|
||||
(recentf-mode +1))
|
||||
|
||||
;; Move the custom file
|
||||
(acdw/set `((custom-file ,(acdw/in-dir "custom.el"))))
|
||||
;; Minibuffer
|
||||
(setc minibuffer-prompt-properties
|
||||
'(read-only t
|
||||
cursor-intangible t
|
||||
face minibuffer-prompt)
|
||||
enable-recursive-minibuffers t
|
||||
file-name-shadow-properties '(invisible t intangible t)
|
||||
read-answer-short t)
|
||||
(minibuffer-depth-indicate-mode +1)
|
||||
(file-name-shadow-mode +1)
|
||||
(fset 'yes-or-no-p #'y-or-n-p)
|
||||
|
||||
(setup (:require savehist)
|
||||
(:option (append savehist-additional-variables) 'kill-ring
|
||||
(append savehist-additional-variables) 'search-ring
|
||||
(append savehist-additional-variables) 'regexp-search-ring
|
||||
history-length t
|
||||
history-delete-duplicates t
|
||||
savehist-autosave-interval 6
|
||||
savehist-file (acdw/in-dir "savehist.el"))
|
||||
(savehist-mode +1))
|
||||
|
||||
(setup (:require icomplete)
|
||||
(:option completion-ignore-case t
|
||||
read-buffer-completion-ignore-case t
|
||||
icomplete-delay-completions-threshold 0
|
||||
icomplete-max-delay-chars 0
|
||||
icomplete-compute-delay 0
|
||||
icomplete-show-matches-on-no-input t
|
||||
icomplete-with-buffer-completion-tables t
|
||||
icomplete-in-buffer t
|
||||
completion-styles '(partial-completion substring flex))
|
||||
(fido-mode -1)
|
||||
(icomplete-mode +1))
|
||||
|
||||
(setup imenu
|
||||
(:option imenu-auto-rescan t))
|
||||
|
||||
;; Cursor
|
||||
(acdw/set '((cursor-type bar)
|
||||
(cursor-in-non-selected-windows hollow)))
|
||||
|
||||
;; (defun hook--overwrite-mode-change-cursor ()
|
||||
;; (setq cursor-type (if overwrite-mode 'hbar 'bar)))
|
||||
;; (add-hook 'overwrite-mode-hook #'hook--overwrite-mode-change-cursor)
|
||||
(setc cursor-type 'bar
|
||||
cursor-in-non-selected-windows 'hollow)
|
||||
|
||||
;; Scrolling
|
||||
(acdw/set '((auto-window-vscroll nil)
|
||||
(fast-but-imprecise-scrolling t)
|
||||
(scroll-margin 0)
|
||||
(scroll-conservatively 101)
|
||||
(scroll-preserve-screen-position 1)))
|
||||
(setc auto-window-vscroll nil
|
||||
fast-but-imprecise-scrolling t
|
||||
scroll-margin 0
|
||||
scroll-conservatively 101
|
||||
scroll-preserve-screen-position 1)
|
||||
|
||||
;; Bindings
|
||||
(acdw/binds (("C-h" ehelp-command :after ("ehelp" nil nil 'keymap))
|
||||
([remap just-one-space] cycle-spacing)
|
||||
("M-/" hippie-expand)
|
||||
("M-=" count-words)
|
||||
("C-x C-b" ibuffer)))
|
||||
;; MS Windows
|
||||
(setc 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)
|
||||
|
||||
;;; Startup
|
||||
(acdw/set `((inhibit-startup-screen t)
|
||||
(initial-buffer-choice t)
|
||||
(initial-scratch-message
|
||||
,(concat ";; Howdy, "
|
||||
(nth 0 (split-string user-full-name)) "!"
|
||||
" Welcome to GNU Emacs.\n\n"))))
|
||||
;; Dired
|
||||
(setup dired
|
||||
(:option 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)
|
||||
(:also-load dired-x)
|
||||
(:hook dired-hide-details-mode
|
||||
hl-line-mode)
|
||||
(:acdw/map "C-x C-j" dired-jump))
|
||||
|
||||
;;; Windows settings
|
||||
(when (eq acdw/system :work)
|
||||
(acdw/set `((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))))
|
||||
;; Eshell
|
||||
(setup eshell
|
||||
(:option eshell-directory-name (acdw/in-dir "eshell/" t)
|
||||
eshell-aliases-file (acdw/in-dir "eshell/aliases" t)))
|
||||
|
||||
(acdw/set '((default-directory (expand-file-name "~/"))))
|
||||
;; Garbage collection
|
||||
(add-hook 'minibuffer-setup-hook #'acdw/gc-disable)
|
||||
(add-hook 'minibuffer-exit-hook #'acdw/gc-enable)
|
||||
(add-function :after after-focus-change-function
|
||||
(defun hook--gc-when-unfocused ()
|
||||
(acdw/when-unfocused #'garbage-collect)))
|
||||
|
||||
;; Etc. good defaults
|
||||
(setc custom-file (acdw/in-dir "custom.el")
|
||||
inhibit-startup-screen t
|
||||
initial-buffer-choice t
|
||||
initial-scratch-message (concat ";; Howdy, " (nth 0 (split-string
|
||||
user-full-name))
|
||||
"! Welcome to GNU Emacs.\n\n")
|
||||
default-directory (expand-file-name "~/")
|
||||
disabled-command-function nil
|
||||
load-prefer-newer t
|
||||
comp-async-report-warnings-errors nil
|
||||
frame-title-format "%b %+%* GNU Emacs")
|
||||
|
||||
;; Etc. bindings
|
||||
(autoload 'ehelp-command "ehelp" nil nil 'keymap)
|
||||
(define-key acdw/map (kbd "C-h") 'ehelp-command)
|
||||
(define-key acdw/map [remap just-one-space] #'cycle-spacing)
|
||||
(define-key acdw/map (kbd "M-/") #'hippie-expand)
|
||||
(define-key acdw/map (kbd "M-=") #'count-words)
|
||||
(define-key acdw/map (kbd "C-x C-b") #'ibuffer)
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;;; Here ends the package-less configuration. Everything following requires a
|
||||
;;; package to be downloaded. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
;;; Interactivity
|
||||
|
||||
|
||||
;;;; Begin-end
|
||||
(setup (:straight beginend)
|
||||
(beginend-global-mode +1))
|
||||
|
||||
;;;; Expand-region
|
||||
(setup (:straight expand-region)
|
||||
(:acdw/map "C-=" er/expand-region))
|
||||
|
||||
;;;; CRUX
|
||||
(setup (:straight crux)
|
||||
(:with-map acdw/map
|
||||
(:bind "M-o" crux-other-window-or-switch-buffer)
|
||||
(:bind "C-a" crux-move-beginning-of-line)
|
||||
(:bind "C-k" crux-kill-and-join-forward))
|
||||
(crux-reopen-as-root-mode +1))
|
||||
|
||||
;;; Functionality
|
||||
|
||||
;;;; Undo-fu
|
||||
(setup (:straight undo-fu)
|
||||
(:with-map acdw/map
|
||||
(:bind "C-/" undo-fu-only-undo
|
||||
"C-?" undo-fu-only-redo)))
|
||||
|
||||
(setup (:straight undo-fu-session)
|
||||
(:option undo-fu-session-incompatible-files '("/COMMIT_EDITMSG\\'"
|
||||
"/git-rebase-todo\\'")
|
||||
undo-fu-session-directory (acdw/in-dir "undo/" t))
|
||||
(global-undo-fu-session-mode +1))
|
||||
|
||||
;;; Minibuffer
|
||||
|
||||
(acdw/set '((minibuffer-prompt-properties (read-only t
|
||||
cursor-intangible t
|
||||
face minibuffer-prompt))
|
||||
(enable-recursive-minibuffers t)
|
||||
(file-name-shadow-properties (invisible t))))
|
||||
(minibuffer-depth-indicate-mode +1)
|
||||
(file-name-shadow-mode +1)
|
||||
;;;; Icomplete-vertical
|
||||
(setup (:straight icomplete-vertical)
|
||||
(let ((map icomplete-minibuffer-map))
|
||||
(let ((command #'icomplete-forward-completions))
|
||||
(define-key map (kbd "<down>") command)
|
||||
(define-key map (kbd "C-n") command))
|
||||
(let ((command #'icomplete-backward-completions))
|
||||
(define-key map (kbd "<up>") command)
|
||||
(define-key map (kbd "C-p") command))
|
||||
(define-key map (kbd "RET") #'icomplete-force-complete-and-exit)
|
||||
(define-key map (kbd "C-RET") #'minibuffer-complete-and-exit))
|
||||
(icomplete-vertical-mode +1))
|
||||
|
||||
(acdw/pkg recursion-indicator
|
||||
:set '((recursion-indicator-general "%")
|
||||
(recursion-indicator-minibuffer "@"))
|
||||
:now ((recursion-indicator-mode +1)))
|
||||
;;;; Orderless
|
||||
(setup (:straight orderless)
|
||||
(:option (prepend completion-styles) 'orderless))
|
||||
|
||||
;; Save history
|
||||
(when (require 'savehist)
|
||||
(acdw/set `((savehist-additional-variables
|
||||
(kill-ring search-ring regexp-search-ring))
|
||||
(history-length t)
|
||||
(history-delete-duplicates t)
|
||||
(savehist-autosave-interval 6)
|
||||
(savehist-file ,(acdw/in-dir "savehist.el"))))
|
||||
(savehist-mode +1))
|
||||
|
||||
;; God mode
|
||||
(acdw/pkg god-mode
|
||||
:binds (("<escape>" god-local-mode)
|
||||
("i" god-local-mode :map god-local-mode-map)
|
||||
("." repeat :map god-local-mode-map)
|
||||
("C-x C-1" delete-other-windows)
|
||||
("C-x C-2" split-window-below)
|
||||
("C-x C-3" split-window-right)
|
||||
("C-x C-0" delete-window))
|
||||
:now ((defun acdw/god-mode-update-cursor ()
|
||||
(setq cursor-type (if (or god-local-mode buffer-read-only)
|
||||
'box
|
||||
'bar)))
|
||||
(defun acdw/god-mode-toggle-on-overwrite ()
|
||||
(if (bound-and-true-p overwrite-mode)
|
||||
(progn
|
||||
(setq cursor-type 'hbar)
|
||||
(god-local-mode-pause))
|
||||
(god-local-mode-resume)
|
||||
(acdw/god-mode-update-cursor)))
|
||||
(require 'god-mode)
|
||||
(god-mode))
|
||||
:hooks (((god-mode-enabled-hook god-mode-disabled-hook)
|
||||
acdw/god-mode-update-cursor)
|
||||
(overwrite-mode-hook acdw/god-mode-toggle-on-overwrite)))
|
||||
|
||||
;; Icomplete (-vertical)
|
||||
(when (require 'icomplete)
|
||||
(acdw/set '((completion-ignore-case t)
|
||||
(read-buffer-completion-ignore-case t)
|
||||
(icomplete-delay-completions-threshold 0)
|
||||
(icomplete-max-delay-chars 0)
|
||||
(icomplete-compute-delay 0)
|
||||
(icomplete-show-matches-on-no-input t)
|
||||
(icomplete-with-buffer-completion-tables t)
|
||||
(icomplete-in-buffer t)))
|
||||
(acdw/pkg orderless
|
||||
:set '((completion-styles (orderless))))
|
||||
(acdw/pkg icomplete-vertical
|
||||
:binds (("<down>" icomplete-forward-completions
|
||||
:map icomplete-minibuffer-map)
|
||||
("C-n" icomplete-forward-completions
|
||||
:map icomplete-minibuffer-map)
|
||||
("<up>" icomplete-backward-completions
|
||||
:map icomplete-minibuffer-map)
|
||||
("C-p" icomplete-backward-completions
|
||||
:map icomplete-minibuffer-map)
|
||||
("C-v" icomplete-vertical-toggle
|
||||
:map icomplete-minibuffer-map)
|
||||
("RET" icomplete-force-complete-and-exit
|
||||
:map icomplete-minibuffer-map)
|
||||
("C-j" minibuffer-complete-and-exit
|
||||
:map icomplete-minibuffer-map))
|
||||
:now ((fido-mode -1)
|
||||
(icomplete-mode +1)
|
||||
(icomplete-vertical-mode +1))))
|
||||
|
||||
;; Consult
|
||||
(acdw/pkg consult
|
||||
:binds (;; C-c bindings (`mode-specific-map')
|
||||
("C-c h" consult-history)
|
||||
("C-c m" consult-mode-command)
|
||||
;;;; Consult
|
||||
(setup (:straight consult)
|
||||
(:with-map acdw/map
|
||||
(:bind-autoload
|
||||
;; C-c bindings (`mode-specific-map')
|
||||
"C-c h" consult-history
|
||||
"C-c m" consult-mode-command
|
||||
;; 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)
|
||||
("C-x r x" consult-register)
|
||||
("C-x r b" consult-bookmark)
|
||||
"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
|
||||
"C-x r x" consult-register
|
||||
"C-x r b" consult-bookmark
|
||||
;; M-g bindings (`goto-map')
|
||||
("M-g o" consult-outline)
|
||||
("M-g m" consult-mark)
|
||||
("M-g k" consult-global-mark)
|
||||
("M-g i" consult-imenu)
|
||||
("M-g e" consult-error)
|
||||
"M-g o" consult-outline
|
||||
"M-g m" consult-mark
|
||||
"M-g k" consult-global-mark
|
||||
"M-g i" consult-imenu
|
||||
"M-g e" consult-error
|
||||
;; M-s bindings (`search-map')
|
||||
("M-s g" consult-grep) ; alts:
|
||||
; consult-git-grep,
|
||||
; consult-ripgrep
|
||||
("M-s f" consult-find) ; alts:
|
||||
; consult-locate
|
||||
("M-s l" consult-line)
|
||||
("M-s m" consult-multi-occur)
|
||||
("M-s k" consult-keep-lines)
|
||||
("M-s u" consult-focus-lines)
|
||||
"M-s g" consult-grep ; alts: consult-git-grep, consult-ripgrep
|
||||
"M-s f" consult-find ; alts: consult-locate
|
||||
"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)
|
||||
("<f1> a" consult-apropos)
|
||||
("C-h a" consult-apropos))
|
||||
:now ((autoload 'consult-register-preview "consult"))
|
||||
:set '((register-preview-delay 0)
|
||||
(register-preview-function #'consult-register-preview)))
|
||||
"M-y" consult-yank-pop
|
||||
"<f1> a" consult-apropos
|
||||
"C-h a" consult-apropos))
|
||||
(autoload 'consult-register-preview "consult")
|
||||
(:option register-preview-delay 0
|
||||
register-preview-function #'consult-register-preview))
|
||||
|
||||
;; begin-end
|
||||
(acdw/pkg beginend
|
||||
:now ((beginend-global-mode)))
|
||||
;;;; Marginalia
|
||||
(setup (:straight marginalia)
|
||||
(:option marginalia-annotators '(marginalia-annotators-heavy
|
||||
marginalia-annotators-light))
|
||||
(marginalia-mode +1))
|
||||
|
||||
;; Marginalia
|
||||
(acdw/pkg marginalia
|
||||
:set '((marginalia-annotators (marginalia-annotators-heavy
|
||||
marginalia-annotators-light)))
|
||||
:now ((marginalia-mode +1)))
|
||||
;;; UI
|
||||
|
||||
;; Imenu
|
||||
(when (require 'imenu)
|
||||
(acdw/set '((imenu-auto-rescan t))))
|
||||
|
||||
;; Fonts
|
||||
(acdw/set-faces ((fixed-pitch . ((t (:inherit default))))))
|
||||
|
||||
;;; Packages
|
||||
|
||||
;; Undo-fu
|
||||
(acdw/pkg undo-fu
|
||||
:binds (("C-/" undo-fu-only-undo)
|
||||
("C-?" undo-fu-only-redo)))
|
||||
(acdw/pkg undo-fu-session
|
||||
:set `((undo-fu-session-incompatible-files ("/COMMIT_EDITMSG\\'"
|
||||
"/git-rebase-todo\\'"))
|
||||
(undo-fu-session-directory ,(acdw/in-dir "undo/" t)))
|
||||
:then ((global-undo-fu-session-mode +1)))
|
||||
|
||||
;; Modus themes
|
||||
(acdw/pkg (modus-themes
|
||||
;;;; Modus themes
|
||||
(setup (:straight (modus-themes
|
||||
:host gitlab
|
||||
:repo "protesilaos/modus-themes")
|
||||
:set `((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-scale-headings nil)
|
||||
(modus-themes-mode-line nil))
|
||||
:now ((acdw/sunrise-sunset #'modus-themes-load-operandi
|
||||
#'modus-themes-load-vivendi)))
|
||||
:repo "protesilaos/modus-themes"))
|
||||
(: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))
|
||||
|
||||
;; Expand-region
|
||||
(acdw/pkg expand-region
|
||||
:binds (("C-=" er/expand-region)))
|
||||
|
||||
;; CRUX
|
||||
(acdw/pkg crux
|
||||
:binds (("M-o" crux-other-window-or-switch-buffer)
|
||||
([remap move-beginning-of-line] crux-move-beginning-of-line)
|
||||
([remap kill-line] crux-kill-and-join-forward)))
|
||||
;;; Frame title
|
||||
|
||||
(acdw/set `((frame-title-format
|
||||
"%b %+%* GNU Emacs")))
|
||||
|
||||
;;; Mode line
|
||||
|
||||
;; Minions
|
||||
(acdw/pkg minions)
|
||||
|
||||
;; Simple mode line
|
||||
(acdw/pkg simple-modeline
|
||||
:set '((simple-modeline-segments
|
||||
((;; left
|
||||
acdw-modeline/modified
|
||||
;;;; Mode line
|
||||
(setup (:straight simple-modeline)
|
||||
(setup (:straight minions))
|
||||
(:option simple-modeline-segments
|
||||
'((acdw-modeline/modified
|
||||
acdw-modeline/buffer-name
|
||||
acdw-modeline/vc-branch
|
||||
simple-modeline-segment-position
|
||||
simple-modeline-segment-word-count)
|
||||
(;; right
|
||||
simple-modeline-segment-misc-info
|
||||
(simple-modeline-segment-misc-info
|
||||
simple-modeline-segment-process
|
||||
acdw-modeline/god-mode-indicator
|
||||
acdw-modeline/minions
|
||||
simple-modeline-segment-major-mode))))
|
||||
:now ((require 'acdw-modeline)
|
||||
(simple-modeline-mode +1)))
|
||||
simple-modeline-segment-major-mode)))
|
||||
(require 'acdw-modeline)
|
||||
(simple-modeline-mode +1))
|
||||
|
||||
;;; Magit
|
||||
;;; Utilities
|
||||
|
||||
(acdw/pkg magit
|
||||
:binds (("g" magit-status :map acdw/leader))
|
||||
:set `((magit-display-buffer-function
|
||||
,(defun magit-display-buffer-same-window (buffer)
|
||||
;;;; 0x0 -- upload files to a nullpointer
|
||||
(setup (:straight (0x0 :host nil
|
||||
:repo "https://git.sr.ht/~zge/nullpointer-emacs"))
|
||||
(:option 0x0-default-host 'ttm))
|
||||
|
||||
;;; Applications
|
||||
|
||||
;;;; Magit
|
||||
(setup (:straight magit)
|
||||
(:acdw/leader "g" magit-status)
|
||||
(:option magit-display-buffer-function
|
||||
(defun magit-display-buffer-same-window (buffer)
|
||||
"Display BUFFER in the selected window like God intended."
|
||||
(display-buffer buffer
|
||||
'(display-buffer-same-window))))
|
||||
(magit-popup-display-buffer-action
|
||||
((display-buffer-same-window)))))
|
||||
(display-buffer buffer '(display-buffer-same-window)))
|
||||
magit-popup-display-buffer-action '((display-buffer-same-window))))
|
||||
|
||||
;;; Web browsing
|
||||
;;;; File browsing
|
||||
(setup (:straight dired-subtree)
|
||||
(define-key dired-mode-map "i" #'dired-subtree-toggle))
|
||||
|
||||
(acdw/set '((browse-url-browser-function browse-url-firefox)
|
||||
(browse-url-new-window-flag t)
|
||||
(browse-url-firefox-new-window-is-tab t)
|
||||
(shr-max-width fill-column)
|
||||
(shr-width fill-column)))
|
||||
(setup (:straight dired-collapse)
|
||||
(:hook-into dired-mode))
|
||||
|
||||
;;;; Web browsing
|
||||
(when (eq acdw/system :work)
|
||||
(add-to-list 'exec-path "C:/Program Files/Mozilla Firefox"))
|
||||
|
||||
(acdw/hooks ((text-mode-hook goto-address-mode)
|
||||
(prog-mode-hook goto-address-prog-mode)))
|
||||
(setc browse-url-browser-function 'browse-url-firefox
|
||||
browse-url-new-window-flag t
|
||||
browse-url-firefox-new-window-is-tab t
|
||||
shr-max-width fill-column
|
||||
shr-width fill-column)
|
||||
|
||||
;;; Gemini/gopher browsing
|
||||
(add-hook 'text-mode-hook #'goto-address-mode)
|
||||
(add-hook 'prog-mode-hook #'goto-address-prog-mode)
|
||||
|
||||
(acdw/pkg (elpher
|
||||
:repo "git://thelambdalab.xyz/elpher.git")
|
||||
:set '((elpher-ipv4-always t)
|
||||
(elpher-certificate-directory
|
||||
(acdw/in-var "elpher/")))
|
||||
:now ((acdw/bind-after-map "elpher" elpher-mode-map
|
||||
(("n" elpher-next-link :map-after "elpher")
|
||||
("p" elpher-prev-link :map-after "elpher")
|
||||
("o" elpher-follow-current-link :map-after "elpher")
|
||||
("G" elpher-go-current :map-after "elpher")))
|
||||
;;;; Gemini/gopher browsing
|
||||
(setup (:straight (elpher :host nil
|
||||
:repo "git://thelambdalab.xyz/elpher.git"))
|
||||
(:option elpher-ipv4-always t
|
||||
elpher-certificate-directory (acdw/in-dir "elpher/"))
|
||||
(:bind "n" elpher-next-link
|
||||
"p" elpher-prev-link
|
||||
"o" elpher-follow-current-link
|
||||
"G" elpher-go-current)
|
||||
(:hook acdw/reading-mode)
|
||||
(when (boundp 'god-exempt-major-modes)
|
||||
(add-to-list 'god-exempt-major-modes 'elpher-mode))))
|
||||
(:option (append god-exempt-major-modes) 'elpher-mode)))
|
||||
|
||||
(acdw/pkg (gemini-mode
|
||||
:repo "https://git.carcosa.net/jmcbray/gemini.el.git")
|
||||
:now ((add-to-list 'auto-mode-alist
|
||||
'("\\.\\(gemini\\|gmi\\)\\'" . gemini-mode))))
|
||||
(setup (:straight (gemini-mode
|
||||
:host nil
|
||||
:repo "https://git.carcosa.net/jmcbray/gemini.el.git"))
|
||||
(:option (append auto-mode-alist)
|
||||
'("\\.\\(gemini\\|gmi\\)\\'" . gemini-mode)))
|
||||
|
||||
;;; Dired
|
||||
(acdw/pkg dired
|
||||
:local t
|
||||
:set `((dired-recursive-copies always)
|
||||
(dired-recursive-deletes always)
|
||||
(delete-by-moving-to-trash t)
|
||||
(dired-listing-switches "-Al")
|
||||
(ls-lisp-dirs-first t)
|
||||
(dired-dwim-target t))
|
||||
:now ((autoload 'dired-mode-map "dired" nil nil 'keymap)
|
||||
(acdw/pkg dired-subtree)
|
||||
(acdw/pkg dired-x
|
||||
:local t
|
||||
:binds (("C-x C-j" dired-jump)))
|
||||
(acdw/pkg dired-collapse
|
||||
:hooks ((dired-mode-hook dired-collapse-mode)))
|
||||
(defun hook--dired-mode ()
|
||||
(hl-line-mode +1)
|
||||
(dired-hide-details-mode +1)))
|
||||
:hooks ((dired-mode-hook hook--dired-mode))
|
||||
:binds (("i" dired-subtree-toggle :map dired-mode-map)))
|
||||
;;;; Read e-books (nov.el)
|
||||
(setup (:straight nov)
|
||||
(:option nov-text-width fill-column
|
||||
(append auto-mode-alist) '("\\.epub\\'" . nov-mode)))
|
||||
|
||||
;;; Eshell
|
||||
|
||||
(acdw/set `((eshell-directory-name ,(acdw/in-dir "eshell/" t))
|
||||
(eshell-aliases-file ,(acdw/in-dir "eshell/aliases" t))))
|
||||
|
||||
;;; Org-mode
|
||||
(acdw/pkg (org
|
||||
:repo "https://code.orgmode.org/bzg/org-mode.git")
|
||||
:now ((require 'acdw-org))
|
||||
:set `((org-directory "~/org")
|
||||
(org-hide-emphasis-markers t)
|
||||
(org-fontify-whole-heading-line t)
|
||||
(org-fontify-done-headline t)
|
||||
(org-fontify-quote-and-verse-blocks t)
|
||||
(org-src-fontify-natively t)
|
||||
(org-pretty-entities t)
|
||||
(org-tags-column ,(- 0 fill-column -3))
|
||||
(org-src-tab-acts-natively t)
|
||||
(org-src-window-setup current-window)
|
||||
(org-confirm-babel-evaluate nil)
|
||||
(org-adapt-indentation nil)
|
||||
(org-catch-invisible-edits smart)
|
||||
(org-special-ctrl-a/e t)
|
||||
(org-special-ctrl-k t)
|
||||
(org-imenu-depth 3)
|
||||
(org-export-headline-levels 8)
|
||||
(org-export-with-smart-quotes t)
|
||||
(org-export-with-sub-superscripts t))
|
||||
:hooks ((before-save-hook acdw/hook--org-mode-fix-blank-lines))
|
||||
:binds (("RET" unpackaged/org-return-dwim
|
||||
:map org-mode-map :map-after 'org)))
|
||||
|
||||
;;; Nov.el -- ebook reader
|
||||
(acdw/pkg nov
|
||||
:now ((autoload #'nov-mode "nov")
|
||||
(add-to-list 'auto-mode-alist '("\\.epub\\'" . nov-mode)))
|
||||
:set `((nov-text-width ,fill-column)))
|
||||
|
||||
;;; 0x0 -- upload files
|
||||
(acdw/pkg (0x0 :repo "https://git.sr.ht/~zge/nullpointer-emacs")
|
||||
:set '((0x0-default-host ttm)))
|
||||
;;;; Org mode
|
||||
(setup (:straight (org :host nil
|
||||
:repo "https://code.orgmode.org/bzg/org-mode.git"))
|
||||
(require 'acdw-org)
|
||||
(:option org-directory "~/org"
|
||||
org-hide-emphasis-markers t
|
||||
org-fontify-whole-heading-line t
|
||||
org-fontify-done-headline t
|
||||
org-fontify-quote-and-verse-blocks t
|
||||
org-src-fontify-natively t
|
||||
org-pretty-entities t
|
||||
org-tags-column (- 0 fill-column -3)
|
||||
org-src-tab-acts-natively t
|
||||
org-src-window-setup 'current-window
|
||||
org-confirm-babel-evaluate nil
|
||||
org-adapt-indentation nil
|
||||
org-catch-invisible-edits 'smart
|
||||
org-special-ctrl-a/e t
|
||||
org-special-ctrl-k t
|
||||
org-imenu-depth 3
|
||||
org-export-headline-levels 8
|
||||
org-export-with-smart-quotes t
|
||||
org-export-with-sub-superscripts t)
|
||||
(:bind "RET" unpackaged/org-return-dwim)
|
||||
(add-hook 'before-save-hook #'acdw/hook--org-mode-fix-blank-lines))
|
||||
|
||||
;;; Programming languages
|
||||
|
||||
;; General
|
||||
;;;; Formatting
|
||||
(setup (:straight (apheleia :host github
|
||||
:repo "raxod502/apheleia"))
|
||||
(apheleia-global-mode +1))
|
||||
|
||||
(acdw/set `((smie-indent-basic ,tab-width)))
|
||||
|
||||
;; Formatting
|
||||
|
||||
(acdw/pkg (apheleia
|
||||
:host github
|
||||
:repo "raxod502/apheleia")
|
||||
:now ((apheleia-global-mode +1))
|
||||
:then ((add-to-list 'apheleia-formatters
|
||||
'(shfmt . ("shfmt")))
|
||||
(add-to-list 'apheleia-mode-alist
|
||||
'(sh-mode . shfmt))))
|
||||
|
||||
;; Shell(s)
|
||||
(when (executable-find "shellcheck")
|
||||
(acdw/pkg flymake-shellcheck
|
||||
:hooks ((sh-mode-hook (flymake-mode
|
||||
flymake-shellcheck-load)))))
|
||||
|
||||
(acdw/set `((sh-basic-offset ,tab-width)
|
||||
(sh-indent-after-case 0)
|
||||
(sh-indent-for-case-alt +)
|
||||
(sh-indent-for-case-label 0)))
|
||||
|
||||
(defun hook--sh-mode-indent-like-shfmt ()
|
||||
"Try to mirror `shfmt' formatting in shell scripts."
|
||||
(setq indent-tabs-mode t))
|
||||
(add-hook 'sh-mode-hook #'hook--sh-mode-indent-like-shfmt)
|
||||
|
||||
;; Emacs lisp
|
||||
(acdw/set '((eval-expression-print-length nil)
|
||||
(eval-expression-print-level nil)))
|
||||
|
||||
(when (require 'cl-lib)
|
||||
(setq-default lisp-indent-function #'common-lisp-indent-function)
|
||||
;;;; Emacs lisp
|
||||
(setup emacs-lisp
|
||||
(require 'cl-lib)
|
||||
(:option eval-expression-print-length nil
|
||||
eval-expression-print-level nil
|
||||
lisp-indent-function #'common-lisp-indent-function)
|
||||
(put 'cl-flet 'common-lisp-indent-function
|
||||
(get 'flet 'common-lisp-indent-function))
|
||||
(put 'cl-labels 'common-lisp-indent-function
|
||||
|
@ -526,34 +519,36 @@
|
|||
(put 'dotimes-protect 'common-lisp-indent-function
|
||||
(get 'when 'common-lisp-indent-function)))
|
||||
|
||||
;; Racket
|
||||
(acdw/pkg racket-mode)
|
||||
;;;; Shell scripts
|
||||
(setup sh
|
||||
(: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)
|
||||
|
||||
;; Web stuff
|
||||
(acdw/set '((css-indent-offset 2)
|
||||
(js-indent-level 2)
|
||||
(sgml-indent-offset 2)))
|
||||
(when (executable-find "shfmt")
|
||||
(:option (append apheleia-formatters) '(shfmt . ("shfmt"))
|
||||
(append apheleia-mode-alist) '(sh-mode . shfmt)))
|
||||
|
||||
;;; Miscellaneous
|
||||
(when (executable-find "shellcheck")
|
||||
(straight-use-package 'flymake-shellcheck)
|
||||
(:hook flymake-mode
|
||||
flymake-shellcheck-load)))
|
||||
|
||||
(acdw/set '((disabled-command-function nil)
|
||||
(load-prefer-newer t)
|
||||
(comp-async-report-warnings-errors nil)))
|
||||
|
||||
(fset 'yes-or-no-p #'y-or-n-p)
|
||||
|
||||
;; Garbage collection
|
||||
(defun hook--gc-cons-maximize ()
|
||||
(setq gc-cons-threshold most-positive-fixnum))
|
||||
(add-hook 'minibuffer-setup-hook #'hook--gc-cons-maximize)
|
||||
|
||||
(defun hook--gc-cons-baseline ()
|
||||
(setq gc-cons-threshold gc-cons-threshold-basis))
|
||||
(add-hook 'minibuffer-exit-hook #'hook--gc-cons-baseline)
|
||||
|
||||
(defun hook--gc-when-unfocused ()
|
||||
(acdw/when-unfocused #'garbage-collect))
|
||||
(add-function :after after-focus-change-function
|
||||
#'hook--gc-when-unfocused)
|
||||
;;;; Web languages
|
||||
(setup (:straight web-mode)
|
||||
(:option css-level-offset 2
|
||||
js-indent-level 2
|
||||
sgml-indent-offset 2)
|
||||
(dolist (extension '("\\(p\\|dj\\)?html"
|
||||
"html?"
|
||||
"\\(tpl\\.\\)?php"
|
||||
"[agj]sp"
|
||||
"as[cp]x"
|
||||
"erb"
|
||||
"mustache"))
|
||||
(add-to-list 'auto-mode-alist
|
||||
`(,(concat "\\." extension "\\'") . web-mode))))
|
||||
|
||||
;;; init.el ends here
|
||||
|
|
342
lisp/acdw.el
342
lisp/acdw.el
|
@ -55,6 +55,26 @@ Ready for use with `after-focus-change-function'."
|
|||
(run-at-time sunset-time (* 60 60 24) sunset-command)
|
||||
(run-at-time "12:00am" (* 60 60 24) sunset-command)))
|
||||
|
||||
;;; Garbage collection hacks
|
||||
|
||||
(defconst acdw/gc-cons-threshold-basis (* 800 1024 1024)
|
||||
"Basis value for `gc-cons-threshold' to return to after jumping.
|
||||
800 KB is Emacs's default.")
|
||||
|
||||
(defconst acdw/gc-cons-percentage-basis 0.1
|
||||
"Basis value for `gc-cons-percentage' to return to after jumping.
|
||||
0.1 is Emacs's default.")
|
||||
|
||||
(defun acdw/gc-disable ()
|
||||
"Disable garbage collection by setting relevant variables to their maxima."
|
||||
(setq gc-cons-threshold most-positive-fixnum
|
||||
gc-cons-percentage 0.8))
|
||||
|
||||
(defun acdw/gc-enable ()
|
||||
"Re-enable garbage collection by setting relevant variables back to bases."
|
||||
(setq gc-cons-threshold acdw/gc-cons-threshold-basis
|
||||
gc-cons-percentage acdw/gc-cons-percentage-basis))
|
||||
|
||||
;;; Directories (think `no-littering')
|
||||
|
||||
(defvar acdw/dir (expand-file-name
|
||||
|
@ -73,184 +93,204 @@ directory."
|
|||
|
||||
;;; Settings
|
||||
|
||||
(defun acdw/set (assignments)
|
||||
"Perform `customize-set-variable' on each of ASSIGNMENTS.
|
||||
;; (defun acdw/set (assignments)
|
||||
;; "Perform `customize-set-variable' on each of ASSIGNMENTS.
|
||||
|
||||
ASSIGNMENTS is a list where each element is of the form
|
||||
(VARIABLE VALUE [COMMENT])."
|
||||
(let (setting) ; for return value
|
||||
(dolist (assignment assignments setting)
|
||||
(customize-set-variable (car assignment)
|
||||
(cadr assignment)
|
||||
(if (and (caddr assignment)
|
||||
(stringp (caddr assignment)))
|
||||
(caddr assignment)
|
||||
"Customized by `acdw/set'."))
|
||||
(setq setting (car assignment)))))
|
||||
;; ASSIGNMENTS is a list where each element is of the form
|
||||
;; (VARIABLE VALUE [COMMENT])."
|
||||
;; (let (setting) ; for return value
|
||||
;; (dolist (assignment assignments setting)
|
||||
;; (customize-set-variable (car assignment)
|
||||
;; (cadr assignment)
|
||||
;; (if (and (caddr assignment)
|
||||
;; (stringp (caddr assignment)))
|
||||
;; (caddr assignment)
|
||||
;; "Customized by `acdw/set'."))
|
||||
;; (setq setting (car assignment)))))
|
||||
|
||||
;;; Faces
|
||||
|
||||
(defun acdw/set-face (face spec)
|
||||
"Customize FACE according to SPEC, and register it with `customize'.
|
||||
SPEC is as for `defface'."
|
||||
(put face 'customized-face spec)
|
||||
(face-spec-set face spec))
|
||||
;; (defun acdw/set-face (face spec)
|
||||
;; "Customize FACE according to SPEC, and register it with `customize'.
|
||||
;; SPEC is as for `defface'."
|
||||
;; (put face 'customized-face spec)
|
||||
;; (face-spec-set face spec))
|
||||
|
||||
(defmacro acdw/set-faces (face-specs)
|
||||
"Run `acdw/set-face' over each face in FACE-SPECS."
|
||||
(let (face-list)
|
||||
(dolist (face face-specs)
|
||||
(push `(acdw/set-face ',(car face) ',(cdr face)) face-list))
|
||||
`(progn
|
||||
,@face-list)))
|
||||
;; (defmacro acdw/set-faces (face-specs)
|
||||
;; "Run `acdw/set-face' over each face in FACE-SPECS."
|
||||
;; (let (face-list)
|
||||
;; (dolist (face face-specs)
|
||||
;; (push `(acdw/set-face ',(car face) ',(cdr face)) face-list))
|
||||
;; `(progn
|
||||
;; ,@face-list)))
|
||||
|
||||
;;; Hooks
|
||||
(defmacro acdw/hooks (hook-specs &rest args)
|
||||
"Add functions to hooks, according to HOOK-SPECS.
|
||||
;; (defmacro acdw/hooks (hook-specs &rest args)
|
||||
;; "Add functions to hooks, according to HOOK-SPECS.
|
||||
|
||||
Each HOOK-SPEC is of the following format: (HOOKS FUNCS [DEPTH] [LOCAL]).
|
||||
Either HOOKS or FUNCS can also be a list, in which case `add-hook' is called
|
||||
over the Cartesian product of HOOKS and FUNCS. In each HOOK-SPEC, DEPTH and
|
||||
LOCAL apply to all hooks defined; if finer control is needed, either pass the
|
||||
same hooks and functions in different HOOK-SPECs, or just use `add-hook'.
|
||||
;; Each HOOK-SPEC is of the following format: (HOOKS FUNCS [DEPTH] [LOCAL]).
|
||||
;; Either HOOKS or FUNCS can also be a list, in which case `add-hook' is called
|
||||
;; over the Cartesian product of HOOKS and FUNCS. In each HOOK-SPEC, DEPTH and
|
||||
;; LOCAL apply to all hooks defined; if finer control is needed, either pass the
|
||||
;; same hooks and functions in different HOOK-SPECs, or just use `add-hook'.
|
||||
|
||||
ARGS accept the following keywords:
|
||||
;; ARGS accept the following keywords:
|
||||
|
||||
:after FEATURE .. `autoload' all functions after FEATURE."
|
||||
(let ((after (plist-get args :after))
|
||||
(command-list))
|
||||
(dolist (spec hook-specs)
|
||||
(let* ((hooks (car spec))
|
||||
(funcs (cadr spec))
|
||||
(depth (or (caddr spec) 0))
|
||||
(local (cadddr spec)))
|
||||
(when (not (listp hooks)) (setq hooks (list hooks)))
|
||||
(when (not (listp funcs)) (setq funcs (list funcs)))
|
||||
(dolist (hook hooks)
|
||||
(dolist (func funcs)
|
||||
(push `(add-hook ',hook #',func ,depth ,local) command-list)
|
||||
(when after
|
||||
(push `(autoload #',func ,after) command-list))))))
|
||||
`(progn
|
||||
,@command-list)))
|
||||
;; :after FEATURE .. `autoload' all functions after FEATURE."
|
||||
;; (let ((after (plist-get args :after))
|
||||
;; (command-list))
|
||||
;; (dolist (spec hook-specs)
|
||||
;; (let* ((hooks (car spec))
|
||||
;; (funcs (cadr spec))
|
||||
;; (depth (or (caddr spec) 0))
|
||||
;; (local (cadddr spec)))
|
||||
;; (when (not (listp hooks)) (setq hooks (list hooks)))
|
||||
;; (when (not (listp funcs)) (setq funcs (list funcs)))
|
||||
;; (dolist (hook hooks)
|
||||
;; (dolist (func funcs)
|
||||
;; (push `(add-hook ',hook #',func ,depth ,local) command-list)
|
||||
;; (when after
|
||||
;; (push `(autoload #',func ,after) command-list))))))
|
||||
;; `(progn
|
||||
;; ,@command-list)))
|
||||
|
||||
;;; Keybindings
|
||||
|
||||
(defvar acdw/bind-default-map 'acdw/map
|
||||
"The default keymap to use with `acdw/bind'.")
|
||||
;; (defvar acdw/bind-default-map 'acdw/map
|
||||
;; "The default keymap to use with `acdw/bind'.")
|
||||
|
||||
(defmacro acdw/bind (key command &rest args)
|
||||
"A simple key-binding macro to take care of the repetitive stuff
|
||||
automatically.
|
||||
;; (defmacro acdw/bind (key command &rest args)
|
||||
;; "A simple key-binding macro to take care of the repetitive stuff
|
||||
;; automatically.
|
||||
|
||||
If KEY is a vector, it's passed directly to `define-key',
|
||||
otherwise it's wrapped in `kbd'.
|
||||
;; If KEY is a vector, it's passed directly to `define-key',
|
||||
;; otherwise it's wrapped in `kbd'.
|
||||
|
||||
The following keywords are recognized:
|
||||
;; The following keywords are recognized:
|
||||
|
||||
:after ARGS .. call `autoload' on COMMAND using ARGS before
|
||||
binding the key. ARGS can be just the filename to
|
||||
load; in that case it's wrapped in a list.
|
||||
;; :after ARGS .. call `autoload' on COMMAND using ARGS before
|
||||
;; binding the key. ARGS can be just the filename to
|
||||
;; load; in that case it's wrapped in a list.
|
||||
|
||||
:map KEYMAP .. define KEY in KEYMAP instead of the
|
||||
default `acdw/bind-default-map'. If `:after' is also supplied,
|
||||
run `autoload' on KEYMAP (except when using `:map-after', see).
|
||||
;; :map KEYMAP .. define KEY in KEYMAP instead of the
|
||||
;; default `acdw/bind-default-map'. If `:after' is also supplied,
|
||||
;; run `autoload' on KEYMAP (except when using `:map-after', see).
|
||||
|
||||
:map-after FILE .. run the underlying `define-key' command in an
|
||||
`with-eval-after-load'. For the rare occasion when the keymap is
|
||||
defined in a different file than the command it binds (looking
|
||||
at you, `org-mode')."
|
||||
(let ((after (when-let (sym (plist-get args :after))
|
||||
(if (not (listp sym))
|
||||
(list sym)
|
||||
sym)))
|
||||
(map-after (plist-get args :map-after))
|
||||
(keymap (or (plist-get args :map) acdw/bind-default-map))
|
||||
(keycode (if (vectorp key) key (kbd key)))
|
||||
(command-list))
|
||||
(let ((define-key-command `(define-key ,keymap ,keycode ',command)))
|
||||
(if map-after
|
||||
(push `(with-eval-after-load ,map-after
|
||||
,define-key-command)
|
||||
command-list)
|
||||
(push define-key-command command-list)))
|
||||
(when after
|
||||
(unless (fboundp command)
|
||||
(push `(autoload ',command ,@after) command-list))
|
||||
(unless (or map-after
|
||||
(eq keymap acdw/bind-default-map))
|
||||
(push `(autoload ',keymap ,(car after) nil nil 'keymap) command-list)))
|
||||
`(progn
|
||||
,@command-list)))
|
||||
;; :map-after FILE .. run the underlying `define-key' command in an
|
||||
;; `with-eval-after-load'. For the rare occasion when the keymap is
|
||||
;; defined in a different file than the command it binds (looking
|
||||
;; at you, `org-mode')."
|
||||
;; (let ((after (when-let (sym (plist-get args :after))
|
||||
;; (if (not (listp sym))
|
||||
;; (list sym)
|
||||
;; sym)))
|
||||
;; (map-after (plist-get args :map-after))
|
||||
;; (keymap (or (plist-get args :map) acdw/bind-default-map))
|
||||
;; (keycode (if (vectorp key) key (kbd key)))
|
||||
;; (command-list))
|
||||
;; (let ((define-key-command `(define-key ,keymap ,keycode ',command)))
|
||||
;; (if map-after
|
||||
;; (push `(with-eval-after-load ,map-after
|
||||
;; ,define-key-command)
|
||||
;; command-list)
|
||||
;; (push define-key-command command-list)))
|
||||
;; (when after
|
||||
;; (unless (fboundp command)
|
||||
;; (push `(autoload ',command ,@after) command-list))
|
||||
;; (unless (or map-after
|
||||
;; (eq keymap acdw/bind-default-map))
|
||||
;; (push `(autoload ',keymap ,(car after) nil nil 'keymap) command-list)))
|
||||
;; `(progn
|
||||
;; ,@command-list)))
|
||||
|
||||
(defmacro acdw/binds (bindings)
|
||||
"Bind multiple keys at once."
|
||||
(let (bind-list)
|
||||
(dolist (bind bindings)
|
||||
(push `(acdw/bind ,@bind) bind-list))
|
||||
`(progn
|
||||
,@bind-list)))
|
||||
;; (defmacro acdw/binds (bindings)
|
||||
;; "Bind multiple keys at once."
|
||||
;; (let (bind-list)
|
||||
;; (dolist (bind bindings)
|
||||
;; (push `(acdw/bind ,@bind) bind-list))
|
||||
;; `(progn
|
||||
;; ,@bind-list)))
|
||||
|
||||
;; convenience
|
||||
(defmacro acdw/bind-after-map (file keymap bindings)
|
||||
"Wrap multiple calls of `acdw/bind' after FILE and with KEYMAP.
|
||||
KEYMAP can be nil."
|
||||
(declare (indent 2))
|
||||
(let ((bind-list)
|
||||
(extra-args (if keymap
|
||||
`(:after ,file :map ,keymap)
|
||||
`(:after ,file))))
|
||||
(dolist (binding bindings)
|
||||
(push `(acdw/bind ,@binding ,@extra-args) bind-list))
|
||||
`(progn
|
||||
,@bind-list)))
|
||||
;; (defmacro acdw/bind-after-map (file keymap bindings)
|
||||
;; "Wrap multiple calls of `acdw/bind' after FILE and with KEYMAP.
|
||||
;; KEYMAP can be nil."
|
||||
;; (declare (indent 2))
|
||||
;; (let ((bind-list)
|
||||
;; (extra-args (if keymap
|
||||
;; `(:after ,file :map ,keymap)
|
||||
;; `(:after ,file))))
|
||||
;; (dolist (binding bindings)
|
||||
;; (push `(acdw/bind ,@binding ,@extra-args) bind-list))
|
||||
;; `(progn
|
||||
;; ,@bind-list)))
|
||||
|
||||
;;; Packages
|
||||
|
||||
(defmacro acdw/pkg (package &rest args)
|
||||
"Set up a package using `straight.el'.
|
||||
;; (defmacro acdw/pkg (package &rest args)
|
||||
;; "Set up a package using `straight.el'.
|
||||
|
||||
ARGS can include the following keywords:
|
||||
;; ARGS can include the following keywords:
|
||||
|
||||
:local BOOL .. if BOOL is non-nil, don't run `straight-use-package' on
|
||||
PACKAGE. Good for using `acdw/pkg' on local features.
|
||||
:require BOOL .. if BOOL is non-nil, run `require' on PACKAGE before anything.
|
||||
:now FORMS .. run FORMS immediately.
|
||||
:then FORMS .. run FORMS after loading PACKAGE, using `with-eval-after-load'.
|
||||
:set SETTINGS .. pass SETTINGS to `acdw/set', right after `:now' forms.
|
||||
SETTINGS should be properly quoted, just like they'd be passed
|
||||
to the function.
|
||||
:binds BINDS .. run `acdw/bind-after-map' on BINDS.
|
||||
:hooks HOOKS .. run `acdw/hooks' on HOOKS."
|
||||
(declare (indent 1))
|
||||
(let ((local-pkg (plist-get args :local))
|
||||
(require-pkg (plist-get args :require))
|
||||
(now-forms (plist-get args :now))
|
||||
(settings (plist-get args :set))
|
||||
(binds (plist-get args :binds))
|
||||
(hooks (plist-get args :hooks))
|
||||
(then-forms (plist-get args :then))
|
||||
(requirement (if (listp package)
|
||||
(car package)
|
||||
package))
|
||||
(final-form))
|
||||
(when then-forms
|
||||
(push `(with-eval-after-load ',requirement ,@then-forms) final-form))
|
||||
(when hooks
|
||||
(push `(acdw/hooks ,hooks :after ,(symbol-name requirement)) final-form))
|
||||
(when binds
|
||||
(push `(acdw/bind-after-map ,(symbol-name requirement) nil ,binds)
|
||||
final-form))
|
||||
(when settings
|
||||
(push `(acdw/set ,settings) final-form))
|
||||
(when now-forms
|
||||
(push `(progn ,@now-forms) final-form))
|
||||
(unless local-pkg
|
||||
(push `(straight-use-package ',package) final-form))
|
||||
(when require-pkg
|
||||
(push `(require ',requirement) final-form))
|
||||
`(progn
|
||||
,@final-form)))
|
||||
;; :local BOOL .. if BOOL is non-nil, don't run `straight-use-package' on
|
||||
;; PACKAGE. Good for using `acdw/pkg' on local features.
|
||||
;; :require BOOL .. if BOOL is non-nil, run `require' on PACKAGE before anything.
|
||||
;; :now FORMS .. run FORMS immediately.
|
||||
;; :then FORMS .. run FORMS after loading PACKAGE, using `with-eval-after-load'.
|
||||
;; :set SETTINGS .. pass SETTINGS to `acdw/set', right after `:now' forms.
|
||||
;; SETTINGS should be properly quoted, just like they'd be passed
|
||||
;; to the function.
|
||||
;; :binds BINDS .. run `acdw/bind-after-map' on BINDS.
|
||||
;; :hooks HOOKS .. run `acdw/hooks' on HOOKS."
|
||||
;; (declare (indent 1))
|
||||
;; (let ((local-pkg (plist-get args :local))
|
||||
;; (require-pkg (plist-get args :require))
|
||||
;; (now-forms (plist-get args :now))
|
||||
;; (settings (plist-get args :set))
|
||||
;; (binds (plist-get args :binds))
|
||||
;; (hooks (plist-get args :hooks))
|
||||
;; (then-forms (plist-get args :then))
|
||||
;; (requirement (if (listp package)
|
||||
;; (car package)
|
||||
;; package))
|
||||
;; (final-form))
|
||||
;; (when then-forms
|
||||
;; (push `(with-eval-after-load ',requirement ,@then-forms) final-form))
|
||||
;; (when hooks
|
||||
;; (push `(acdw/hooks ,hooks :after ,(symbol-name requirement)) final-form))
|
||||
;; (when binds
|
||||
;; (push `(acdw/bind-after-map ,(symbol-name requirement) nil ,binds)
|
||||
;; final-form))
|
||||
;; (when settings
|
||||
;; (push `(acdw/set ,settings) final-form))
|
||||
;; (when now-forms
|
||||
;; (push `(progn ,@now-forms) final-form))
|
||||
;; (unless local-pkg
|
||||
;; (push `(straight-use-package ',package) final-form))
|
||||
;; (when require-pkg
|
||||
;; (push `(require ',requirement) final-form))
|
||||
;; `(progn
|
||||
;; ,@final-form)))
|
||||
|
||||
;;; Reading mode
|
||||
|
||||
(define-minor-mode acdw/reading-mode
|
||||
"A mode for reading."
|
||||
:init-value t
|
||||
:lighter " Read"
|
||||
(if acdw/reading-mode
|
||||
(progn ;; turn on
|
||||
(display-fill-column-indicator-mode -1)
|
||||
(dolist (mode '(visual-fill-column-mode
|
||||
iscroll-mode))
|
||||
(when (fboundp mode)
|
||||
(funcall mode +1))))
|
||||
;; turn off
|
||||
(display-fill-column-indicator-mode +1)
|
||||
(dolist (mode '(visual-fill-column-mode
|
||||
iscroll-mode))
|
||||
(when (fboundp mode)
|
||||
(funcall mode -1)))))
|
||||
|
||||
;;; Keymap & Mode
|
||||
|
||||
|
|
Loading…
Reference in New Issue