diff --git a/lisp/org.el b/lisp/org.el index 2c100c863..148c0ea65 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 96f1ecd60..cddc33d8f 100644 --- a/testing/lisp/test-org.el +++ b/testing/lisp/test-org.el @@ -4524,14 +4524,15 @@ Paragraph" '((: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" (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]] :tag:" + (let ((org-tags-column 0)) + (org-fix-tags-on-the-fly) + (insert "x") + (buffer-string)))))) (ert-deftest test-org/tags-at () (should