Add cmd!, cmd!!, cmds! convenience macros
It's kind of silly that our command lambda macros (λ! and λ!!) need a snippet, special key sequence or copy-paste to insert, so in the spirit of fn! -- and to make sure they take up less space than `lambda!` -- I've added `cmd!` and `cmd!!` aliases. `lambda!` and `lambda!!` are now deprecated. λ! and λ!! will remain. I've also added `cmds!` as a convenience wrapper around general-predicate-dispatch.
This commit is contained in:
parent
d4d8c48265
commit
a9bf0b8985
5 changed files with 68 additions and 62 deletions
|
@ -341,10 +341,10 @@ Some items are not supported by the `nsm.el' module."
|
||||||
(delete-file file)
|
(delete-file file)
|
||||||
(signal (car e) (cdr e)))))))
|
(signal (car e) (cdr e)))))))
|
||||||
|
|
||||||
(fset 'doom--run-vanilla-emacs (lambda! (doom--run-sandbox 'vanilla)))
|
(fset 'doom--run-vanilla-emacs (cmd! (doom--run-sandbox 'vanilla)))
|
||||||
(fset 'doom--run-vanilla-doom (lambda! (doom--run-sandbox 'vanilla-doom)))
|
(fset 'doom--run-vanilla-doom (cmd! (doom--run-sandbox 'vanilla-doom)))
|
||||||
(fset 'doom--run-vanilla-doom+ (lambda! (doom--run-sandbox 'vanilla-doom+)))
|
(fset 'doom--run-vanilla-doom+ (cmd! (doom--run-sandbox 'vanilla-doom+)))
|
||||||
(fset 'doom--run-full-doom (lambda! (doom--run-sandbox 'doom)))
|
(fset 'doom--run-full-doom (cmd! (doom--run-sandbox 'doom)))
|
||||||
|
|
||||||
(defvar doom-sandbox-emacs-lisp-mode-map
|
(defvar doom-sandbox-emacs-lisp-mode-map
|
||||||
(let ((map (make-sparse-keymap)))
|
(let ((map (make-sparse-keymap)))
|
||||||
|
|
|
@ -139,24 +139,6 @@ at the values with which this function was called."
|
||||||
;;
|
;;
|
||||||
;;; Sugars
|
;;; Sugars
|
||||||
|
|
||||||
(defmacro λ! (&rest body)
|
|
||||||
"Expands to (lambda () (interactive) ,@body).
|
|
||||||
A factory for quickly producing interaction commands, particularly for keybinds
|
|
||||||
or aliases."
|
|
||||||
(declare (doc-string 1) (pure t) (side-effect-free t))
|
|
||||||
`(lambda (&rest _) (interactive) ,@body))
|
|
||||||
(defalias 'lambda! 'λ!)
|
|
||||||
|
|
||||||
(defun λ!! (command &optional arg)
|
|
||||||
"Expands to a command that interactively calls COMMAND with prefix ARG.
|
|
||||||
A factory for quickly producing interactive, prefixed commands for keybinds or
|
|
||||||
aliases."
|
|
||||||
(declare (doc-string 1) (pure t) (side-effect-free t))
|
|
||||||
(lambda (&rest _) (interactive)
|
|
||||||
(let ((current-prefix-arg arg))
|
|
||||||
(call-interactively command))))
|
|
||||||
(defalias 'lambda!! 'λ!!)
|
|
||||||
|
|
||||||
(defun dir! ()
|
(defun dir! ()
|
||||||
"Returns the directory of the emacs lisp file this macro is called from."
|
"Returns the directory of the emacs lisp file this macro is called from."
|
||||||
(when-let (path (file!))
|
(when-let (path (file!))
|
||||||
|
@ -256,6 +238,40 @@ See `if!' for details on this macro's purpose."
|
||||||
(declare (indent defun) (doc-string 1) (pure t) (side-effect-free t))
|
(declare (indent defun) (doc-string 1) (pure t) (side-effect-free t))
|
||||||
`(cl-function (lambda ,arglist ,@body)))
|
`(cl-function (lambda ,arglist ,@body)))
|
||||||
|
|
||||||
|
(defmacro cmd! (&rest body)
|
||||||
|
"Expands to (lambda () (interactive) ,@body).
|
||||||
|
A factory for quickly producing interaction commands, particularly for keybinds
|
||||||
|
or aliases."
|
||||||
|
(declare (doc-string 1) (pure t) (side-effect-free t))
|
||||||
|
`(lambda (&rest _) (interactive) ,@body))
|
||||||
|
|
||||||
|
(defmacro cmd!! (command &rest args)
|
||||||
|
"Expands to a closure that interactively calls COMMAND with ARGS.
|
||||||
|
A factory for quickly producing interactive, prefixed commands for keybinds or
|
||||||
|
aliases."
|
||||||
|
(declare (doc-string 1) (pure t) (side-effect-free t))
|
||||||
|
`(lambda (&rest _) (interactive)
|
||||||
|
(funcall-interactively ,command ,@args)))
|
||||||
|
|
||||||
|
(defmacro cmds! (&rest branches)
|
||||||
|
"Expands to a `menu-item' dispatcher for keybinds."
|
||||||
|
(declare (doc-string 1))
|
||||||
|
(let ((docstring (if (stringp (car branches)) (pop branches) ""))
|
||||||
|
fallback)
|
||||||
|
(when (cl-oddp (length branches))
|
||||||
|
(setq fallback (car (last branches))
|
||||||
|
branches (butlast branches)))
|
||||||
|
`(general-predicate-dispatch ,fallback
|
||||||
|
:docstring ,docstring
|
||||||
|
,@branches)))
|
||||||
|
|
||||||
|
;; For backwards compatibility
|
||||||
|
(defalias 'λ! 'cmd!)
|
||||||
|
(defalias 'λ!! 'cmd!!)
|
||||||
|
;; DEPRECATED These have been superseded by `cmd!' and `cmd!!'
|
||||||
|
(define-obsolete-function-alias 'lambda! 'cmd! "3.0.0")
|
||||||
|
(define-obsolete-function-alias 'lambda!! 'cmd!! "3.0.0")
|
||||||
|
|
||||||
|
|
||||||
;;; Mutation
|
;;; Mutation
|
||||||
(defmacro appendq! (sym &rest lists)
|
(defmacro appendq! (sym &rest lists)
|
||||||
|
|
32
docs/api.org
32
docs/api.org
|
@ -18,8 +18,8 @@ It is integrated into Helpful, in Doom.
|
||||||
- [[#disable-packages][disable-packages!]]
|
- [[#disable-packages][disable-packages!]]
|
||||||
- [[#doom][doom!]]
|
- [[#doom][doom!]]
|
||||||
- [[#file-exists-p][file-exists-p!]]
|
- [[#file-exists-p][file-exists-p!]]
|
||||||
- [[#lambda][lambda!]]
|
- [[#cmd][cmd!]]
|
||||||
- [[#lambda-1][lambda!!]]
|
- [[#cmd-1][cmd!!]]
|
||||||
- [[#letenv][letenv!]]
|
- [[#letenv][letenv!]]
|
||||||
- [[#load][load!]]
|
- [[#load][load!]]
|
||||||
- [[#map][map!]]
|
- [[#map][map!]]
|
||||||
|
@ -238,38 +238,30 @@ It is integrated into Helpful, in Doom.
|
||||||
#+RESULTS:
|
#+RESULTS:
|
||||||
: /home/hlissner/.emacs.d/LICENSE
|
: /home/hlissner/.emacs.d/LICENSE
|
||||||
|
|
||||||
*** lambda!
|
*** cmd!
|
||||||
#+BEGIN_SRC elisp :eval no
|
#+BEGIN_SRC elisp :eval no
|
||||||
(map! "C-j" (lambda! (newline) (indent-according-to-mode)))
|
(map! "C-j" (cmd! (newline) (indent-according-to-mode)))
|
||||||
|
|
||||||
;; The `λ!' short-form alias exists. If you have the snippets module enabled and
|
|
||||||
;; Doom's default snippets, the 'lam' snippet will expand into 'λ!'. Otherwise,
|
|
||||||
;; you can use `lambda!'.
|
|
||||||
(map! "C-j" (λ! (newline) (indent-according-to-mode)))
|
|
||||||
#+END_SRC
|
#+END_SRC
|
||||||
*** lambda!!
|
|
||||||
|
*** cmd!!
|
||||||
When ~newline~ is passed a numerical prefix argument (=C-u 5 M-x newline=), it
|
When ~newline~ is passed a numerical prefix argument (=C-u 5 M-x newline=), it
|
||||||
inserts N newlines. We can use ~lambda!!~ to easily create a keybinds that bakes
|
inserts N newlines. We can use ~cmd!!~ to easily create a keybinds that bakes in
|
||||||
in the prefix arg into the command call:
|
the prefix arg into the command call:
|
||||||
|
|
||||||
#+BEGIN_SRC elisp :eval no
|
#+BEGIN_SRC elisp :eval no
|
||||||
(map! "C-j" (lambda!! #'newline 5))
|
(map! "C-j" (cmd!! #'newline 5))
|
||||||
|
|
||||||
;; The `λ!!' short-form alias exists. If you have the snippets module enabled
|
|
||||||
;; and Doom's default snippets, a 'lam' snippet is available to expand into
|
|
||||||
;; 'λ!'. Otherwise, you can use `lambda!!'.
|
|
||||||
(map! "C-j" (λ!! #'newline 5))
|
|
||||||
#+END_SRC
|
#+END_SRC
|
||||||
|
|
||||||
Or to create aliases for functions that behave differently:
|
Or to create aliases for functions that behave differently:
|
||||||
|
|
||||||
#+BEGIN_SRC elisp :eval no
|
#+BEGIN_SRC elisp :eval no
|
||||||
(fset 'insert-5-newlines (lambda!! #'newline 5))
|
(fset 'insert-5-newlines (cmd!! #'newline 5))
|
||||||
|
|
||||||
;; The equivalent of C-u M-x org-global-cycle, which resets the org document to
|
;; The equivalent of C-u M-x org-global-cycle, which resets the org document to
|
||||||
;; its startup visibility settings.
|
;; its startup visibility settings.
|
||||||
(fset 'org-reset-global-visibility (lambda!! #'org-global-cycle '(4))
|
(fset 'org-reset-global-visibility (cmd!! #'org-global-cycle '(4))
|
||||||
#+END_SRC
|
#+END_SRC
|
||||||
|
|
||||||
*** letenv!
|
*** letenv!
|
||||||
#+BEGIN_SRC elisp
|
#+BEGIN_SRC elisp
|
||||||
(letenv! (("SHELL" "/bin/sh"))
|
(letenv! (("SHELL" "/bin/sh"))
|
||||||
|
|
|
@ -120,7 +120,7 @@
|
||||||
;;; <leader> i --- insert
|
;;; <leader> i --- insert
|
||||||
(:prefix-map ("i" . "insert")
|
(:prefix-map ("i" . "insert")
|
||||||
:desc "Current file name" "f" #'+default/insert-file-path
|
:desc "Current file name" "f" #'+default/insert-file-path
|
||||||
:desc "Current file path" "F" (λ!! #'+default/insert-file-path t)
|
:desc "Current file path" "F" (cmd!! #'+default/insert-file-path t)
|
||||||
:desc "Snippet" "s" #'yas-insert-snippet
|
:desc "Snippet" "s" #'yas-insert-snippet
|
||||||
:desc "Unicode" "u" #'unicode-chars-list-chars
|
:desc "Unicode" "u" #'unicode-chars-list-chars
|
||||||
:desc "From clipboard" "y" #'+default/yank-pop)
|
:desc "From clipboard" "y" #'+default/yank-pop)
|
||||||
|
@ -412,7 +412,7 @@
|
||||||
;;; Text scaling
|
;;; Text scaling
|
||||||
[C-mouse-4] #'text-scale-increase
|
[C-mouse-4] #'text-scale-increase
|
||||||
[C-mouse-5] #'text-scale-decrease
|
[C-mouse-5] #'text-scale-decrease
|
||||||
[C-down-mouse-2] (λ! (text-scale-set 0))
|
[C-down-mouse-2] (cmd! (text-scale-set 0))
|
||||||
"M-+" #'doom/reset-font-size
|
"M-+" #'doom/reset-font-size
|
||||||
"M-=" #'doom/increase-font-size
|
"M-=" #'doom/increase-font-size
|
||||||
"M--" #'doom/decrease-font-size
|
"M--" #'doom/decrease-font-size
|
||||||
|
@ -463,7 +463,7 @@
|
||||||
:map company-search-map
|
:map company-search-map
|
||||||
"C-n" #'company-search-repeat-forward
|
"C-n" #'company-search-repeat-forward
|
||||||
"C-p" #'company-search-repeat-backward
|
"C-p" #'company-search-repeat-backward
|
||||||
"C-s" (λ! (company-search-abort) (company-filter-candidates)))
|
"C-s" (cmd! (company-search-abort) (company-filter-candidates)))
|
||||||
|
|
||||||
;;; ein notebooks
|
;;; ein notebooks
|
||||||
(:after ein:notebook-multilang
|
(:after ein:notebook-multilang
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
"C-u" #'evil-delete-back-to-indentation
|
"C-u" #'evil-delete-back-to-indentation
|
||||||
"C-v" #'yank
|
"C-v" #'yank
|
||||||
"C-w" #'doom/delete-backward-word
|
"C-w" #'doom/delete-backward-word
|
||||||
"C-z" (λ! (ignore-errors (call-interactively #'undo))))
|
"C-z" (cmd! (ignore-errors (call-interactively #'undo))))
|
||||||
|
|
||||||
(when (featurep! :editor evil +everywhere)
|
(when (featurep! :editor evil +everywhere)
|
||||||
(define-key! :keymaps +default-minibuffer-maps
|
(define-key! :keymaps +default-minibuffer-maps
|
||||||
|
@ -39,19 +39,17 @@
|
||||||
;;; Global keybindings
|
;;; Global keybindings
|
||||||
|
|
||||||
;; Smart tab, these will only work in GUI Emacs
|
;; Smart tab, these will only work in GUI Emacs
|
||||||
(map! :i [tab] (general-predicate-dispatch nil ; fall back to nearest keymap
|
(map! :i [tab] (cmds! (and (featurep! :editor snippets)
|
||||||
(and (featurep! :editor snippets)
|
(bound-and-true-p yas-minor-mode)
|
||||||
(bound-and-true-p yas-minor-mode)
|
(yas-maybe-expand-abbrev-key-filter 'yas-expand))
|
||||||
(yas-maybe-expand-abbrev-key-filter 'yas-expand))
|
#'yas-expand
|
||||||
#'yas-expand
|
(and (featurep! :completion company +tng)
|
||||||
(and (featurep! :completion company +tng)
|
(+company-has-completion-p))
|
||||||
(+company-has-completion-p))
|
#'+company/complete)
|
||||||
#'+company/complete)
|
:v [tab] (cmds! (and (bound-and-true-p yas-minor-mode)
|
||||||
:v [tab] (general-predicate-dispatch nil
|
(or (eq evil-visual-selection 'line)
|
||||||
(and (bound-and-true-p yas-minor-mode)
|
(not (memq (char-after) (list ?\( ?\[ ?\{ ?\} ?\] ?\))))))
|
||||||
(or (eq evil-visual-selection 'line)
|
#'yas-insert-snippet)
|
||||||
(not (memq (char-after) (list ?\( ?\[ ?\{ ?\} ?\] ?\))))))
|
|
||||||
#'yas-insert-snippet)
|
|
||||||
|
|
||||||
;; Smarter newlines
|
;; Smarter newlines
|
||||||
:i [remap newline] #'newline-and-indent ; auto-indent on newline
|
:i [remap newline] #'newline-and-indent ; auto-indent on newline
|
||||||
|
@ -136,7 +134,7 @@
|
||||||
"C-p" #'company-select-previous-or-abort
|
"C-p" #'company-select-previous-or-abort
|
||||||
"C-j" #'company-select-next-or-abort
|
"C-j" #'company-select-next-or-abort
|
||||||
"C-k" #'company-select-previous-or-abort
|
"C-k" #'company-select-previous-or-abort
|
||||||
"C-s" (λ! (company-search-abort) (company-filter-candidates))
|
"C-s" (cmd! (company-search-abort) (company-filter-candidates))
|
||||||
[escape] #'company-search-abort))
|
[escape] #'company-search-abort))
|
||||||
;; TAB auto-completion in term buffers
|
;; TAB auto-completion in term buffers
|
||||||
(:after comint :map comint-mode-map
|
(:after comint :map comint-mode-map
|
||||||
|
@ -456,8 +454,8 @@
|
||||||
;;; <leader> i --- insert
|
;;; <leader> i --- insert
|
||||||
(:prefix-map ("i" . "insert")
|
(:prefix-map ("i" . "insert")
|
||||||
:desc "Current file name" "f" #'+default/insert-file-path
|
:desc "Current file name" "f" #'+default/insert-file-path
|
||||||
:desc "Current file path" "F" (λ!! #'+default/insert-file-path t)
|
:desc "Current file path" "F" (cmd!! #'+default/insert-file-path t)
|
||||||
:desc "Evil ex path" "p" (λ! (evil-ex "R!echo "))
|
:desc "Evil ex path" "p" (cmd! (evil-ex "R!echo "))
|
||||||
:desc "From evil register" "r" #'evil-ex-registers
|
:desc "From evil register" "r" #'evil-ex-registers
|
||||||
:desc "Snippet" "s" #'yas-insert-snippet
|
:desc "Snippet" "s" #'yas-insert-snippet
|
||||||
:desc "Unicode" "u" #'unicode-chars-list-chars
|
:desc "Unicode" "u" #'unicode-chars-list-chars
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue