aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lisp/emacs-lisp/tabulated-list.el61
1 files changed, 49 insertions, 12 deletions
diff --git a/lisp/emacs-lisp/tabulated-list.el b/lisp/emacs-lisp/tabulated-list.el
index 00b029d8f3e..cf297f1ef4a 100644
--- a/lisp/emacs-lisp/tabulated-list.el
+++ b/lisp/emacs-lisp/tabulated-list.el
@@ -102,6 +102,8 @@ It is called with two arguments, ID and COLS. ID is a Lisp
102object identifying the entry, and COLS is a vector of column 102object identifying the entry, and COLS is a vector of column
103descriptors, as documented in `tabulated-list-entries'.") 103descriptors, as documented in `tabulated-list-entries'.")
104 104
105(defvar tabulated-list--near-rows)
106
105(defvar-local tabulated-list-sort-key nil 107(defvar-local tabulated-list-sort-key nil
106 "Sort key for the current Tabulated List mode buffer. 108 "Sort key for the current Tabulated List mode buffer.
107If nil, no additional sorting is performed. 109If nil, no additional sorting is performed.
@@ -298,6 +300,14 @@ column. Negate the predicate that would be returned if
298 (lambda (a b) (not (funcall sorter a b))) 300 (lambda (a b) (not (funcall sorter a b)))
299 sorter)))) 301 sorter))))
300 302
303(defsubst tabulated-list--col-local-max-widths (col)
304 "Return maximum entry widths at column COL around current row.
305Check the current row, the previous one and the next row."
306 (apply #'max (mapcar (lambda (x)
307 (let ((nt (elt x col)))
308 (string-width (if (stringp nt) nt (car nt)))))
309 tabulated-list--near-rows)))
310
301(defun tabulated-list-print (&optional remember-pos update) 311(defun tabulated-list-print (&optional remember-pos update)
302 "Populate the current Tabulated List mode buffer. 312 "Populate the current Tabulated List mode buffer.
303This sorts the `tabulated-list-entries' list if sorting is 313This sorts the `tabulated-list-entries' list if sorting is
@@ -340,8 +350,14 @@ changing `tabulated-list-sort-key'."
340 (unless tabulated-list-use-header-line 350 (unless tabulated-list-use-header-line
341 (tabulated-list-print-fake-header))) 351 (tabulated-list-print-fake-header)))
342 ;; Finally, print the resulting list. 352 ;; Finally, print the resulting list.
343 (dolist (elt entries) 353 (while entries
344 (let ((id (car elt))) 354 (let* ((elt (car entries))
355 (tabulated-list--near-rows
356 (list
357 (or (tabulated-list-get-entry (point-at-bol 0)) (cadr elt))
358 (cadr elt)
359 (or (cadr (cadr entries)) (cadr elt))))
360 (id (car elt)))
345 (and entry-id 361 (and entry-id
346 (equal entry-id id) 362 (equal entry-id id)
347 (setq entry-id nil 363 (setq entry-id nil
@@ -368,7 +384,8 @@ changing `tabulated-list-sort-key'."
368 (t t))) 384 (t t)))
369 (let ((old (point))) 385 (let ((old (point)))
370 (forward-line 1) 386 (forward-line 1)
371 (delete-region old (point))))))) 387 (delete-region old (point))))))
388 (setq entries (cdr entries)))
372 (set-buffer-modified-p nil) 389 (set-buffer-modified-p nil)
373 ;; If REMEMBER-POS was specified, move to the "old" location. 390 ;; If REMEMBER-POS was specified, move to the "old" location.
374 (if saved-pt 391 (if saved-pt
@@ -402,8 +419,6 @@ of column descriptors."
402N is the column number, COL-DESC is a column descriptor (see 419N is the column number, COL-DESC is a column descriptor (see
403`tabulated-list-entries'), and X is the column number at point. 420`tabulated-list-entries'), and X is the column number at point.
404Return the column number after insertion." 421Return the column number after insertion."
405 ;; TODO: don't truncate to `width' if the next column is align-right
406 ;; and has some space left.
407 (let* ((format (aref tabulated-list-format n)) 422 (let* ((format (aref tabulated-list-format n))
408 (name (nth 0 format)) 423 (name (nth 0 format))
409 (width (nth 1 format)) 424 (width (nth 1 format))
@@ -414,12 +429,29 @@ Return the column number after insertion."
414 (label-width (string-width label)) 429 (label-width (string-width label))
415 (help-echo (concat (car format) ": " label)) 430 (help-echo (concat (car format) ": " label))
416 (opoint (point)) 431 (opoint (point))
417 (not-last-col (< (1+ n) (length tabulated-list-format)))) 432 (not-last-col (< (1+ n) (length tabulated-list-format)))
433 available-space)
434 (when not-last-col
435 (let* ((next-col-format (aref tabulated-list-format (1+ n)))
436 (next-col-right-align (plist-get (nthcdr 3 next-col-format)
437 :right-align))
438 (next-col-width (nth 1 next-col-format)))
439 (setq available-space
440 (if (and (not right-align)
441 next-col-right-align)
442 (-
443 (+ width next-col-width)
444 (min next-col-width
445 (tabulated-list--col-local-max-widths (1+ n))))
446 width))))
418 ;; Truncate labels if necessary (except last column). 447 ;; Truncate labels if necessary (except last column).
419 (and not-last-col 448 ;; Don't truncate to `width' if the next column is align-right
420 (> label-width width) 449 ;; and has some space left, truncate to `available-space' instead.
421 (setq label (truncate-string-to-width label width nil nil t) 450 (when (and not-last-col
422 label-width width)) 451 (> label-width available-space)
452 (setq label (truncate-string-to-width
453 label available-space nil nil t)
454 label-width available-space)))
423 (setq label (bidi-string-mark-left-to-right label)) 455 (setq label (bidi-string-mark-left-to-right label))
424 (when (and right-align (> width label-width)) 456 (when (and right-align (> width label-width))
425 (let ((shift (- width label-width))) 457 (let ((shift (- width label-width)))
@@ -437,7 +469,7 @@ Return the column number after insertion."
437 (when not-last-col 469 (when not-last-col
438 (when (> pad-right 0) (insert (make-string pad-right ?\s))) 470 (when (> pad-right 0) (insert (make-string pad-right ?\s)))
439 (insert (propertize 471 (insert (propertize
440 (make-string (- next-x x label-width pad-right) ?\s) 472 (make-string (- width (min width label-width)) ?\s)
441 'display `(space :align-to ,next-x)))) 473 'display `(space :align-to ,next-x))))
442 (put-text-property opoint (point) 'tabulated-list-column-name name) 474 (put-text-property opoint (point) 'tabulated-list-column-name name)
443 next-x))) 475 next-x)))
@@ -494,7 +526,12 @@ this is the vector stored within it."
494 (when (< pos eol) 526 (when (< pos eol)
495 (delete-region pos (next-single-property-change pos prop nil eol)) 527 (delete-region pos (next-single-property-change pos prop nil eol))
496 (goto-char pos) 528 (goto-char pos)
497 (tabulated-list-print-col col desc (current-column)) 529 (let ((tabulated-list--near-rows
530 (list
531 (tabulated-list-get-entry (point-at-bol 0))
532 entry
533 (or (tabulated-list-get-entry (point-at-bol 2)) entry))))
534 (tabulated-list-print-col col desc (current-column)))
498 (if change-entry-data 535 (if change-entry-data
499 (aset entry col desc)) 536 (aset entry col desc))
500 (put-text-property pos (point) 'tabulated-list-id id) 537 (put-text-property pos (point) 'tabulated-list-id id)