Function: evil-define-type
evil-define-type is a macro defined in evil-macros.el.
Signature
(evil-define-type TYPE DOC [[KEY FUNC]...])
Documentation
Define type TYPE.
DOC is a general description and shows up in all docstrings.
Optional keyword arguments:
- :expand - expansion function. This function should accept two
positions in the current buffer, BEG and END,and return a pair of
expanded buffer positions.
- :contract - the opposite of :expand. Optional.
- :one-to-one - non-nil if expansion is one-to-one. This means that
:expand followed by :contract always return the original range.
- :normalize - normalization function. This function should accept
two unexpanded positions and adjust them before expansion. May be
used to deal with buffer boundaries.
- :string - description function. Takes two buffer positions and
returns a human-readable string. For example "2 lines"
If further keywords and functions are specified, they are assumed to be transformations on buffer positions, like :expand and :contract.
Source Code
;; Defined in ~/.emacs.d/elpa/evil-20251108.138/evil-macros.el
(defmacro evil-define-type (type doc &rest body)
"Define type TYPE.
DOC is a general description and shows up in all docstrings.
Optional keyword arguments:
- `:expand' - expansion function. This function should accept two
positions in the current buffer, BEG and END,and return a pair of
expanded buffer positions.
- `:contract' - the opposite of `:expand'. Optional.
- `:one-to-one' - non-nil if expansion is one-to-one. This means that
`:expand' followed by `:contract' always return the original range.
- `:normalize' - normalization function. This function should accept
two unexpanded positions and adjust them before expansion. May be
used to deal with buffer boundaries.
- `:string' - description function. Takes two buffer positions and
returns a human-readable string. For example \"2 lines\"
If further keywords and functions are specified, they are assumed to
be transformations on buffer positions, like `:expand' and `:contract'.
\(fn TYPE DOC [[KEY FUNC]...])"
(declare (indent defun)
(doc-string 2)
(debug (&define name
[&optional stringp]
[&rest [keywordp function-form]])))
(let ((plist (list :one-to-one t)) ; standard values
args defun-forms func key name string sym val)
;; keywords
(while (keywordp (car-safe body))
(setq key (pop body)
val (pop body))
(if (plist-member plist key) ; not a function
(setq plist (plist-put plist key val))
(setq func val
sym (intern (replace-regexp-in-string
"^:" "" (symbol-name key)))
name (intern (format "evil-%s-%s" type sym))
args (car (cdr-safe func))
string (cadr (cdr-safe func))
string (if (stringp string)
(format "%s\n\n" string) "")
plist (plist-put plist key `',name))
(push
(cond
((eq key :string)
`(defun ,name (beg end &rest properties)
,(format "Return size of %s from BEG to END \
with PROPERTIES.\n\n%s%s" type string doc)
(let ((type ',type)
plist range)
(when (and beg end)
(evil-sort beg end)
(save-excursion
(unless (plist-get properties :expanded)
(setq range (apply #'evil-expand
beg end type properties)
beg (evil-range-beginning range)
end (evil-range-end range)
type (evil-type range type)
plist (evil-range-properties range))
(setq properties
(evil-concat-plists properties plist)))
(or (apply #',func beg end
(when ,(> (length args) 2)
properties))
""))))))
(t
`(defun ,name (beg end &rest properties)
,(format "Perform %s transformation on %s from BEG to END \
with PROPERTIES.\n\n%s%s" sym type string doc)
(let ((type ',type)
plist range)
(when (and beg end)
(evil-sort beg end)
(save-excursion
(when (memq ,key '(:expand :contract))
(setq properties
(plist-put properties
:expanded ,(eq key :expand))))
(setq range (or (apply #',func beg end
(when ,(> (length args) 2)
properties))
(apply #'evil-range
beg end type properties))
beg (evil-range-beginning range)
end (evil-range-end range)
type (evil-type range type)
plist (evil-range-properties range))
(setq properties
(evil-concat-plists properties plist))
(apply #'evil-range beg end type properties)))))))
defun-forms)))
;; :one-to-one requires both or neither of :expand and :contract
(when (plist-get plist :expand)
(setq plist (plist-put plist :one-to-one
(and (plist-get plist :contract)
(plist-get plist :one-to-one)))))
`(progn
(evil--add-to-alist evil-type-properties ',type (list ,@plist))
,@defun-forms
',type)))