Function: dirvish-define-attribute

dirvish-define-attribute is a macro defined in dirvish.el.

Signature

(dirvish-define-attribute NAME DOCSTRING &rest BODY)

Documentation

Define a Dirvish attribute NAME with DOCSTRING.

An Dirvish attribute contains:
- a PREDICATE form, which is the value of :when keyword
- a SETUP form, which is the value of :setup keyword
- a RENDER function runs BODY (excludes all the keywords)

During redisplay, the PREDICATE is evaluated with WIN-WIDTH (from window-width) bound locally, a nil result means the attribute should not be rendered. Otherwise, SETUP form is evalutated once and RENDER is called for every file line in the viewport with the following arguments:

- f-beg from dired-move-to-filename
- f-end from dired-move-to-end-of-filename
- f-str from (buffer-substring F-BEG F-END)
- f-name from dired-get-filename
- f-attrs from file-attributes
- f-type from file-directory-p along with file-symlink-p
- l-beg from line-beginning-position
- l-end from line-end-position
- hl-face from dirvish-hl-line face, only passed in for current line
- w-width from window-width

RENDER should return a cons of (TYPE . VAL) where:
- TYPE can be one of ov, left or right
- When TYPE is ov, VAL is a overlay to be put; otherwise VAL is a string

The collected left strings as a whole is then attached to f-end, while right would fill up remaining space within the file line. These keywords are used to calculate the starting position of the collected right strings:

- :width: a form denotes the constant length of the attribute.
- :right: like :width, but only used by right TYPE RENDER.

Source Code

;; Defined in /nix/store/1gijwny2yx4fggrsb9l110h1ybs1gdk5-emacs-packages-deps/share/emacs/site-lisp/elpa/dirvish-20260725.1520/dirvish.el
;;;; Attributes

(defmacro dirvish-define-attribute (name docstring &rest body)
  "Define a Dirvish attribute NAME with DOCSTRING.
An Dirvish attribute contains:
- a PREDICATE form, which is the value of `:when' keyword
- a SETUP form, which is the value of `:setup' keyword
- a RENDER function runs BODY (excludes all the keywords)

During redisplay, the PREDICATE is evaluated with WIN-WIDTH (from
`window-width') bound locally, a nil result means the attribute should
not be rendered.  Otherwise, SETUP form is evalutated once and RENDER is
called for every file line in the viewport with the following arguments:

- `f-beg'   from `dired-move-to-filename'
- `f-end'   from `dired-move-to-end-of-filename'
- `f-str'   from (`buffer-substring' F-BEG F-END)
- `f-name'  from `dired-get-filename'
- `f-attrs' from `file-attributes'
- `f-type'  from `file-directory-p' along with `file-symlink-p'
- `l-beg'   from `line-beginning-position'
- `l-end'   from `line-end-position'
- `hl-face' from `dirvish-hl-line' face, only passed in for current line
- `w-width' from `window-width'

RENDER should return a cons of (TYPE . VAL) where:
- TYPE can be one of `ov', `left' or `right'
- When TYPE is `ov', VAL is a overlay to be put; otherwise VAL is a string

The collected `left' strings as a whole is then attached to `f-end',
while `right' would fill up remaining space within the file line.  These
keywords are used to calculate the starting position of the collected
`right' strings:

- `:width': a form denotes the constant length of the attribute.
- `:right': like `:width', but only used by `right' TYPE RENDER."
  (declare (indent defun) (doc-string 2))
  (let ((render (intern (format "dirvish-attribute-%s-rd" name)))
        (args '(f-beg f-end f-str f-name f-attrs
                      f-type l-beg l-end hl-face w-width))
        options)
    (while (keywordp (car body)) (dotimes (_ 2) (push (pop body) options)))
    (setq options (reverse options))
    `(progn
       (add-to-list
        'dirvish--available-attrs
        (cons ',name '(,(or (plist-get options :width) 0)
                       ,(or (plist-get options :right) 0)
                       ,(or (plist-get options :when) t)
                       ,(or (plist-get options :setup) nil)
                       ,render ,docstring)))
       (defun ,render ,args (ignore ,@args) ,@body))))