diff options
| -rw-r--r-- | lisp/emacs-lisp/tabulated-list.el | 61 |
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 | |||
| 102 | object identifying the entry, and COLS is a vector of column | 102 | object identifying the entry, and COLS is a vector of column |
| 103 | descriptors, as documented in `tabulated-list-entries'.") | 103 | descriptors, 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. |
| 107 | If nil, no additional sorting is performed. | 109 | If 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. | ||
| 305 | Check 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. |
| 303 | This sorts the `tabulated-list-entries' list if sorting is | 313 | This 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." | |||
| 402 | N is the column number, COL-DESC is a column descriptor (see | 419 | N 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. |
| 404 | Return the column number after insertion." | 421 | Return 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) |