Merge branch 'develop' of https://github.com/hlissner/doom-emacs into develop
This commit is contained in:
commit
e5fc8b6c81
81 changed files with 1423 additions and 900 deletions
|
@ -10,34 +10,33 @@
|
|||
set -e
|
||||
|
||||
cleanup() {
|
||||
emacsclient --eval '(kill-emacs)'
|
||||
emacsclient --eval '(let (kill-emacs-hook) (kill-emacs))'
|
||||
}
|
||||
|
||||
# If emacs isn't running, we start a temporary daemon, solely for this window.
|
||||
daemon=
|
||||
if ! pgrep emacs >/dev/null; then
|
||||
emacs --daemon
|
||||
trap cleanup EXIT INT TERM
|
||||
daemon=1
|
||||
if ! emacsclient -e nil; then
|
||||
emacs --daemon
|
||||
trap cleanup EXIT INT TERM
|
||||
daemon=1
|
||||
fi
|
||||
|
||||
# org-capture key mapped to argument flags
|
||||
keys=$(emacsclient -e "(+org-capture-available-keys)" | cut -d '"' -f2)
|
||||
while getopts $keys opt; do
|
||||
key="\"$opt\""
|
||||
break
|
||||
key="\"$opt\""
|
||||
break
|
||||
done
|
||||
shift $((OPTIND-1))
|
||||
|
||||
[ -t 0 ] && str="$*" || str=$(cat)
|
||||
|
||||
if [[ $daemon ]]; then
|
||||
emacsclient -a "" \
|
||||
-c -F '((name . "org-capture") (width . 70) (height . 25) (transient . t))' \
|
||||
-e "(+org-capture/open-frame \"$str\" ${key:-nil})"
|
||||
emacsclient -a "" \
|
||||
-c -F '((name . "org-capture") (width . 70) (height . 25) (transient . t))' \
|
||||
-e "(+org-capture/open-frame \"$str\" ${key:-nil} t)"
|
||||
else
|
||||
# Non-daemon servers flicker a lot if frames are created from terminal, so
|
||||
# we do it internally instead.
|
||||
emacsclient -a "" \
|
||||
-e "(+org-capture/open-frame \"$str\" ${key:-nil})"
|
||||
# Non-daemon servers flicker a lot if frames are created from terminal, so we
|
||||
# do it internally instead.
|
||||
emacsclient -a "" \
|
||||
-e "(+org-capture/open-frame \"$str\" ${key:-nil})"
|
||||
fi
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
;; Like persistent-soft, caches assume a 2-tier structure, where all caches are
|
||||
;; namespaced by location.
|
||||
|
||||
(defvar doom-cache-alists ()
|
||||
(defvar doom-cache-alists '(t)
|
||||
"An alist of alists, containing lists of variables for the doom cache library
|
||||
to persist across Emacs sessions.")
|
||||
|
||||
|
@ -24,7 +24,7 @@ name under `pcache-directory' (by default a subdirectory under
|
|||
(defun doom|save-persistent-cache ()
|
||||
"Hook to run when an Emacs session is killed. Saves all persisted variables
|
||||
listed in `doom-cache-alists' to files."
|
||||
(dolist (alist doom-cache-alists)
|
||||
(dolist (alist (butlast doom-cache-alists 1))
|
||||
(cl-loop with key = (car alist)
|
||||
for var in (cdr alist)
|
||||
if (symbol-value var)
|
||||
|
@ -54,8 +54,8 @@ Warning: this is incompatible with buffer-local variables."
|
|||
(dolist (var variables)
|
||||
(when (doom-cache-exists var location)
|
||||
(set var (doom-cache-get var location))))
|
||||
(map-put doom-cache-alists location
|
||||
(append variables (cdr (assq location doom-cache-alists)))))
|
||||
(setf (alist-get location doom-cache-alists)
|
||||
(append variables (cdr (assq location doom-cache-alists)))))
|
||||
|
||||
;;;###autoload
|
||||
(defun doom-cache-desist (location &optional variables)
|
||||
|
@ -63,10 +63,11 @@ Warning: this is incompatible with buffer-local variables."
|
|||
`doom-cache-alists', thus preventing them from being saved between sessions.
|
||||
Does not affect the actual variables themselves or their values."
|
||||
(if variables
|
||||
(map-put doom-cache-alists location
|
||||
(cl-set-difference (cdr (assq location doom-cache-alists))
|
||||
variables))
|
||||
(map-delete doom-cache-alists location)))
|
||||
(setf (alist-get location doom-cache-alists)
|
||||
(cl-set-difference (cdr (assq location doom-cache-alists))
|
||||
variables))
|
||||
(delq (assq location doom-cache-alists)
|
||||
doom-cache-alists)))
|
||||
|
||||
;;;###autoload
|
||||
(defun doom-cache-get (key &optional location)
|
||||
|
|
|
@ -186,8 +186,7 @@ possible, or just one char if that's not possible."
|
|||
(save-excursion
|
||||
(insert-char ?\s (- ocol (current-column)) nil))))
|
||||
;;
|
||||
((and (= n 1)
|
||||
(bound-and-true-p smartparens-mode))
|
||||
((and (= n 1) (bound-and-true-p smartparens-mode))
|
||||
(cond ((and (memq (char-before) (list ?\ ?\t))
|
||||
(save-excursion
|
||||
(and (> (- (skip-chars-backward " \t" (line-beginning-position))) 0)
|
||||
|
@ -213,7 +212,7 @@ possible, or just one char if that's not possible."
|
|||
((run-hook-with-args-until-success 'doom-delete-backward-functions))
|
||||
((doom/backward-delete-whitespace-to-column)))))))
|
||||
;; Otherwise, do simple deletion.
|
||||
(t (delete-char (- n) killflag))))
|
||||
((delete-char (- n) killflag))))
|
||||
|
||||
;;;###autoload
|
||||
(defun doom/retab (arg &optional beg end)
|
||||
|
|
47
core/autoload/hydras.el
Normal file
47
core/autoload/hydras.el
Normal file
|
@ -0,0 +1,47 @@
|
|||
;;; core/autoload/hydras.el -*- lexical-binding: t; -*-
|
||||
|
||||
;;;###autoload (autoload 'doom-text-zoom-hydra/body "core/autoload/hydras" nil nil)
|
||||
(defhydra doom-text-zoom-hydra (:hint t :color red)
|
||||
"
|
||||
Text zoom: _j_:zoom in, _k_:zoom out, _0_:reset
|
||||
"
|
||||
("j" text-scale-increase "in")
|
||||
("k" text-scale-decrease "out")
|
||||
("0" (text-scale-set 0) "reset"))
|
||||
|
||||
;;;###autoload (autoload 'doom-window-nav-hydra/body "core/autoload/hydras" nil nil)
|
||||
(defhydra doom-window-nav-hydra (:hint nil)
|
||||
"
|
||||
Split: _v_ert _s_:horz
|
||||
Delete: _c_lose _o_nly
|
||||
Switch Window: _h_:left _j_:down _k_:up _l_:right
|
||||
Buffers: _p_revious _n_ext _b_:select _f_ind-file
|
||||
Resize: _H_:splitter left _J_:splitter down _K_:splitter up _L_:splitter right
|
||||
Move: _a_:up _z_:down _i_menu
|
||||
"
|
||||
("z" scroll-up-line)
|
||||
("a" scroll-down-line)
|
||||
("i" idomenu)
|
||||
|
||||
("h" windmove-left)
|
||||
("j" windmove-down)
|
||||
("k" windmove-up)
|
||||
("l" windmove-right)
|
||||
|
||||
("p" previous-buffer)
|
||||
("n" next-buffer)
|
||||
("b" switch-to-buffer)
|
||||
("f" find-file)
|
||||
|
||||
("s" split-window-below)
|
||||
("v" split-window-right)
|
||||
|
||||
("c" delete-window)
|
||||
("o" delete-other-windows)
|
||||
|
||||
("H" hydra-move-splitter-left)
|
||||
("J" hydra-move-splitter-down)
|
||||
("K" hydra-move-splitter-up)
|
||||
("L" hydra-move-splitter-right)
|
||||
|
||||
("q" nil))
|
|
@ -1,31 +0,0 @@
|
|||
;;; core/autoload/memoize.el -*- lexical-binding: t; -*-
|
||||
|
||||
;;;###autoload
|
||||
(defvar doom-memoized-table (make-hash-table :test 'equal :size 10)
|
||||
"A lookup table containing memoized functions. The keys are argument lists,
|
||||
and the value is the function's return value.")
|
||||
|
||||
;;;###autoload
|
||||
(defun doom-memoize (name)
|
||||
"Memoizes an existing function. NAME is a symbol."
|
||||
(let ((func (symbol-function name)))
|
||||
(put name 'function-documentation
|
||||
(concat (documentation func) " (memoized)"))
|
||||
(fset name
|
||||
`(lambda (&rest args)
|
||||
(let ((key (cons ',name args)))
|
||||
(or (gethash key doom-memoized-table)
|
||||
(puthash key (apply ',func args)
|
||||
doom-memoized-table)))))))
|
||||
|
||||
;;;###autoload
|
||||
(defmacro def-memoized! (name arglist &rest body)
|
||||
"Create a memoize'd function. NAME, ARGLIST, DOCSTRING and BODY
|
||||
have the same meaning as in `defun'."
|
||||
(declare (indent defun) (doc-string 3))
|
||||
`(,(if (bound-and-true-p byte-compile-current-file)
|
||||
'with-no-warnings
|
||||
'progn)
|
||||
(defun ,name ,arglist ,@body)
|
||||
(doom-memoize ',name)))
|
||||
|
|
@ -14,15 +14,17 @@
|
|||
table))))
|
||||
|
||||
(defmacro doom--condition-case! (&rest body)
|
||||
`(condition-case-unless-debug ex
|
||||
`(condition-case-unless-debug e
|
||||
(progn ,@body)
|
||||
('user-error
|
||||
(print! (bold (red " NOTICE: %s" ex))))
|
||||
(print! (bold (red " NOTICE: %s" e))))
|
||||
('file-error
|
||||
(print! (bold (red " FILE ERROR: %s" (error-message-string ex))))
|
||||
(print! (bold (red " FILE ERROR: %s" (error-message-string e))))
|
||||
(print! " Trying again...")
|
||||
(quiet! (doom-refresh-packages-maybe t))
|
||||
,@body)))
|
||||
,@body)
|
||||
('error
|
||||
(print! (bold (red " FATAL ERROR: %s\n Run again with the -d flag for details" e))))))
|
||||
|
||||
(defun doom--refresh-pkg-cache ()
|
||||
"Clear the cache for `doom-refresh-packages-maybe'."
|
||||
|
@ -88,11 +90,12 @@ list of the package."
|
|||
(list name old-version new-version)))))
|
||||
|
||||
;;;###autoload
|
||||
(defun doom-package-prop (name prop)
|
||||
(defun doom-package-prop (name prop &optional eval)
|
||||
"Return PROPerty in NAME's plist."
|
||||
(cl-check-type name symbol)
|
||||
(cl-check-type prop keyword)
|
||||
(plist-get (cdr (assq name doom-packages)) prop))
|
||||
(let ((value (plist-get (cdr (assq name doom-packages)) prop)))
|
||||
(if eval (eval value) value)))
|
||||
|
||||
;;;###autoload
|
||||
(defun doom-package-different-backend-p (name)
|
||||
|
@ -164,9 +167,9 @@ files."
|
|||
if (and (or (not backend)
|
||||
(eq (doom-package-backend sym t) backend))
|
||||
(or (eq ignored 'any)
|
||||
(if ignored
|
||||
(plist-get plist :ignore)
|
||||
(not (plist-get plist :ignore))))
|
||||
(let* ((form (plist-get plist :ignore))
|
||||
(value (eval form)))
|
||||
(if ignored value (not value))))
|
||||
(or (eq disabled 'any)
|
||||
(if disabled
|
||||
(plist-get plist :disable)
|
||||
|
@ -236,9 +239,9 @@ Used by `doom-packages-update'."
|
|||
(let (quelpa-pkgs elpa-pkgs)
|
||||
;; Separate quelpa from elpa packages
|
||||
(dolist (pkg (mapcar #'car package-alist))
|
||||
(when (and (or (not (doom-package-prop pkg :freeze))
|
||||
(when (and (or (not (doom-package-prop pkg :freeze 'eval))
|
||||
include-frozen-p)
|
||||
(not (doom-package-prop pkg :ignore))
|
||||
(not (doom-package-prop pkg :ignore 'eval))
|
||||
(not (doom-package-different-backend-p pkg)))
|
||||
(push pkg
|
||||
(if (eq (doom-package-backend pkg) 'quelpa)
|
||||
|
@ -345,7 +348,7 @@ example; the package name can be omitted)."
|
|||
(package-install name))
|
||||
(if (not (package-installed-p name))
|
||||
(doom--delete-package-files name)
|
||||
(map-put doom-packages name plist)
|
||||
(setf (alist-get name doom-packages) plist)
|
||||
name)))
|
||||
|
||||
;;;###autoload
|
||||
|
@ -388,9 +391,10 @@ package.el as appropriate."
|
|||
(unless (package-installed-p name)
|
||||
(user-error "%s isn't installed" name))
|
||||
(let ((inhibit-message (not doom-debug-mode))
|
||||
(spec (assq name quelpa-cache))
|
||||
quelpa-p)
|
||||
(when (assq name quelpa-cache)
|
||||
(setq quelpa-cache (map-delete quelpa-cache name))
|
||||
(when spec
|
||||
(setq quelpa-cache (delq spec quelpa-cache))
|
||||
(quelpa-save-cache)
|
||||
(setq quelpa-p t))
|
||||
(package-delete (cadr (assq name package-alist)) force-p)
|
||||
|
@ -439,11 +443,11 @@ calls."
|
|||
"Update `quelpa-cache' upon a successful `package-delete'."
|
||||
(doom-initialize-packages)
|
||||
(let ((name (package-desc-name desc)))
|
||||
(when (and (not (package-installed-p name))
|
||||
(assq name quelpa-cache))
|
||||
(setq quelpa-cache (map-delete quelpa-cache name))
|
||||
(quelpa-save-cache)
|
||||
(doom--delete-package-files name))))
|
||||
(unless (package-installed-p name)
|
||||
(when-let* ((spec (assq name quelpa-cache)))
|
||||
(setq quelpa-cache (delq spec quelpa-cache))
|
||||
(quelpa-save-cache)
|
||||
(doom--delete-package-files name)))))
|
||||
|
||||
|
||||
;;
|
||||
|
|
|
@ -78,10 +78,10 @@ BODY will be run when this dispatcher is called."
|
|||
(append
|
||||
(when aliases
|
||||
`((dolist (alias ',aliases)
|
||||
(map-put doom--dispatch-alias-alist alias ',cmd))))
|
||||
`((map-put doom--dispatch-command-alist ',cmd
|
||||
(list :desc ,docstring
|
||||
:body (lambda (args) ,form))))))))
|
||||
(setf (alist-get alias doom--dispatch-alias-alist) ',cmd))))
|
||||
`((setf (alist-get ',cmd doom--dispatch-command-alist)
|
||||
(list :desc ,docstring
|
||||
:body (lambda (args) ,form))))))))
|
||||
|
||||
|
||||
;;
|
||||
|
@ -749,6 +749,7 @@ If RECOMPILE-P is non-nil, only recompile out-of-date files."
|
|||
(message "Couldn't find any valid targets")
|
||||
(message "No targets to %scompile" (if recompile-p "re" "")))
|
||||
(cl-return-from 'byte-compile))
|
||||
(require 'use-package)
|
||||
(condition-case e
|
||||
(let ((use-package-defaults use-package-defaults)
|
||||
(use-package-expand-minimally t))
|
||||
|
@ -796,7 +797,7 @@ If RECOMPILE-P is non-nil, only recompile out-of-date files."
|
|||
(if recompile-p "Recompiled" "Compiled")
|
||||
total-ok (- (length target-files) total-noop)
|
||||
total-noop))))
|
||||
(error
|
||||
((debug error)
|
||||
(print! (red "\n%s\n\n%%s" "There were breaking errors.")
|
||||
"Reverting changes...")
|
||||
(signal 'doom-error (list 'byte-compile e))))))))
|
||||
|
|
|
@ -148,22 +148,27 @@ fundamental-mode) for performance sake."
|
|||
sp-show-pair-from-inside t
|
||||
sp-cancel-autoskip-on-backward-movement nil
|
||||
sp-show-pair-delay 0.1
|
||||
sp-max-pair-length 3)
|
||||
sp-max-pair-length 4
|
||||
sp-max-prefix-length 50)
|
||||
|
||||
;; smartparens conflicts with evil-mode's replace state
|
||||
(add-hook 'evil-replace-state-entry-hook #'turn-off-smartparens-mode)
|
||||
(add-hook 'evil-replace-state-exit-hook #'turn-on-smartparens-mode)
|
||||
;; Slim down on smartparens' opinionated behavior
|
||||
(defun doom|disable-smartparens-navigate-skip-match ()
|
||||
(setq sp-navigate-skip-match nil
|
||||
sp-navigate-consider-sgml-tags nil))
|
||||
(add-hook 'after-change-major-mode-hook #'doom|disable-smartparens-navigate-skip-match)
|
||||
|
||||
;; autopairing in `eval-expression' and `evil-ex'
|
||||
(defun doom|init-smartparens-in-eval-expression ()
|
||||
"Enable `smartparens-mode' in the minibuffer, during `eval-expression' or
|
||||
`evil-ex'."
|
||||
(when (memq this-command '(eval-expression evil-ex))
|
||||
(smartparens-mode)))
|
||||
(add-hook 'minibuffer-setup-hook #'doom|init-smartparens-in-eval-expression)
|
||||
|
||||
(sp-local-pair 'minibuffer-inactive-mode "'" nil :actions nil)
|
||||
(sp-local-pair '(xml-mode nxml-mode php-mode) "<!--" "-->"
|
||||
:post-handlers '(("| " "SPC")))
|
||||
|
||||
;; smartparenss conflicts with evil-mode's replace state
|
||||
(add-hook 'evil-replace-state-entry-hook #'turn-off-smartparens-mode)
|
||||
(add-hook 'evil-replace-state-exit-hook #'turn-on-smartparens-mode)
|
||||
|
||||
(smartparens-global-mode +1))
|
||||
|
||||
|
|
|
@ -46,68 +46,25 @@ If any hook returns non-nil, all hooks after it are ignored.")
|
|||
|
||||
;;
|
||||
(def-package! which-key
|
||||
:config
|
||||
:defer 1
|
||||
:after-call pre-command-hook
|
||||
:init
|
||||
(setq which-key-sort-order #'which-key-prefix-then-key-order
|
||||
which-key-sort-uppercase-first nil
|
||||
which-key-add-column-padding 1
|
||||
which-key-max-display-columns nil
|
||||
which-key-min-display-lines 6
|
||||
which-key-side-window-slot -10)
|
||||
:config
|
||||
;; embolden local bindings
|
||||
(set-face-attribute 'which-key-local-map-description-face nil :weight 'bold)
|
||||
(which-key-setup-side-window-bottom)
|
||||
(setq-hook! 'which-key-init-buffer-hook line-spacing 3)
|
||||
(add-hook 'doom-post-init-hook #'which-key-mode))
|
||||
(which-key-mode +1))
|
||||
|
||||
|
||||
(def-package! hydra
|
||||
:defer t
|
||||
:config
|
||||
(setq lv-use-seperator t)
|
||||
|
||||
(defhydra doom@text-zoom (:hint t :color red)
|
||||
"
|
||||
Text zoom: _j_:zoom in, _k_:zoom out, _0_:reset
|
||||
"
|
||||
("j" text-scale-increase "in")
|
||||
("k" text-scale-decrease "out")
|
||||
("0" (text-scale-set 0) "reset"))
|
||||
|
||||
(defhydra doom@window-nav (:hint nil)
|
||||
"
|
||||
Split: _v_ert _s_:horz
|
||||
Delete: _c_lose _o_nly
|
||||
Switch Window: _h_:left _j_:down _k_:up _l_:right
|
||||
Buffers: _p_revious _n_ext _b_:select _f_ind-file
|
||||
Resize: _H_:splitter left _J_:splitter down _K_:splitter up _L_:splitter right
|
||||
Move: _a_:up _z_:down _i_menu
|
||||
"
|
||||
("z" scroll-up-line)
|
||||
("a" scroll-down-line)
|
||||
("i" idomenu)
|
||||
|
||||
("h" windmove-left)
|
||||
("j" windmove-down)
|
||||
("k" windmove-up)
|
||||
("l" windmove-right)
|
||||
|
||||
("p" previous-buffer)
|
||||
("n" next-buffer)
|
||||
("b" switch-to-buffer)
|
||||
("f" find-file)
|
||||
|
||||
("s" split-window-below)
|
||||
("v" split-window-right)
|
||||
|
||||
("c" delete-window)
|
||||
("o" delete-other-windows)
|
||||
|
||||
("H" hydra-move-splitter-left)
|
||||
("J" hydra-move-splitter-down)
|
||||
("K" hydra-move-splitter-up)
|
||||
("L" hydra-move-splitter-right)
|
||||
|
||||
("q" nil)))
|
||||
;; `hydra'
|
||||
(setq lv-use-seperator t)
|
||||
|
||||
|
||||
;;
|
||||
|
@ -117,10 +74,11 @@ If any hook returns non-nil, all hooks after it are ignored.")
|
|||
KEYS should be a string in kbd format.
|
||||
DESC should be a string describing what KEY does.
|
||||
MODES should be a list of major mode symbols."
|
||||
(if modes
|
||||
(dolist (mode modes)
|
||||
(which-key-add-major-mode-key-based-replacements mode key desc))
|
||||
(which-key-add-key-based-replacements key desc)))
|
||||
(after! which-key
|
||||
(if modes
|
||||
(dolist (mode modes)
|
||||
(which-key-add-major-mode-key-based-replacements mode key desc))
|
||||
(which-key-add-key-based-replacements key desc))))
|
||||
|
||||
|
||||
(defun doom--keyword-to-states (keyword)
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
;; Built in packages we use a lot of
|
||||
(require 'subr-x)
|
||||
(require 'cl-lib)
|
||||
(require 'map)
|
||||
|
||||
(eval-and-compile
|
||||
(unless EMACS26+
|
||||
|
@ -11,7 +10,23 @@
|
|||
;; if-let and when-let are deprecated in Emacs 26+ in favor of their
|
||||
;; if-let* variants, so we alias them for 25 users.
|
||||
(defalias 'if-let* #'if-let)
|
||||
(defalias 'when-let* #'when-let))))
|
||||
(defalias 'when-let* #'when-let)
|
||||
|
||||
;; `alist-get' doesn't have its 5th argument before Emacs 26
|
||||
(defun doom*alist-get (key alist &optional default remove testfn)
|
||||
"Return the value associated with KEY in ALIST.
|
||||
If KEY is not found in ALIST, return DEFAULT.
|
||||
Use TESTFN to lookup in the alist if non-nil. Otherwise, use `assq'.
|
||||
|
||||
This is a generalized variable suitable for use with `setf'.
|
||||
When using it to set a value, optional argument REMOVE non-nil
|
||||
means to remove KEY from ALIST if the new value is `eql' to DEFAULT."
|
||||
(ignore remove) ;;Silence byte-compiler.
|
||||
(let ((x (if (not testfn)
|
||||
(assq key alist)
|
||||
(assoc key alist testfn))))
|
||||
(if x (cdr x) default)))
|
||||
(advice-add #'alist-get :override #'doom*alist-get))))
|
||||
|
||||
|
||||
;;
|
||||
|
@ -36,6 +51,7 @@ Returns
|
|||
(file-exists-p \"/an/absolute/path\"))))
|
||||
|
||||
This is used by `associate!', `file-exists-p!' and `project-file-exists-p!'."
|
||||
(declare (pure t) (side-effect-free t))
|
||||
(cond ((stringp spec)
|
||||
`(file-exists-p
|
||||
,(if (file-name-absolute-p spec)
|
||||
|
@ -57,6 +73,7 @@ This is used by `associate!', `file-exists-p!' and `project-file-exists-p!'."
|
|||
(t spec)))
|
||||
|
||||
(defun doom--resolve-hook-forms (hooks)
|
||||
(declare (pure t) (side-effect-free t))
|
||||
(cl-loop with quoted-p = (eq (car-safe hooks) 'quote)
|
||||
for hook in (doom-enlist (doom-unquote hooks))
|
||||
if (eq (car-safe hook) 'quote)
|
||||
|
@ -82,24 +99,26 @@ This is used by `associate!', `file-exists-p!' and `project-file-exists-p!'."
|
|||
|
||||
(defun doom-unquote (exp)
|
||||
"Return EXP unquoted."
|
||||
(declare (pure t) (side-effect-free t))
|
||||
(while (memq (car-safe exp) '(quote function))
|
||||
(setq exp (cadr exp)))
|
||||
exp)
|
||||
|
||||
(defun doom-enlist (exp)
|
||||
"Return EXP wrapped in a list, or as-is if already a list."
|
||||
(declare (pure t) (side-effect-free t))
|
||||
(if (listp exp) exp (list exp)))
|
||||
|
||||
(defun doom-keyword-intern (str)
|
||||
"Converts STR (a string) into a keyword (`keywordp')."
|
||||
(or (stringp str)
|
||||
(signal 'wrong-type-argument (list 'stringp str)))
|
||||
(declare (pure t) (side-effect-free t))
|
||||
(cl-check-type str string)
|
||||
(intern (concat ":" str)))
|
||||
|
||||
(defun doom-keyword-name (keyword)
|
||||
"Returns the string name of KEYWORD (`keywordp') minus the leading colon."
|
||||
(or (keywordp keyword)
|
||||
(signal 'wrong-type-argument (list 'keywordp keyword)))
|
||||
(declare (pure t) (side-effect-free t))
|
||||
(cl-check-type :test keyword)
|
||||
(substring (symbol-name keyword) 1))
|
||||
|
||||
(cl-defun doom-files-in
|
||||
|
@ -184,17 +203,17 @@ MATCH is a string regexp. Only entries that match it will be included."
|
|||
;; Macros
|
||||
;;
|
||||
|
||||
(defmacro FILE! ()
|
||||
(defun FILE! ()
|
||||
"Return the emacs lisp file this macro is called from."
|
||||
`(cond ((bound-and-true-p byte-compile-current-file))
|
||||
((stringp (car-safe current-load-list)) (car current-load-list))
|
||||
(load-file-name)
|
||||
(buffer-file-name)))
|
||||
(cond ((bound-and-true-p byte-compile-current-file))
|
||||
(load-file-name)
|
||||
(buffer-file-name)
|
||||
((stringp (car-safe current-load-list)) (car current-load-list))))
|
||||
|
||||
(defmacro DIR! ()
|
||||
(defun DIR! ()
|
||||
"Returns the directory of the emacs lisp file this macro is called from."
|
||||
`(let ((file (FILE!)))
|
||||
(and file (file-name-directory file))))
|
||||
(let ((file (FILE!)))
|
||||
(and file (file-name-directory file))))
|
||||
|
||||
(defmacro λ! (&rest body)
|
||||
"A shortcut for inline interactive lambdas."
|
||||
|
@ -402,7 +421,7 @@ The available conditions are:
|
|||
collect `(add-hook ',hook #',hook-name))
|
||||
`((add-hook 'after-change-major-mode-hook #',hook-name))))))
|
||||
(match
|
||||
`(map-put doom-auto-minor-mode-alist ,match ',mode))
|
||||
`(add-to-list 'doom-auto-minor-mode-alist '(,match . ,mode)))
|
||||
((user-error "Invalid `associate!' rules for mode [%s] (:modes %s :match %s :files %s :when %s)"
|
||||
mode modes match files when)))))
|
||||
|
||||
|
|
|
@ -7,7 +7,8 @@
|
|||
"A hash table of enabled modules. Set by `doom-initialize-modules'.")
|
||||
|
||||
(defvar doom-modules-dirs
|
||||
(list (expand-file-name "modules/" doom-private-dir) doom-modules-dir)
|
||||
(list (expand-file-name "modules/" doom-private-dir)
|
||||
doom-modules-dir)
|
||||
"A list of module root directories. Order determines priority.")
|
||||
|
||||
(defconst doom-obsolete-modules
|
||||
|
@ -35,8 +36,6 @@ A warning will be put out if these deprecated modules are used.")
|
|||
session of Dooming. Will noop if used more than once, unless FORCE-P is
|
||||
non-nil."
|
||||
(when (or force-p (not doom-init-modules-p))
|
||||
;; Set `doom-init-modules-p' early, so `doom-pre-init-hook' won't infinitely
|
||||
;; recurse by accident if any of them need `doom-initialize-modules'.
|
||||
(setq doom-init-modules-p t)
|
||||
(when doom-private-dir
|
||||
(condition-case e
|
||||
|
@ -52,12 +51,14 @@ non-nil."
|
|||
|
||||
(defun doom-module-p (category module)
|
||||
"Returns t if CATEGORY MODULE is enabled (ie. present in `doom-modules')."
|
||||
(declare (pure t) (side-effect-free t))
|
||||
(and (hash-table-p doom-modules)
|
||||
(gethash (cons category module) doom-modules)
|
||||
t))
|
||||
|
||||
(defun doom-module-get (category module &optional property)
|
||||
"Returns the plist for CATEGORY MODULE. Gets PROPERTY, specifically, if set."
|
||||
(declare (pure t) (side-effect-free t))
|
||||
(when-let* ((plist (gethash (cons category module) doom-modules)))
|
||||
(if property
|
||||
(plist-get plist property)
|
||||
|
@ -103,7 +104,8 @@ MODULE (symbol).
|
|||
|
||||
If the category isn't enabled this will always return nil. For finding disabled
|
||||
modules use `doom-module-locate-path'."
|
||||
(let ((path (doom-module-get category module :path)))
|
||||
(let ((path (doom-module-get category module :path))
|
||||
file-name-handler-alist)
|
||||
(if file (expand-file-name file path)
|
||||
path)))
|
||||
|
||||
|
@ -120,7 +122,8 @@ This doesn't require modules to be enabled. For enabled modules us
|
|||
(setq category (substring (symbol-name category) 1)))
|
||||
(when (and module (symbolp module))
|
||||
(setq module (symbol-name module)))
|
||||
(cl-loop for default-directory in doom-modules-dirs
|
||||
(cl-loop with file-name-handler-alist = nil
|
||||
for default-directory in doom-modules-dirs
|
||||
for path = (concat category "/" module "/" file)
|
||||
if (file-exists-p path)
|
||||
return (expand-file-name path)))
|
||||
|
@ -140,6 +143,7 @@ This doesn't require modules to be enabled. For enabled modules us
|
|||
(defun doom-module-load-path (&optional all-p)
|
||||
"Return a list of absolute file paths to activated modules. If ALL-P is
|
||||
non-nil, return paths of possible modules, activated or otherwise."
|
||||
(declare (pure t) (side-effect-free t))
|
||||
(append (if all-p
|
||||
(doom-files-in doom-modules-dirs
|
||||
:type 'dirs
|
||||
|
@ -184,7 +188,7 @@ non-nil, return paths of possible modules, activated or otherwise."
|
|||
;;
|
||||
;; This will load X on the first invokation of `find-file-hook' (then it will
|
||||
;; remove itself from the hook/function).
|
||||
(defvar doom--deferred-packages-alist ())
|
||||
(defvar doom--deferred-packages-alist '(t))
|
||||
(after! use-package-core
|
||||
(add-to-list 'use-package-deferring-keywords :after-call nil #'eq)
|
||||
(setq use-package-keywords
|
||||
|
@ -192,10 +196,9 @@ non-nil, return paths of possible modules, activated or otherwise."
|
|||
|
||||
(defalias 'use-package-normalize/:after-call 'use-package-normalize-symlist)
|
||||
(defun use-package-handler/:after-call (name _keyword hooks rest state)
|
||||
(let ((fn (intern (format "doom|transient-hook--load-%s" name)))
|
||||
(hooks (delete-dups hooks)))
|
||||
(if (plist-get state :demand)
|
||||
(use-package-process-keywords name rest state)
|
||||
(if (plist-get state :demand)
|
||||
(use-package-process-keywords name rest state)
|
||||
(let ((fn (intern (format "doom|transient-hook--load-%s" name))))
|
||||
(use-package-concat
|
||||
`((fset ',fn
|
||||
(lambda (&rest _)
|
||||
|
@ -208,15 +211,19 @@ non-nil, return paths of possible modules, activated or otherwise."
|
|||
(if (functionp hook)
|
||||
(advice-remove hook #',fn)
|
||||
(remove-hook hook #',fn)))
|
||||
(map-delete doom--deferred-packages-alist ',name)
|
||||
(delq (assq ',name doom--deferred-packages-alist)
|
||||
doom--deferred-packages-alist)
|
||||
(fmakunbound ',fn))))
|
||||
(cl-loop for hook in hooks
|
||||
collect (if (functionp hook)
|
||||
`(advice-add #',hook :before #',fn)
|
||||
`(add-hook ',hook #',fn)))
|
||||
`((map-put doom--deferred-packages-alist
|
||||
',name
|
||||
'(,@hooks ,@(cdr (assq name doom--deferred-packages-alist)))))
|
||||
(let (forms)
|
||||
(dolist (hook hooks forms)
|
||||
(push (if (functionp hook)
|
||||
`(advice-add #',hook :before #',fn)
|
||||
`(add-hook ',hook #',fn))
|
||||
forms)))
|
||||
`((unless (assq ',name doom--deferred-packages-alist)
|
||||
(push '(,name) doom--deferred-packages-alist))
|
||||
(nconc (assq ',name doom--deferred-packages-alist)
|
||||
'(,@hooks)))
|
||||
(use-package-process-keywords name rest state))))))
|
||||
|
||||
|
||||
|
@ -276,7 +283,7 @@ to least)."
|
|||
(throw 'doom-modules t))))
|
||||
(let ((path (doom-module-locate-path category module)))
|
||||
(if (not path)
|
||||
(message "Couldn't find the %s %s module" category module)
|
||||
(message "Warning: couldn't find the %s %s module" category module)
|
||||
(let ((key (cons category module)))
|
||||
(doom-module-set category module :flags flags :path path)
|
||||
(push `(let ((doom--current-module ',key))
|
||||
|
@ -330,23 +337,21 @@ to have them return non-nil (or exploit that to overwrite Doom's config)."
|
|||
|
||||
(defmacro require! (category module &rest plist)
|
||||
"Loads the module specified by CATEGORY (a keyword) and MODULE (a symbol)."
|
||||
(let ((doom-modules (copy-hash-table doom-modules)))
|
||||
(apply #'doom-module-set category module
|
||||
(mapcar #'eval plist))
|
||||
(let ((module-path (doom-module-locate-path category module)))
|
||||
(if (directory-name-p module-path)
|
||||
`(condition-case-unless-debug ex
|
||||
(let ((doom--current-module ',(cons category module)))
|
||||
(load! "init" ,module-path :noerror)
|
||||
(let ((doom--stage 'config))
|
||||
(load! "config" ,module-path :noerror)))
|
||||
('error
|
||||
(lwarn 'doom-modules :error
|
||||
"%s in '%s %s' -> %s"
|
||||
(car ex) ,category ',module
|
||||
(error-message-string ex))))
|
||||
(warn 'doom-modules :warning "Couldn't find module '%s %s'"
|
||||
category module)))))
|
||||
`(let ((module-path (doom-module-locate-path ,category ',module)))
|
||||
(doom-module-set ,category ',module ,@plist)
|
||||
(if (directory-name-p module-path)
|
||||
(condition-case-unless-debug ex
|
||||
(let ((doom--current-module ',(cons category module)))
|
||||
(load! "init" module-path :noerror)
|
||||
(let ((doom--stage 'config))
|
||||
(load! "config" module-path :noerror)))
|
||||
('error
|
||||
(lwarn 'doom-modules :error
|
||||
"%s in '%s %s' -> %s"
|
||||
(car ex) ,category ',module
|
||||
(error-message-string ex))))
|
||||
(warn 'doom-modules :warning "Couldn't find module '%s %s'"
|
||||
,category ',module))))
|
||||
|
||||
(defmacro featurep! (module &optional submodule flag)
|
||||
"Returns t if MODULE SUBMODULE is enabled. If FLAG is provided, returns t if
|
||||
|
@ -370,8 +375,8 @@ omitted. eg. (featurep! +flag1)"
|
|||
module (car module-pair)
|
||||
submodule (cdr module-pair))))
|
||||
(if flag
|
||||
(and (memq flag (doom-module-get module submodule :flags)) t)
|
||||
(doom-module-p module submodule)))
|
||||
`(and (memq ',flag (doom-module-get ,module ',submodule :flags)) t)
|
||||
`(doom-module-p ,module ',submodule)))
|
||||
|
||||
|
||||
;;
|
||||
|
|
|
@ -171,7 +171,7 @@ them."
|
|||
;; Module package macros
|
||||
;;
|
||||
|
||||
(defmacro package! (name &rest plist)
|
||||
(cl-defmacro package! (name &rest plist &key recipe pin disable _ignore _freeze)
|
||||
"Declares a package and how to install it (if applicable).
|
||||
|
||||
This macro is declarative and does not load nor install packages. It is used to
|
||||
|
@ -200,31 +200,27 @@ Returns t if package is successfully registered, and nil if it was disabled
|
|||
elsewhere."
|
||||
(declare (indent defun))
|
||||
(doom--assert-stage-p 'packages #'package!)
|
||||
(let* ((old-plist (cdr (assq name doom-packages)))
|
||||
(pkg-recipe (or (plist-get plist :recipe)
|
||||
(and old-plist (plist-get old-plist :recipe))))
|
||||
(pkg-pin (or (plist-get plist :pin)
|
||||
(and old-plist (plist-get old-plist :pin))))
|
||||
(pkg-disable (or (plist-get plist :disable)
|
||||
(and old-plist (plist-get old-plist :disable)))))
|
||||
(when pkg-disable
|
||||
(add-to-list 'doom-disabled-packages name nil #'eq))
|
||||
(when pkg-recipe
|
||||
(when (= 0 (% (length pkg-recipe) 2))
|
||||
(setq plist (plist-put plist :recipe (cons name pkg-recipe))))
|
||||
(when pkg-pin
|
||||
(setq plist (plist-put plist :pin nil))))
|
||||
(dolist (prop '(:ignore :freeze))
|
||||
(when-let* ((val (plist-get plist prop)))
|
||||
(setq plist (plist-put plist prop (eval val)))))
|
||||
(when (file-in-directory-p (or (bound-and-true-p byte-compile-current-file)
|
||||
load-file-name)
|
||||
doom-private-dir)
|
||||
(let ((plist (append plist (cdr (assq name doom-packages)))))
|
||||
(when recipe
|
||||
(when (cl-evenp (length recipe))
|
||||
(setq plist (plist-put plist :recipe (cons name recipe))))
|
||||
(setq pin nil
|
||||
plist (plist-put plist :pin nil)))
|
||||
(when (file-in-directory-p (FILE!) doom-private-dir)
|
||||
(setq plist (plist-put plist :private t)))
|
||||
`(progn
|
||||
,(if pkg-pin `(map-put package-pinned-packages ',name ,pkg-pin))
|
||||
(map-put doom-packages ',name ',plist)
|
||||
(not (memq ',name doom-disabled-packages)))))
|
||||
(let (newplist)
|
||||
(while plist
|
||||
(unless (null (cadr plist))
|
||||
(push (cadr plist) newplist)
|
||||
(push (car plist) newplist))
|
||||
(pop plist)
|
||||
(pop plist))
|
||||
(setq plist newplist))
|
||||
(macroexp-progn
|
||||
(append (if disable `((add-to-list 'doom-disabled-packages ',name nil #'eq)))
|
||||
(if pin `((setf (alist-get ',name package-pinned-packages) ,pin)))
|
||||
`((setf (alist-get ',name doom-packages) ',plist)
|
||||
(not (memq ',name doom-disabled-packages)))))))
|
||||
|
||||
(defmacro packages! (&rest packages)
|
||||
"A convenience macro like `package!', but allows you to declare multiple
|
||||
|
|
|
@ -67,7 +67,9 @@ Also see `doom-before-switch-buffer-hook'.")
|
|||
enable-recursive-minibuffers nil
|
||||
frame-inhibit-implied-resize t
|
||||
;; remove continuation arrow on right fringe
|
||||
fringe-indicator-alist (map-delete fringe-indicator-alist 'continuation)
|
||||
fringe-indicator-alist
|
||||
(delq (assq 'continuation fringe-indicator-alist)
|
||||
fringe-indicator-alist)
|
||||
highlight-nonselected-windows nil
|
||||
image-animate-loop t
|
||||
indicate-buffer-boundaries nil
|
||||
|
@ -126,13 +128,13 @@ Also see `doom-before-switch-buffer-hook'.")
|
|||
(format "%s modeline segment" name))))
|
||||
(cond ((and (symbolp (car body))
|
||||
(not (cdr body)))
|
||||
(map-put doom--modeline-var-alist name (car body))
|
||||
`(map-put doom--modeline-var-alist ',name ',(car body)))
|
||||
(add-to-list 'doom--modeline-var-alist (cons name (car body)))
|
||||
`(add-to-list 'doom--modeline-var-alist (cons ',name ',(car body))))
|
||||
(t
|
||||
(map-put doom--modeline-fn-alist name sym)
|
||||
(add-to-list 'doom--modeline-fn-alist (cons name sym))
|
||||
`(progn
|
||||
(fset ',sym (lambda () ,docstring ,@body))
|
||||
(map-put doom--modeline-fn-alist ',name ',sym)
|
||||
(add-to-list 'doom--modeline-fn-alist (cons ',name ',sym))
|
||||
,(unless (bound-and-true-p byte-compile-current-file)
|
||||
`(let (byte-compile-warnings)
|
||||
(byte-compile #',sym))))))))
|
||||
|
@ -308,7 +310,7 @@ DEFAULT is non-nil, set the default mode-line for all buffers."
|
|||
|
||||
;; highlight matching delimiters
|
||||
(def-package! paren
|
||||
:after-call post-command-hook
|
||||
:after-call (after-find-file doom-before-switch-buffer-hook)
|
||||
:config
|
||||
(setq show-paren-delay 0.1
|
||||
show-paren-highlight-openparen t
|
||||
|
@ -549,7 +551,7 @@ frame's window-system, the theme will be reloaded.")
|
|||
(custom-set-faces
|
||||
(when (fontp doom-font)
|
||||
(let ((xlfd (font-xlfd-name doom-font)))
|
||||
(map-put default-frame-alist 'font xlfd)
|
||||
(add-to-list 'default-frame-alist (cons 'font xlfd))
|
||||
`(fixed-pitch ((t (:font ,xlfd))))))
|
||||
(when (fontp doom-variable-pitch-font)
|
||||
`(variable-pitch ((t (:font ,(font-xlfd-name doom-variable-pitch-font))))))
|
||||
|
@ -712,7 +714,7 @@ windows, switch to `doom-fallback-buffer'. Otherwise, delegate to original
|
|||
(defun doom|init-ui ()
|
||||
"Initialize Doom's user interface by applying all its advice and hooks."
|
||||
;; Make `next-buffer', `other-buffer', etc. ignore unreal buffers.
|
||||
(map-put default-frame-alist 'buffer-predicate #'doom-buffer-frame-predicate)
|
||||
(add-to-list 'default-frame-alist (cons 'buffer-predicate #'doom-buffer-frame-predicate))
|
||||
;; Switch to `doom-fallback-buffer' if on last real buffer
|
||||
(advice-add #'kill-this-buffer :around #'doom*switch-to-fallback-buffer-maybe)
|
||||
;; Don't kill the fallback buffer
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
company
|
||||
:ui
|
||||
doom-dashboard
|
||||
popup
|
||||
:tools
|
||||
password-store
|
||||
:lang
|
||||
|
|
|
@ -12,17 +12,18 @@
|
|||
(defun +email--mark-seen (docid msg target)
|
||||
(mu4e~proc-move docid (mu4e~mark-check-target target) "+S-u-N"))
|
||||
|
||||
(map-delete mu4e-marks 'delete)
|
||||
(map-put mu4e-marks 'trash
|
||||
(list :char '("d" . "▼")
|
||||
:prompt "dtrash"
|
||||
:dyn-target (lambda (_target msg) (mu4e-get-trash-folder msg))
|
||||
:action #'+email--mark-seen))
|
||||
;; Refile will be my "archive" function.
|
||||
(map-put mu4e-marks 'refile
|
||||
(list :char '("r" . "▶") :prompt "refile"
|
||||
:show-target (lambda (_target) "archive")
|
||||
:action #'+email--mark-seen))
|
||||
(delq (assq 'delete mu4e-marks) mu4e-marks)
|
||||
(setf (alist-get 'trash mu4e-marks)
|
||||
(list :char '("d" . "▼")
|
||||
:prompt "dtrash"
|
||||
:dyn-target (lambda (_target msg) (mu4e-get-trash-folder msg))
|
||||
:action #'+email--mark-seen)
|
||||
;; Refile will be my "archive" function.
|
||||
(alist-get 'refile mu4e-marks)
|
||||
(list :char '("d" . "▼")
|
||||
:prompt "dtrash"
|
||||
:dyn-target (lambda (_target msg) (mu4e-get-trash-folder msg))
|
||||
:action #'+email--mark-seen))
|
||||
|
||||
;; This hook correctly modifies gmail flags on emails when they are marked.
|
||||
;; Without it, refiling (archiving), trashing, and flagging (starring) email
|
||||
|
|
|
@ -40,6 +40,7 @@ default/fallback account."
|
|||
(setq-default mu4e-context-current context))
|
||||
context)))
|
||||
|
||||
;; FIXME obsolete :email
|
||||
;;;###autoload
|
||||
(def-setting! :email (label letvars &optional default-p)
|
||||
:obsolete set-email-account!
|
||||
|
|
|
@ -3,10 +3,12 @@
|
|||
This module turns adds an IRC client to Emacs ([[https://github.com/jorgenschaefer/circe][~circe~)]] with native notifications ([[https://github.com/eqyiel/circe-notifications][circe-notifications]]).
|
||||
|
||||
* Table of Contents :TOC:
|
||||
- [[#dependencies][Dependencies]]
|
||||
- [[#configure][Configure]]
|
||||
- [[#pass-the-unix-password-manager][Pass: the unix password manager]]
|
||||
- [[#emacs-auth-source-api][Emacs' auth-source API]]
|
||||
- [[Dependencies][Dependencies]]
|
||||
- [[Configure][Configure]]
|
||||
- [[Pass: the unix password manager][Pass: the unix password manager]]
|
||||
- [[Emacs' auth-source API][Emacs' auth-source API]]
|
||||
- [[Appendix][Appendix]]
|
||||
- [[Commands][Commands]]
|
||||
|
||||
* Dependencies
|
||||
This module has no dependencies, besides =gnutls-cli= or =openssl= for secure connections.
|
||||
|
@ -52,6 +54,15 @@ But wait, there's more! This stores your password in a public variable which cou
|
|||
|
||||
And you're good to go!
|
||||
|
||||
Note that =+pass-get-user= tries to find your username by looking for the fields
|
||||
listed in =+pass-user-fields= (by default =login=, =user==, =username== and =email=)=).
|
||||
An example configuration looks like
|
||||
|
||||
#+BEGIN_SRC txt :tangle no
|
||||
mysecretpassword
|
||||
username: myusername
|
||||
#+END_SRC
|
||||
|
||||
** Emacs' auth-source API
|
||||
~auth-source~ is built into Emacs. As suggested [[https://github.com/jorgenschaefer/circe/wiki/Configuration#safer-password-management][in the circe wiki]], you can store (and retrieve) encrypted passwords with it.
|
||||
|
||||
|
@ -78,3 +89,24 @@ And you're good to go!
|
|||
:channels ("#emacs")))
|
||||
#+END_SRC
|
||||
|
||||
* Appendix
|
||||
** Commands
|
||||
|
||||
To connect to IRC you can invoke the ~=irc~ function using =M-x= or your own
|
||||
custom keybinding.
|
||||
|
||||
| command | description |
|
||||
|---------+-------------------------------------------|
|
||||
| ~=irc~ | Connect to IRC and all configured servers |
|
||||
|
||||
When in a circe buffer these keybindings will be available.
|
||||
|
||||
| command | key | description |
|
||||
|------------------------+-----------+----------------------------------------------|
|
||||
| ~tracking-next-buffer~ | =SPC m a= | Switch to the next active buffer |
|
||||
| ~circe-command-JOIN~ | =SPC m j= | Join a channel |
|
||||
| ~+irc/send-message~ | =SPC m m= | Send a private message |
|
||||
| ~circe-command-NAMES~ | =SPC m n= | List the names of the current channel |
|
||||
| ~circe-command-PART~ | =SPC m p= | Part the current channel |
|
||||
| ~+irc/quit~ | =SPC m Q= | Kill the current circe session and workgroup |
|
||||
| ~circe-reconnect~ | =SPC m R= | Reconnect the current server |
|
||||
|
|
|
@ -36,6 +36,12 @@ workspace for it."
|
|||
(and (+irc-setup-wconf inhibit-workspace)
|
||||
(call-interactively #'circe)))
|
||||
|
||||
;;;###autoload
|
||||
(defun +irc/send-message (who what)
|
||||
"Send WHO a message containing WHAT."
|
||||
(interactive "sWho: \nsWhat: ")
|
||||
(circe-command-MSG who what))
|
||||
|
||||
;;;###autoload
|
||||
(defun +irc/quit ()
|
||||
"Kill current circe session and workgroup."
|
||||
|
|
16
modules/app/irc/autoload/settings.el
Normal file
16
modules/app/irc/autoload/settings.el
Normal file
|
@ -0,0 +1,16 @@
|
|||
;;; app/irc/autoload/settings.el -*- lexical-binding: t; -*-
|
||||
|
||||
;;;###autodef
|
||||
(defun set-irc-server! (server letvars)
|
||||
"Registers an irc SERVER for circe.
|
||||
|
||||
See `circe-network-options' for details."
|
||||
(after! circe
|
||||
(push (cons server letvars) circe-network-options)))
|
||||
|
||||
;; FIXME obsolete :irc
|
||||
;;;###autoload
|
||||
(def-setting! :irc (server letvars)
|
||||
:obsolete set-irc-server!
|
||||
`(after! circe
|
||||
(push (cons ,server ,letvars) circe-network-options)))
|
|
@ -36,11 +36,6 @@ See `circe-notifications-watch-strings'.")
|
|||
Useful for ZNC users who want to avoid the deluge of notifications during buffer
|
||||
playback.")
|
||||
|
||||
(def-setting! :irc (server letvars)
|
||||
"Registers an irc server for circe."
|
||||
`(after! circe
|
||||
(push (cons ,server ,letvars) circe-network-options)))
|
||||
|
||||
(defvar +irc--defer-timer nil)
|
||||
|
||||
(defsubst +irc--pad (left right)
|
||||
|
@ -125,7 +120,23 @@ playback.")
|
|||
|
||||
(after! solaire-mode
|
||||
;; distinguish chat/channel buffers from server buffers.
|
||||
(add-hook 'circe-chat-mode-hook #'solaire-mode)))
|
||||
(add-hook 'circe-chat-mode-hook #'solaire-mode))
|
||||
|
||||
(map!
|
||||
(:localleader
|
||||
(:map circe-mode-map
|
||||
:desc "Next active buffer" :n "a" #'tracking-next-buffer
|
||||
:desc "Join channel" :n "j" #'circe-command-JOIN
|
||||
:desc "Send private message" :n "m" #'+irc/send-message
|
||||
:desc "Part current channel" :n "p" #'circe-command-PART
|
||||
:desc "Quit irc" :n "Q" #'+irc/quit
|
||||
:desc "Reconnect" :n "R" #'circe-reconnect
|
||||
|
||||
(:when (featurep! :completion ivy)
|
||||
:desc "Jump to channel" :n "c" #'+irc/ivy-jump-to-channel))
|
||||
|
||||
(:map circe-channel-mode-map
|
||||
:desc "Show names" :n "n" #'circe-command-NAMES))))
|
||||
|
||||
|
||||
(def-package! circe-color-nicks
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
:config
|
||||
(helm-mode +1)
|
||||
;; helm is too heavy for find-file-at-point
|
||||
(map-put helm-completing-read-handlers-alist 'find-file-at-point nil))
|
||||
(add-to-list 'helm-completing-read-handlers-alist (cons #'find-file-at-point nil)))
|
||||
|
||||
|
||||
(def-package! helm
|
||||
|
@ -179,11 +179,11 @@
|
|||
|
||||
(map! (:after helm
|
||||
:map helm-map
|
||||
:ni "M-[" #'helm-previous-source
|
||||
:ni "M-]" #'helm-next-source
|
||||
:ni "M-l" #'helm-execute-persistent-action
|
||||
:ni "M-j" #'helm-next-line
|
||||
:ni "M-k" #'helm-previous-line
|
||||
:ni "C-S-p" #'helm-previous-source
|
||||
:ni "C-S-n" #'helm-next-source
|
||||
:ni "C-l" #'helm-execute-persistent-action
|
||||
:ni "C-j" #'helm-next-line
|
||||
:ni "C-k" #'helm-previous-line
|
||||
:ni "C-f" #'helm-next-page
|
||||
:ni "C-b" #'helm-previous-page
|
||||
:n [tab] #'helm-select-action ; TODO: Ivy has "ga".
|
||||
|
@ -206,7 +206,7 @@
|
|||
:map (helm-find-files-map helm-read-file-map)
|
||||
:n "go" #'helm-ff-run-switch-other-window
|
||||
:n "/" #'helm-ff-run-find-sh-command
|
||||
:ni "S-<return>" #'helm-ff-run-switch-other-window
|
||||
:ni "M-<return>" #'helm-ff-run-switch-other-window
|
||||
:ni "M-h" #'helm-find-files-up-one-level
|
||||
:n "=" #'helm-ff-run-ediff-file
|
||||
:n "%" #'helm-ff-run-query-replace-regexp
|
||||
|
@ -219,16 +219,16 @@
|
|||
:map helm-buffer-map
|
||||
:n "go" #'helm-buffer-switch-other-window
|
||||
:n "gO" #'display-buffer
|
||||
:ni "S-<return>" #'helm-buffer-switch-other-window
|
||||
:ni "M-<return>" #'display-buffer
|
||||
:ni "M-<return>" #'helm-buffer-switch-other-window
|
||||
:ni "<return>" #'display-buffer
|
||||
:n "=" #'helm-buffer-run-ediff
|
||||
:n "%" #'helm-buffer-run-query-replace-regexp
|
||||
:n "D" #'helm-buffer-run-kill-persistent) ; Ivy has "D".
|
||||
(:after helm-regexp
|
||||
:map helm-moccur-map
|
||||
:n "go" #'helm-moccur-run-goto-line-ow
|
||||
:ni "S-<return>" #'helm-moccur-run-goto-line-ow)
|
||||
:ni "M-<return>" #'helm-moccur-run-goto-line-ow)
|
||||
(:after helm-grep
|
||||
:map helm-grep-map
|
||||
:n "go" #'helm-grep-run-other-window-action
|
||||
:ni "S-<return>" #'helm-grep-run-other-window-action)))
|
||||
:ni "M-<return>" #'helm-grep-run-other-window-action)))
|
||||
|
|
43
modules/completion/ivy/autoload/hydras.el
Normal file
43
modules/completion/ivy/autoload/hydras.el
Normal file
|
@ -0,0 +1,43 @@
|
|||
;;; completion/ivy/autoload/hydras.el -*- lexical-binding: t; -*-
|
||||
|
||||
;;;###autoload (autoload '+ivy-coo-hydra/body "completion/ivy/autoload/hydras" nil nil)
|
||||
(defhydra +ivy-coo-hydra (:hint nil :color pink)
|
||||
"
|
||||
Move ^^^^^^^^^^ | Call ^^^^ | Cancel^^ | Options^^ | Action _w_/_s_/_a_: %s(ivy-action-name)
|
||||
----------^^^^^^^^^^-+--------------^^^^-+-------^^-+--------^^-+---------------------------------
|
||||
_g_ ^ ^ _k_ ^ ^ _u_ | _f_orward _o_ccur | _i_nsert | _c_alling: %-7s(if ivy-calling \"on\" \"off\") _C_ase-fold: %-10`ivy-case-fold-search
|
||||
^↨^ _h_ ^+^ _l_ ^↕^ | _RET_ done ^^ | _q_uit | _m_atcher: %-7s(ivy--matcher-desc) _t_runcate: %-11`truncate-lines
|
||||
_G_ ^ ^ _j_ ^ ^ _d_ | _TAB_ alt-done ^^ | ^ ^ | _<_/_>_: shrink/grow
|
||||
"
|
||||
;; arrows
|
||||
("j" ivy-next-line)
|
||||
("k" ivy-previous-line)
|
||||
("l" ivy-alt-done)
|
||||
("h" ivy-backward-delete-char)
|
||||
("g" ivy-beginning-of-buffer)
|
||||
("G" ivy-end-of-buffer)
|
||||
("d" ivy-scroll-up-command)
|
||||
("u" ivy-scroll-down-command)
|
||||
("e" ivy-scroll-down-command)
|
||||
;; actions
|
||||
("q" keyboard-escape-quit :exit t)
|
||||
("C-g" keyboard-escape-quit :exit t)
|
||||
("<escape>" keyboard-escape-quit :exit t)
|
||||
("C-o" nil)
|
||||
("i" nil)
|
||||
("TAB" ivy-alt-done :exit nil)
|
||||
("C-j" ivy-alt-done :exit nil)
|
||||
("RET" ivy-done :exit t)
|
||||
("C-m" ivy-done :exit t)
|
||||
("C-SPC" ivy-call-and-recenter :exit nil)
|
||||
("f" ivy-call)
|
||||
("c" ivy-toggle-calling)
|
||||
("m" ivy-toggle-fuzzy)
|
||||
(">" ivy-minibuffer-grow)
|
||||
("<" ivy-minibuffer-shrink)
|
||||
("w" ivy-prev-action)
|
||||
("s" ivy-next-action)
|
||||
("a" ivy-read-action)
|
||||
("t" (setq truncate-lines (not truncate-lines)))
|
||||
("C" ivy-toggle-case-fold)
|
||||
("o" ivy-occur :exit t))
|
|
@ -126,49 +126,8 @@ immediately runs it on the current candidate (ending the ivy session)."
|
|||
:init
|
||||
(after! ivy
|
||||
(define-key! ivy-minibuffer-map
|
||||
"\C-o" #'+ivy@coo/body
|
||||
(kbd "M-o") #'ivy-dispatching-done-hydra))
|
||||
:config
|
||||
(defhydra +ivy@coo (:hint nil :color pink)
|
||||
"
|
||||
Move ^^^^^^^^^^ | Call ^^^^ | Cancel^^ | Options^^ | Action _w_/_s_/_a_: %s(ivy-action-name)
|
||||
----------^^^^^^^^^^-+--------------^^^^-+-------^^-+--------^^-+---------------------------------
|
||||
_g_ ^ ^ _k_ ^ ^ _u_ | _f_orward _o_ccur | _i_nsert | _c_alling: %-7s(if ivy-calling \"on\" \"off\") _C_ase-fold: %-10`ivy-case-fold-search
|
||||
^↨^ _h_ ^+^ _l_ ^↕^ | _RET_ done ^^ | _q_uit | _m_atcher: %-7s(ivy--matcher-desc) _t_runcate: %-11`truncate-lines
|
||||
_G_ ^ ^ _j_ ^ ^ _d_ | _TAB_ alt-done ^^ | ^ ^ | _<_/_>_: shrink/grow
|
||||
"
|
||||
;; arrows
|
||||
("j" ivy-next-line)
|
||||
("k" ivy-previous-line)
|
||||
("l" ivy-alt-done)
|
||||
("h" ivy-backward-delete-char)
|
||||
("g" ivy-beginning-of-buffer)
|
||||
("G" ivy-end-of-buffer)
|
||||
("d" ivy-scroll-up-command)
|
||||
("u" ivy-scroll-down-command)
|
||||
("e" ivy-scroll-down-command)
|
||||
;; actions
|
||||
("q" keyboard-escape-quit :exit t)
|
||||
("C-g" keyboard-escape-quit :exit t)
|
||||
("<escape>" keyboard-escape-quit :exit t)
|
||||
("C-o" nil)
|
||||
("i" nil)
|
||||
("TAB" ivy-alt-done :exit nil)
|
||||
("C-j" ivy-alt-done :exit nil)
|
||||
("RET" ivy-done :exit t)
|
||||
("C-m" ivy-done :exit t)
|
||||
("C-SPC" ivy-call-and-recenter :exit nil)
|
||||
("f" ivy-call)
|
||||
("c" ivy-toggle-calling)
|
||||
("m" ivy-toggle-fuzzy)
|
||||
(">" ivy-minibuffer-grow)
|
||||
("<" ivy-minibuffer-shrink)
|
||||
("w" ivy-prev-action)
|
||||
("s" ivy-next-action)
|
||||
("a" ivy-read-action)
|
||||
("t" (setq truncate-lines (not truncate-lines)))
|
||||
("C" ivy-toggle-case-fold)
|
||||
("o" ivy-occur :exit t)))
|
||||
"\C-o" #'+ivy-coo-hydra/body
|
||||
(kbd "M-o") #'ivy-dispatching-done-hydra)))
|
||||
|
||||
|
||||
(def-package! wgrep
|
||||
|
@ -186,26 +145,28 @@ immediately runs it on the current candidate (ending the ivy session)."
|
|||
(advice-add #'ivy-posframe-setup :override #'ignore)
|
||||
:config
|
||||
(setq ivy-fixed-height-minibuffer nil
|
||||
ivy-posframe-parameters `((min-width . 90)
|
||||
(min-height . ,ivy-height)
|
||||
(internal-border-width . 10)))
|
||||
ivy-posframe-parameters
|
||||
`((min-width . 90)
|
||||
(min-height . ,ivy-height)
|
||||
(internal-border-width . 10)))
|
||||
|
||||
;; ... let's do it manually
|
||||
(dolist (fn (list 'ivy-posframe-display-at-frame-bottom-left
|
||||
'ivy-posframe-display-at-frame-center
|
||||
'ivy-posframe-display-at-point
|
||||
'ivy-posframe-display-at-frame-bottom-window-center
|
||||
'ivy-posframe-display
|
||||
'ivy-posframe-display-at-window-bottom-left
|
||||
'ivy-posframe-display-at-window-center
|
||||
'+ivy-display-at-frame-center-near-bottom))
|
||||
(map-put ivy-display-functions-props fn '(:cleanup ivy-posframe-cleanup)))
|
||||
|
||||
(map-put ivy-display-functions-alist 't '+ivy-display-at-frame-center-near-bottom)
|
||||
;; ... let's do it manually instead
|
||||
(unless (assq 'ivy-posframe-display-at-frame-bottom-left ivy-display-functions-props)
|
||||
(dolist (fn (list 'ivy-posframe-display-at-frame-bottom-left
|
||||
'ivy-posframe-display-at-frame-center
|
||||
'ivy-posframe-display-at-point
|
||||
'ivy-posframe-display-at-frame-bottom-window-center
|
||||
'ivy-posframe-display
|
||||
'ivy-posframe-display-at-window-bottom-left
|
||||
'ivy-posframe-display-at-window-center
|
||||
'+ivy-display-at-frame-center-near-bottom))
|
||||
(push (cons fn '(:cleanup ivy-posframe-cleanup)) ivy-display-functions-props)))
|
||||
;; default to posframe display function
|
||||
(setf (alist-get t ivy-display-functions-alist) #'+ivy-display-at-frame-center-near-bottom)
|
||||
|
||||
;; posframe doesn't work well with async sources
|
||||
(dolist (fn '(swiper counsel-rg counsel-ag counsel-pt counsel-grep counsel-git-grep))
|
||||
(map-put ivy-display-functions-alist fn nil)))
|
||||
(setf (alist-get fn ivy-display-functions-alist) nil)))
|
||||
|
||||
|
||||
(def-package! flx
|
||||
|
@ -216,7 +177,8 @@ immediately runs it on the current candidate (ending the ivy session)."
|
|||
'((counsel-ag . ivy--regex-plus)
|
||||
(counsel-rg . ivy--regex-plus)
|
||||
(counsel-pt . ivy--regex-plus)
|
||||
(counsel-grep-or-swiper . ivy--regex-plus)
|
||||
(counsel-grep . ivy--regex-plus)
|
||||
(swiper . ivy--regex-plus)
|
||||
(t . ivy--regex-fuzzy))
|
||||
ivy-initial-inputs-alist nil))
|
||||
|
||||
|
|
|
@ -162,7 +162,7 @@
|
|||
"M-RET" (+ivy-do-action! #'+ivy-git-grep-other-window-action))))
|
||||
|
||||
;; easymotion
|
||||
:m "gs" #'+default/easymotion ; lazy-load `evil-easymotion'
|
||||
:m "gs" #'+evil/easymotion ; lazy-load `evil-easymotion'
|
||||
(:after evil-easymotion
|
||||
:map evilem-map
|
||||
"a" (evilem-create #'evil-forward-arg)
|
||||
|
|
|
@ -35,18 +35,3 @@
|
|||
buffers."
|
||||
(interactive "<a>")
|
||||
(doom/kill-matching-buffers pattern bang))
|
||||
|
||||
;;;###autoload
|
||||
(defun +default/easymotion ()
|
||||
"Invoke and lazy-load `evil-easymotion' without compromising which-key
|
||||
integration."
|
||||
(interactive)
|
||||
(let ((prefix (this-command-keys)))
|
||||
(evil-define-key* 'motion 'global prefix nil)
|
||||
(evilem-default-keybindings prefix)
|
||||
(which-key-reload-key-sequence
|
||||
(vconcat (where-is-internal evil-this-operator
|
||||
evil-normal-state-map
|
||||
t)
|
||||
prefix))))
|
||||
|
||||
|
|
|
@ -44,10 +44,6 @@
|
|||
(sp-local-pair 'ruby-mode "{" "}"
|
||||
:pre-handlers '(:rem sp-ruby-prehandler)
|
||||
:post-handlers '(:rem sp-ruby-posthandler))
|
||||
;; sp's default rules for these modes are obnoxious, so disable them
|
||||
(provide 'smartparens-elixir)
|
||||
(provide 'smartparens-latex)
|
||||
(provide 'smartparens-lua)
|
||||
|
||||
;; Expand {|} => { | }
|
||||
;; Expand {|} => {
|
||||
|
@ -63,6 +59,18 @@
|
|||
(sp-local-pair '(emacs-lisp-mode org-mode markdown-mode gfm-mode)
|
||||
"[" nil :post-handlers '(:rem ("| " "SPC")))
|
||||
|
||||
;; Reasonable default pairs for comments
|
||||
(sp-local-pair (append sp--html-modes '(markdown-mode gfm-mode))
|
||||
"<!--" "-->" :actions '(insert) :post-handlers '(("| " "SPC")))
|
||||
|
||||
(sp-local-pair
|
||||
'(js2-mode typescript-mode rjsx-mode rust-mode
|
||||
c-mode c++-mode objc-mode java-mode php-mode
|
||||
css-mode scss-mode less-css-mode stylus-mode)
|
||||
"/*" "*/"
|
||||
:actions '(insert)
|
||||
:post-handlers '(("| " "SPC") ("|\n*/[i][d-2]" "RET") ("\n* ||\n*/[i][d-2]" "*")))
|
||||
|
||||
;; Highjacks backspace to:
|
||||
;; a) balance spaces inside brackets/parentheses ( | ) -> (|)
|
||||
;; b) delete space-indented `tab-width' steps at a time
|
||||
|
|
|
@ -7,7 +7,8 @@
|
|||
(signal 'wrong-number-of-arguments (list 'even (length aliases))))
|
||||
(after! eshell
|
||||
(while aliases
|
||||
(map-put +eshell-aliases (pop aliases) (list (pop aliases))))
|
||||
(setf (alist-get (pop aliases) +eshell-aliases nil nil #'equal)
|
||||
(list (pop aliases))))
|
||||
(when (boundp 'eshell-command-aliases-list)
|
||||
(if +eshell--default-aliases
|
||||
(setq eshell-command-aliases-list
|
||||
|
|
|
@ -50,3 +50,42 @@ info in the `header-line-format' is a good indication."
|
|||
(propertize author 'face 'git-timemachine-minibuffer-author-face)
|
||||
(propertize sha-or-subject 'face 'git-timemachine-minibuffer-detail-face)
|
||||
date-full date-relative))))
|
||||
|
||||
;;;###autoload (autoload '+hydra-smerge/body "emacs/vc/autoload" nil nil)
|
||||
(defhydra +hydra-smerge (:hint nil
|
||||
:pre (if (not smerge-mode) (smerge-mode 1))
|
||||
;; Disable `smerge-mode' when quitting hydra if
|
||||
;; no merge conflicts remain.
|
||||
:post (smerge-auto-leave))
|
||||
"
|
||||
[smerge]
|
||||
Movement Keep Diff Other
|
||||
╭─────────────────────────────────────────────────────────╯
|
||||
^_g_^ [_b_] base [_<_] upper/base [_C_] Combine
|
||||
^_C-k_^ [_u_] upper [_=_] upper/lower [_r_] resolve
|
||||
^_k_ ↑^ [_l_] lower [_>_] base/lower [_R_] remove
|
||||
^_j_ ↓^ [_a_] all [_H_] hightlight
|
||||
^_C-j_^ [_RET_] current [_E_] ediff ╭──────────
|
||||
^_G_^ │ [_q_] quit
|
||||
"
|
||||
("g" (progn (goto-char (point-min)) (smerge-next)))
|
||||
("G" (progn (goto-char (point-max)) (smerge-prev)))
|
||||
("C-j" smerge-next)
|
||||
("C-k" smerge-prev)
|
||||
("j" next-line)
|
||||
("k" previous-line)
|
||||
("b" smerge-keep-base)
|
||||
("u" smerge-keep-upper)
|
||||
("l" smerge-keep-lower)
|
||||
("a" smerge-keep-all)
|
||||
("RET" smerge-keep-current)
|
||||
("\C-m" smerge-keep-current)
|
||||
("<" smerge-diff-base-upper)
|
||||
("=" smerge-diff-upper-lower)
|
||||
(">" smerge-diff-base-lower)
|
||||
("H" smerge-refine)
|
||||
("E" smerge-ediff)
|
||||
("C" smerge-combine-with-next)
|
||||
("r" smerge-resolve)
|
||||
("R" smerge-kill-current)
|
||||
("q" nil :color blue))
|
||||
|
|
|
@ -22,22 +22,24 @@
|
|||
|
||||
|
||||
;; `git-commit-mode'
|
||||
;; see https://chris.beams.io/posts/git-commit/
|
||||
(setq git-commit-fill-column 72
|
||||
git-commit-summary-max-length 50
|
||||
git-commit-style-convention-checks '(overlong-summary-line non-empty-second-line))
|
||||
(defun +vc|enforce-git-commit-conventions ()
|
||||
"See https://chris.beams.io/posts/git-commit/"
|
||||
(setq fill-column 72
|
||||
git-commit-summary-max-length 50
|
||||
git-commit-style-convention-checks '(overlong-summary-line non-empty-second-line)))
|
||||
(add-hook 'git-commit-mode-hook #'+vc|enforce-git-commit-conventions)
|
||||
(when (featurep! :feature evil)
|
||||
(add-hook 'git-commit-mode-hook #'evil-insert-state))
|
||||
|
||||
|
||||
;;
|
||||
;; `vc'
|
||||
;; `vc' (built-in)
|
||||
;;
|
||||
|
||||
;; `vc-hooks'
|
||||
(setq vc-make-backup-files nil)
|
||||
|
||||
;; `vc-annotate'
|
||||
;; `vc-annotate' (built-in)
|
||||
(after! vc-annotate
|
||||
(set-popup-rules!
|
||||
'(("^\\vc-d" :select nil) ; *vc-diff*
|
||||
|
@ -46,18 +48,8 @@
|
|||
'(vc-annotate-mode vc-git-log-view-mode)
|
||||
'normal))
|
||||
|
||||
;; `smerge-mode'
|
||||
(defun +vcs|enable-smerge-mode-maybe ()
|
||||
"Auto-enable `smerge-mode' when merge conflict is detected."
|
||||
(save-excursion
|
||||
(goto-char (point-min))
|
||||
(when (re-search-forward "^<<<<<<< " nil :noerror)
|
||||
(smerge-mode 1)
|
||||
(when (and (featurep 'hydra) +vc-auto-hydra-smerge)
|
||||
(+hydra-smerge/body)))))
|
||||
(add-hook 'find-file-hook #'+vcs|enable-smerge-mode-maybe)
|
||||
|
||||
(after! smerge-mode ; built-in
|
||||
;; `smerge-mode' (built-in)
|
||||
(after! smerge-mode
|
||||
(unless EMACS26+
|
||||
(with-no-warnings
|
||||
(defalias #'smerge-keep-upper #'smerge-keep-mine)
|
||||
|
@ -66,40 +58,5 @@
|
|||
(defalias #'smerge-diff-upper-lower #'smerge-diff-mine-other)
|
||||
(defalias #'smerge-diff-base-lower #'smerge-diff-base-other)))
|
||||
|
||||
(defhydra +hydra-smerge (:hint nil
|
||||
:pre (smerge-mode 1)
|
||||
;; Disable `smerge-mode' when quitting hydra if
|
||||
;; no merge conflicts remain.
|
||||
:post (smerge-auto-leave))
|
||||
"
|
||||
╭────────┐
|
||||
Movement Keep Diff Other │ smerge │
|
||||
╭─────────────────────────────────────────────────┴────────╯
|
||||
^_g_^ [_b_] base [_<_] upper/base [_C_] Combine
|
||||
^_C-k_^ [_u_] upper [_=_] upper/lower [_r_] resolve
|
||||
^_k_ ↑^ [_l_] lower [_>_] base/lower [_R_] remove
|
||||
^_j_ ↓^ [_a_] all [_H_] hightlight
|
||||
^_C-j_^ [_RET_] current [_E_] ediff ╭──────────
|
||||
^_G_^ │ [_q_] quit"
|
||||
("g" (progn (goto-char (point-min)) (smerge-next)))
|
||||
("G" (progn (goto-char (point-max)) (smerge-prev)))
|
||||
("C-j" smerge-next)
|
||||
("C-k" smerge-prev)
|
||||
("j" next-line)
|
||||
("k" previous-line)
|
||||
("b" smerge-keep-base)
|
||||
("u" smerge-keep-upper)
|
||||
("l" smerge-keep-lower)
|
||||
("a" smerge-keep-all)
|
||||
("RET" smerge-keep-current)
|
||||
("\C-m" smerge-keep-current)
|
||||
("<" smerge-diff-base-upper)
|
||||
("=" smerge-diff-upper-lower)
|
||||
(">" smerge-diff-base-lower)
|
||||
("H" smerge-refine)
|
||||
("E" smerge-ediff)
|
||||
("C" smerge-combine-with-next)
|
||||
("r" smerge-resolve)
|
||||
("R" smerge-kill-current)
|
||||
("q" nil :color blue)))
|
||||
(add-hook 'smerge-mode-hook #'+hydra-smerge/body))
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@ function that creates and returns the REPL buffer."
|
|||
;;;###autoload
|
||||
(def-setting! :repl (mode command)
|
||||
:obsolete set-repl-handler!
|
||||
`(push (cons ,mode ,command) +eval-repls))
|
||||
`(set-repl-handler! ,mode ,command))
|
||||
|
||||
|
||||
;;
|
||||
|
|
|
@ -370,3 +370,18 @@ more information on modifiers."
|
|||
"Call `doom/escape' if `evil-force-normal-state' is called interactively."
|
||||
(when (called-interactively-p 'any)
|
||||
(call-interactively #'doom/escape)))
|
||||
|
||||
;;;###autoload
|
||||
(defun +evil/easymotion ()
|
||||
"Invoke and lazy-load `evil-easymotion' without compromising which-key
|
||||
integration."
|
||||
(interactive)
|
||||
(let ((prefix (this-command-keys)))
|
||||
(evil-define-key* 'motion 'global prefix nil)
|
||||
(evilem-default-keybindings prefix)
|
||||
(which-key-reload-key-sequence
|
||||
(vconcat (when evil-this-operator
|
||||
(where-is-internal evil-this-operator
|
||||
evil-normal-state-map
|
||||
t))
|
||||
prefix))))
|
||||
|
|
|
@ -3,39 +3,6 @@
|
|||
;; I'm a vimmer at heart. Its modal philosophy suits me better, and this module
|
||||
;; strives to make Emacs a much better vim than vim was.
|
||||
|
||||
(defvar +evil-collection-disabled-list
|
||||
'(kotlin-mode ; doesn't do anything useful
|
||||
simple
|
||||
;; we'll do these ourselves
|
||||
anaconda-mode
|
||||
company
|
||||
dired
|
||||
helm
|
||||
ivy
|
||||
minibuffer
|
||||
ruby-mode
|
||||
slime)
|
||||
"A list of `evil-collection' modules to disable. See the definition of this
|
||||
variable for an explanation of the defaults (in comments). See
|
||||
`evil-collection-mode-list' for a list of available options.")
|
||||
|
||||
|
||||
(def-package! evil-collection
|
||||
:when (featurep! +everywhere)
|
||||
:defer 1
|
||||
:after-call post-command-hook
|
||||
:preface
|
||||
;; must be set before evil/evil-collection is loaded
|
||||
(setq evil-want-integration nil
|
||||
evil-collection-company-use-tng nil)
|
||||
:config
|
||||
(dolist (sym +evil-collection-disabled-list)
|
||||
(setq evil-collection-mode-list
|
||||
(funcall (if (symbolp sym) #'delq #'delete)
|
||||
sym evil-collection-mode-list)))
|
||||
(evil-collection-init))
|
||||
|
||||
|
||||
(def-package! evil
|
||||
:init
|
||||
(setq evil-want-C-u-scroll t
|
||||
|
@ -60,7 +27,9 @@ variable for an explanation of the defaults (in comments). See
|
|||
evil-normal-state-cursor 'box
|
||||
evil-emacs-state-cursor '(box +evil-emacs-cursor)
|
||||
evil-insert-state-cursor 'bar
|
||||
evil-visual-state-cursor 'hollow)
|
||||
evil-visual-state-cursor 'hollow
|
||||
;; must be set before evil/evil-collection is loaded
|
||||
evil-want-integration (not (featurep! +everywhere)))
|
||||
|
||||
:config
|
||||
(add-hook 'doom-post-init-hook #'evil-mode)
|
||||
|
@ -169,7 +138,193 @@ variable for an explanation of the defaults (in comments). See
|
|||
(evil-set-command-properties
|
||||
'+evil:align :move-point t :ex-arg 'buffer-match :ex-bang t :evil-mc t :keep-visual t :suppress-operator t)
|
||||
(evil-set-command-properties
|
||||
'+evil:mc :move-point nil :ex-arg 'global-match :ex-bang t :evil-mc t))
|
||||
'+evil:mc :move-point nil :ex-arg 'global-match :ex-bang t :evil-mc t)
|
||||
|
||||
;; `evil-collection'
|
||||
;; *Truly* lazy-load evil-collection's modules, and do ourselves, here,
|
||||
;; instead of lazy-loading evil-collection.el so we can ensure `after!' blocks
|
||||
;; in private configs happen after evil-collection has finished.
|
||||
;;
|
||||
;; Also so we can be very selective about what modules it loads.
|
||||
(when (featurep! +everywhere)
|
||||
(after! eldoc
|
||||
(eldoc-add-command-completions "evil-window-"))
|
||||
|
||||
(after! comint
|
||||
(evil-define-key* 'normal comint-mode-map
|
||||
(kbd "C-d") #'evil-scroll-down
|
||||
(kbd "C-n") #'comint-next-input
|
||||
(kbd "C-p") #'comint-previous-input
|
||||
(kbd "gj") #'comint-next-input
|
||||
(kbd "gk") #'comint-previous-input
|
||||
(kbd "]") #'comint-next-input
|
||||
(kbd "[") #'comint-previous-input)
|
||||
(evil-define-key* 'insert comint-mode-map
|
||||
(kbd "<up>") #'comint-previous-input
|
||||
(kbd "<down>") #'comint-next-input))
|
||||
|
||||
(after! cus-edit
|
||||
(evil-set-initial-state 'Custom-mode 'normal)
|
||||
(evil-define-key* 'motion custom-mode-map
|
||||
(kbd "<tab>") 'widget-forward
|
||||
(kbd "S-<tab>") 'widget-backward
|
||||
(kbd "<backtab>") 'widget-backward
|
||||
(kbd "]") 'widget-forward
|
||||
(kbd "[") 'widget-backward
|
||||
(kbd "C-n") 'widget-forward
|
||||
(kbd "C-p") 'widget-backward
|
||||
"gj" 'widget-forward
|
||||
"gk" 'widget-backward)
|
||||
(evil-define-key* 'normal custom-mode-map
|
||||
(kbd "<return>") 'Custom-newline
|
||||
(kbd "C-o") 'Custom-goto-parent
|
||||
"^" 'Custom-goto-parent
|
||||
"<" 'Custom-goto-parent
|
||||
;; quit
|
||||
"q" 'Custom-buffer-done
|
||||
"ZQ" 'evil-quit
|
||||
"ZZ" 'Custom-buffer-done))
|
||||
|
||||
(after! help
|
||||
(evil-set-initial-state 'help-mode 'normal)
|
||||
(evil-define-key* 'normal help-mode-map
|
||||
;; motion
|
||||
(kbd "SPC") 'scroll-up-command
|
||||
(kbd "S-SPC") 'scroll-down-command
|
||||
(kbd "C-f") 'scroll-up-command
|
||||
(kbd "C-b") 'scroll-down-command
|
||||
(kbd "<tab>") 'forward-button
|
||||
(kbd "<backtab>") 'backward-button
|
||||
(kbd "C-o") 'help-go-back
|
||||
(kbd "C-i") 'help-go-forward
|
||||
;; TODO: Enable more help-go-* bindings?
|
||||
;; "gj" 'help-go-forward
|
||||
;; "gk" 'help-go-back
|
||||
;; "\C-j" 'help-go-forward
|
||||
;; "\C-k" 'help-go-back
|
||||
;; The following bindings don't do what they are supposed to. "go" should
|
||||
;; open in the same window and "gO" should open in a different one.
|
||||
"go" 'push-button
|
||||
"gO" 'push-button
|
||||
"g?" 'describe-mode
|
||||
"gr" 'revert-buffer
|
||||
"<" 'help-go-back
|
||||
">" 'help-go-forward
|
||||
"r" 'help-follow
|
||||
;; quit
|
||||
"q" 'quit-window
|
||||
"ZQ" 'evil-quit
|
||||
"ZZ" 'quit-window))
|
||||
|
||||
(add-transient-hook! 'image-mode (evil-collection-init 'image))
|
||||
(add-transient-hook! 'emacs-lisp-mode (evil-collection-init 'elisp-mode))
|
||||
|
||||
(defvar evil-collection-mode-list
|
||||
'(ace-jump-mode
|
||||
ag
|
||||
alchemist
|
||||
;; anaconda-mode
|
||||
arc-mode
|
||||
avy
|
||||
bookmark
|
||||
(buff-menu "buff-menu")
|
||||
calc
|
||||
calendar
|
||||
cider
|
||||
cmake-mode
|
||||
;; comint
|
||||
;; company
|
||||
compile
|
||||
;; custom
|
||||
cus-theme
|
||||
daemons
|
||||
debbugs
|
||||
debug
|
||||
diff-mode
|
||||
;; dired
|
||||
doc-view
|
||||
edebug
|
||||
ediff
|
||||
;; eldoc
|
||||
;; elfeed
|
||||
;; elisp-mode
|
||||
elisp-refs
|
||||
emms
|
||||
epa
|
||||
;; ert
|
||||
eshell
|
||||
eval-sexp-fu
|
||||
etags-select
|
||||
eww
|
||||
flycheck
|
||||
;; free-keys
|
||||
geiser
|
||||
ggtags
|
||||
git-timemachine
|
||||
go-mode
|
||||
;; help
|
||||
guix
|
||||
;; helm
|
||||
ibuffer
|
||||
;; image
|
||||
image+
|
||||
indium
|
||||
info
|
||||
;; ivy
|
||||
js2-mode
|
||||
log-view
|
||||
lsp-ui-imenu
|
||||
lua-mode
|
||||
;; kotlin-mode
|
||||
macrostep
|
||||
man
|
||||
magit
|
||||
mu4e
|
||||
mu4e-conversation
|
||||
neotree
|
||||
notmuch
|
||||
nov
|
||||
;; occur is in replace.el which was built-in before Emacs 26.
|
||||
(occur ,(if EMACS26+ 'replace "replace"))
|
||||
outline
|
||||
p4
|
||||
;; (package-menu package)
|
||||
paren
|
||||
pass
|
||||
(pdf pdf-view)
|
||||
popup
|
||||
proced
|
||||
prodigy
|
||||
profiler
|
||||
python
|
||||
quickrun
|
||||
racer
|
||||
realgud
|
||||
reftex
|
||||
rjsx-mode
|
||||
robe
|
||||
;; ruby-mode
|
||||
rtags
|
||||
;; simple
|
||||
;; slime
|
||||
(term term ansi-term multi-term)
|
||||
tide
|
||||
transmission
|
||||
typescript-mode
|
||||
vc-annotate
|
||||
vdiff
|
||||
view
|
||||
vlf
|
||||
which-key
|
||||
wdired
|
||||
wgrep
|
||||
woman
|
||||
xref
|
||||
(ztree ztree-diff)))
|
||||
|
||||
(dolist (req evil-collection-mode-list)
|
||||
(with-eval-after-load (car (doom-enlist req))
|
||||
(evil-collection-init (list req))))))
|
||||
|
||||
|
||||
;;
|
||||
|
@ -231,12 +386,12 @@ variable for an explanation of the defaults (in comments). See
|
|||
(cons (format "(%s " (or (read-string "(") "")) ")"))
|
||||
|
||||
;; Add escaped-sequence support to embrace
|
||||
(map-put (default-value 'embrace--pairs-list)
|
||||
?\\ (make-embrace-pair-struct
|
||||
:key ?\\
|
||||
:read-function #'+evil--embrace-escaped
|
||||
:left-regexp "\\[[{(]"
|
||||
:right-regexp "\\[]})]")))
|
||||
(setf (alist-get ?\\ (default-value 'embrace--pairs-list))
|
||||
(make-embrace-pair-struct
|
||||
:key ?\\
|
||||
:read-function #'+evil--embrace-escaped
|
||||
:left-regexp "\\[[{(]"
|
||||
:right-regexp "\\[]})]")))
|
||||
|
||||
|
||||
(def-package! evil-escape
|
||||
|
@ -249,12 +404,6 @@ variable for an explanation of the defaults (in comments). See
|
|||
(add-hook 'pre-command-hook #'evil-escape-pre-command-hook)
|
||||
(evil-define-key* '(insert replace visual operator) 'global "\C-g" #'evil-escape)
|
||||
:config
|
||||
;; TODO PR this upstream
|
||||
(defun +evil*escape-func (ret)
|
||||
(if (eq evil-state 'multiedit-insert)
|
||||
#'evil-multiedit-state
|
||||
ret))
|
||||
(advice-add #'evil-escape-func :filter-return #'+evil*escape-func)
|
||||
;; no `evil-escape' in minibuffer
|
||||
(add-hook 'evil-escape-inhibit-functions #'minibufferp))
|
||||
|
||||
|
@ -332,8 +481,7 @@ the new algorithm is confusing, like in python or ruby."
|
|||
;; Add custom commands to whitelisted commands
|
||||
(dolist (fn '(doom/backward-to-bol-or-indent doom/forward-to-last-non-comment-or-eol
|
||||
doom/backward-kill-to-bol-and-indent))
|
||||
(map-put evil-mc-custom-known-commands
|
||||
fn '((:default . evil-mc-execute-default-call))))
|
||||
(add-to-list 'evil-mc-custom-known-commands `(,fn (:default . evil-mc-execute-default-call))))
|
||||
|
||||
;; Activate evil-mc cursors upon switching to insert mode
|
||||
(defun +evil-mc|resume-cursors () (setq evil-mc-frozen nil))
|
||||
|
|
|
@ -2,7 +2,9 @@
|
|||
|
||||
(defun +file-templates--set (pred plist)
|
||||
(if (null (car-safe plist))
|
||||
(setq +file-templates-alist (map-delete +file-templates-alist pred))
|
||||
(setq +file-templates-alist
|
||||
(delq (assoc pred +file-templates-alist)
|
||||
+file-templates-alist))
|
||||
(push `(,pred ,@plist) +file-templates-alist)))
|
||||
|
||||
;;;###autodef
|
||||
|
@ -56,7 +58,7 @@ these properties:
|
|||
;;
|
||||
|
||||
;;;###autoload
|
||||
(cl-defun +file-templates--expand (pred &key project mode trigger ignore)
|
||||
(cl-defun +file-templates--expand (pred &key project mode trigger ignore _when)
|
||||
"Auto insert a yasnippet snippet into current file and enter insert mode (if
|
||||
evil is loaded and enabled)."
|
||||
(when (and pred (not ignore))
|
||||
|
|
|
@ -9,8 +9,9 @@ DOCSET (a string).
|
|||
See `devdocs-alist' for the defaults. "
|
||||
(after! (:when (boundp 'devdocs-alist))
|
||||
(dolist (mode (doom-enlist modes))
|
||||
(map-put devdocs-alist mode docset))))
|
||||
(setf (alist-get mode devdocs-alist) docset))))
|
||||
|
||||
;; FIXME obsolete :devdocs
|
||||
;;;###autoload
|
||||
(def-setting! :devdocs (modes docset)
|
||||
"Map major MODES (one major-mode symbol or a list of them) to a devdocs
|
||||
|
|
|
@ -9,9 +9,13 @@
|
|||
|
||||
;;;###autodef
|
||||
(defun set-docset! (modes &rest docsets)
|
||||
"Registers a list of DOCSETS (strings) for MODES (either one major mode
|
||||
"Registers a list of DOCSETS (strings) for MODES (either one major/minor mode
|
||||
symbol or a list of them).
|
||||
|
||||
If MODES is a minor mode, you can use :add or :remove as the first element of
|
||||
DOCSETS, to instruct it to append (or remove) those from the docsets already set
|
||||
by a major-mode, if any.
|
||||
|
||||
Used by `+lookup/in-docsets' and `+lookup/documentation'."
|
||||
(declare (indent defun))
|
||||
(dolist (mode (doom-enlist modes))
|
||||
|
@ -30,16 +34,9 @@ Used by `+lookup/in-docsets' and `+lookup/documentation'."
|
|||
docsets)))))
|
||||
(add-hook hook fn))))))
|
||||
|
||||
;; FIXME obsolete :docset
|
||||
;;;###autoload
|
||||
(def-setting! :docset (modes &rest docsets)
|
||||
"Registers a list of DOCSETS (strings) for MODES (either one major mode
|
||||
symbol or a list of them).
|
||||
|
||||
If MODES is a minor mode, you can use :add or :remove as the first element of
|
||||
DOCSETS, to instruct it to append (or remove) those from the docsets already set
|
||||
by a major-mode, if any.
|
||||
|
||||
Used by `+lookup/in-docsets' and `+lookup/documentation'."
|
||||
:obsolete set-docset!
|
||||
`(set-docset! ,modes ,@docsets))
|
||||
|
||||
|
|
|
@ -56,6 +56,7 @@ properties:
|
|||
(add-hook 'xref-backend-functions xref-backend nil t))))))
|
||||
(add-hook hook fn))))))
|
||||
|
||||
;; FIXME obsolete :lookup
|
||||
;;;###autoload
|
||||
(def-setting! :lookup (modes &rest plist)
|
||||
:obsolete set-lookup-handlers!
|
||||
|
@ -72,7 +73,7 @@ properties:
|
|||
"Search on: "
|
||||
(mapcar #'car +lookup-provider-url-alist)
|
||||
nil t)))
|
||||
(map-put +lookup--last-provider key provider)
|
||||
(setf (alist-get +lookup--last-provider key) provider)
|
||||
provider))))
|
||||
|
||||
(defun +lookup--symbol-or-region (&optional initial)
|
||||
|
@ -245,7 +246,7 @@ Otherwise, falls back on `find-file-at-point'."
|
|||
((not (and +lookup-file-functions
|
||||
(+lookup--jump-to :file path)))
|
||||
(let ((fullpath (expand-file-name path)))
|
||||
(when (file-equal-p fullpath buffer-file-name)
|
||||
(when (and buffer-file-name (file-equal-p fullpath buffer-file-name))
|
||||
(user-error "Already here"))
|
||||
(let* ((insert-default-directory t)
|
||||
(project-root (doom-project-root 'nocache))
|
||||
|
@ -318,7 +319,9 @@ for the provider."
|
|||
(user-error "The search query is empty"))
|
||||
(funcall +lookup-open-url-fn (format url (url-encode-url search))))
|
||||
(error
|
||||
(map-delete +lookup--last-provider major-mode)
|
||||
(setq +lookup--last-provider
|
||||
(delq (assq major-mode +lookup--last-provider)
|
||||
+lookup--last-provider))
|
||||
(signal (car e) (cdr e)))))
|
||||
|
||||
;;;###autoload
|
||||
|
|
|
@ -9,6 +9,7 @@ can have its own snippets category, if the folder exists."
|
|||
(fset fn (lambda () (yas-activate-extra-mode mode)))
|
||||
(add-hook (intern (format "%s-hook" mode)) fn))))
|
||||
|
||||
;; FIXME obsolete :yas-minor-mode
|
||||
;;;###autoload
|
||||
(def-setting! :yas-minor-mode (mode)
|
||||
:obsolete set-yas-minor-mode!
|
||||
|
|
|
@ -291,7 +291,9 @@ workspace to delete."
|
|||
current-name))))
|
||||
(condition-case-unless-debug ex
|
||||
(let ((workspaces (+workspace-list-names)))
|
||||
(cond ((> (length workspaces) 1)
|
||||
(cond ((delq (selected-frame) (persp-frames-with-persp (get-frame-persp)))
|
||||
(user-error "Can't close workspace, it's visible in another frame"))
|
||||
((> (length workspaces) 1)
|
||||
(+workspace-delete name)
|
||||
(+workspace-switch
|
||||
(if (+workspace-exists-p +workspace--last)
|
||||
|
@ -330,18 +332,16 @@ workspace, otherwise the new workspace is blank."
|
|||
(interactive "iP")
|
||||
(unless name
|
||||
(setq name (format "#%s" (+workspace--generate-id))))
|
||||
(condition-case-unless-debug ex
|
||||
(if (+workspace-exists-p name)
|
||||
(error "%s already exists" name)
|
||||
(+workspace-switch name t)
|
||||
(if clone-p
|
||||
(let ((persp (+workspace-get name)))
|
||||
(dolist (window (window-list))
|
||||
(persp-add-buffer (window-buffer window) persp nil)))
|
||||
(delete-other-windows-internal)
|
||||
(switch-to-buffer (doom-fallback-buffer)))
|
||||
(+workspace/display))
|
||||
('error (+workspace-error (cadr ex) t))))
|
||||
(condition-case e
|
||||
(cond ((+workspace-exists-p name)
|
||||
(error "%s already exists" name))
|
||||
(clone-p (persp-copy name t))
|
||||
(t
|
||||
(+workspace-switch name t)
|
||||
(persp-delete-other-windows)
|
||||
(switch-to-buffer (doom-fallback-buffer))
|
||||
(+workspace/display)))
|
||||
((debug error) (+workspace-error (cadr e) t))))
|
||||
|
||||
;;;###autoload
|
||||
(defun +workspace/switch-to (index)
|
||||
|
|
|
@ -29,8 +29,9 @@ stored in `persp-save-dir'.")
|
|||
;; If emacs is passed --restore, restore the last session on startup. This is
|
||||
;; particularly useful for the `+workspace/restart-emacs-then-restore' command.
|
||||
(defun +workspaces-restore-last-session (&rest _)
|
||||
(add-hook 'emacs-startup-hook #'+workspace/load-session 'append))
|
||||
(map-put command-switch-alist "--restore" #'+workspaces-restore-last-session)
|
||||
(add-hook 'emacs-startup-hook #'+workspace/load-session :append))
|
||||
(add-to-list 'command-switch-alist (cons "--restore" #'+workspaces-restore-last-session))
|
||||
|
||||
|
||||
;;
|
||||
;; Plugins
|
||||
|
@ -41,7 +42,9 @@ stored in `persp-save-dir'.")
|
|||
:init
|
||||
(defun +workspaces|init ()
|
||||
;; Remove default buffer predicate so persp-mode can put in its own
|
||||
(setq default-frame-alist (map-delete default-frame-alist 'buffer-predicate))
|
||||
(setq default-frame-alist
|
||||
(delq (assq 'buffer-predicate default-frame-alist)
|
||||
default-frame-alist))
|
||||
(add-hook 'after-make-frame-functions #'+workspaces|init-frame)
|
||||
(require 'persp-mode)
|
||||
(unless (daemonp)
|
||||
|
@ -160,8 +163,8 @@ Uses `+workspaces-main' to determine the name of the main workspace."
|
|||
(list tag (buffer-name buf) vars
|
||||
(buffer-name (buffer-base-buffer))))
|
||||
:load-function (lambda (savelist &rest _rest)
|
||||
(destructuring-bind
|
||||
(buf-name vars base-buf-name &rest _rest) (cdr savelist)
|
||||
(destructuring-bind (buf-name _vars base-buf-name &rest _)
|
||||
(cdr savelist)
|
||||
(push (cons buf-name base-buf-name)
|
||||
+workspaces--indirect-buffers-to-restore)
|
||||
nil)))
|
||||
|
|
|
@ -5,48 +5,49 @@
|
|||
:var (persp-auto-resume-time
|
||||
persp-auto-save-opt
|
||||
persp-switch-to-added-buffer
|
||||
persp-autokill-persp-when-removed-last-buffer
|
||||
persp-autokill-buffer-on-remove
|
||||
in1 in2 out1 out2
|
||||
persp1 persp1-name persp2 persp2-name
|
||||
doom-before-switch-buffer-hook
|
||||
doom-after-switch-buffer-hook)
|
||||
wconf)
|
||||
|
||||
(before-all
|
||||
(delete-other-windows)
|
||||
(require! :feature workspaces)
|
||||
(require 'persp-mode))
|
||||
(after-all
|
||||
(unload-feature 'persp-mode t))
|
||||
|
||||
(before-each
|
||||
(setq persp-auto-resume-time -1
|
||||
(switch-to-buffer "*scratch*")
|
||||
(setq wconf (current-window-configuration)
|
||||
persp-auto-resume-time -1
|
||||
persp-auto-save-opt 0
|
||||
persp-switch-to-added-buffer nil
|
||||
in1 (get-buffer-create "a")
|
||||
in2 (get-buffer-create "b")
|
||||
out1 (get-buffer-create "c")
|
||||
out2 (get-buffer-create "d"))
|
||||
persp-autokill-persp-when-removed-last-buffer nil
|
||||
persp-autokill-buffer-on-remove nil
|
||||
in1 (get-buffer-create "in1")
|
||||
in2 (get-buffer-create "in2")
|
||||
out1 (get-buffer-create "out1")
|
||||
out2 (get-buffer-create "out2"))
|
||||
(doom-set-buffer-real in1 t)
|
||||
(doom-set-buffer-real out1 t)
|
||||
(let (noninteractive)
|
||||
(persp-mode +1))
|
||||
(let (persp-before-switch-functions persp-activated-functions)
|
||||
(setq persp1-name +workspaces-main
|
||||
persp1 (persp-add-new persp1-name)
|
||||
persp2-name "test"
|
||||
persp2 (persp-add-new persp2-name))
|
||||
(persp-frame-switch +workspaces-main))
|
||||
(delete-other-windows)
|
||||
(switch-to-buffer in1)
|
||||
(persp-add-buffer (list in1 in2))
|
||||
(spy-on 'persp-add-buffer :and-call-through)
|
||||
(doom|init-custom-hooks))
|
||||
(persp-mode +1)
|
||||
(let (persp-before-switch-functions persp-activated-functions)
|
||||
(setq persp1-name +workspaces-main
|
||||
persp1 (persp-add-new persp1-name)
|
||||
persp2-name "test"
|
||||
persp2 (persp-add-new persp2-name))
|
||||
(persp-switch persp1-name)
|
||||
(persp-add-buffer (list in1 in2) persp1))))
|
||||
|
||||
(after-each
|
||||
(doom|init-custom-hooks 'disable)
|
||||
(let (kill-buffer-query-functions kill-buffer-hook)
|
||||
(mapc #'kill-buffer (list in1 in2 out1 out2)))
|
||||
(let (noninteractive)
|
||||
(mapc #'persp-kill (cdr (persp-names)))
|
||||
(persp-mode -1)))
|
||||
(let (noninteractive ignore-window-parameters)
|
||||
(dolist (persp (persp-names))
|
||||
(ignore-errors (persp-kill persp)))
|
||||
(persp-mode -1))
|
||||
(set-window-configuration wconf)
|
||||
(mapc #'kill-buffer (list in1 in2 out1 out2))))
|
||||
|
||||
;;
|
||||
(describe "switch"
|
||||
|
@ -80,7 +81,7 @@
|
|||
(expect (+workspace-contains-buffer-p out1) :to-be nil))
|
||||
(it "automatically adds interactively opened buffers"
|
||||
(expect (+workspace-contains-buffer-p out1) :to-be nil)
|
||||
(switch-to-buffer out1)
|
||||
(with-current-buffer out1 (+workspaces|auto-add-buffer))
|
||||
(expect (+workspace-contains-buffer-p out1)))
|
||||
(xit "returns a list of orphaned buffers"
|
||||
(expect (+workspace-orphaned-buffer-list) :to-contain out2)))
|
||||
|
@ -107,20 +108,6 @@
|
|||
(expect (+workspace-list-names) :not :to-contain persp2-name)))
|
||||
|
||||
(describe "command"
|
||||
(describe "new"
|
||||
(it "creates a new, blank workspace"
|
||||
(quiet! (+workspace/new "X"))
|
||||
(expect (one-window-p))
|
||||
(expect (current-buffer) :to-be (doom-fallback-buffer)))
|
||||
(it "clones a workspace"
|
||||
(quiet! (+workspace/new "X" t))
|
||||
(expect (current-buffer) :to-be in1)))
|
||||
|
||||
(describe "rename"
|
||||
(it "renames the current workspace"
|
||||
(quiet! (+workspace/rename "X"))
|
||||
(expect (+workspace-current-name) :to-equal "X")))
|
||||
|
||||
(describe "close-window-or-workspace"
|
||||
(before-each
|
||||
(+workspace-switch persp2-name)
|
||||
|
@ -132,4 +119,9 @@
|
|||
(it "kills workspace on last window"
|
||||
(quiet! (+workspace/close-window-or-workspace)
|
||||
(+workspace/close-window-or-workspace))
|
||||
(expect (+workspace-current-name) :to-equal persp1-name)))))
|
||||
(expect (+workspace-current-name) :to-equal persp1-name)))
|
||||
|
||||
(describe "rename"
|
||||
(it "renames the current workspace"
|
||||
(quiet! (+workspace/rename "X"))
|
||||
(expect (+workspace-current-name) :to-equal "X")))))
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
;;; lang/assembly/autoload.el -*- lexical-binding: t; -*-
|
||||
|
||||
;;;###autoload
|
||||
(map-put auto-mode-alist "\\.hax\\'" 'haxor-mode)
|
||||
(add-to-list 'auto-mode-alist '("\\.hax\\'" . haxor-mode))
|
||||
|
|
|
@ -83,35 +83,37 @@ compilation database is present in the project.")
|
|||
+cc|fontify-constants))
|
||||
|
||||
;; Custom style, based off of linux
|
||||
(map-put c-style-alist "doom"
|
||||
`((c-basic-offset . ,tab-width)
|
||||
(c-comment-only-line-offset . 0)
|
||||
(c-hanging-braces-alist (brace-list-open)
|
||||
(brace-entry-open)
|
||||
(substatement-open after)
|
||||
(block-close . c-snug-do-while)
|
||||
(arglist-cont-nonempty))
|
||||
(c-cleanup-list brace-else-brace)
|
||||
(c-offsets-alist
|
||||
(statement-block-intro . +)
|
||||
(knr-argdecl-intro . 0)
|
||||
(substatement-open . 0)
|
||||
(substatement-label . 0)
|
||||
(statement-cont . +)
|
||||
(case-label . +)
|
||||
;; align args with open brace OR don't indent at all (if open
|
||||
;; brace is at eolp and close brace is after arg with no trailing
|
||||
;; comma)
|
||||
(arglist-intro . +)
|
||||
(arglist-close +cc-lineup-arglist-close 0)
|
||||
;; don't over-indent lambda blocks
|
||||
(inline-open . 0)
|
||||
(inlambda . 0)
|
||||
;; indent access keywords +1 level, and properties beneath them
|
||||
;; another level
|
||||
(access-label . -)
|
||||
(inclass +cc-c++-lineup-inclass +)
|
||||
(label . 0))))
|
||||
(unless (assoc "doom" c-style-alist)
|
||||
(push '("doom"
|
||||
(c-basic-offset . ,tab-width)
|
||||
(c-comment-only-line-offset . 0)
|
||||
(c-hanging-braces-alist (brace-list-open)
|
||||
(brace-entry-open)
|
||||
(substatement-open after)
|
||||
(block-close . c-snug-do-while)
|
||||
(arglist-cont-nonempty))
|
||||
(c-cleanup-list brace-else-brace)
|
||||
(c-offsets-alist
|
||||
(statement-block-intro . +)
|
||||
(knr-argdecl-intro . 0)
|
||||
(substatement-open . 0)
|
||||
(substatement-label . 0)
|
||||
(statement-cont . +)
|
||||
(case-label . +)
|
||||
;; align args with open brace OR don't indent at all (if open
|
||||
;; brace is at eolp and close brace is after arg with no trailing
|
||||
;; comma)
|
||||
(arglist-intro . +)
|
||||
(arglist-close +cc-lineup-arglist-close 0)
|
||||
;; don't over-indent lambda blocks
|
||||
(inline-open . 0)
|
||||
(inlambda . 0)
|
||||
;; indent access keywords +1 level, and properties beneath them
|
||||
;; another level
|
||||
(access-label . -)
|
||||
(inclass +cc-c++-lineup-inclass +)
|
||||
(label . 0)))
|
||||
c-style-alist))
|
||||
|
||||
;;; Keybindings
|
||||
;; Disable electric keys because it interferes with smartparens and custom
|
||||
|
@ -133,9 +135,6 @@ compilation database is present in the project.")
|
|||
:when '(+cc-sp-point-is-template-p +cc-sp-point-after-include-p)
|
||||
:post-handlers '(("| " "SPC"))))
|
||||
(sp-with-modes '(c-mode c++-mode objc-mode java-mode)
|
||||
(sp-local-pair "/*" "*/" :post-handlers '(("||\n[i]" "RET") ("| " "SPC")))
|
||||
;; Doxygen blocks
|
||||
(sp-local-pair "/**" "*/" :post-handlers '(("||\n[i]" "RET") ("||\n[i]" "SPC")))
|
||||
(sp-local-pair "/*!" "*/" :post-handlers '(("||\n[i]" "RET") ("[d-1]< | " "SPC")))))
|
||||
|
||||
|
||||
|
|
|
@ -5,14 +5,7 @@
|
|||
|
||||
|
||||
(def-package! clj-refactor
|
||||
:after clojure-mode
|
||||
:config
|
||||
;; setup some extra namespace auto completion for great awesome
|
||||
(dolist (ns '(("re-frame" . "re-frame.core")
|
||||
("reagent" . "reagent.core")
|
||||
("str" . "clojure.string")))
|
||||
(map-put cljr-magic-require-namespaces (car ns) (cdr ns))))
|
||||
|
||||
:after clojure-mode)
|
||||
|
||||
(def-package! cider
|
||||
;; NOTE: if you don't have an org directory set (the dir doesn't exist), cider
|
||||
|
@ -23,13 +16,7 @@
|
|||
(setq nrepl-hide-special-buffers t
|
||||
cider-stacktrace-default-filters '(tooling dup)
|
||||
cider-prompt-save-file-on-load nil
|
||||
cider-repl-use-clojure-font-lock t
|
||||
;; Setup cider for clojurescript / figwheel dev.
|
||||
cider-cljs-lein-repl
|
||||
"(do (require 'figwheel-sidecar.repl-api)
|
||||
(figwheel-sidecar.repl-api/start-figwheel!)
|
||||
(figwheel-sidecar.repl-api/cljs-repl))")
|
||||
|
||||
cider-repl-use-clojure-font-lock t)
|
||||
(set-popup-rule! "^\\*cider-repl" :quit nil :select nil)
|
||||
(set-repl-handler! 'clojure-mode #'+clojure/repl)
|
||||
(set-eval-handler! 'clojure-mode #'cider-eval-region)
|
||||
|
|
|
@ -7,9 +7,9 @@
|
|||
:definition #'crystal-def-jump
|
||||
:references #'crystal-tool-imp)
|
||||
(set-eval-handler! 'crystal-mode
|
||||
'((:command . "crystal")
|
||||
(:exec . "%c %s")
|
||||
(:description . "Run Crystal script"))))
|
||||
'((:command . "crystal")
|
||||
(:exec . "%c %s")
|
||||
(:description . "Run Crystal script"))))
|
||||
|
||||
|
||||
(def-package! flycheck-crystal
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
;;; lang/csharp/config.el -*- lexical-binding: t; -*-
|
||||
|
||||
(map-put auto-mode-alist '"\\.shader$" 'dshader-mode) ; unity shaders
|
||||
;; unity shaders
|
||||
(add-to-list 'auto-mode-alist '("\\.shader$" . shader-mode))
|
||||
|
||||
|
||||
(def-package! omnisharp
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
;;; lang/data/config.el -*- lexical-binding: t; -*-
|
||||
|
||||
;; Built in plugins
|
||||
(dolist (spec '(("/sxhkdrc\\'" . conf-mode)
|
||||
("\\.\\(?:hex\\|nes\\)\\'" . hexl-mode)
|
||||
("\\.plist\\'" . nxml-mode)))
|
||||
(map-put auto-mode-alist (car spec) (cdr spec)))
|
||||
(unless after-init-time
|
||||
(push '("/sxhkdrc\\'" . conf-mode) auto-mode-alist)
|
||||
(push '("\\.\\(?:hex\\|nes\\)\\'" . hexl-mode) auto-mode-alist)
|
||||
(push '("\\.plist\\'" . nxml-mode) auto-mode-alist))
|
||||
|
||||
(after! nxml-mode
|
||||
(set-company-backend! 'nxml-mode '(company-nxml company-yasnippet)))
|
||||
|
|
|
@ -2,6 +2,9 @@
|
|||
|
||||
(def-package! elixir-mode
|
||||
:defer t
|
||||
:init
|
||||
;; disable default smartparens config
|
||||
(provide 'smartparens-elixir)
|
||||
:config
|
||||
;; ...and only complete the basics
|
||||
(after! smartparens
|
||||
|
@ -9,7 +12,6 @@
|
|||
(sp-local-pair "do" "end"
|
||||
:when '(("RET" "<evil-ret>"))
|
||||
:unless '(sp-in-comment-p sp-in-string-p)
|
||||
:skip-match 'sp-elixir-skip-def-p
|
||||
:post-handlers '("||\n[i]"))
|
||||
(sp-local-pair "do " " end" :unless '(sp-in-comment-p sp-in-string-p))
|
||||
(sp-local-pair "fn " " end" :unless '(sp-in-comment-p sp-in-string-p))))
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
;;; lang/emacs-lisp/config.el -*- lexical-binding: t; -*-
|
||||
|
||||
(def-package! elisp-mode ; built-in
|
||||
:mode ("/Cask$" . emacs-lisp-mode)
|
||||
:config
|
||||
(add-to-list 'auto-mode-alist '("\\.Cask\\'" . emacs-lisp-mode))
|
||||
|
||||
(defun +emacs-lisp|init ()
|
||||
(set-repl-handler! 'emacs-lisp-mode #'+emacs-lisp/repl)
|
||||
(set-eval-handler! 'emacs-lisp-mode #'+emacs-lisp-eval)
|
||||
(set-lookup-handlers! 'emacs-lisp-mode :documentation 'info-lookup-symbol)
|
||||
|
@ -61,6 +61,8 @@
|
|||
return t))
|
||||
(flycheck-mode -1))))
|
||||
|
||||
(add-transient-hook! 'emacs-lisp-mode (+emacs-lisp|init))
|
||||
|
||||
|
||||
;;
|
||||
;; Plugins
|
||||
|
@ -74,21 +76,21 @@
|
|||
;; `macrostep'
|
||||
(map! :after macrostep
|
||||
:map macrostep-keymap
|
||||
:n "RET" #'macrostep-expand
|
||||
:n "e" #'macrostep-expand
|
||||
:n "u" #'macrostep-collapse
|
||||
:n "c" #'macrostep-collapse
|
||||
:n "RET" #'macrostep-expand
|
||||
:n "e" #'macrostep-expand
|
||||
:n "u" #'macrostep-collapse
|
||||
:n "c" #'macrostep-collapse
|
||||
|
||||
:n "TAB" #'macrostep-next-macro
|
||||
:n "n" #'macrostep-next-macro
|
||||
:n "J" #'macrostep-next-macro
|
||||
:n [tab] #'macrostep-next-macro
|
||||
:n "C-n" #'macrostep-next-macro
|
||||
:n "J" #'macrostep-next-macro
|
||||
|
||||
:n "S-TAB" #'macrostep-prev-macro
|
||||
:n "K" #'macrostep-prev-macro
|
||||
:n "p" #'macrostep-prev-macro
|
||||
:n [backtab] #'macrostep-prev-macro
|
||||
:n "K" #'macrostep-prev-macro
|
||||
:n "C-p" #'macrostep-prev-macro
|
||||
|
||||
:n "q" #'macrostep-collapse-all
|
||||
:n "C" #'macrostep-collapse-all)
|
||||
:n "q" #'macrostep-collapse-all
|
||||
:n "C" #'macrostep-collapse-all)
|
||||
|
||||
(after! evil
|
||||
;; `evil-normalize-keymaps' seems to be required for macrostep or it won't
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
"/rebar\\.config\\(?:\\.script\\)?$"
|
||||
;; erlang configs
|
||||
"/\\(?:app\\|sys\\)\\.config$"))
|
||||
(map-put auto-mode-alist regexp 'erlang-mode))
|
||||
(add-to-list 'auto-mode-alist (cons regexp 'erlang-mode)))
|
||||
|
||||
|
||||
(def-package! flycheck-rebar3
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
("\\.[Jj][Mm][Dd]\\'" . ess-jags-mode))
|
||||
:init
|
||||
(unless (featurep! :lang julia)
|
||||
(map-put auto-mode-alist "\\.jl\'" 'ess-julia-mode))
|
||||
(add-to-list 'auto-mode-alist '("\\.jl\\'" . ess-julia-mode)))
|
||||
:config
|
||||
(add-hook 'ess-mode-hook #'doom|enable-line-numbers)
|
||||
(setq ess-offset-continued 'straight
|
||||
|
|
|
@ -2,17 +2,8 @@
|
|||
;;;###if (featurep! +dante)
|
||||
|
||||
(def-package! dante
|
||||
:after haskell-mode
|
||||
:hook (haskell-mode . dante-mode)
|
||||
:config
|
||||
(add-hook 'haskell-mode-hook #'interactive-haskell-mode))
|
||||
|
||||
|
||||
(def-package! company-ghc
|
||||
:when (featurep! :completion company)
|
||||
:after haskell-mode
|
||||
:init
|
||||
(add-hook 'haskell-mode-hook #'ghc-comp-init)
|
||||
:config
|
||||
(setq company-ghc-show-info 'oneline)
|
||||
(set-company-backend! 'haskell-mode #'company-ghc))
|
||||
(when (featurep! :feature syntax-checker)
|
||||
(add-hook! 'dante-mode-hook
|
||||
(flycheck-add-next-checker 'haskell-dante '(warning . haskell-hlint)))))
|
||||
|
|
|
@ -4,9 +4,8 @@
|
|||
(when (featurep! +dante)
|
||||
(unless (executable-find "cabal")
|
||||
(warn! "Couldn't find cabal, haskell-mode may have issues"))
|
||||
|
||||
(unless (executable-find "ghc-mod")
|
||||
(warn! "Couldn't find ghc-mod on PATH. Code completion will not work")))
|
||||
(unless (executable-find "hlint")
|
||||
(warn! "Couldn't find hlint. Flycheck may have issues in haskell-mode/")))
|
||||
|
||||
(when (featurep! +intero)
|
||||
(unless (executable-find "stack")
|
||||
|
|
|
@ -5,9 +5,7 @@
|
|||
|
||||
;;
|
||||
(cond ((featurep! +dante)
|
||||
(package! dante)
|
||||
(when (featurep! :completion company)
|
||||
(package! company-ghc)))
|
||||
(package! dante))
|
||||
(t
|
||||
(package! intero)
|
||||
(package! hindent)))
|
||||
|
|
|
@ -17,11 +17,6 @@
|
|||
;; Other
|
||||
:yield "import"))
|
||||
|
||||
(after! smartparens
|
||||
(sp-with-modes '(js2-mode typescript-mode rjsx-mode)
|
||||
(sp-local-pair "/**" "" :post-handlers '(("| " "SPC") ("|\n*/[i][d-2]" "RET")))
|
||||
(sp-local-pair "/*" "*/" :post-handlers '(("| " "SPC") ("|\n*/[i][d-2]" "RET")))))
|
||||
|
||||
|
||||
;;
|
||||
;; Major modes
|
||||
|
@ -66,7 +61,7 @@
|
|||
magic-mode-regexp-match-limit t)
|
||||
(progn (goto-char (match-beginning 1))
|
||||
(not (sp-point-in-string-or-comment)))))
|
||||
(map-put magic-mode-alist #'+javascript-jsx-file-p 'rjsx-mode)
|
||||
(add-to-list 'magic-mode-alist '(+javascript-jsx-file-p . rjsx-mode))
|
||||
:config
|
||||
(set-electric! 'rjsx-mode :chars '(?\} ?\) ?. ?>))
|
||||
(add-hook! 'rjsx-mode-hook
|
||||
|
@ -76,7 +71,7 @@
|
|||
;; `rjsx-electric-gt' relies on js2's parser to tell it when the cursor is in
|
||||
;; a self-closing tag, so that it can insert a matching ending tag at point.
|
||||
;; However, the parser doesn't run immediately, so a fast typist can outrun
|
||||
;; it, causing issues, so force it to parse.
|
||||
;; it, causing tags to stay unclosed, so force it to parse.
|
||||
(defun +javascript|reparse (n)
|
||||
;; if n != 1, rjsx-electric-gt calls rjsx-maybe-reparse itself
|
||||
(if (= n 1) (rjsx-maybe-reparse)))
|
||||
|
@ -134,23 +129,19 @@
|
|||
:config
|
||||
(setq tide-completion-detailed t
|
||||
tide-always-show-documentation t)
|
||||
|
||||
;; code completion
|
||||
(after! company
|
||||
;; tide affects the global `company-backends', undo this so doom can handle
|
||||
;; it buffer-locally
|
||||
(setq-default company-backends (delq 'company-tide (default-value 'company-backends))))
|
||||
(set-company-backend! 'tide-mode 'company-tide)
|
||||
|
||||
;; navigation
|
||||
(set-lookup-handlers! 'tide-mode
|
||||
:definition #'tide-jump-to-definition
|
||||
:references #'tide-references
|
||||
:documentation #'tide-documentation-at-point)
|
||||
|
||||
;; resolve to `doom-project-root' if `tide-project-root' fails
|
||||
(advice-add #'tide-project-root :override #'+javascript*tide-project-root)
|
||||
|
||||
;; cleanup tsserver when no tide buffers are left
|
||||
(add-hook! 'tide-mode-hook
|
||||
(add-hook 'kill-buffer-hook #'+javascript|cleanup-tide-processes nil t))
|
||||
|
|
|
@ -14,6 +14,9 @@
|
|||
;; Plugins
|
||||
;;
|
||||
|
||||
;; sp's default rules are obnoxious, so disable them
|
||||
(provide 'smartparens-latex)
|
||||
|
||||
(after! tex
|
||||
;; Set some varibles to fontify common LaTeX commands.
|
||||
(load! "+fontification")
|
||||
|
@ -75,33 +78,30 @@
|
|||
(setcar (cdr (assoc "Check" TeX-command-list)) "chktex -v6 %s")
|
||||
;; Set a custom item indentation
|
||||
(dolist (env '("itemize" "enumerate" "description"))
|
||||
(map-put LaTeX-indent-environment-list
|
||||
env '(+latex/LaTeX-indent-item)))
|
||||
(add-to-list 'LaTeX-indent-environment-list `(,env +latex/LaTeX-indent-item)))
|
||||
|
||||
;;
|
||||
;; Use Okular if the user says so.
|
||||
(when (featurep! +okular)
|
||||
;; Configure Okular as viewer. Including a bug fix
|
||||
;; (https://bugs.kde.org/show_bug.cgi?id=373855)
|
||||
(map-put TeX-view-program-list
|
||||
"Okular" '(("okular --unique file:%o" (mode-io-correlate "#src:%n%a"))))
|
||||
(map-put TeX-view-program-list 'output-pdf '("Okular")))
|
||||
(add-to-list 'TeX-view-program-list '("Okular" ("okular --unique file:%o" (mode-io-correlate "#src:%n%a"))))
|
||||
(add-to-list 'TeX-view-program-selection '(output-pdf "Okular")))
|
||||
|
||||
;; Or Skim
|
||||
(when (featurep! +skim)
|
||||
(map-put TeX-view-program-list
|
||||
"Skim" '("/Applications/Skim.app/Contents/SharedSupport/displayline -b -g %n %o %b"))
|
||||
(map-put TeX-view-program-selection 'output-pdf '("Skim")))
|
||||
(add-to-list 'TeX-view-program-list '("Skim" "/Applications/Skim.app/Contents/SharedSupport/displayline -b -g %n %o %b"))
|
||||
(add-to-list 'TeX-view-program-selection 'output-pdf '("Skim")))
|
||||
|
||||
;; Or Zathura
|
||||
(when (featurep! +zathura)
|
||||
(map-put TeX-view-program-selection 'output-pdf '("Zathura")))
|
||||
(add-to-list 'TeX-view-program-selection '(output-pdf "Zathura")))
|
||||
|
||||
;; Or PDF-tools, but only if the module is also loaded
|
||||
(when (and (featurep! :tools pdf)
|
||||
(featurep! +pdf-tools))
|
||||
(map-put TeX-view-program-list "PDF Tools" '("TeX-pdf-tools-sync-view"))
|
||||
(map-put TeX-view-program-selection 'output-pdf '("PDF Tools"))
|
||||
(add-to-list 'TeX-view-program-list ("PDF Tools" "TeX-pdf-tools-sync-view"))
|
||||
(add-to-list 'TeX-view-program-selection '(output-pdf "PDF Tools"))
|
||||
;; Enable auto reverting the PDF document with PDF Tools
|
||||
(add-hook 'TeX-after-compilation-finished-functions #'TeX-revert-document-buffer)))
|
||||
|
||||
|
@ -124,8 +124,8 @@
|
|||
:init
|
||||
(setq latex-preview-pane-multifile-mode 'auctex)
|
||||
:config
|
||||
(map-put TeX-view-program-list "preview-pane" '(latex-preview-pane-mode))
|
||||
(map-put TeX-view-program-selection 'output-pdf '("preview-pane"))
|
||||
(add-to-list 'TeX-view-program-list '("preview-pane" latex-preview-pane-mode))
|
||||
(add-to-list 'TeX-view-program-selection '(output-pdf "preview-pane"))
|
||||
(define-key! doc-view-mode-map
|
||||
(kbd "ESC") #'delete-window
|
||||
"q" #'delete-window
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
;;; lang/lua/config.el -*- lexical-binding: t; -*-
|
||||
|
||||
;; sp's default rules are obnoxious, so disable them
|
||||
(provide 'smartparens-lua)
|
||||
|
||||
(after! lua-mode
|
||||
(set-lookup-handlers! 'lua-mode :documentation 'lua-search-documentation)
|
||||
(set-electric! 'lua-mode :words '("else" "end"))
|
||||
|
|
|
@ -3,6 +3,9 @@
|
|||
(def-package! markdown-mode
|
||||
:mode ("/README\\(?:\\.\\(?:markdown\\|md\\)\\)?\\'" . gfm-mode)
|
||||
:init
|
||||
(when (featurep! +pandoc)
|
||||
(setq markdown-command "pandoc --from=markdown --to=html --standalone --mathjax --highlight-style=pygments"))
|
||||
|
||||
(setq markdown-enable-wiki-links t
|
||||
markdown-italic-underscore t
|
||||
markdown-asymmetric-header t
|
||||
|
@ -47,3 +50,10 @@
|
|||
:nv "t" #'markdown-toc-generate-toc
|
||||
:nv "i" #'markdown-insert-image
|
||||
:nv "l" #'markdown-insert-link)))
|
||||
|
||||
(def-package! pandoc-mode
|
||||
:when (featurep! +pandoc)
|
||||
:commands
|
||||
pandoc-mode
|
||||
:hook
|
||||
(markdown-mode . conditionally-turn-on-pandoc))
|
||||
|
|
6
modules/lang/markdown/doctor.el
Normal file
6
modules/lang/markdown/doctor.el
Normal file
|
@ -0,0 +1,6 @@
|
|||
;; -*- lexical-binding: t; no-byte-compile: t; -*-
|
||||
;;; lang/markdown/doctor.el
|
||||
|
||||
(when (featurep! +pandoc)
|
||||
(unless (executable-find "pandoc")
|
||||
(warn! "Couldn't find pandoc, markdown-mode may have issues")))
|
|
@ -4,3 +4,7 @@
|
|||
(package! markdown-mode)
|
||||
(package! markdown-toc)
|
||||
|
||||
(when (featurep! +pandoc)
|
||||
(package! pandoc-mode))
|
||||
|
||||
|
||||
|
|
|
@ -36,7 +36,7 @@ string). Stops at the first function to return non-nil.")
|
|||
(or (cdr (assq lang +org-babel-mode-alist))
|
||||
lang)))
|
||||
nil t)))
|
||||
(map-put org-babel-load-languages lang t))
|
||||
(add-to-list 'org-babel-load-languages (cons lang t)))
|
||||
t)))
|
||||
(advice-add #'org-babel-confirm-evaluate :around #'+org*babel-lazy-load-library)
|
||||
|
||||
|
|
|
@ -25,17 +25,15 @@
|
|||
:when (featurep! :feature evil +everywhere)
|
||||
:hook (org-mode . evil-org-mode)
|
||||
:init
|
||||
(setq evil-org-key-theme '(navigation insert textobjects))
|
||||
(defvar evil-org-key-theme '(navigation insert textobjects))
|
||||
(add-hook 'org-load-hook #'+org|setup-evil)
|
||||
(add-hook 'evil-org-mode-hook #'evil-normalize-keymaps)
|
||||
:config
|
||||
;; in case it is called later
|
||||
(advice-add #'evil-org-set-key-theme :after #'+org|setup-evil))
|
||||
|
||||
(def-package! evil-org-agenda
|
||||
:when (featurep! :feature evil +everywhere)
|
||||
:after org-agenda
|
||||
:config (evil-org-agenda-set-keys))
|
||||
(advice-add #'evil-org-set-key-theme :after #'+org|setup-evil)
|
||||
(def-package! evil-org-agenda
|
||||
:after org-agenda
|
||||
:config (evil-org-agenda-set-keys)))
|
||||
|
||||
|
||||
;;
|
||||
|
@ -266,8 +264,10 @@ between the two."
|
|||
[remap doom/backward-to-bol-or-indent] #'org-beginning-of-line
|
||||
[remap doom/forward-to-last-non-comment-or-eol] #'org-end-of-line))
|
||||
|
||||
(defun +org|setup-evil (&rest _)
|
||||
(require 'evil-org)
|
||||
(defun +org|setup-evil (&rest args)
|
||||
;; In case this hook is used in an advice on `evil-org-set-key-theme', this
|
||||
;; prevents recursive requires.
|
||||
(unless args (require 'evil-org))
|
||||
;; By default, TAB cycles the visibility of all children under the current
|
||||
;; tree between three states. I want to toggle the tree between two states,
|
||||
;; without affecting its children.
|
||||
|
@ -341,7 +341,7 @@ between the two."
|
|||
(defun +org|setup-hacks ()
|
||||
"Getting org to behave."
|
||||
;; Don't open separate windows
|
||||
(map-put org-link-frame-setup 'file #'find-file)
|
||||
(setf (alist-get 'file org-link-frame-setup) #'find-file)
|
||||
;; Let OS decide what to do with files when opened
|
||||
(setq org-file-apps
|
||||
`(("pdf" . default)
|
||||
|
|
|
@ -22,9 +22,9 @@
|
|||
(setq sh-indent-after-continuation 'always)
|
||||
|
||||
;; recognize function names with dashes in them
|
||||
(map-put sh-imenu-generic-expression
|
||||
'sh '((nil "^\\s-*function\\s-+\\([[:alpha:]_-][[:alnum:]_-]*\\)\\s-*\\(?:()\\)?" 1)
|
||||
(nil "^\\s-*\\([[:alpha:]_-][[:alnum:]_-]*\\)\\s-*()" 1)))
|
||||
(add-to-list 'sh-imenu-generic-expression
|
||||
'(sh (nil "^\\s-*function\\s-+\\([[:alpha:]_-][[:alnum:]_-]*\\)\\s-*\\(?:()\\)?" 1)
|
||||
(nil "^\\s-*\\([[:alpha:]_-][[:alnum:]_-]*\\)\\s-*()" 1)))
|
||||
|
||||
;; `sh-set-shell' is chatty about setting up indentation rules
|
||||
(advice-add #'sh-set-shell :around #'doom*shut-up)
|
||||
|
|
|
@ -3,10 +3,6 @@
|
|||
;; An improved newline+continue comment function
|
||||
(setq-hook! css-mode comment-indent-function #'+css/comment-indent-new-line)
|
||||
|
||||
(after! smartparens
|
||||
(sp-with-modes '(css-mode scss-mode less-css-mode stylus-mode)
|
||||
(sp-local-pair "/*" "*/" :post-handlers '(("||\n[i]" "RET") ("| " "SPC")))))
|
||||
|
||||
(map! :map* (css-mode-map scss-mode-map less-css-mode-map)
|
||||
:localleader
|
||||
:n "rb" #'+css/toggle-inline-or-block)
|
||||
|
|
|
@ -16,7 +16,25 @@
|
|||
:mode "templates/.+\\.php$"
|
||||
:config
|
||||
(setq web-mode-enable-html-entities-fontification t
|
||||
web-mode-enable-auto-quoting nil)
|
||||
web-mode-auto-close-style 2)
|
||||
|
||||
(after! smartparens
|
||||
;; let smartparens handle these
|
||||
(setq web-mode-enable-auto-quoting nil
|
||||
web-mode-enable-auto-pairing t)
|
||||
;; Remove web-mode auto pairs that end with >, because smartparens autopairs
|
||||
;; them, causing duplicates. Also remove truncated autopairs, like <?p and
|
||||
;; hp ?>.
|
||||
(dolist (alist web-mode-engines-auto-pairs)
|
||||
(setcdr alist (delq nil
|
||||
(mapcar (lambda (pair)
|
||||
(unless (string-match-p "^[a-z-]" (cdr pair))
|
||||
(cons (car pair)
|
||||
(if (equal (substring (cdr pair) -1) ">")
|
||||
(substring (cdr pair) 0 -1)
|
||||
(cdr pair)))))
|
||||
(cdr alist)))))
|
||||
(setf (alist-get nil web-mode-engines-auto-pairs) nil))
|
||||
|
||||
(map! :map web-mode-map
|
||||
(:localleader
|
||||
|
|
|
@ -21,11 +21,12 @@
|
|||
:after-call (doom-before-switch-buffer after-find-file)
|
||||
:config
|
||||
;; Register missing indent variables
|
||||
(setq editorconfig-indentation-alist
|
||||
(append '((mips-mode mips-tab-width)
|
||||
(haxor-mode haxor-tab-width)
|
||||
(nasm-mode nasm-basic-offset))
|
||||
editorconfig-indentation-alist))
|
||||
(unless (assq 'mips-mode editorconfig-indentation-alist)
|
||||
(setq editorconfig-indentation-alist
|
||||
(append '((mips-mode mips-tab-width)
|
||||
(haxor-mode haxor-tab-width)
|
||||
(nasm-mode nasm-basic-offset))
|
||||
editorconfig-indentation-alist)))
|
||||
|
||||
(defun doom*editorconfig-smart-detection (orig-fn &rest args)
|
||||
"Retrieve the properties for the current file. If it doesn't have an
|
||||
|
@ -51,7 +52,8 @@ extension, try to guess one."
|
|||
;; editorconfig to ignore indentation there. I prefer dynamic indentation
|
||||
;; support built into Emacs.
|
||||
(dolist (mode '(emacs-lisp-mode lisp-mode))
|
||||
(map-delete editorconfig-indentation-alist mode))
|
||||
(delq (assq mode editorconfig-indentation-alist)
|
||||
editorconfig-indentation-alist))
|
||||
|
||||
;;
|
||||
(editorconfig-mode +1))
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
;;; tools/ein/autoload.el -*- lexical-binding: t; -*-
|
||||
|
||||
;; FIXME obsolete :ein-notebook-dir
|
||||
;;;###autoload
|
||||
(def-setting! :ein-notebook-dir (dir)
|
||||
"Set the default directory from where to open Jupyter notebooks."
|
||||
|
@ -33,4 +34,47 @@
|
|||
(goto-char (1+ res))
|
||||
(widget-button-press (point)))))
|
||||
|
||||
|
||||
;;;###autoload (autoload '+ein-hydra/body "tools/ein/autoload" nil nil)
|
||||
(defhydra +ein-hydra (:hint t :color red)
|
||||
"
|
||||
Operations on Cells^^^^^^ Other
|
||||
----------------------------^^^^^^ ----------------------------------^^^^
|
||||
[_k_/_j_]^^ select prev/next [_t_]^^ toggle output
|
||||
[_K_/_J_]^^ move up/down [_C-l_/_C-S-l_] clear/clear all output
|
||||
[_C-k_/_C-j_]^^ merge above/below [_C-o_]^^ open console
|
||||
[_O_/_o_]^^ insert above/below [_C-s_/_C-r_] save/rename notebook
|
||||
[_y_/_p_/_d_] copy/paste [_x_]^^ close notebook
|
||||
[_u_]^^^^ change type [_q_]^^ quit
|
||||
[_RET_]^^^^ execute
|
||||
"
|
||||
("q" nil :exit t)
|
||||
("h" ein:notebook-worksheet-open-prev-or-last)
|
||||
("j" ein:worksheet-goto-next-input)
|
||||
("k" ein:worksheet-goto-prev-input)
|
||||
("l" ein:notebook-worksheet-open-next-or-first)
|
||||
("H" ein:notebook-worksheet-move-prev)
|
||||
("J" ein:worksheet-move-cell-down)
|
||||
("K" ein:worksheet-move-cell-up)
|
||||
("L" ein:notebook-worksheet-move-next)
|
||||
("t" ein:worksheet-toggle-output)
|
||||
("d" ein:worksheet-kill-cell)
|
||||
("R" ein:worksheet-rename-sheet)
|
||||
("y" ein:worksheet-copy-cell)
|
||||
("p" ein:worksheet-yank-cell)
|
||||
("o" ein:worksheet-insert-cell-below)
|
||||
("O" ein:worksheet-insert-cell-above)
|
||||
("u" ein:worksheet-change-cell-type)
|
||||
("RET" ein:worksheet-execute-cell-and-goto-next)
|
||||
;; Output
|
||||
("C-l" ein:worksheet-clear-output)
|
||||
("C-S-l" ein:worksheet-clear-all-output)
|
||||
;;Console
|
||||
("C-o" ein:console-open :exit t)
|
||||
;; Merge and split cells
|
||||
("C-k" ein:worksheet-merge-cell)
|
||||
("C-j" spacemacs/ein:worksheet-merge-cell-next)
|
||||
("s" ein:worksheet-split-cell-at-point)
|
||||
;; Notebook
|
||||
("C-s" ein:notebook-save-notebook-command)
|
||||
("C-r" ein:notebook-rename-command)
|
||||
("x" ein:notebook-close :exit t))
|
||||
|
|
|
@ -40,49 +40,4 @@
|
|||
|
||||
;; Ace-link on notebook list buffers
|
||||
(after! ein-notebooklist
|
||||
(define-key ein:notebooklist-mode-map "o" #'+ein/ace-link-ein))
|
||||
|
||||
;; add hydra
|
||||
(defhydra +ein/hydra (:hint t :color red)
|
||||
"
|
||||
Operations on Cells^^^^^^ Other
|
||||
----------------------------^^^^^^ ----------------------------------^^^^
|
||||
[_k_/_j_]^^ select prev/next [_t_]^^ toggle output
|
||||
[_K_/_J_]^^ move up/down [_C-l_/_C-S-l_] clear/clear all output
|
||||
[_C-k_/_C-j_]^^ merge above/below [_C-o_]^^ open console
|
||||
[_O_/_o_]^^ insert above/below [_C-s_/_C-r_] save/rename notebook
|
||||
[_y_/_p_/_d_] copy/paste [_x_]^^ close notebook
|
||||
[_u_]^^^^ change type [_q_]^^ quit
|
||||
[_RET_]^^^^ execute
|
||||
"
|
||||
("q" nil :exit t)
|
||||
("h" ein:notebook-worksheet-open-prev-or-last)
|
||||
("j" ein:worksheet-goto-next-input)
|
||||
("k" ein:worksheet-goto-prev-input)
|
||||
("l" ein:notebook-worksheet-open-next-or-first)
|
||||
("H" ein:notebook-worksheet-move-prev)
|
||||
("J" ein:worksheet-move-cell-down)
|
||||
("K" ein:worksheet-move-cell-up)
|
||||
("L" ein:notebook-worksheet-move-next)
|
||||
("t" ein:worksheet-toggle-output)
|
||||
("d" ein:worksheet-kill-cell)
|
||||
("R" ein:worksheet-rename-sheet)
|
||||
("y" ein:worksheet-copy-cell)
|
||||
("p" ein:worksheet-yank-cell)
|
||||
("o" ein:worksheet-insert-cell-below)
|
||||
("O" ein:worksheet-insert-cell-above)
|
||||
("u" ein:worksheet-change-cell-type)
|
||||
("RET" ein:worksheet-execute-cell-and-goto-next)
|
||||
;; Output
|
||||
("C-l" ein:worksheet-clear-output)
|
||||
("C-S-l" ein:worksheet-clear-all-output)
|
||||
;;Console
|
||||
("C-o" ein:console-open :exit t)
|
||||
;; Merge and split cells
|
||||
("C-k" ein:worksheet-merge-cell)
|
||||
("C-j" spacemacs/ein:worksheet-merge-cell-next)
|
||||
("s" ein:worksheet-split-cell-at-point)
|
||||
;; Notebook
|
||||
("C-s" ein:notebook-save-notebook-command)
|
||||
("C-r" ein:notebook-rename-command)
|
||||
("x" ein:notebook-close :exit t)))
|
||||
(define-key ein:notebooklist-mode-map "o" #'+ein/ace-link-ein)))
|
||||
|
|
|
@ -64,6 +64,7 @@ search of your username. May prompt for your gpg passphrase."
|
|||
;; Commands
|
||||
;;
|
||||
|
||||
;;;###autoload (autoload 'password-store-dir "password-store")
|
||||
;;;###autoload (autoload 'password-store-list "password-store")
|
||||
;;;###autoload (autoload 'password-store--completing-read "password-store")
|
||||
|
||||
|
@ -113,6 +114,7 @@ fields in `+pass-url-fields' is used to find the url field."
|
|||
;; Ivy interface
|
||||
;;
|
||||
|
||||
;;;###autoload
|
||||
(defun +pass/ivy (arg)
|
||||
"TODO"
|
||||
(interactive "P")
|
||||
|
|
|
@ -34,7 +34,7 @@
|
|||
"k" #'pass-prev-entry
|
||||
"d" #'pass-kill
|
||||
"\C-j" #'pass-next-directory
|
||||
"\C-k" #'pass-next-directory))
|
||||
"\C-k" #'pass-prev-directory))
|
||||
|
||||
|
||||
;; Is built into Emacs 26+
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
;;; tools/prodigy/autoload.el -*- lexical-binding: t; -*-
|
||||
|
||||
;; FIXME obsolete :service
|
||||
;;;###autoload
|
||||
(def-setting! :service (&rest plist)
|
||||
"TODO"
|
||||
|
|
13
modules/tools/rgb/autoload.el
Normal file
13
modules/tools/rgb/autoload.el
Normal file
|
@ -0,0 +1,13 @@
|
|||
;;; tools/rgb/autoload.el -*- lexical-binding: t; -*-
|
||||
|
||||
;;;###autoload (autoload '+rgb-kurecolor-hydra/body "tools/rgb/autoload" nil nil)
|
||||
(defhydra +rgb-kurecolor-hydra (:color pink :hint nil)
|
||||
"
|
||||
Inc/Dec _w_/_W_ brightness _d_/_D_ saturation _e_/_E_ hue "
|
||||
("w" kurecolor-decrease-brightness-by-step)
|
||||
("W" kurecolor-increase-brightness-by-step)
|
||||
("d" kurecolor-decrease-saturation-by-step)
|
||||
("D" kurecolor-increase-saturation-by-step)
|
||||
("e" kurecolor-decrease-hue-by-step)
|
||||
("E" kurecolor-increase-hue-by-step)
|
||||
("q" nil "cancel" :color blue))
|
|
@ -1,19 +0,0 @@
|
|||
;;; tools/rgb/config.el -*- lexical-binding: t; -*-
|
||||
|
||||
;;
|
||||
;; Plugins
|
||||
;;
|
||||
|
||||
(def-package! kurecolor
|
||||
:after rainbow-mode
|
||||
:config
|
||||
(defhydra +rgb@kurecolor (:color pink :hint nil)
|
||||
"
|
||||
Inc/Dec _w_/_W_ brightness _d_/_D_ saturation _e_/_E_ hue "
|
||||
("w" kurecolor-decrease-brightness-by-step)
|
||||
("W" kurecolor-increase-brightness-by-step)
|
||||
("d" kurecolor-decrease-saturation-by-step)
|
||||
("D" kurecolor-increase-saturation-by-step)
|
||||
("e" kurecolor-decrease-hue-by-step)
|
||||
("E" kurecolor-increase-hue-by-step)
|
||||
("q" nil "cancel" :color blue)))
|
|
@ -1,17 +1,62 @@
|
|||
;;; tools/wakatime/autoload.el -*- lexical-binding: t; -*-
|
||||
|
||||
;;;###autoload
|
||||
(add-hook 'doom-after-switch-buffer-hook #'+wakatime|autostart)
|
||||
(defvar +wakatime-api-file (concat doom-cache-dir "wakatime.el")
|
||||
"Where the wakatime api key is cached.")
|
||||
|
||||
(defvar +wakatime-hide-filenames nil
|
||||
"If non-nil, obfuscate files and only show what projects you're working on.")
|
||||
|
||||
;;;###autoload
|
||||
(defalias '+wakatime/start '+wakatime|autostart)
|
||||
(add-hook 'doom-post-init-hook #'+wakatime|delayed-autostart)
|
||||
|
||||
;;;###autoload
|
||||
(defun +wakatime|autostart ()
|
||||
(defun +wakatime/setup ()
|
||||
"Setup Wakatime in Emacs and start `global-wakatime-mode'.
|
||||
|
||||
This will prompt you for your api key. You only need to run this when your api
|
||||
changes."
|
||||
(interactive)
|
||||
(when (y-or-n-p "No API key is registered. Open a browser on the wakatime api key page?")
|
||||
(browse-url "https://wakatime.com/settings/api-key"))
|
||||
(let ((api-key (read-string "Enter your wakatime API key: ")))
|
||||
(unless api-key
|
||||
(user-error "No api key was received."))
|
||||
(setq wakatime-api-key api-key)
|
||||
(with-temp-file +wakatime-api-file
|
||||
(prin1 `(setq wakatime-api-key ,wakatime-api-key)
|
||||
(current-buffer)))
|
||||
(require 'wakatime-mode)
|
||||
(unless (or (and wakatime-cli-path (file-executable-p wakatime-cli-path))
|
||||
(not (equal (wakatime-find-binary "wakatime") "wakatime")))
|
||||
(user-error "Couldn't find wakatime executable (%s)"
|
||||
(or wakatime-cli-path "wakatime")))
|
||||
(global-wakatime-mode +1)
|
||||
(message "Wakatime enabled. You're good to go!")))
|
||||
|
||||
;;;###autoload
|
||||
(defun +wakatime|autostart (&rest _)
|
||||
"Initialize wakatime (if `wakatime-api-key' is set, otherwise no-op with a
|
||||
warning)."
|
||||
(interactive)
|
||||
(if (boundp 'wakatime-api-key)
|
||||
(unless (bound-and-true-p wakatime-api-key)
|
||||
(ignore-errors (load +wakatime-api-file t t)))
|
||||
(if (bound-and-true-p wakatime-api-key)
|
||||
(global-wakatime-mode +1)
|
||||
(message "No `wakatime-api-key' set! wakaktime-mode will stay disabled."))
|
||||
(remove-hook 'doom-after-switch-buffer-hook #'+wakatime-init))
|
||||
(message "wakatime-mode isn't set up. Run `M-x +wakatime/start' to do so."))
|
||||
;;
|
||||
(remove-hook 'doom-before-switch-buffer-hook #'+wakatime|autostart)
|
||||
(advice-remove 'after-find-file #'+wakatime|autostart))
|
||||
|
||||
;;;###autoload
|
||||
(defun +wakatime|delayed-autostart (&rest _)
|
||||
"Lazily initialize `wakatime-mode' until the next time you switch buffers or
|
||||
open a file."
|
||||
(add-hook 'doom-before-switch-buffer-hook #'+wakatime|autostart)
|
||||
;; this is necessary in case the user opens emacs with file arguments
|
||||
(advice-add 'after-find-file :before #'+wakatime|autostart))
|
||||
|
||||
(defun +wakatime*append-hide-filenames-option (ret)
|
||||
"Enables filename obfuscation in wakatime if `+wakatime-hide-filenames' is
|
||||
non-nil."
|
||||
(concat ret (if +wakatime-hide-filenames " --hide-filenames")))
|
||||
(advice-add #'wakatime-client-command :filter-return #'+wakatime*append-hide-filenames-option )
|
||||
|
|
|
@ -234,10 +234,7 @@ instead of switch-to-buffer-*."
|
|||
(defun +popup*org-pop-to-buffer (orig-fn buf &optional norecord)
|
||||
"Use `pop-to-buffer' instead of `switch-to-buffer' to open buffer.'"
|
||||
(if +popup-mode
|
||||
(pop-to-buffer
|
||||
(cond ((stringp buf) (get-buffer-create buf))
|
||||
((bufferp buf) buf)
|
||||
(t (error "Invalid buffer %s" buf))))
|
||||
(pop-to-buffer buf nil norecord)
|
||||
(funcall orig-fn buf norecord)))
|
||||
(advice-add #'org-switch-to-buffer-other-window :around #'+popup*org-pop-to-buffer)
|
||||
|
||||
|
|
|
@ -33,6 +33,7 @@ the buffer is visible, then set another timer and try again later."
|
|||
default window parameters for popup windows, clears leftover transient timers
|
||||
and enables `+popup-buffer-mode'."
|
||||
(with-selected-window window
|
||||
(setq alist (delq (assq 'actions alist) alist))
|
||||
(when (and alist +popup--populate-wparams)
|
||||
;; Emacs 26+ will automatically map the window-parameters alist entry to
|
||||
;; the popup window, so we need this for Emacs 25.x users
|
||||
|
@ -58,58 +59,63 @@ and enables `+popup-buffer-mode'."
|
|||
`transient' window parameter (see `+popup-window-parameters').
|
||||
+ And finally deletes the window!"
|
||||
(let ((buffer (window-buffer window))
|
||||
(inhibit-quit t)
|
||||
ttl)
|
||||
(when (and (buffer-file-name buffer)
|
||||
(buffer-modified-p buffer)
|
||||
(or (+popup-parameter-fn 'autosave window buffer)
|
||||
(y-or-n-p "Popup buffer is modified. Save it?")))
|
||||
(with-current-buffer buffer (save-buffer)))
|
||||
(set-buffer-modified-p nil)
|
||||
(inhibit-quit t))
|
||||
(and (buffer-file-name buffer)
|
||||
(buffer-modified-p buffer)
|
||||
(let ((autosave (+popup-parameter 'autosave window)))
|
||||
(cond ((eq autosave 't))
|
||||
((null autosave)
|
||||
(y-or-n-p "Popup buffer is modified. Save it?"))
|
||||
((functionp autosave)
|
||||
(funcall autosave buffer))))
|
||||
(with-current-buffer buffer (save-buffer)))
|
||||
(let ((ignore-window-parameters t))
|
||||
(delete-window window))
|
||||
(if-let* ((wconf (window-parameter window 'saved-wconf)))
|
||||
(set-window-configuration wconf)
|
||||
(delete-window window)))
|
||||
(unless (window-live-p window)
|
||||
(with-current-buffer buffer
|
||||
(set-buffer-modified-p nil)
|
||||
(+popup-buffer-mode -1)
|
||||
;; t = default
|
||||
;; integer = ttl
|
||||
;; nil = no timer
|
||||
(unless +popup--inhibit-transient
|
||||
(setq ttl (+popup-parameter-fn 'ttl window buffer))
|
||||
(when ttl
|
||||
(when (eq ttl t)
|
||||
(setq ttl (or (plist-get +popup-defaults :ttl)
|
||||
0)))
|
||||
(cl-assert (integerp ttl) t)
|
||||
(if (= ttl 0)
|
||||
(+popup--kill-buffer buffer 0)
|
||||
(add-hook 'kill-buffer-hook #'+popup|kill-buffer-hook nil t)
|
||||
(setq +popup--timer
|
||||
(run-at-time ttl nil #'+popup--kill-buffer
|
||||
buffer ttl)))))))))
|
||||
(let ((ttl (+popup-parameter 'ttl window)))
|
||||
(when (eq ttl 't)
|
||||
(setq ttl (plist-get +popup-defaults :ttl)))
|
||||
(cond ((null ttl))
|
||||
((functionp ttl)
|
||||
(funcall ttl buffer))
|
||||
((not (integerp ttl))
|
||||
(signal 'wrong-type-argument (list 'integerp ttl)))
|
||||
((= ttl 0)
|
||||
(+popup--kill-buffer buffer 0))
|
||||
((add-hook 'kill-buffer-hook #'+popup|kill-buffer-hook nil t))
|
||||
((setq +popup--timer
|
||||
(run-at-time ttl nil #'+popup--kill-buffer
|
||||
buffer ttl))))))))))
|
||||
|
||||
(defun +popup--normalize-alist (alist)
|
||||
"Merge `+popup-default-alist' and `+popup-default-parameters' with ALIST."
|
||||
(let ((alist ; handle defaults
|
||||
(cl-remove-duplicates
|
||||
(append alist +popup-default-alist)
|
||||
:key #'car :from-end t))
|
||||
(parameters
|
||||
(cl-remove-duplicates
|
||||
(append (cdr (assq 'window-parameters alist))
|
||||
+popup-default-parameters)
|
||||
:key #'car :from-end t)))
|
||||
;; handle `size'
|
||||
(when-let* ((size (cdr (assq 'size alist)))
|
||||
(side (or (cdr (assq 'side alist)) 'bottom))
|
||||
(param (if (memq side '(left right))
|
||||
'window-width
|
||||
'window-height)))
|
||||
(setq alist (map-delete alist 'size))
|
||||
(map-put alist param size))
|
||||
(setcdr (assq 'window-parameters alist)
|
||||
(cl-remove-if #'null parameters :key #'cdr))
|
||||
(cl-remove-if #'null alist :key #'cdr)))
|
||||
(when alist
|
||||
(let ((alist ; handle defaults
|
||||
(cl-remove-duplicates
|
||||
(append alist +popup-default-alist)
|
||||
:key #'car :from-end t))
|
||||
(parameters
|
||||
(cl-remove-duplicates
|
||||
(append (cdr (assq 'window-parameters alist))
|
||||
+popup-default-parameters)
|
||||
:key #'car :from-end t)))
|
||||
;; handle `size'
|
||||
(when-let* ((size (cdr (assq 'size alist)))
|
||||
(side (or (cdr (assq 'side alist)) 'bottom))
|
||||
(param (if (memq side '(left right))
|
||||
'window-width
|
||||
'window-height)))
|
||||
(setq list (assq-delete-all 'size alist))
|
||||
(setcdr (assq param alist) size))
|
||||
(setcdr (assq 'window-parameters alist)
|
||||
parameters)
|
||||
alist)))
|
||||
|
||||
|
||||
;;
|
||||
|
@ -120,23 +126,21 @@ and enables `+popup-buffer-mode'."
|
|||
(defun +popup-buffer-p (&optional buffer)
|
||||
"Return non-nil if BUFFER is a popup buffer. Defaults to the current buffer."
|
||||
(when +popup-mode
|
||||
(unless buffer
|
||||
(setq buffer (current-buffer)))
|
||||
(cl-assert (bufferp buffer) t)
|
||||
(and (buffer-live-p buffer)
|
||||
(buffer-local-value '+popup-buffer-mode buffer)
|
||||
buffer)))
|
||||
(let ((buffer (or buffer (current-buffer))))
|
||||
(and (bufferp buffer)
|
||||
(buffer-live-p buffer)
|
||||
(buffer-local-value '+popup-buffer-mode buffer)
|
||||
buffer))))
|
||||
|
||||
;;;###autoload
|
||||
(defun +popup-window-p (&optional window)
|
||||
"Return non-nil if WINDOW is a popup window. Defaults to the current window."
|
||||
(when +popup-mode
|
||||
(unless window
|
||||
(setq window (selected-window)))
|
||||
(cl-assert (windowp window) t)
|
||||
(and (window-live-p window)
|
||||
(window-parameter window 'popup)
|
||||
window)))
|
||||
(let ((window (or window (selected-window))))
|
||||
(and (windowp window)
|
||||
(window-live-p window)
|
||||
(window-parameter window 'popup)
|
||||
window))))
|
||||
|
||||
;;;###autoload
|
||||
(defun +popup-buffer (buffer &optional alist)
|
||||
|
@ -216,11 +220,14 @@ restoring it if `+popup-buffer-mode' is disabled."
|
|||
+ If a function, it takes the current buffer as its argument and must return one
|
||||
of the above values."
|
||||
(when (bound-and-true-p +popup-buffer-mode)
|
||||
(let ((modeline (+popup-parameter-fn 'modeline nil (current-buffer))))
|
||||
(let ((modeline (+popup-parameter 'modeline)))
|
||||
(cond ((eq modeline 't))
|
||||
((or (eq modeline 'nil)
|
||||
(null modeline))
|
||||
;; TODO use `mode-line-format' window parameter instead (emacs 26+)
|
||||
(hide-mode-line-mode +1))
|
||||
((functionp modeline)
|
||||
(funcall modeline))
|
||||
((symbolp modeline)
|
||||
(when-let* ((hide-mode-line-format (doom-modeline modeline)))
|
||||
(hide-mode-line-mode +1)))))))
|
||||
|
@ -246,9 +253,9 @@ restoring it if `+popup-buffer-mode' is disabled."
|
|||
(defun +popup|cleanup-rules ()
|
||||
"Cleans up any duplicate popup rules."
|
||||
(interactive)
|
||||
(cl-delete-duplicates
|
||||
+popup--display-buffer-alist
|
||||
:key #'car :test #'equal :from-end t)
|
||||
(setq +popup--display-buffer-alist
|
||||
(cl-delete-duplicates +popup--display-buffer-alist
|
||||
:key #'car :test #'equal :from-end t))
|
||||
(when +popup-mode
|
||||
(setq display-buffer-alist +popup--display-buffer-alist)))
|
||||
|
||||
|
@ -291,16 +298,15 @@ This will do nothing if the popup's `quit' window parameter is either nil or
|
|||
(interactive
|
||||
(list (selected-window)
|
||||
current-prefix-arg))
|
||||
(unless window
|
||||
(setq window (selected-window)))
|
||||
(when (and (+popup-window-p window)
|
||||
(or force-p
|
||||
(memq (+popup-parameter-fn 'quit window window)
|
||||
'(t current))))
|
||||
(when +popup--remember-last
|
||||
(+popup--remember (list window)))
|
||||
(delete-window window)
|
||||
t))
|
||||
(let ((window (or window (selected-window))))
|
||||
(when (and (+popup-window-p window)
|
||||
(or force-p
|
||||
(memq (+popup-parameter-fn 'quit window window)
|
||||
'(t current))))
|
||||
(when +popup--remember-last
|
||||
(+popup--remember (list window)))
|
||||
(delete-window window)
|
||||
t)))
|
||||
|
||||
;;;###autoload
|
||||
(defun +popup/close-all (&optional force-p)
|
||||
|
@ -372,6 +378,19 @@ the message buffer in a popup window."
|
|||
prevent the popup(s) from messing up the UI (or vice versa)."
|
||||
(save-popups! (apply orig-fn args)))
|
||||
|
||||
;;;###autoload
|
||||
(defun +popup-display-buffer-fullframe (buffer alist)
|
||||
"Displays the buffer fullscreen."
|
||||
(let ((wconf (current-window-configuration)))
|
||||
(when-let (window (or (display-buffer-reuse-window buffer alist)
|
||||
(display-buffer-same-window buffer alist)
|
||||
(display-buffer-pop-up-window buffer alist)
|
||||
(display-buffer-use-some-window buffer alist)))
|
||||
(set-window-parameter window 'saved-wconf wconf)
|
||||
(add-to-list 'window-persistent-parameters '(saved-wconf . t))
|
||||
(delete-other-windows window)
|
||||
window)))
|
||||
|
||||
;;;###autoload
|
||||
(defun +popup-display-buffer-stacked-side-window (buffer alist)
|
||||
"A `display-buffer' action that serves as an alternative to
|
||||
|
@ -426,7 +445,7 @@ Accepts the same arguments as `display-buffer-in-side-window'. You must set
|
|||
(lambda (_side) (frame-root-window (selected-frame)))))
|
||||
(when-let* ((window (window--make-major-side-window buffer side slot alist)))
|
||||
(set-window-parameter window 'window-vslot vslot)
|
||||
(map-put window-persistent-parameters 'window-vslot 'writable)
|
||||
(add-to-list 'window-persistent-parameters '(window-vslot . writable))
|
||||
window)))
|
||||
(t
|
||||
;; Scan windows on SIDE.
|
||||
|
@ -570,11 +589,11 @@ and may be called only if no window on SIDE exists yet."
|
|||
;; Initialize `window-side' parameter of new window to SIDE and
|
||||
;; make that parameter persistent.
|
||||
(set-window-parameter window 'window-side side)
|
||||
(map-put window-persistent-parameters 'window-side 'writable)
|
||||
(add-to-list 'window-persistent-parameters '(window-side . writable))
|
||||
;; Install `window-slot' parameter of new window and make that
|
||||
;; parameter persistent.
|
||||
(set-window-parameter window 'window-slot slot)
|
||||
(map-put window-persistent-parameters 'window-slot 'writable)
|
||||
(add-to-list 'window-persistent-parameters '(window-slot . writable))
|
||||
;; Auto-adjust height/width of new window unless a size has been
|
||||
;; explicitly requested.
|
||||
(unless (if left-or-right
|
||||
|
|
|
@ -10,11 +10,11 @@
|
|||
:quit t
|
||||
:select #'ignore
|
||||
:ttl 5)
|
||||
"Default setup for `set-popup-rule!' ")
|
||||
"Default properties for popup rules defined with `set-popup-rule!'.")
|
||||
|
||||
;;;###autoload
|
||||
(defun +popup--make (predicate plist)
|
||||
(cond ((not (keywordp (car plist)))
|
||||
(cond ((and plist (not (keywordp (car plist))))
|
||||
;; FIXME deprecated popup rule support
|
||||
(message "Warning: the old usage of `set-popup-rule!' is deprecated; update the rule for '%s'"
|
||||
predicate)
|
||||
|
@ -51,14 +51,13 @@
|
|||
(defun set-popup-rule! (predicate &rest plist)
|
||||
"Define a popup rule.
|
||||
|
||||
Buffers displayed by `pop-to-buffer' and `display-buffer' (or their siblings)
|
||||
will be tested against PREDICATE, which is either a) a regexp string (which is
|
||||
matched against the buffer's name) or b) a function that takes no arguments and
|
||||
returns a boolean.
|
||||
These rules affect buffers displayed with `pop-to-buffer' and `display-buffer'
|
||||
(or their siblings). Buffers displayed with `switch-to-buffer' (and its
|
||||
variants) will not be affected by these rules (as they are unaffected by
|
||||
`display-buffer-alist', which powers the popup management system).
|
||||
|
||||
Buffers displayed with `switch-to-buffer' and its variants will not be affected
|
||||
by these rules (as they are unaffected by `display-buffer-alist', which powers
|
||||
the popup management system).
|
||||
PREDICATE can be either a) a regexp string (matched against the buffer's name)
|
||||
or b) a function that takes no arguments and returns a boolean.
|
||||
|
||||
PLIST can be made up of any of the following properties:
|
||||
|
||||
|
@ -72,83 +71,93 @@ PLIST can be made up of any of the following properties:
|
|||
`+popup-display-buffer-stacked-side-window' or `display-buffer-in-side-window'
|
||||
is in :actions or `+popup-default-display-buffer-actions'.
|
||||
|
||||
:size/:width/:height FLOAT|INT
|
||||
Determines the size of the popup. If opened at the top or bottom, the width is
|
||||
irrelevant unless it is opened in an adjacent slot. Same deal with the left
|
||||
and right side.
|
||||
:size/:width/:height FLOAT|INT|FN
|
||||
Determines the size of the popup. If more tha one of these size properties are
|
||||
given :size always takes precedence, and is mapped with window-width or
|
||||
window-height depending on what :side the popup is opened. Setting a height
|
||||
for a popup that opens on the left or right is harmless, but comes into play
|
||||
if two popups occupy the same :vslot.
|
||||
|
||||
If given a FLOAT (0 < x < 1), the number represents how much of the window
|
||||
will be consumed by the popup (a percentage).
|
||||
If given an INT, the number determines the size in lines (height) or units of
|
||||
If a FLOAT (0 < x < 1), the number represents how much of the window will be
|
||||
consumed by the popup (a percentage).
|
||||
If an INT, the number determines the size in lines (height) or units of
|
||||
character width (width).
|
||||
If a function, it takes one argument: the popup window, and can do whatever it
|
||||
wants with it, typically resize it, like `+popup-shrink-to-fit'.
|
||||
|
||||
:slot/:vslot INT
|
||||
This only applies to popups with a :side. For popups opened at the top or
|
||||
bottom, slot designates the horizontal positioning of a popup. If two popups
|
||||
are assigned the same slot (and same vslot), the later popup will replace the
|
||||
earlier one. If the later popup has a lower slot, it will open to the older
|
||||
popup's left. A higher slot opens it to the old popup's right.
|
||||
(This only applies to popups with a :side and only if :actions is blank or
|
||||
contains the `+popup-display-buffer-stacked-side-window' action) These control
|
||||
how multiple popups are laid out. INT can be any integer, positive and
|
||||
negative.
|
||||
|
||||
On the other hand, vslot operates the same way, but controls how popups are
|
||||
stacked.
|
||||
:slot controls lateral positioning (e.g. the horizontal positioning for
|
||||
top/bottom popups, or vertical positioning for left/right popups).
|
||||
:vslot controls popup stacking (from the edge of the frame toward the center).
|
||||
|
||||
When a popup is opened on the left and right, slot determines vertical
|
||||
position and vslot horizontal.
|
||||
Let's assume popup A and B are opened with :side 'bottom, in that order.
|
||||
If they possess the same :slot and :vslot, popup B will replace popup A.
|
||||
If popup B has a higher :slot, it will open to the right of popup A.
|
||||
If popup B has a lower :slot, it will open to the left of popup A.
|
||||
If popup B has a higher :vslot, it will open above popup A.
|
||||
If popup B has a lower :vslot, it will open below popup A.
|
||||
|
||||
:ttl INT|BOOL|FN
|
||||
Stands for time-to-live. CDR can be t, an integer, nil or a function that
|
||||
returns one of these. It represents the number of seconds before the buffer
|
||||
belonging to a closed popup window is killed.
|
||||
Stands for time-to-live. It can be t, an integer, nil or a function. This
|
||||
controls how (and if) the popup system will clean up after the popup.
|
||||
|
||||
If t, CDR will default to `+popup-ttl'.
|
||||
If any non-zero integer, wait that many seconds before killing the buffer (and
|
||||
any associated processes).
|
||||
If 0, the buffer is immediately killed.
|
||||
If nil, the buffer won't be killed.
|
||||
If a function, it must return one of the other possible values above. It takes
|
||||
the popup buffer as its sole argument.
|
||||
If nil, the buffer won't be killed and is left to its own devices.
|
||||
If t, resort to the default :ttl in `+popup-defaults'. If none exists, this is
|
||||
the same as nil.
|
||||
If a function, it takes one argument: the target popup buffer. The popup
|
||||
system does nothing else and ignores the function's return value.
|
||||
|
||||
:quit BOOL|FN
|
||||
CDR can be t, 'other, 'current, nil, or a function that returns one of these.
|
||||
This determines the behavior of the ESC/C-g keys in or outside of popup
|
||||
windows.
|
||||
:quit FN|BOOL|'other|'current
|
||||
Can be t, 'other, 'current, nil, or a function. This determines the behavior
|
||||
of the ESC/C-g keys in or outside of popup windows.
|
||||
|
||||
If t, close the popup if ESC/C-g is pressed inside or outside of popups.
|
||||
If t, close the popup if ESC/C-g is pressed anywhere.
|
||||
If 'other, close this popup if ESC/C-g is pressed outside of any popup. This
|
||||
is great for popups you just want to peek at and discard, but might also
|
||||
want to poke around in, without the risk of closing it from the inside.
|
||||
is great for popups you may press ESC/C-g a lot in.
|
||||
If 'current, close the current popup if ESC/C-g is pressed from inside of the
|
||||
popup.
|
||||
If nil, pressing ESC/C-g will never close this buffer.
|
||||
If a function, it is checked each time ESC/C-g is pressed to determine the
|
||||
fate of the popup window. This function takes one argument: the popup window
|
||||
and must return one of the other possible values.
|
||||
popup. This makes it harder to accidentally close a popup until you really
|
||||
want to.
|
||||
If nil, pressing ESC/C-g will never close this popup.
|
||||
If a function, it takes one argument: the to-be-closed popup window, and is
|
||||
run when ESC/C-g is pressed while that popup is open. It must return one of
|
||||
the other values to determine the fate of the popup.
|
||||
|
||||
:select BOOL|FN
|
||||
CDR can be a boolean or function. The boolean determines whether to focus the
|
||||
Can be a boolean or function. The boolean determines whether to focus the
|
||||
popup window after it opens (non-nil) or focus the origin window (nil).
|
||||
|
||||
If a function, it takes two arguments: the popup window and the source window
|
||||
(where you were before the popup was opened). It does nothing else, and
|
||||
ignores its return value.
|
||||
If a function, it takes two arguments: the popup window and originating window
|
||||
(where you were before the popup opened). The popup system does nothing else
|
||||
and ignores the function's return value.
|
||||
|
||||
:modeline BOOL|SYMBOL|FN
|
||||
CDR can be t (show the default modeline), a symbol representing the name of a
|
||||
Can be t (show the default modeline), a symbol representing the name of a
|
||||
modeline defined with `def-modeline!', nil (show no modeline) or a function
|
||||
that returns one of these. The function takes one argument: the popup buffer.
|
||||
that returns a modeline format. The function takes no arguments and is run in
|
||||
the context of the popup buffer.
|
||||
|
||||
:autosave BOOL|FN
|
||||
This parameter determines what to do with modified buffers in closing popup
|
||||
windows. CDR can be a t, 'ignore, a function or nil.
|
||||
This parameter determines what to do with modified buffers when closing popup
|
||||
windows. It accepts t, 'ignore, a function or nil.
|
||||
|
||||
If t, no prompts. Just save them automatically (if they're file-visiting
|
||||
buffers).
|
||||
If 'ignore, no prompts, no saving. Just silently kill it.
|
||||
buffers). Same as 'ignore for non-file-visiting buffers.
|
||||
If nil (the default), prompt the user what to do if the buffer is
|
||||
file-visiting and modified.
|
||||
If a function, the return value must return one of the other values. It takes
|
||||
two arguments: the popup window and buffer.
|
||||
If 'ignore, no prompts, no saving. Just silently kill it.
|
||||
If a function, it is run with one argument: the popup buffer, and must return
|
||||
non-nil to save or nil to do nothing (but no prompts).
|
||||
|
||||
:parameters ALIST
|
||||
An alist of custom window parameters. See \(info window-parameters)
|
||||
An alist of custom window parameters. See `(elisp)Window Parameters'.
|
||||
|
||||
If any of these are omitted, defaults derived from `+popup-defaults' will be
|
||||
used."
|
||||
|
@ -160,9 +169,11 @@ used."
|
|||
|
||||
;;;###autodef
|
||||
(defun set-popup-rules! (&rest rulesets)
|
||||
"Like `set-popup-rules!', but defines multiple popup rules. Every entry in RULESETS
|
||||
should be a list of lists (each sublist is a popup rule that could be passed to
|
||||
`set-popup-rule!').
|
||||
"Defines multiple popup rules.
|
||||
|
||||
Every entry in RULESETS should be a list of alists where the CAR is the
|
||||
predicate and CDR is a plist. See `set-popup-rule!' for details on the predicate
|
||||
and plist.
|
||||
|
||||
Example:
|
||||
|
||||
|
|
|
@ -70,8 +70,8 @@ adjustment.")
|
|||
window--sides-inhibit-check nil)
|
||||
(+popup|cleanup-rules)
|
||||
(dolist (prop +popup-window-parameters)
|
||||
(setq window-persistent-parameters
|
||||
(map-delete window-persistent-parameters prop))))))
|
||||
(delq (assq prop window-persistent-parameters)
|
||||
window-persistent-parameters)))))
|
||||
|
||||
(define-minor-mode +popup-buffer-mode
|
||||
"Minor mode for individual popup windows.
|
||||
|
@ -103,7 +103,7 @@ should match the arguments of `+popup-define' or the :popup setting."
|
|||
(declare (indent defun))
|
||||
`(let ((+popup--display-buffer-alist +popup--old-display-buffer-alist)
|
||||
display-buffer-alist)
|
||||
(set-popup-rules! ,@rules)
|
||||
(set-popup-rules! ,rules)
|
||||
(when (bound-and-true-p +popup-mode)
|
||||
(setq display-buffer-alist +popup--display-buffer-alist))
|
||||
,@body))
|
||||
|
|
212
modules/ui/popup/test/test-popup.el
Normal file
212
modules/ui/popup/test/test-popup.el
Normal file
|
@ -0,0 +1,212 @@
|
|||
;; -*- no-byte-compile: t; -*-
|
||||
;;; ui/popup/test/test-popup.el
|
||||
|
||||
(describe "ui/popup"
|
||||
:var (display-buffer-alist
|
||||
+popup-default-display-buffer-actions
|
||||
+popup--display-buffer-alist
|
||||
+popup-defaults
|
||||
wconf)
|
||||
|
||||
(before-all
|
||||
(require! :ui popup)
|
||||
(delete-other-windows)
|
||||
(switch-to-buffer "*scratch*")
|
||||
(setq wconf (current-window-configuration))
|
||||
(+popup-mode +1))
|
||||
(after-all
|
||||
(+popup-mode -1))
|
||||
|
||||
(before-each
|
||||
(setq display-buffer-alist nil
|
||||
+popup--display-buffer-alist nil
|
||||
+popup-default-display-buffer-actions '(+popup-display-buffer-stacked-side-window)
|
||||
+popup-defaults '(:side bottom :select ignore :ttl nil :slot 1 :vslot 1)))
|
||||
(after-each
|
||||
(set-window-configuration wconf))
|
||||
|
||||
(describe "set-popup-rule!"
|
||||
(it "sets popup rules"
|
||||
(set-popup-rule! "does-not-exist" :size 10)
|
||||
(let ((rule (cdr (assoc "does-not-exist" display-buffer-alist))))
|
||||
(expect rule :to-contain '(+popup-buffer))
|
||||
(expect rule :to-contain '(size . 10))))
|
||||
(it "shadows old rules"
|
||||
(set-popup-rule! "a" :size 10)
|
||||
(set-popup-rule! "a" :size 20)
|
||||
(expect (cdr (assoc "a" display-buffer-alist))
|
||||
:to-contain '(size . 20)))
|
||||
(it "resolves to defaults"
|
||||
(let ((+popup-defaults '(:size 5)))
|
||||
(set-popup-rule! "a")
|
||||
(expect (cdr (assoc "a" display-buffer-alist))
|
||||
:to-contain '(size . 5)))))
|
||||
|
||||
(describe "popup rules"
|
||||
:var (origin a b c d e f g)
|
||||
(before-all (setq origin (current-buffer)))
|
||||
(before-each
|
||||
(dolist (name '(a b c d e f g))
|
||||
(set name (get-buffer-create (symbol-name name)))))
|
||||
(after-each
|
||||
(let (kill-buffer-query-functions kill-buffer-hook)
|
||||
(dolist (x (list a b c d e f g))
|
||||
(ignore-errors (delete-window (get-buffer-window x)))
|
||||
(kill-buffer x))))
|
||||
|
||||
(describe "slot positioning"
|
||||
(before-each
|
||||
(set-popup-rules!
|
||||
'(("a" :slot 1 :vslot 1)
|
||||
("b" :slot 2 :vslot 1)
|
||||
("c" :slot 1 :vslot 2)
|
||||
("d" :slot 2 :vslot 2)
|
||||
("e" :slot 1 :vslot 3)
|
||||
("f" :slot 1 :vslot 3)
|
||||
("g"))))
|
||||
|
||||
(it "replaces popups with the same slots"
|
||||
(mapc #'display-buffer (list e f))
|
||||
(expect (length (+popup-windows)) :to-be 1))
|
||||
|
||||
(it "replaces popups among multiple that have the same slots"
|
||||
(let ((first (display-buffer a))
|
||||
(second (display-buffer b))
|
||||
(third (display-buffer e))
|
||||
(fourth (display-buffer f)))
|
||||
(expect (+popup-windows) :to-have-same-items-as
|
||||
(list first second fourth))))
|
||||
|
||||
(describe ":slot"
|
||||
(it "opens left of others if lower"
|
||||
(let ((first (display-buffer b))
|
||||
(second (display-buffer a)))
|
||||
(expect (length (+popup-windows)) :to-be 2)
|
||||
(expect (window-in-direction 'left first t)
|
||||
:to-equal second)))
|
||||
(it "opens right of others if higher"
|
||||
(let ((first (display-buffer a))
|
||||
(second (display-buffer b)))
|
||||
(expect (length (+popup-windows)) :to-be 2)
|
||||
(expect (window-in-direction 'right first t)
|
||||
:to-equal second)))
|
||||
(it "obeys default :slot"
|
||||
(let ((window (display-buffer g)))
|
||||
(expect (window-parameter window 'window-slot) :to-be 1)
|
||||
(expect (window-parameter window 'window-vslot) :to-be 1))))
|
||||
|
||||
(describe ":vslot"
|
||||
;; TODO Implement this, somehow
|
||||
(xit "opens lower :vslot popups above others"
|
||||
(let ((first (display-buffer c))
|
||||
(second (display-buffer a)))
|
||||
(expect (length (+popup-windows)) :to-be 2)
|
||||
(expect (window-in-direction 'above first t)
|
||||
:to-equal second)))
|
||||
(it "opens higher :vslot popups below others"
|
||||
(let ((first (display-buffer c))
|
||||
(second (display-buffer e)))
|
||||
(expect (length (+popup-windows)) :to-be 2)
|
||||
(expect (window-in-direction 'below first t)
|
||||
:to-equal second)))))
|
||||
|
||||
(describe ":select"
|
||||
(it "selects the popup if non-nil"
|
||||
(set-popup-rule! "^a$" :select t)
|
||||
(display-buffer a)
|
||||
(expect (current-buffer) :to-equal a))
|
||||
(it "selects the originating window if nil"
|
||||
(set-popup-rule! "^a$" :select nil)
|
||||
(display-buffer a)
|
||||
(expect (current-buffer) :to-equal origin))
|
||||
(it "fall back to base selection if passed #'ignore"
|
||||
(spy-on 'ignore)
|
||||
(set-popup-rule! "^a$" :select #'ignore)
|
||||
(save-window-excursion
|
||||
(display-buffer a)
|
||||
(expect (current-buffer) :to-equal origin))
|
||||
(save-window-excursion
|
||||
(pop-to-buffer a)
|
||||
(expect (current-buffer) :to-equal a))
|
||||
(expect 'ignore :to-have-been-called-times 2)))
|
||||
|
||||
(describe ":modeline"
|
||||
(it "disables the mode-line if nil"
|
||||
(set-popup-rule! "a" :modeline nil :select t)
|
||||
(display-buffer a)
|
||||
(expect mode-line-format :to-be nil))
|
||||
(it "uses the default mode-line if t"
|
||||
(set-popup-rule! "a" :modeline t :select t)
|
||||
(display-buffer a)
|
||||
(expect mode-line-format :to-equal (default-value 'mode-line-format)))
|
||||
(it "uses a predefined mode-line if passed a symbol"
|
||||
(def-modeline! test-popup-modeline ("x") ())
|
||||
(set-popup-rule! "a" :modeline 'test-popup-modeline :select t)
|
||||
(display-buffer a)
|
||||
(expect mode-line-format :to-equal (doom-modeline 'test-popup-modeline)))
|
||||
(it "runs the handler if passed a function"
|
||||
(set-popup-rule! "a" :modeline (lambda () (setq mode-line-format '("x"))) :select t)
|
||||
(display-buffer a)
|
||||
(expect mode-line-format :to-equal '("x"))))
|
||||
|
||||
;; TODO
|
||||
(xdescribe ":autosave")
|
||||
|
||||
(describe ":quit"
|
||||
(it "will close from anywhere if :quit = t"
|
||||
(set-popup-rule! "a" :quit t)
|
||||
(save-window-excursion
|
||||
(display-buffer a)
|
||||
(call-interactively #'+popup/close-all)
|
||||
(expect (get-buffer-window a) :to-be nil))
|
||||
(save-window-excursion
|
||||
(pop-to-buffer a)
|
||||
(call-interactively #'+popup/close)
|
||||
(expect (get-buffer-window a) :to-be nil)))
|
||||
(it "will only close from outside if :quit = 'other"
|
||||
(set-popup-rule! "a" :quit 'other)
|
||||
(save-window-excursion
|
||||
(display-buffer a)
|
||||
(call-interactively #'+popup/close-all)
|
||||
(expect (get-buffer-window a) :to-be nil))
|
||||
(save-window-excursion
|
||||
(pop-to-buffer a)
|
||||
(call-interactively #'+popup/close)
|
||||
(expect (get-buffer-window a))))
|
||||
(it "will only close from inside if :quit = 'current"
|
||||
(set-popup-rule! "a" :quit 'current)
|
||||
(save-window-excursion
|
||||
(display-buffer a)
|
||||
(call-interactively #'+popup/close-all)
|
||||
(expect (get-buffer-window a)))
|
||||
(save-window-excursion
|
||||
(pop-to-buffer a)
|
||||
(call-interactively #'+popup/close)
|
||||
(expect (get-buffer-window a) :to-be nil)))
|
||||
(it "never close a if :quit = nil"
|
||||
(set-popup-rule! "a" :quit nil)
|
||||
(save-window-excursion
|
||||
(display-buffer a)
|
||||
(call-interactively #'+popup/close-all)
|
||||
(expect (get-buffer-window a)))
|
||||
(save-window-excursion
|
||||
(pop-to-buffer a)
|
||||
(call-interactively #'+popup/close)
|
||||
(expect (get-buffer-window a)))))
|
||||
|
||||
;; TODO
|
||||
(xdescribe ":ttl")
|
||||
(xdescribe ":size")
|
||||
(xdescribe ":width")
|
||||
(xdescribe ":height")
|
||||
(xdescribe ":side")
|
||||
(xdescribe ":actions"))
|
||||
|
||||
;; TODO
|
||||
(xdescribe "predicate functions"
|
||||
(describe "buffer-p")
|
||||
(describe "window-p"))
|
||||
|
||||
;; TODO
|
||||
(xdescribe "save-popups!")
|
||||
(xdescribe "with-popup-rules!"))
|
|
@ -28,6 +28,7 @@ besides what is listed.")
|
|||
:lambda "λ"
|
||||
:def "ƒ"
|
||||
:composition "∘"
|
||||
:map "↦"
|
||||
;; Types
|
||||
:null "∅"
|
||||
:true "𝕋"
|
||||
|
@ -48,7 +49,8 @@ besides what is listed.")
|
|||
:yield "⟻"
|
||||
;; Other
|
||||
:tuple "⨂"
|
||||
:pipe "")
|
||||
:pipe ""
|
||||
:dot "•")
|
||||
"Options plist for `pretty-code-get-pairs'.")
|
||||
|
||||
(defvar +pretty-code--iosevka-ligeratures-enabled nil)
|
||||
|
|
26
modules/ui/vc-gutter/autoload.el
Normal file
26
modules/ui/vc-gutter/autoload.el
Normal file
|
@ -0,0 +1,26 @@
|
|||
;;; ui/vc-gutter/autoload.el -*- lexical-binding: t; -*-
|
||||
|
||||
;;;###autoload (autoload '+vc-gutter-hydra/body "ui/vc-gutter/autoload" nil nil)
|
||||
(defhydra +vc-gutter-hydra
|
||||
(:body-pre (git-gutter-mode 1) :hint nil)
|
||||
"
|
||||
[git gutter]
|
||||
Movement Hunk Actions Misc. +%-4s(car (git-gutter:statistic))/ -%-4s(cdr (git-gutter:statistic))
|
||||
╭──────────────────────────────────┴────────────────╯
|
||||
^_g_^ [_s_] stage [_R_] set start Rev
|
||||
^_k_^ [_r_] revert
|
||||
^↑ ^ [_m_] mark
|
||||
^↓ ^ [_p_] popup ╭─────────────────────
|
||||
^_j_^ │[_q_] quit
|
||||
^_G_^ │[_Q_] Quit and disable"
|
||||
("j" (progn (git-gutter:next-hunk 1) (recenter)))
|
||||
("k" (progn (git-gutter:previous-hunk 1) (recenter)))
|
||||
("g" (progn (goto-char (point-min)) (git-gutter:next-hunk 1)))
|
||||
("G" (progn (goto-char (point-min)) (git-gutter:previous-hunk 1)))
|
||||
("s" git-gutter:stage-hunk)
|
||||
("r" git-gutter:revert-hunk)
|
||||
("m" git-gutter:mark-hunk)
|
||||
("p" git-gutter:popup-hunk)
|
||||
("R" git-gutter:set-start-revision)
|
||||
("q" nil :color blue)
|
||||
("Q" (git-gutter-mode -1) :color blue))
|
|
@ -51,30 +51,6 @@ to the right fringe.")
|
|||
;; update git-gutter when using these commands
|
||||
(add-hook 'magit-post-refresh-hook #'+version-control|update-git-gutter)
|
||||
|
||||
(defhydra +version-control@git-gutter
|
||||
(:body-pre (git-gutter-mode 1) :hint nil)
|
||||
"
|
||||
╭─────────────────┐
|
||||
Movement Hunk Actions Misc. │ gg: +%-4s(car (git-gutter:statistic))/ -%-3s(cdr (git-gutter:statistic)) │
|
||||
╭──────────────────────────────────┴─────────────────╯
|
||||
^_g_^ [_s_] stage [_R_] set start Rev
|
||||
^_k_^ [_r_] revert
|
||||
^↑ ^ [_m_] mark
|
||||
^↓ ^ [_p_] popup ╭──────────────────────
|
||||
^_j_^ │[_q_] quit
|
||||
^_G_^ │[_Q_] Quit and disable"
|
||||
("j" (progn (git-gutter:next-hunk 1) (recenter)))
|
||||
("k" (progn (git-gutter:previous-hunk 1) (recenter)))
|
||||
("g" (progn (goto-char (point-min)) (git-gutter:next-hunk 1)))
|
||||
("G" (progn (goto-char (point-min)) (git-gutter:previous-hunk 1)))
|
||||
("s" git-gutter:stage-hunk)
|
||||
("r" git-gutter:revert-hunk)
|
||||
("m" git-gutter:mark-hunk)
|
||||
("p" git-gutter:popup-hunk)
|
||||
("R" git-gutter:set-start-revision)
|
||||
("q" nil :color blue)
|
||||
("Q" (git-gutter-mode -1) :color blue))
|
||||
|
||||
;; subtle diff indicators in the fringe
|
||||
(when +vc-gutter-default-style
|
||||
;; places the git gutter outside the margins.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue