summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicolas Goaziou <mail@nicolasgoaziou.fr>2016-09-30 00:56:58 +0200
committerNicolas Goaziou <mail@nicolasgoaziou.fr>2016-09-30 00:58:21 +0200
commitb3c556d83ac5407aa250557d4bec89aef238684f (patch)
tree0e0ffe0142c18950daca361d9756f64177b786ba
parent12196b84726f88d16f273752966a8efbca144188 (diff)
downloadorg-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.el39
-rw-r--r--testing/lisp/test-org.el17
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