emacs-elpa-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[elpa] externals/valign b0cea9f 012/198: Make point appear in the middle


From: Stefan Monnier
Subject: [elpa] externals/valign b0cea9f 012/198: Make point appear in the middle for empty cells
Date: Tue, 1 Dec 2020 18:19:06 -0500 (EST)

branch: externals/valign
commit b0cea9f08da5109a4c80b4668521411d10e9940a
Author: Yuan Fu <casouri@gmail.com>
Commit: Yuan Fu <casouri@gmail.com>

    Make point appear in the middle for empty cells
    
    * valign.el (valign--clean-text-property): New function.
    (valign-table): Add comments.  Add a case when aligning empty cells.
---
 valign.el | 60 +++++++++++++++++++++++++++++++++++++++++++++++++-----------
 1 file changed, 49 insertions(+), 11 deletions(-)

diff --git a/valign.el b/valign.el
index 183ddbd..f21eb33 100644
--- a/valign.el
+++ b/valign.el
@@ -219,6 +219,20 @@ white space stretching to XPOS, a pixel x position."
      beg end 'display
      `(space :align-to (,xpos)))))
 
+(defun valign--clean-text-property (beg end)
+  "Clean up the display text property between BEG and END."
+  (save-excursion
+    (let (match)
+      (goto-char beg)
+      (while (and (setq match (text-property-search-forward
+                               'display nil (lambda (p _)
+                                              (and (consp p)
+                                                   (eq (car p) 'image)))))
+                  (< (point) end))
+        (put-text-property (prop-match-beginning match)
+                           (prop-match-end match)
+                           'display nil)))))
+
 (defun valign-initial-alignment (beg end)
   "Perform initial alignment for tables between BEG and END.
 Supposed to be called from jit-lock."
@@ -289,27 +303,33 @@ for the former, and 'multi-column for the latter."
   (condition-case err
       (save-excursion
         (let (end column-width-list column-idx pos ssw bar-width
-                  separator-row-point rev-list)
+                  separator-row-point rev-list right-point)
           ;; ‘separator-row-point’ marks the point for separator-row,
-          ;; so we can later come back to it and align it.
-          ;; ‘rev-list’ is the reverse list of right positions of each
-          ;; separator row cell.
+          ;; so we can later come back to it and align it. ‘rev-list’
+          ;; is the reverse list of right positions of each separator
+          ;; row cell. ‘right-point’ marks point before the right bar
+          ;; for each cell.
           (if (not (valign--end-of-table))
               (user-error "Not on a table"))
           (setq end (point))
           (valign--beginning-of-table)
           (setq column-width-list
                 (valign--calculate-column-width-list end))
-          ;; Iterate each line and apply tab stops.
+          ;; Iterate each cell and apply tab stops.
           (valign--do-table column-idx end
+            ;; We don’t align the separator row yet, but will come
+            ;; back to it.
             (if (valign--sperator-p)
                 (setq separator-row-point (point))
               (save-excursion
-                (when (save-excursion (search-forward "|" nil t))
+                ;; Check there is a right bar.
+                (when (save-excursion
+                        (setq right-point (search-forward "|" nil t)))
                   ;; We are after the left bar (“|”).
                   ;; Start aligning this cell.
                   (let* ((col-width (or (nth column-idx column-width-list)
-                                        0))
+                                        0)) ;; Pixel width of the column
+                         ;; Pixel width of the cell.
                          (cell-width (valign--cell-width))
                          ;; single-space-width
                          (ssw (or ssw (valign--glyph-width-at-point)))
@@ -317,18 +337,34 @@ for the former, and 'multi-column for the latter."
                                         (valign--glyph-width-at-point
                                          (1- (point)))))
                          tab-width tab-start tab-end)
-                    ;; Initialize some numbers.
+                    ;; Initialize some numbers when we are at a new
+                    ;; line. ‘pos’ is the pixel position of the
+                    ;; current point, i.e., after the left bar.
                     (if (eq column-idx 0)
                         (setq pos (valign--pixel-width-from-to
                                    (line-beginning-position) (point))
                               rev-list nil))
+                    ;; Clean up old tabs (i.e., stuff used for padding).
+                    (valign--clean-text-property (point) (1- right-point))
                     ;; Align an empty cell.
                     (if (eq cell-width 0)
                         (progn
                           (setq tab-start (point))
                           (valign--skip-space-forward)
-                          (valign--put-text-property
-                           tab-start (point) (+ pos col-width ssw)))
+                          (if (< (- (point) tab-start) 2)
+                              (valign--put-text-property
+                               tab-start (point) (+ pos col-width ssw))
+                            ;; When possible, we try to add two tabs
+                            ;; and the point can appear in the middle
+                            ;; of the cell, instead of on the very
+                            ;; left or very right.
+                            (valign--put-text-property
+                             tab-start
+                             (1+ tab-start)
+                             (+ pos (/ col-width 2) ssw))
+                            (valign--put-text-property
+                             (1+ tab-start) (point)
+                             (+ pos col-width ssw))))
                       ;; Align a left-aligned cell.
                       (pcase (valign--cell-alignment)
                         ('left (search-forward "|" nil t)
@@ -346,6 +382,7 @@ for the former, and 'multi-column for the latter."
                                 (valign--put-text-property
                                  tab-start (point)
                                  (+ pos tab-width)))))
+                    ;; Update ‘pos’ for the next cell.
                     (setq pos (+ pos col-width bar-width ssw))
                     (push (- pos bar-width) rev-list))))))
           ;; After aligning all rows, align the separator row.
@@ -359,7 +396,8 @@ for the former, and 'multi-column for the latter."
                      (col-idx 0))
                  (while (search-forward "+" end t)
                    (valign--separator-row-add-overlay
-                    p (1- (point)) (or (nth col-idx (reverse rev-list)) 0))
+                    p (1- (point))
+                    (or (nth col-idx (reverse rev-list)) 0))
                    (cl-incf col-idx)
                    (setq p (point)))
                  ;; Last column



reply via email to

[Prev in Thread] Current Thread [Next in Thread]