diff options
Diffstat (limited to 'lisp/emacs-lisp/tabulated-list.el')
-rw-r--r-- | lisp/emacs-lisp/tabulated-list.el | 139 |
1 files changed, 73 insertions, 66 deletions
diff --git a/lisp/emacs-lisp/tabulated-list.el b/lisp/emacs-lisp/tabulated-list.el index 3d944bf5e16..7d815a3cedc 100644 --- a/lisp/emacs-lisp/tabulated-list.el +++ b/lisp/emacs-lisp/tabulated-list.el @@ -115,16 +115,25 @@ where: This should be either a function, or a list. If a list, each element has the form (ID [DESC1 ... DESCN]), where: + - ID is nil, or a Lisp object uniquely identifying this entry, which is used to keep the cursor on the \"same\" entry when rearranging the list. Comparison is done with `equal'. - Each DESC is a column descriptor, one for each column - specified in `tabulated-list-format'. A descriptor is either - a string, which is printed as-is, or a list (LABEL . PROPS), - which means to use `insert-text-button' to insert a text - button with label LABEL and button properties PROPS. - The string, or button label, must not contain any newline. + specified in `tabulated-list-format'. The descriptor DESC is + one of: + + - A string, which is printed as-is, and must not contain any + newlines. + + - An image descriptor (a list), which is used to insert an + image (see Info node `(elisp) Image Descriptors'). + + - A list (LABEL . PROPS), which means to use + `insert-text-button' to insert a text button with label + LABEL and button properties PROPS. LABEL must not contain + any newlines. If `tabulated-list-entries' is a function, it is called with no arguments and must return a list of the above form.") @@ -255,18 +264,14 @@ variables `tabulated-list-tty-sort-indicator-asc' and Populated by `tabulated-list-init-header'.") (defvar tabulated-list--header-overlay nil) -(defun tabulated-list-line-number-width () - "Return the width taken by `display-line-numbers' in the current buffer." - ;; line-number-display-width returns the value for the selected - ;; window, which might not be the window in which the current buffer - ;; is displayed. - (if (not display-line-numbers) - 0 - (let ((cbuf-window (get-buffer-window (current-buffer) t))) - (if (window-live-p cbuf-window) - (with-selected-window cbuf-window - (line-number-display-width 'columns)) - 4)))) +(define-obsolete-function-alias 'tabulated-list-line-number-width + 'header-line-indent--line-number-width "29.1") +(define-obsolete-function-alias 'tabulated-list-watch-line-number-width + 'header-line-indent--watch-line-number-width "29.1") +(define-obsolete-function-alias 'tabulated-list-watch-line-number-width + 'header-line-indent--watch-line-number-width "29.1") +(define-obsolete-function-alias 'tabulated-list-window-scroll-function + 'header-line-indent--window-scroll-function "29.1") (defun tabulated-list-init-header () "Set up header line for the Tabulated List buffer." @@ -280,9 +285,9 @@ Populated by `tabulated-list-init-header'.") (hcols (mapcar #'car tabulated-list-format)) (tabulated-list--near-rows (list hcols hcols)) (cols nil)) - (if display-line-numbers - (setq x (+ x (tabulated-list-line-number-width)))) - (push (propertize " " 'display `(space :align-to ,x)) cols) + (push (propertize " " 'display + `(space :align-to (+ header-line-indent-width ,x))) + cols) (dotimes (n len) (let* ((col (aref tabulated-list-format n)) (not-last-col (< n (1- len))) @@ -333,20 +338,25 @@ Populated by `tabulated-list-init-header'.") (when (> shift 0) (setq cols (cons (car cols) - (cons (propertize (make-string shift ?\s) - 'display - `(space :align-to ,(+ x shift))) - (cdr cols)))) + (cons + (propertize + (make-string shift ?\s) + 'display + `(space :align-to + (+ header-line-indent-width ,(+ x shift)))) + (cdr cols)))) (setq x (+ x shift))))) (if (>= pad-right 0) - (push (propertize " " - 'display `(space :align-to ,next-x) - 'face 'fixed-pitch) + (push (propertize + " " + 'display `(space :align-to + (+ header-line-indent-width ,next-x)) + 'face 'fixed-pitch) cols)) (setq x next-x))) (setq cols (apply 'concat (nreverse cols))) (if tabulated-list-use-header-line - (setq header-line-format cols) + (setq header-line-format (list "" 'header-line-indent cols)) (setq-local tabulated-list--header-string cols)))) (defun tabulated-list-print-fake-header () @@ -547,7 +557,9 @@ Return the column number after insertion." (props (nthcdr 3 format)) (pad-right (or (plist-get props :pad-right) 1)) (right-align (plist-get props :right-align)) - (label (if (stringp col-desc) col-desc (car col-desc))) + (label (cond ((stringp col-desc) col-desc) + ((eq (car col-desc) 'image) " ") + (t (car col-desc)))) (label-width (string-width label)) (help-echo (concat (car format) ": " label)) (opoint (point)) @@ -571,11 +583,15 @@ Return the column number after insertion." 'display `(space :align-to ,(+ x shift)))) (setq width (- width shift)) (setq x (+ x shift)))) - (if (stringp col-desc) - (insert (if (get-text-property 0 'help-echo label) - label - (propertize label 'help-echo help-echo))) - (apply 'insert-text-button label (cdr col-desc))) + (cond ((stringp col-desc) + (insert (if (get-text-property 0 'help-echo label) + label + (propertize label 'help-echo help-echo)))) + ((eq (car col-desc) 'image) + (insert (propertize " " + 'display col-desc + 'help-echo help-echo))) + ((apply 'insert-text-button label (cdr col-desc)))) (let ((next-x (+ x pad-right width))) ;; No need to append any spaces if this is the last column. (when not-last-col @@ -668,6 +684,10 @@ With a numeric prefix argument N, sort the Nth column. If the numeric prefix is -1, restore order the list was originally displayed in." (interactive "P") + (when (and n + (or (>= n (length tabulated-list-format)) + (< n -1))) + (user-error "Invalid column number")) (if (equal n -1) ;; Restore original order. (progn @@ -712,6 +732,7 @@ Interactively, N is the prefix numeric argument, and defaults to 1." (interactive "p") (let ((start (current-column)) + (entry (tabulated-list-get-entry)) (nb-cols (length tabulated-list-format)) (col-nb 0) (total-width 0) @@ -719,14 +740,25 @@ Interactively, N is the prefix numeric argument, and defaults to col-width) (while (and (not found) (< col-nb nb-cols)) - (if (> start - (setq total-width - (+ total-width - (setq col-width - (cadr (aref tabulated-list-format - col-nb)))))) + (if (>= start + (setq total-width + (+ total-width + (max (setq col-width + (cadr (aref tabulated-list-format + col-nb))) + (let ((desc (aref entry col-nb))) + (string-width (if (stringp desc) + desc + (car desc))))) + (or (plist-get (nthcdr 3 (aref tabulated-list-format + col-nb)) + :pad-right) + 1)))) (setq col-nb (1+ col-nb)) (setq found t) + ;; `tabulated-list-format' may be a constant (sharing list + ;; structures), so copy it before mutating. + (setq tabulated-list-format (copy-tree tabulated-list-format t)) (setf (cadr (aref tabulated-list-format col-nb)) (max 1 (+ col-width n))) (tabulated-list-print t) @@ -739,23 +771,6 @@ Interactively, N is the prefix numeric argument, and defaults to (interactive "p") (tabulated-list-widen-current-column (- n))) -(defvar tabulated-list--current-lnum-width nil) -(defun tabulated-list-watch-line-number-width (_window) - (if display-line-numbers - (let ((lnum-width (tabulated-list-line-number-width))) - (when (not (= tabulated-list--current-lnum-width lnum-width)) - (setq-local tabulated-list--current-lnum-width lnum-width) - (tabulated-list-init-header))))) - -(defun tabulated-list-window-scroll-function (window _start) - (if display-line-numbers - (let ((lnum-width - (with-selected-window window - (line-number-display-width 'columns)))) - (when (not (= tabulated-list--current-lnum-width lnum-width)) - (setq-local tabulated-list--current-lnum-width lnum-width) - (tabulated-list-init-header))))) - (defun tabulated-list-next-column (&optional arg) "Go to the start of the next column after point on the current line. If ARG is provided, move that many columns." @@ -826,15 +841,7 @@ as the ewoc pretty-printer." ;; Avoid messing up the entries' display just because the first ;; column of the first entry happens to begin with a R2L letter. (setq bidi-paragraph-direction 'left-to-right) - ;; This is for if/when they turn on display-line-numbers - (add-hook 'display-line-numbers-mode-hook #'tabulated-list-revert nil t) - ;; This is for if/when they customize the line-number face or when - ;; the line-number width needs to change due to scrolling. - (setq-local tabulated-list--current-lnum-width 0) - (add-hook 'pre-redisplay-functions - #'tabulated-list-watch-line-number-width nil t) - (add-hook 'window-scroll-functions - #'tabulated-list-window-scroll-function nil t)) + (header-line-indent-mode)) (put 'tabulated-list-mode 'mode-class 'special) |