Browse Source

Fix `org-kill-line' on tag lines

* lisp/org.el (org-kill-line): Preserve tags when `org-special-ctrl-k'
  is non-nil.
* testing/lisp/test-org.el (test-org/kill-line): New test.

Reported-by: Matt Lundin <mdl@imapmail.org>
<http://lists.gnu.org/r/emacs-orgmode/2018-07/msg00122.html>
Nicolas Goaziou 1 year ago
parent
commit
d975b44fd4
2 changed files with 71 additions and 2 deletions
  1. 3 2
      lisp/org.el
  2. 68 0
      testing/lisp/test-org.el

+ 3 - 2
lisp/org.el

@@ -22837,10 +22837,11 @@ depending on context."
 	"`\\[org-kill-line]' aborted as it would kill a hidden subtree")))
     (call-interactively
      (if (bound-and-true-p visual-line-mode) 'kill-visual-line 'kill-line)))
-   ((looking-at org-tag-line-re)
+   ((org-match-line org-tag-line-re)
     (let ((end (save-excursion
 		 (goto-char (match-beginning 1))
-		 (skip-chars-backward " \t"))))
+		 (skip-chars-backward " \t")
+		 (point))))
       (if (<= end (point))		;on tags part
 	  (kill-region (point) (line-end-position))
 	(kill-region (point) end)))

+ 68 - 0
testing/lisp/test-org.el

@@ -1639,6 +1639,74 @@
 	    (org-toggle-fixed-width)
 	    (buffer-string)))))
 
+(ert-deftest test-org/kill-line ()
+  "Test `org-kill-line' specifications."
+  ;; At the beginning of a line, kill whole line.
+  (should
+   (equal ""
+	  (org-test-with-temp-text "abc"
+	    (org-kill-line)
+	    (buffer-string))))
+  ;; In the middle of a line, kill line until its end.
+  (should
+   (equal "a"
+	  (org-test-with-temp-text "a<point>bc"
+	    (org-kill-line)
+	    (buffer-string))))
+  ;; Do not kill newline character.
+  (should
+   (equal "\n123"
+	  (org-test-with-temp-text "abc\n123"
+	    (org-kill-line)
+	    (buffer-string))))
+  (should
+   (equal "a\n123"
+	  (org-test-with-temp-text "a<point>bc\n123"
+	    (org-kill-line)
+	    (buffer-string))))
+  ;; When `org-special-ctrl-k' is non-nil and point is at a headline,
+  ;; kill until tags.
+  (should
+   (equal "* A :tag:"
+	  (org-test-with-temp-text "* A<point>B :tag:"
+	    (let ((org-special-ctrl-k t)
+		  (org-tags-column 0))
+	      (org-kill-line))
+	    (buffer-string))))
+  ;; If point is on tags, only kill part left until the end of line.
+  (should
+   (equal "* A :tag:"
+	  (org-test-with-temp-text "* A :tag:<point>tag2:"
+	    (let ((org-special-ctrl-k t)
+		  (org-tags-column 0))
+	      (org-kill-line))
+	    (buffer-string))))
+  ;; However, if point is at the beginning of the line, kill whole
+  ;; headline.
+  (should
+   (equal ""
+	  (org-test-with-temp-text "* AB :tag:"
+	    (let ((org-special-ctrl-k t)
+		  (org-tags-column 0))
+	      (org-kill-line))
+	    (buffer-string))))
+  ;; When `org-ctrl-k-protect-subtree' is non-nil, and point is in
+  ;; invisible text, ask before removing it.  When set to `error',
+  ;; throw an error.
+  (should-error
+   (org-test-with-temp-text "* H\n** <point>H2\nContents\n* H3"
+     (org-overview)
+     (let ((org-special-ctrl-k nil)
+	   (org-ctrl-k-protect-subtree t))
+       (cl-letf (((symbol-function 'y-or-n-p) 'ignore))
+	 (org-kill-line)))))
+  (should-error
+   (org-test-with-temp-text "* H\n** <point>H2\nContents\n* H3"
+     (org-overview)
+     (let ((org-special-ctrl-k nil)
+	   (org-ctrl-k-protect-subtree 'error))
+       (org-kill-line)))))
+
 
 
 ;;; Headline