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
|
||||
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
|
||||
wrapped in a lambda. A list of symbols will expand into a series of add-hook calls.
|
||||
FUNC-OR-FORMS can be a quoted symbol, a list of quoted symbols, or forms. Forms
|
||||
will be wrapped in a lambda. A list of symbols will expand into a series of
|
||||
add-hook calls.
|
||||
|
||||
Examples:
|
||||
(add-hook! 'some-mode-hook 'enable-something)
|
||||
(add-hook! some-mode '(enable-something and-another))
|
||||
(add-hook! '(one-mode-hook second-mode-hook) 'enable-something)
|
||||
(add-hook! (one-mode second-mode) 'enable-something)
|
||||
(add-hook! (one-mode second-mode) (setq v 5) (setq a 2))
|
||||
|
||||
If HOOK is omitted, then default to `__PACKAGE__' to determine HOOK."
|
||||
(add-hook! (one-mode second-mode) (setq v 5) (setq a 2))"
|
||||
(declare (indent defun) (debug t))
|
||||
(unless func-or-forms
|
||||
(unless (bound-and-true-p __PACKAGE__)
|
||||
(error "add-hook!: FUNC-OR-FORMS is empty"))
|
||||
(setq func-or-forms hook
|
||||
hook __PACKAGE__))
|
||||
(error "add-hook!: FUNC-OR-FORMS is empty"))
|
||||
(let* ((val (car func-or-forms))
|
||||
(quoted-p (eq (car-safe hook) 'quote))
|
||||
(hook (if quoted-p (cadr hook) hook))
|
||||
|
@ -60,15 +56,14 @@ If HOOK is omitted, then default to `__PACKAGE__' to determine HOOK."
|
|||
(-list hook)))))
|
||||
funcs))))
|
||||
|
||||
(defmacro associate! (&rest rest)
|
||||
(defmacro associate! (mode &rest plist)
|
||||
"Associate a major or minor mode to certain patterns and project files."
|
||||
(declare (indent 1))
|
||||
(let* ((mode (if (keywordp (car rest)) __PACKAGE__ (pop rest)))
|
||||
(minor (plist-get rest :minor))
|
||||
(in (plist-get rest :in))
|
||||
(match (plist-get rest :match))
|
||||
(files (plist-get rest :files))
|
||||
(pred (plist-get rest :when)))
|
||||
(let* ((minor (plist-get plist :minor))
|
||||
(in (plist-get plist :in))
|
||||
(match (plist-get plist :match))
|
||||
(files (plist-get plist :files))
|
||||
(pred (plist-get plist :when)))
|
||||
(cond ((or files in pred)
|
||||
(when (and files (not (or (listp files) (stringp files))))
|
||||
(user-error "associate! :files expects a string or list of strings"))
|
||||
|
|
|
@ -37,27 +37,33 @@
|
|||
"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
|
||||
:config
|
||||
(shackle-mode 1)
|
||||
:init
|
||||
(setq shackle-default-alignment 'below
|
||||
shackle-select-reused-windows t)
|
||||
|
||||
(def-setting! :popup (rule)
|
||||
"Prepend a new popup rule to `shackle-rules'."
|
||||
;; 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)))
|
||||
:config
|
||||
(shackle-mode 1)
|
||||
|
||||
;;; Baseline popup-window rules
|
||||
;; :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.
|
||||
(set! :popup
|
||||
|
|
|
@ -9,27 +9,31 @@
|
|||
"An alist of settings, mapping setting keywords to setter functions, which can
|
||||
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
|
||||
return forms, which will be run when `set!' is used to call this setting."
|
||||
(declare (indent defun))
|
||||
(unless (keywordp keyword)
|
||||
(error "Not a valid property name: %s" name))
|
||||
(let ((sym (intern (format "doom--set%s" keyword))))
|
||||
(setq doom-settings (assq-delete-all keyword doom-settings))
|
||||
`(push (cons ,keyword
|
||||
(defun ,sym ,arglist
|
||||
,docstring
|
||||
,@body))
|
||||
doom-settings)))
|
||||
(error "Not a valid property name: %s" keyword))
|
||||
(unless (or (symbolp setter-fn)
|
||||
(functionp setter-fn))
|
||||
(error "Not a valid setting function for %s" keyword))
|
||||
(push (list keyword
|
||||
:source load-file-name
|
||||
:docstring docstring
|
||||
:fn setter-fn)
|
||||
doom-settings))
|
||||
|
||||
(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))
|
||||
(let ((set-fn (cdr (assq keyword doom-settings))))
|
||||
(when set-fn
|
||||
(let* ((plist (cdr (assq keyword doom-settings)))
|
||||
(fn (plist-get plist :fn)))
|
||||
(when (and doom-debug-mode (not fn))
|
||||
(message "No setting found for %s" keyword))
|
||||
(when fn
|
||||
(macroexp-progn
|
||||
(mapcar (lambda (&rest args) (apply set-fn args))
|
||||
(mapcar (lambda (args) `(apply #',fn ',(-list args)))
|
||||
rest)))))
|
||||
|
||||
(provide 'core-set)
|
||||
|
|
|
@ -14,6 +14,10 @@
|
|||
;; 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
|
||||
:init
|
||||
(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-override-mode 1)
|
||||
;; Switch to evil-easymotion/avy after first snipe
|
||||
(define-key evil-snipe-parent-transient-map (kbd "C-;")
|
||||
(λ! (require 'evil-easymotion)
|
||||
(call-interactively +evil--snipe-repeat-fn))))
|
||||
(map! :map evil-snipe-parent-transient-map
|
||||
"C-;" (λ! (require 'evil-easymotion)
|
||||
(call-interactively +evil--snipe-repeat-fn))))
|
||||
|
||||
|
||||
(use-package! evil-surround
|
||||
|
@ -369,28 +373,27 @@ if on a delimiter, jump to the matching one (`evilmi-jump-items')."
|
|||
"^#.*#$"))
|
||||
|
||||
: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
|
||||
;; overridden when the neotree buffer is spawned). So we bind them in a hook.
|
||||
(add-hook 'neo-after-create-hook '+evil|neotree-init-keymap)
|
||||
(defun +evil|neotree-init-keymap (&rest _)
|
||||
(let ((map evil-motion-state-local-map))
|
||||
(define-key map (kbd "\\\\") 'evil-window-prev)
|
||||
(define-key map (kbd "RET") 'neotree-enter)
|
||||
(define-key map (kbd "<return>") 'neotree-enter)
|
||||
(define-key map (kbd "ESC ESC") 'neotree-hide)
|
||||
(define-key map [return] 'neotree-enter)
|
||||
(define-key map "q" 'neotree-hide)
|
||||
(define-key map "J" 'neotree-select-next-sibling-node)
|
||||
(define-key map "K" 'neotree-select-previous-sibling-node)
|
||||
(define-key map "H" 'neotree-select-up-node)
|
||||
(define-key map "L" 'neotree-select-down-node)
|
||||
(define-key map "v" 'neotree-enter-vertical-split)
|
||||
(define-key map "s" 'neotree-enter-horizontal-split)
|
||||
(define-key map "c" 'neotree-create-node)
|
||||
(define-key map "d" 'neotree-delete-node)
|
||||
(define-key map "\C-r" 'neotree-refresh)
|
||||
(define-key map "r" 'neotree-rename-node)
|
||||
(define-key map "R" 'neotree-change-root))))
|
||||
(map! :Lm "\\\\" 'evil-window-prev
|
||||
:Lm "RET" 'neotree-enter
|
||||
:Lm "<return>" 'neotree-enter
|
||||
:Lm "ESC ESC" 'neotree-hide
|
||||
:Lm [return] 'neotree-enter
|
||||
:Lm "q" 'neotree-hide
|
||||
:Lm "J" 'neotree-select-next-sibling-node
|
||||
:Lm "K" 'neotree-select-previous-sibling-node
|
||||
:Lm "H" 'neotree-select-up-node
|
||||
:Lm "L" 'neotree-select-down-node
|
||||
:Lm "v" 'neotree-enter-vertical-split
|
||||
:Lm "s" 'neotree-enter-horizontal-split
|
||||
:Lm "c" 'neotree-create-node
|
||||
:Lm "d" 'neotree-delete-node
|
||||
:Lm "\C-r" 'neotree-refresh
|
||||
:Lm "r" 'neotree-rename-node
|
||||
:Lm "R" 'neotree-change-root)))
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue