Rethink setting system
This commit is contained in:
parent
89c7ee0273
commit
093fa1b5a3
4 changed files with 75 additions and 67 deletions
|
@ -26,23 +26,19 @@ during compilation."
|
||||||
HOOK can be one hook or a list of hooks. If the hook(s) are not quoted, -hook is
|
HOOK can be one hook or a list of hooks. If the hook(s) are not quoted, -hook is
|
||||||
appended to them automatically. If they are quoted, they are used verbatim.
|
appended to them automatically. If they are quoted, they are used verbatim.
|
||||||
|
|
||||||
FUNC-OR-FORMS can be a quoted symbol, a list of quoted symbols, or forms. Forms will be
|
FUNC-OR-FORMS can be a quoted symbol, a list of quoted symbols, or forms. Forms
|
||||||
wrapped in a lambda. A list of symbols will expand into a series of add-hook calls.
|
will be wrapped in a lambda. A list of symbols will expand into a series of
|
||||||
|
add-hook calls.
|
||||||
|
|
||||||
Examples:
|
Examples:
|
||||||
(add-hook! 'some-mode-hook 'enable-something)
|
(add-hook! 'some-mode-hook 'enable-something)
|
||||||
(add-hook! some-mode '(enable-something and-another))
|
(add-hook! some-mode '(enable-something and-another))
|
||||||
(add-hook! '(one-mode-hook second-mode-hook) 'enable-something)
|
(add-hook! '(one-mode-hook second-mode-hook) 'enable-something)
|
||||||
(add-hook! (one-mode second-mode) 'enable-something)
|
(add-hook! (one-mode second-mode) 'enable-something)
|
||||||
(add-hook! (one-mode second-mode) (setq v 5) (setq a 2))
|
(add-hook! (one-mode second-mode) (setq v 5) (setq a 2))"
|
||||||
|
|
||||||
If HOOK is omitted, then default to `__PACKAGE__' to determine HOOK."
|
|
||||||
(declare (indent defun) (debug t))
|
(declare (indent defun) (debug t))
|
||||||
(unless func-or-forms
|
(unless func-or-forms
|
||||||
(unless (bound-and-true-p __PACKAGE__)
|
(error "add-hook!: FUNC-OR-FORMS is empty"))
|
||||||
(error "add-hook!: FUNC-OR-FORMS is empty"))
|
|
||||||
(setq func-or-forms hook
|
|
||||||
hook __PACKAGE__))
|
|
||||||
(let* ((val (car func-or-forms))
|
(let* ((val (car func-or-forms))
|
||||||
(quoted-p (eq (car-safe hook) 'quote))
|
(quoted-p (eq (car-safe hook) 'quote))
|
||||||
(hook (if quoted-p (cadr hook) hook))
|
(hook (if quoted-p (cadr hook) hook))
|
||||||
|
@ -60,15 +56,14 @@ If HOOK is omitted, then default to `__PACKAGE__' to determine HOOK."
|
||||||
(-list hook)))))
|
(-list hook)))))
|
||||||
funcs))))
|
funcs))))
|
||||||
|
|
||||||
(defmacro associate! (&rest rest)
|
(defmacro associate! (mode &rest plist)
|
||||||
"Associate a major or minor mode to certain patterns and project files."
|
"Associate a major or minor mode to certain patterns and project files."
|
||||||
(declare (indent 1))
|
(declare (indent 1))
|
||||||
(let* ((mode (if (keywordp (car rest)) __PACKAGE__ (pop rest)))
|
(let* ((minor (plist-get plist :minor))
|
||||||
(minor (plist-get rest :minor))
|
(in (plist-get plist :in))
|
||||||
(in (plist-get rest :in))
|
(match (plist-get plist :match))
|
||||||
(match (plist-get rest :match))
|
(files (plist-get plist :files))
|
||||||
(files (plist-get rest :files))
|
(pred (plist-get plist :when)))
|
||||||
(pred (plist-get rest :when)))
|
|
||||||
(cond ((or files in pred)
|
(cond ((or files in pred)
|
||||||
(when (and files (not (or (listp files) (stringp files))))
|
(when (and files (not (or (listp files) (stringp files))))
|
||||||
(user-error "associate! :files expects a string or list of strings"))
|
(user-error "associate! :files expects a string or list of strings"))
|
||||||
|
|
|
@ -37,27 +37,33 @@
|
||||||
"Active keymap in popup windows.")
|
"Active keymap in popup windows.")
|
||||||
|
|
||||||
|
|
||||||
|
;;
|
||||||
|
;; Bootstrap
|
||||||
|
;;
|
||||||
|
|
||||||
|
(doom-def-setting :popup
|
||||||
|
(lambda (&rest rule)
|
||||||
|
(let ((pattern (car rule))
|
||||||
|
(plist (cdr rule)))
|
||||||
|
;; Align popups by default (error if this doesn't happen)
|
||||||
|
(unless (plist-member plist :align)
|
||||||
|
(plist-put plist :align t))
|
||||||
|
;; Select popups by default
|
||||||
|
(unless (or (plist-member plist :select)
|
||||||
|
(plist-member plist :noselect))
|
||||||
|
(plist-put plist :select t))
|
||||||
|
(push (cons pattern plist) shackle-rules)))
|
||||||
|
"Prepend a new popup rule to `shackle-rules'.")
|
||||||
|
|
||||||
(package! shackle :demand t
|
(package! shackle :demand t
|
||||||
:config
|
:init
|
||||||
(shackle-mode 1)
|
|
||||||
(setq shackle-default-alignment 'below
|
(setq shackle-default-alignment 'below
|
||||||
shackle-select-reused-windows t)
|
shackle-select-reused-windows t)
|
||||||
|
|
||||||
(def-setting! :popup (rule)
|
:config
|
||||||
"Prepend a new popup rule to `shackle-rules'."
|
(shackle-mode 1)
|
||||||
;; Ensure some default attributes are set for window rules
|
|
||||||
(let ((pattern (car rule))
|
|
||||||
(ruleset (cdr rule)))
|
|
||||||
;; Align popups by default (error if this doesn't happen)
|
|
||||||
(unless (plist-member ruleset :align)
|
|
||||||
(plist-put ruleset :align shackle-default-alignment))
|
|
||||||
;; Select popups by default
|
|
||||||
(unless (or (plist-member ruleset :select)
|
|
||||||
(plist-member ruleset :noselect))
|
|
||||||
(plist-put ruleset :select t))
|
|
||||||
(setq rule (append (list pattern) ruleset))
|
|
||||||
`(push ',rule shackle-rules)))
|
|
||||||
|
|
||||||
|
;;; Baseline popup-window rules
|
||||||
;; :noesc and :modeline are custom settings and are not part of shackle. See
|
;; :noesc and :modeline are custom settings and are not part of shackle. See
|
||||||
;; `doom*popup-init' and `doom-popup-buffer' for how they're used.
|
;; `doom*popup-init' and `doom-popup-buffer' for how they're used.
|
||||||
(set! :popup
|
(set! :popup
|
||||||
|
|
|
@ -9,27 +9,31 @@
|
||||||
"An alist of settings, mapping setting keywords to setter functions, which can
|
"An alist of settings, mapping setting keywords to setter functions, which can
|
||||||
be a lambda or symbol.")
|
be a lambda or symbol.")
|
||||||
|
|
||||||
(defmacro def-setting! (keyword arglist &optional docstring &rest body)
|
(defun doom-def-setting (keyword setter-fn &optional docstring)
|
||||||
"Define a setting macro. Takes the same arguments as `defmacro'. This should
|
"Define a setting macro. Takes the same arguments as `defmacro'. This should
|
||||||
return forms, which will be run when `set!' is used to call this setting."
|
return forms, which will be run when `set!' is used to call this setting."
|
||||||
(declare (indent defun))
|
(declare (indent defun))
|
||||||
(unless (keywordp keyword)
|
(unless (keywordp keyword)
|
||||||
(error "Not a valid property name: %s" name))
|
(error "Not a valid property name: %s" keyword))
|
||||||
(let ((sym (intern (format "doom--set%s" keyword))))
|
(unless (or (symbolp setter-fn)
|
||||||
(setq doom-settings (assq-delete-all keyword doom-settings))
|
(functionp setter-fn))
|
||||||
`(push (cons ,keyword
|
(error "Not a valid setting function for %s" keyword))
|
||||||
(defun ,sym ,arglist
|
(push (list keyword
|
||||||
,docstring
|
:source load-file-name
|
||||||
,@body))
|
:docstring docstring
|
||||||
doom-settings)))
|
:fn setter-fn)
|
||||||
|
doom-settings))
|
||||||
|
|
||||||
(defmacro set! (keyword &rest rest)
|
(defmacro set! (keyword &rest rest)
|
||||||
"Set an option defined by `doom-define-settings'. Skip if doesn't exist."
|
"Set an option defined by `def-setting!'. Skip if doesn't exist."
|
||||||
(declare (indent defun))
|
(declare (indent defun))
|
||||||
(let ((set-fn (cdr (assq keyword doom-settings))))
|
(let* ((plist (cdr (assq keyword doom-settings)))
|
||||||
(when set-fn
|
(fn (plist-get plist :fn)))
|
||||||
|
(when (and doom-debug-mode (not fn))
|
||||||
|
(message "No setting found for %s" keyword))
|
||||||
|
(when fn
|
||||||
(macroexp-progn
|
(macroexp-progn
|
||||||
(mapcar (lambda (&rest args) (apply set-fn args))
|
(mapcar (lambda (args) `(apply #',fn ',(-list args)))
|
||||||
rest)))))
|
rest)))))
|
||||||
|
|
||||||
(provide 'core-set)
|
(provide 'core-set)
|
||||||
|
|
|
@ -14,6 +14,10 @@
|
||||||
;; evil-mode
|
;; evil-mode
|
||||||
;;
|
;;
|
||||||
|
|
||||||
|
(doom-def-setting :evil-state
|
||||||
|
'evil-set-initial-state
|
||||||
|
"Set the initialize STATE of MODE using `evil-set-initial-state'.")
|
||||||
|
|
||||||
(use-package! evil :demand t
|
(use-package! evil :demand t
|
||||||
:init
|
:init
|
||||||
(setq evil-want-C-u-scroll t
|
(setq evil-want-C-u-scroll t
|
||||||
|
@ -316,9 +320,9 @@ if on a delimiter, jump to the matching one (`evilmi-jump-items')."
|
||||||
(evil-snipe-mode 1)
|
(evil-snipe-mode 1)
|
||||||
(evil-snipe-override-mode 1)
|
(evil-snipe-override-mode 1)
|
||||||
;; Switch to evil-easymotion/avy after first snipe
|
;; Switch to evil-easymotion/avy after first snipe
|
||||||
(define-key evil-snipe-parent-transient-map (kbd "C-;")
|
(map! :map evil-snipe-parent-transient-map
|
||||||
(λ! (require 'evil-easymotion)
|
"C-;" (λ! (require 'evil-easymotion)
|
||||||
(call-interactively +evil--snipe-repeat-fn))))
|
(call-interactively +evil--snipe-repeat-fn))))
|
||||||
|
|
||||||
|
|
||||||
(use-package! evil-surround
|
(use-package! evil-surround
|
||||||
|
@ -369,28 +373,27 @@ if on a delimiter, jump to the matching one (`evilmi-jump-items')."
|
||||||
"^#.*#$"))
|
"^#.*#$"))
|
||||||
|
|
||||||
:config
|
:config
|
||||||
(evil-set-initial-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.
|
||||||
(add-hook 'neo-after-create-hook '+evil|neotree-init-keymap)
|
(add-hook 'neo-after-create-hook '+evil|neotree-init-keymap)
|
||||||
(defun +evil|neotree-init-keymap (&rest _)
|
(defun +evil|neotree-init-keymap (&rest _)
|
||||||
(let ((map evil-motion-state-local-map))
|
(map! :Lm "\\\\" 'evil-window-prev
|
||||||
(define-key map (kbd "\\\\") 'evil-window-prev)
|
:Lm "RET" 'neotree-enter
|
||||||
(define-key map (kbd "RET") 'neotree-enter)
|
:Lm "<return>" 'neotree-enter
|
||||||
(define-key map (kbd "<return>") 'neotree-enter)
|
:Lm "ESC ESC" 'neotree-hide
|
||||||
(define-key map (kbd "ESC ESC") 'neotree-hide)
|
:Lm [return] 'neotree-enter
|
||||||
(define-key map [return] 'neotree-enter)
|
:Lm "q" 'neotree-hide
|
||||||
(define-key map "q" 'neotree-hide)
|
:Lm "J" 'neotree-select-next-sibling-node
|
||||||
(define-key map "J" 'neotree-select-next-sibling-node)
|
:Lm "K" 'neotree-select-previous-sibling-node
|
||||||
(define-key map "K" 'neotree-select-previous-sibling-node)
|
:Lm "H" 'neotree-select-up-node
|
||||||
(define-key map "H" 'neotree-select-up-node)
|
:Lm "L" 'neotree-select-down-node
|
||||||
(define-key map "L" 'neotree-select-down-node)
|
:Lm "v" 'neotree-enter-vertical-split
|
||||||
(define-key map "v" 'neotree-enter-vertical-split)
|
:Lm "s" 'neotree-enter-horizontal-split
|
||||||
(define-key map "s" 'neotree-enter-horizontal-split)
|
:Lm "c" 'neotree-create-node
|
||||||
(define-key map "c" 'neotree-create-node)
|
:Lm "d" 'neotree-delete-node
|
||||||
(define-key map "d" 'neotree-delete-node)
|
:Lm "\C-r" 'neotree-refresh
|
||||||
(define-key map "\C-r" 'neotree-refresh)
|
:Lm "r" 'neotree-rename-node
|
||||||
(define-key map "r" 'neotree-rename-node)
|
:Lm "R" 'neotree-change-root)))
|
||||||
(define-key map "R" 'neotree-change-root))))
|
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue