[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[elpa] master 5136626: * packages/csv-mode/csv-mode.el: Auto-shorten col
From: |
Stefan Monnier |
Subject: |
[elpa] master 5136626: * packages/csv-mode/csv-mode.el: Auto-shorten columns as well |
Date: |
Tue, 22 Oct 2019 10:25:54 -0400 (EDT) |
branch: master
commit 5136626383fd2fb7e96bbe694bbacee824a30dce
Author: Stefan Monnier <address@hidden>
Commit: Stefan Monnier <address@hidden>
* packages/csv-mode/csv-mode.el: Auto-shorten columns as well
(csv--column-widths): Also return the position of the widest field in
each column.
(csv-align-fields, csv--jit-align): Update accordingly.
(csv--jit-width-change): New function.
(csv--jit-merge-columns): Use it on overlays placed on the widest field
of each column, to detect when they're shortened.
---
packages/csv-mode/csv-mode.el | 68 ++++++++++++++++++++++++++++++++++---------
1 file changed, 54 insertions(+), 14 deletions(-)
diff --git a/packages/csv-mode/csv-mode.el b/packages/csv-mode/csv-mode.el
index 336f9d3..73d34bb 100644
--- a/packages/csv-mode/csv-mode.el
+++ b/packages/csv-mode/csv-mode.el
@@ -4,7 +4,7 @@
;; Author: "Francis J. Wright" <address@hidden>
;; Maintainer: address@hidden
-;; Version: 1.9
+;; Version: 1.10
;; Package-Requires: ((emacs "24.1") (cl-lib "0.5"))
;; Keywords: convenience
@@ -990,7 +990,9 @@ The fields yanked are those last killed by
`csv-kill-fields'."
(defun csv--column-widths (beg end)
"Return a list of two lists (COLUMN-WIDTHS FIELD-WIDTHS).
-COLUMN-WIDTHS contains the widths of the columns after point.
+COLUMN-WIDTHS is a list of elements (WIDTH START END)
+indicating the widths of the columns after point (and the position of the
+widest field that determined the overall width).
FIELD-WIDTHS contains the widths of each individual field after
point."
(let ((column-widths '())
@@ -1001,17 +1003,19 @@ point."
(or (csv-not-looking-at-record)
(let ((w column-widths)
(col (current-column))
+ (beg (point))
field-width)
(while (not (eolp))
(csv-end-of-field)
(setq field-width (- (current-column) col))
(push field-width field-widths)
(if w
- (if (> field-width (car w)) (setcar w field-width))
- (setq w (list field-width)
+ (if (> field-width (caar w))
+ (setcar w (list field-width beg (point))))
+ (setq w (list (list field-width beg (point)))
column-widths (nconc column-widths w)))
(or (eolp) (forward-char)) ; Skip separator.
- (setq w (cdr w) col (current-column)))))
+ (setq w (cdr w) col (current-column) beg (point)))))
(forward-line))
(list column-widths (nreverse field-widths))))
@@ -1057,7 +1061,7 @@ If there is no selected region, default to the whole
buffer."
(align-padding (if (bolp) 0 csv-align-padding))
(left-padding 0) (right-padding 0)
(field-width (pop field-widths))
- (column-width (pop w))
+ (column-width (car (pop w)))
(x (- column-width field-width))) ; Required padding.
(csv-end-of-field)
(set-marker end (point)) ; End of current field.
@@ -1372,23 +1376,59 @@ setting works better)."
(defvar-local csv--jit-columns nil)
(defun csv--jit-merge-columns (column-widths)
- ;; FIXME: Keep track for each column of where is its widest field,
- ;; and arrange to recompute that column's width when that line's
- ;; field shrinks.
+ ;; FIXME: The incremental update (delayed by jit-lock-context-time) of column
+ ;; width is a bit jarring at times. It's OK while scrolling or when
+ ;; extending a column, but not right when enabling the csv-align-mode or
+ ;; when shortening the longest field (or deleting the line containing it),
+ ;; because in that case we have *several* cascaded updates, e.g.:
+ ;; - Remove the line with the longest field of column N.
+ ;; - Edit some line: this line is updated as if its field was the widest,
+ ;; hence its subsequent fields are too much to the left.
+ ;; - The rest is updated starting from the first few lines (according
+ ;; to jit-lock-chunk-size).
+ ;; - After the first few lines, come the next set of few lines,
+ ;; which may cause the previous few lines to need refresh again.
+ ;; - etc.. until arriving again at the edited line which is re-aligned
+ ;; again.
+ ;; - etc.. until the end of the windows, potentially causing yet more
+ ;; refreshes as we discover yet-wider fields for this column.
(let ((old-columns csv--jit-columns)
(changed nil))
(while (and old-columns column-widths)
- (when (> (car column-widths) (car old-columns))
+ (when (or (> (caar column-widths) (caar old-columns))
+ ;; Apparently modification-hooks aren't run when the
+ ;; whole text containing the overlay is deleted (e.g.
+ ;; the whole line), so detect this case here.
+ ;; It's a bit too late, but better than never.
+ (null (overlay-buffer (cdar old-columns))))
(setq changed t) ;; Return non-nil if some existing column changed.
- (setf (car old-columns) (car column-widths)))
+ (pcase-let ((`(,width ,beg ,end) (car column-widths)))
+ (setf (caar old-columns) width)
+ (move-overlay (cdar old-columns) beg end)))
(setq old-columns (cdr old-columns))
(setq column-widths (cdr column-widths)))
(when column-widths
;; New columns appeared.
- (setq csv--jit-columns (nconc csv--jit-columns
- (copy-sequence column-widths))))
+ (setq csv--jit-columns
+ (nconc csv--jit-columns
+ (mapcar (lambda (x)
+ (pcase-let*
+ ((`(,width ,beg ,end) x)
+ (ol (make-overlay beg end)))
+ (overlay-put ol 'csv-width t)
+ (overlay-put ol 'evaporate t)
+ (overlay-put ol 'modification-hooks
+ (list #'csv--jit-width-change))
+ (cons width ol)))
+ column-widths))))
changed))
+(defun csv--jit-width-change (ol after _beg _end &optional len)
+ (when (and after (> len 0))
+ ;; (let ((x (rassq ol csv--jit-columns)))
+ ;; (when x (setf (car x) -1)))
+ (delete-overlay ol)))
+
(defun csv--jit-unalign (beg end)
(remove-text-properties beg end
'(display nil csv--jit nil invisible nil
@@ -1479,7 +1519,7 @@ setting works better)."
(left-padding 0) (right-padding 0)
(field-width (pop field-widths))
(column-width
- (min (pop w)
+ (min (car (pop w))
(or width-config
;; Don't apply csv-align-max-width
;; to the last field!
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [elpa] master 5136626: * packages/csv-mode/csv-mode.el: Auto-shorten columns as well,
Stefan Monnier <=