diff options
author | Nicolas Goaziou <mail@nicolasgoaziou.fr> | 2016-09-30 00:56:58 +0200 |
---|---|---|
committer | Nicolas Goaziou <mail@nicolasgoaziou.fr> | 2016-09-30 00:58:21 +0200 |
commit | b3c556d83ac5407aa250557d4bec89aef238684f (patch) | |
tree | 0e0ffe0142c18950daca361d9756f64177b786ba | |
parent | 12196b84726f88d16f273752966a8efbca144188 (diff) | |
download | org-mode-b3c556d83ac5407aa250557d4bec89aef238684f.tar.gz |
Fix tags alignment when headline contains invisible text
* lisp/org.el (org-align-tags-here): Do not use `org-move-to-column',
which may move point on the other side of some invisible text.
Refactor code.
* testing/lisp/test-org.el (test-org/tag-align): Add test.
Reported-by: Michael Fiano <michael.fiano@gmail.com>
<http://permalink.gmane.org/gmane.emacs.orgmode/109435>
-rw-r--r-- | lisp/org.el | 39 | ||||
-rw-r--r-- | testing/lisp/test-org.el | 17 |
2 files changed, 30 insertions, 26 deletions
diff --git a/lisp/org.el b/lisp/org.el index 2c100c8..148c0ea 100644 --- a/lisp/org.el +++ b/lisp/org.el @@ -14951,28 +14951,23 @@ If ONOFF is `on' or `off', don't toggle but set to this state." res)) (defun org-align-tags-here (to-col) - ;; Assumes that this is a headline - "Align tags on the current headline to TO-COL." - (let ((pos (point)) (col (current-column)) ncol tags-l p) - (beginning-of-line 1) - (if (and (looking-at ".*?\\([ \t]+\\)\\(:[[:alnum:]_@#%:]+:\\)[ \t]*$") - (< pos (match-beginning 2))) - (progn - (setq tags-l (string-width (match-string 2))) - (goto-char (match-beginning 1)) - (insert " ") - (delete-region (point) (1+ (match-beginning 2))) - (setq ncol (max (current-column) - (1+ col) - (if (> to-col 0) - to-col - (- (abs to-col) tags-l)))) - (setq p (point)) - (insert (make-string (- ncol (current-column)) ?\ )) - (setq ncol (current-column)) - (when indent-tabs-mode (tabify p (point-at-eol))) - (org-move-to-column (min ncol col))) - (goto-char pos)))) + "Align tags on the current headline to TO-COL. +Assume point is on a headline." + (let ((pos (point))) + (beginning-of-line) + (if (or (not (looking-at ".*?\\([ \t]+\\)\\(:[[:alnum:]_@#%:]+:\\)[ \t]*$")) + (>= pos (match-beginning 2))) + ;; No tags or point within tags: do not align. + (goto-char pos) + (goto-char (match-beginning 1)) + (let ((shift (max (- (if (>= to-col 0) to-col + (- (abs to-col) (string-width (match-string 2)))) + (current-column)) + 1))) + (replace-match (make-string shift ?\s) nil nil nil 1) + ;; Preserve initial position, if possible. In any case, stop + ;; before tags. + (when (< pos (point)) (goto-char pos)))))) (defun org-set-tags-command (&optional arg just-align) "Call the set-tags command for the current entry." diff --git a/testing/lisp/test-org.el b/testing/lisp/test-org.el index 96f1ecd..cddc33d 100644 --- a/testing/lisp/test-org.el +++ b/testing/lisp/test-org.el @@ -4524,14 +4524,15 @@ Paragraph<point>" '((:startgroup) ("group") ("t1") ("t2") (:endgroup))))) (ert-deftest test-org/tag-align () - "Test `org-align-tags-here' with different display width." + "Test `org-align-tags-here' specifications" + ;; Test aligning tags with different display width. (should ;; 12345678901234567890 (equal "* Test :abc:" (org-test-with-temp-text "* Test :abc:" (let ((org-tags-column -20) (indent-tabs-mode nil)) - (org-fix-tags-on-the-fly)) + (org-fix-tags-on-the-fly)) (buffer-string)))) (should ;; 12345678901234567890 @@ -4539,8 +4540,16 @@ Paragraph<point>" (org-test-with-temp-text "* Test :日本語:" (let ((org-tags-column -20) (indent-tabs-mode nil)) - (org-fix-tags-on-the-fly)) - (buffer-string))))) + (org-fix-tags-on-the-fly)) + (buffer-string)))) + ;; Make sure aligning tags do not skip invisible text. + (should + (equal "* [[linkx]] :tag:" + (org-test-with-temp-text "* [[link<point>]] :tag:" + (let ((org-tags-column 0)) + (org-fix-tags-on-the-fly) + (insert "x") + (buffer-string)))))) (ert-deftest test-org/tags-at () (should |