aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniel Mendler2025-01-11 16:36:56 +0100
committerEli Zaretskii2025-01-25 11:43:45 +0200
commit5294d450da47734bbe2ca259505674bcae5ff573 (patch)
treeed0094e16bacaebdc48f6d98738885a718ef2e86
parent35576fde5670dffe104a6b2a76837a1f0a4c16ce (diff)
downloademacs-5294d450da47734bbe2ca259505674bcae5ff573.tar.gz
emacs-5294d450da47734bbe2ca259505674bcae5ff573.zip
ibuffer: Display column titles in header line
If the option `ibuffer-use-header-line' is set to `title', display column titles in the header line. * lisp/ibuffer.el (ibuffer--format-title) (ibuffer--format-summary): New functions extracted from `ibuffer-update-title-and-summary'. (ibuffer-update-title-and-summary): Use them. (ibuffer-update): Do not always override `header-line-format'. (ibuffer-use-header-line): Update docstring and option `:type'. * lisp/ibuf-macs.el (define-ibuffer-sorter): Add "@" to the interactive specification for clicks on the header line. * etc/NEWS: Announce the change. (Bug#75497)
-rw-r--r--etc/NEWS4
-rw-r--r--lisp/ibuf-macs.el2
-rw-r--r--lisp/ibuffer.el166
3 files changed, 95 insertions, 77 deletions
diff --git a/etc/NEWS b/etc/NEWS
index e7c54574688..385e943c997 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -354,6 +354,10 @@ You can now set `asm-comment-char' from 'asm-mode-hook' instead.
354The variable 'ibuffer-formats' configures the Ibuffer formats. Add 354The variable 'ibuffer-formats' configures the Ibuffer formats. Add
355'recency' to the format to display the column. 355'recency' to the format to display the column.
356 356
357*** New value 'title' for the user option 'ibuffer-use-header-line'.
358Display column titles in the header line if 'ibuffer-use-header-line' is
359set to 'title'.
360
357*** New user option 'ibuffer-human-readable-size'. 361*** New user option 'ibuffer-human-readable-size'.
358When non-nil, buffer sizes are shown in human readable format. 362When non-nil, buffer sizes are shown in human readable format.
359 363
diff --git a/lisp/ibuf-macs.el b/lisp/ibuf-macs.el
index ff3dc755c36..7dbc9b4125a 100644
--- a/lisp/ibuf-macs.el
+++ b/lisp/ibuf-macs.el
@@ -146,7 +146,7 @@ value if and only if `a' is \"less than\" `b'.
146 `(progn 146 `(progn
147 (defun ,(intern (concat "ibuffer-do-sort-by-" (symbol-name name))) () 147 (defun ,(intern (concat "ibuffer-do-sort-by-" (symbol-name name))) ()
148 ,(or documentation "No :documentation specified for this sorting method.") 148 ,(or documentation "No :documentation specified for this sorting method.")
149 (interactive) 149 (interactive "@")
150 (setq ibuffer-sorting-mode ',name) 150 (setq ibuffer-sorting-mode ',name)
151 (when (eq ibuffer-sorting-mode ibuffer-last-sorting-mode) 151 (when (eq ibuffer-sorting-mode ibuffer-last-sorting-mode)
152 (setq ibuffer-sorting-reversep (not ibuffer-sorting-reversep))) 152 (setq ibuffer-sorting-reversep (not ibuffer-sorting-reversep)))
diff --git a/lisp/ibuffer.el b/lisp/ibuffer.el
index 11340d4bd9e..a94d9fddade 100644
--- a/lisp/ibuffer.el
+++ b/lisp/ibuffer.el
@@ -310,8 +310,10 @@ in completion lists of the `ibuffer-jump-to-buffer' command."
310 :type 'boolean) 310 :type 'boolean)
311 311
312(defcustom ibuffer-use-header-line t 312(defcustom ibuffer-use-header-line t
313 "If non-nil, display a header line containing current filters." 313 "If non-nil, display a header line.
314 :type 'boolean) 314If the variable's value is t, the header line displays the current
315filters. For the value `title', display the column titles."
316 :type '(choice boolean (const :tag "Column titles" :value title)))
315 317
316(defcustom ibuffer-default-directory nil 318(defcustom ibuffer-default-directory nil
317 "The default directory to use for a new Ibuffer buffer. 319 "The default directory to use for a new Ibuffer buffer.
@@ -2048,59 +2050,90 @@ the value of point at the beginning of the line for that buffer."
2048 (ibuffer-update-format) 2050 (ibuffer-update-format)
2049 (ibuffer-redisplay t)) 2051 (ibuffer-redisplay t))
2050 2052
2053(defun ibuffer--format-title (element &optional header-line)
2054 (if (stringp element)
2055 element
2056 (pcase-let ((`(,sym ,min ,_max ,align) element))
2057 ;; Ignore negative MIN, since the titles are left-aligned.
2058 (when (cl-minusp min)
2059 (setq min (- min)))
2060 (let* ((name (or (get sym 'ibuffer-column-name)
2061 (error "Unknown column %s in ibuffer-formats" sym)))
2062 (len (length name))
2063 (hmap (get sym 'header-mouse-map))
2064 (strname (if (< len min)
2065 (ibuffer-format-column name
2066 (- min len)
2067 align)
2068 name)))
2069 (when hmap
2070 (setq
2071 strname
2072 (propertize strname 'mouse-face 'highlight 'keymap
2073 (if header-line
2074 (define-keymap "<header-line>" hmap)
2075 hmap))))
2076 strname))))
2077
2078(defun ibuffer--format-summary (element)
2079 (if (stringp element)
2080 (make-string (length element) ?\s)
2081 (pcase-let ((`(,sym ,min ,_max ,align) element))
2082 ;; Ignore negative MIN, since the summaries are left-aligned.
2083 (when (cl-minusp min)
2084 (setq min (- min)))
2085 (let* ((summary
2086 (if (get sym 'ibuffer-column-summarizer)
2087 (funcall (get sym 'ibuffer-column-summarizer)
2088 (get sym 'ibuffer-column-summary))
2089 (make-string
2090 (length (get sym 'ibuffer-column-name))
2091 ?\s)))
2092 (len (length summary)))
2093 (if (< len min)
2094 (ibuffer-format-column summary
2095 (- min len)
2096 align)
2097 summary)))))
2098
2051(defun ibuffer-update-title-and-summary (format) 2099(defun ibuffer-update-title-and-summary (format)
2052 (ibuffer-assert-ibuffer-mode) 2100 (ibuffer-assert-ibuffer-mode)
2053 ;; Don't do funky font-lock stuff here 2101 ;; Don't do funky font-lock stuff here
2054 (let ((inhibit-modification-hooks t)) 2102 (let ((inhibit-modification-hooks t))
2055 (if (get-text-property (point-min) 'ibuffer-title) 2103 ;; Insert the title names.
2056 (delete-region (point-min) 2104 (if (eq ibuffer-use-header-line 'title)
2057 (next-single-property-change 2105 (setq header-line-format
2058 (point-min) 'ibuffer-title))) 2106 `("" header-line-indent
2059 (goto-char (point-min)) 2107 ,(propertize " " 'display
2060 (add-text-properties 2108 '(space :align-to header-line-indent-width))
2061 (point) 2109 ,@(mapcar (lambda (e) (ibuffer--format-title e t)) format)))
2062 (progn 2110 (if (get-text-property (point-min) 'ibuffer-title)
2063 (let ((opos (point))) 2111 (delete-region (point-min)
2064 ;; Insert the title names. 2112 (next-single-property-change
2065 (dolist (element format) 2113 (point-min) 'ibuffer-title)))
2066 (insert 2114 (goto-char (point-min))
2067 (if (stringp element) 2115 (add-text-properties
2068 element 2116 (point)
2069 (pcase-let ((`(,sym ,min ,_max ,align) element)) 2117 (progn
2070 ;; Ignore a negative min when we're inserting the title 2118 (let ((opos (point)))
2071 (when (cl-minusp min) 2119 (apply #'insert (mapcar #'ibuffer--format-title format))
2072 (setq min (- min))) 2120 (add-text-properties opos (point) '(ibuffer-title-header t))
2073 (let* ((name (or (get sym 'ibuffer-column-name) 2121 (insert "\n")
2074 (error "Unknown column %s in ibuffer-formats" sym))) 2122 ;; Add the underlines
2075 (len (length name)) 2123 (let ((str (save-excursion
2076 (hmap (get sym 'header-mouse-map)) 2124 (forward-line -1)
2077 (strname (if (< len min) 2125 (beginning-of-line)
2078 (ibuffer-format-column name 2126 (buffer-substring (point) (line-end-position)))))
2079 (- min len) 2127 (apply #'insert (mapcar
2080 align) 2128 (lambda (c)
2081 name))) 2129 (if (not (or (eq c ?\s)
2082 (when hmap 2130 (eq c ?\n)))
2083 (setq 2131 ?-
2084 strname 2132 ?\s))
2085 (propertize strname 'mouse-face 'highlight 'keymap hmap))) 2133 str)))
2086 strname))))) 2134 (insert "\n"))
2087 (add-text-properties opos (point) '(ibuffer-title-header t)) 2135 (point))
2088 (insert "\n") 2136 `(ibuffer-title t font-lock-face ,ibuffer-title-face)))
2089 ;; Add the underlines
2090 (let ((str (save-excursion
2091 (forward-line -1)
2092 (beginning-of-line)
2093 (buffer-substring (point) (line-end-position)))))
2094 (apply #'insert (mapcar
2095 (lambda (c)
2096 (if (not (or (eq c ?\s)
2097 (eq c ?\n)))
2098 ?-
2099 ?\s))
2100 str)))
2101 (insert "\n"))
2102 (point))
2103 `(ibuffer-title t font-lock-face ,ibuffer-title-face))
2104 ;; Now, insert the summary columns. 2137 ;; Now, insert the summary columns.
2105 (goto-char (point-max)) 2138 (goto-char (point-max))
2106 (if (get-text-property (1- (point-max)) 'ibuffer-summary) 2139 (if (get-text-property (1- (point-max)) 'ibuffer-summary)
@@ -2112,27 +2145,7 @@ the value of point at the beginning of the line for that buffer."
2112 (point) 2145 (point)
2113 (progn 2146 (progn
2114 (insert "\n") 2147 (insert "\n")
2115 (dolist (element format) 2148 (apply #'insert (mapcar #'ibuffer--format-summary format))
2116 (insert
2117 (if (stringp element)
2118 (make-string (length element) ?\s)
2119 (pcase-let ((`(,sym ,min ,_max ,align) element))
2120 ;; Ignore a negative min when we're inserting the title.
2121 (when (cl-minusp min)
2122 (setq min (- min)))
2123 (let* ((summary
2124 (if (get sym 'ibuffer-column-summarizer)
2125 (funcall (get sym 'ibuffer-column-summarizer)
2126 (get sym 'ibuffer-column-summary))
2127 (make-string
2128 (length (get sym 'ibuffer-column-name))
2129 ?\s)))
2130 (len (length summary)))
2131 (if (< len min)
2132 (ibuffer-format-column summary
2133 (- min len)
2134 align)
2135 summary))))))
2136 (point)) 2149 (point))
2137 '(ibuffer-summary t))))) 2150 '(ibuffer-summary t)))))
2138 2151
@@ -2197,10 +2210,11 @@ If optional arg SILENT is non-nil, do not display progress messages."
2197 ;; I tried to update this automatically from the mode-line-process format, 2210 ;; I tried to update this automatically from the mode-line-process format,
2198 ;; but changing nil-ness of header-line-format while computing 2211 ;; but changing nil-ness of header-line-format while computing
2199 ;; mode-line-format is asking a bit too much it seems. --Stef 2212 ;; mode-line-format is asking a bit too much it seems. --Stef
2200 (setq header-line-format 2213 (unless (eq ibuffer-use-header-line 'title)
2201 (and ibuffer-use-header-line 2214 (setq header-line-format
2202 ibuffer-filtering-qualifiers 2215 (and ibuffer-use-header-line
2203 ibuffer-header-line-format))) 2216 ibuffer-filtering-qualifiers
2217 ibuffer-header-line-format))))
2204 2218
2205(defun ibuffer-sort-bufferlist (bmarklist) 2219(defun ibuffer-sort-bufferlist (bmarklist)
2206 (unless ibuffer-sorting-functions-alist 2220 (unless ibuffer-sorting-functions-alist