Refactor def-setting!/set!; now evaluates its arguments on set!
This commit is contained in:
parent
5d1013d317
commit
f053980e85
6 changed files with 96 additions and 24 deletions
57
core/autoload/set.el
Normal file
57
core/autoload/set.el
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
;;; set.el
|
||||||
|
(provide 'doom-lib-set)
|
||||||
|
|
||||||
|
;; This provides a centralized configuration system that a) won't evaluate its
|
||||||
|
;; arguments if it doesn't need to (performance), b) won't complain if the
|
||||||
|
;; setting doesn't exist and c) is more elegant than a bunch of `after!' blocks,
|
||||||
|
;; which can cause intermittent stuttering in large quantities. I'm a fan of
|
||||||
|
;; concise, do-what-I-mean front-facing configuration, believe it or not.
|
||||||
|
;;
|
||||||
|
;; Plus, it can benefit from byte-compilation.
|
||||||
|
|
||||||
|
;;;###autoload
|
||||||
|
(defvar doom-settings nil
|
||||||
|
"An alist of settings, mapping setting keywords to setter functions, which can
|
||||||
|
be a lambda or symbol.")
|
||||||
|
|
||||||
|
;;;###autoload
|
||||||
|
(defmacro def-setting! (keyword arglist &optional docstring &rest forms)
|
||||||
|
"Define a setting macro. Like `defmacro', this should return a form to be
|
||||||
|
executed when called with `set!'. FORMS are not evaluated until `set!' calls it."
|
||||||
|
(declare (indent defun) (doc-string 3))
|
||||||
|
(unless (keywordp keyword)
|
||||||
|
(error "Not a valid property name: %s" keyword))
|
||||||
|
(let ((sym (intern (format "doom-setting--setter%s" keyword))))
|
||||||
|
(setq doom-settings (assq-delete-all keyword doom-settings))
|
||||||
|
(prog1
|
||||||
|
`(progn
|
||||||
|
(defun ,sym ,arglist
|
||||||
|
,docstring
|
||||||
|
,@forms)
|
||||||
|
(push ',(list keyword
|
||||||
|
:source (__FILE__)
|
||||||
|
:docstring docstring
|
||||||
|
:fn sym)
|
||||||
|
doom-settings))
|
||||||
|
(let (byte-compile-warnings)
|
||||||
|
(byte-compile sym)))))
|
||||||
|
|
||||||
|
;;;###autoload
|
||||||
|
(defmacro set! (keyword &rest values)
|
||||||
|
"Set an option defined by `def-setting!'. Skip if doesn't exist."
|
||||||
|
(declare (indent defun))
|
||||||
|
(unless values
|
||||||
|
(error "Empty set! for %s" keyword))
|
||||||
|
(cond ((not values)
|
||||||
|
(error "Empty set! for %s" keyword))
|
||||||
|
((not (assq keyword doom-settings))
|
||||||
|
(when doom-debug-mode
|
||||||
|
(warn "No setting found for %s" keyword)))
|
||||||
|
(t
|
||||||
|
(let* ((plist (cdr (assq keyword doom-settings)))
|
||||||
|
(fn (plist-get plist :fn)))
|
||||||
|
(if fn
|
||||||
|
(let ((values (eval `(list ,@values))))
|
||||||
|
(apply fn values))
|
||||||
|
(error "No setting function where one was expected for %s" keyword))))))
|
||||||
|
|
|
@ -189,7 +189,7 @@
|
||||||
(package! wgrep
|
(package! wgrep
|
||||||
:commands (wgrep-setup wgrep-change-to-wgrep-mode)
|
:commands (wgrep-setup wgrep-change-to-wgrep-mode)
|
||||||
:config
|
:config
|
||||||
(set! :popup ("^\\*ivy-occur counsel-ag" :size 25 :select t :regexp t))
|
(set! :popup "^\\*ivy-occur counsel-ag" :size 25 :select t :regexp t)
|
||||||
(setq wgrep-auto-save-buffer t)
|
(setq wgrep-auto-save-buffer t)
|
||||||
(advice-add 'wgrep-abort-changes :after 'doom/popup-close)
|
(advice-add 'wgrep-abort-changes :after 'doom/popup-close)
|
||||||
(advice-add 'wgrep-finish-edit :after 'doom/popup-close))
|
(advice-add 'wgrep-finish-edit :after 'doom/popup-close))
|
||||||
|
|
|
@ -36,18 +36,23 @@
|
||||||
map)
|
map)
|
||||||
"Active keymap in popup windows.")
|
"Active keymap in popup windows.")
|
||||||
|
|
||||||
(def-setting! :popup (&rest rule)
|
(def-setting! :popup (&rest rules)
|
||||||
"Prepend a new popup rule to `shackle-rules'."
|
"Prepend a new popup rule to `shackle-rules'."
|
||||||
(let ((pattern (car rule))
|
(if (not (-all-p 'listp rules))
|
||||||
(plist (cdr rule)))
|
`(cl-pushnew ',rules shackle-rules :key 'car :test 'equal)
|
||||||
;; Align popups by default (error if this doesn't happen)
|
(let (real-rules)
|
||||||
(unless (plist-member plist :align)
|
(dolist (rule rules)
|
||||||
(plist-put plist :align t))
|
(let ((pattern (car rule))
|
||||||
;; Select popups by default
|
(plist (cdr rule)))
|
||||||
(unless (or (plist-member plist :select)
|
;; Align popups by default (error if this doesn't happen)
|
||||||
(plist-member plist :noselect))
|
(unless (plist-member plist :align)
|
||||||
(plist-put plist :select t))
|
(plist-put plist :align t))
|
||||||
(push (cons pattern plist) shackle-rules)))
|
;; Select popups by default
|
||||||
|
(unless (or (plist-member plist :select)
|
||||||
|
(plist-member plist :noselect))
|
||||||
|
(plist-put plist :select t))
|
||||||
|
(push (cons pattern plist) real-rules)))
|
||||||
|
`(setq shackle-rules (append ',real-rules shackle-rules)))))
|
||||||
|
|
||||||
|
|
||||||
;;
|
;;
|
||||||
|
|
|
@ -10,9 +10,19 @@
|
||||||
(defvar +evil-localleader "\\"
|
(defvar +evil-localleader "\\"
|
||||||
"The <localleader> key, used by the `map!' macro for :localleader bindings.")
|
"The <localleader> key, used by the `map!' macro for :localleader bindings.")
|
||||||
|
|
||||||
(def-setting! :evil-state (mode state)
|
(def-setting! :evil-state (&rest mode-state-list)
|
||||||
"Set the initialize STATE of MODE using `evil-set-initial-state'."
|
"Set the initialize STATE of MODE using `evil-set-initial-state'."
|
||||||
(evil-set-initial-state mode state))
|
(if (-all-p 'listp mode-state-list)
|
||||||
|
(macroexp-progn
|
||||||
|
(--map (let ((argc (length it)))
|
||||||
|
(unless (= argc 2)
|
||||||
|
(error ":evil-state sub-lists expect 2 arguments, got %s" argc))
|
||||||
|
`(evil-set-initial-state ',(car it) ',(cadr it)))
|
||||||
|
mode-state-list))
|
||||||
|
(let ((argc (length mode-state-list)))
|
||||||
|
(unless (= argc 2)
|
||||||
|
(error ":evil-state expected 2 arguments, got %s" argc)))
|
||||||
|
`(evil-set-initial-state ',(car mode-state-list) ',(cadr mode-state-list))))
|
||||||
|
|
||||||
|
|
||||||
;;
|
;;
|
||||||
|
@ -36,8 +46,8 @@
|
||||||
|
|
||||||
:config
|
:config
|
||||||
(set! :popup
|
(set! :popup
|
||||||
("*evil-registers*" :size 0.3)
|
'("*evil-registers*" :size 0.3)
|
||||||
("*Command Line*" :size 8))
|
'("*Command Line*" :size 8))
|
||||||
|
|
||||||
(evil-mode +1)
|
(evil-mode +1)
|
||||||
(evil-select-search-module 'evil-search-module 'evil-search)
|
(evil-select-search-module 'evil-search-module 'evil-search)
|
||||||
|
@ -374,7 +384,7 @@ if on a delimiter, jump to the matching one (`evilmi-jump-items')."
|
||||||
"^#.*#$"))
|
"^#.*#$"))
|
||||||
|
|
||||||
:config
|
:config
|
||||||
(set! :evil-state (neotree-mode motion))
|
(set! :evil-state 'neotree-mode 'motion)
|
||||||
|
|
||||||
;; Adding keybindings to `neotree-mode-map' wouldn't work for me (they get
|
;; Adding keybindings to `neotree-mode-map' wouldn't work for me (they get
|
||||||
;; overridden when the neotree buffer is spawned). So we bind them in a hook.
|
;; overridden when the neotree buffer is spawned). So we bind them in a hook.
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
:commands git-gutter-mode
|
:commands git-gutter-mode
|
||||||
:init (add-hook! (text-mode prog-mode conf-mode) 'git-gutter-mode)
|
:init (add-hook! (text-mode prog-mode conf-mode) 'git-gutter-mode)
|
||||||
:config
|
:config
|
||||||
(set! :popup ("^\\*git-gutter.+\\*$" :regexp t :size 15 :noselect t))
|
(set! :popup "^\\*git-gutter.+\\*$" :regexp t :size 15 :noselect t)
|
||||||
|
|
||||||
;; Update git-gutter on focus (in case I was using git externally)
|
;; Update git-gutter on focus (in case I was using git externally)
|
||||||
(add-hook 'focus-in-hook 'git-gutter:update-all-windows)
|
(add-hook 'focus-in-hook 'git-gutter:update-all-windows)
|
||||||
|
@ -31,7 +31,7 @@
|
||||||
(use-package! magit
|
(use-package! magit
|
||||||
:commands magit-status
|
:commands magit-status
|
||||||
:config
|
:config
|
||||||
(set! :popup ("^\\*magit.+" :regexp t))
|
(set! :popup "^\\*magit.+" :regexp t)
|
||||||
(after! evil-snipe
|
(after! evil-snipe
|
||||||
;; evil-snipe conflicts with magit
|
;; evil-snipe conflicts with magit
|
||||||
(add-hook 'magit-mode-hook 'turn-off-evil-snipe-override-mode)))
|
(add-hook 'magit-mode-hook 'turn-off-evil-snipe-override-mode)))
|
||||||
|
|
|
@ -6,13 +6,13 @@
|
||||||
|
|
||||||
(after! vc-annotate
|
(after! vc-annotate
|
||||||
(set! :popup
|
(set! :popup
|
||||||
("*vc-diff*" :size 15 :noselect t)
|
'("*vc-diff*" :size 15 :noselect t)
|
||||||
("*vc-change-log*" :size 15 :select t)
|
'("*vc-change-log*" :size 15 :select t)
|
||||||
(vc-annotate-mode :same t))
|
'(vc-annotate-mode :same t))
|
||||||
|
|
||||||
(set! :evil-state
|
(set! :evil-state
|
||||||
(vc-annotate-mode normal)
|
'(vc-annotate-mode normal)
|
||||||
(vc-git-log-view-mode normal))
|
'(vc-git-log-view-mode normal))
|
||||||
|
|
||||||
(map! :map vc-annotate-mode-map
|
(map! :map vc-annotate-mode-map
|
||||||
:n "q" 'kill-this-buffer
|
:n "q" 'kill-this-buffer
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue