summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicolas Goaziou <mail@nicolasgoaziou.fr>2017-08-26 00:09:51 +0200
committerNicolas Goaziou <mail@nicolasgoaziou.fr>2017-08-26 00:09:51 +0200
commita6840598ed288f2141771512b846ecba9c64b0e1 (patch)
tree0ec46f65f33a0a39250480eec4bed6798441ec9d
parent21a8ec1c0f4d1797288a12cd9bfc6446a2ac03cb (diff)
downloadorg-mode-a6840598ed288f2141771512b846ecba9c64b0e1.tar.gz
Fix `org-copy-visible'release_9.0.10
* lisp/org.el (org-copy-visible): Rewrite function. Do not use dubious `org-find-visible' and `org-find-invisible'. * testing/lisp/test-org.el (test-org/copy-visible): New test. Reported-by: Gary Cheng <garycheng12@gmail.com> <http://lists.gnu.org/archive/html/emacs-orgmode/2017-08/msg00568.html>
-rw-r--r--lisp/org.el18
-rw-r--r--testing/lisp/test-org.el47
2 files changed, 55 insertions, 10 deletions
diff --git a/lisp/org.el b/lisp/org.el
index 85c1a4b..87758fd 100644
--- a/lisp/org.el
+++ b/lisp/org.el
@@ -20898,16 +20898,14 @@ this numeric value."
(defun org-copy-visible (beg end)
"Copy the visible parts of the region."
(interactive "r")
- (let (snippets s)
- (save-excursion
- (save-restriction
- (narrow-to-region beg end)
- (setq s (goto-char (point-min)))
- (while (not (= (point) (point-max)))
- (goto-char (org-find-invisible))
- (push (buffer-substring s (point)) snippets)
- (setq s (goto-char (org-find-visible))))))
- (kill-new (apply 'concat (nreverse snippets)))))
+ (let ((result ""))
+ (while (/= beg end)
+ (when (get-char-property beg 'invisible)
+ (setq beg (next-single-char-property-change beg 'invisible nil end)))
+ (let ((next (next-single-char-property-change beg 'invisible nil end)))
+ (setq result (concat result (buffer-substring beg next)))
+ (setq beg next)))
+ (kill-new result)))
(defun org-copy-special ()
"Copy region in table or copy current subtree.
diff --git a/testing/lisp/test-org.el b/testing/lisp/test-org.el
index 260d391..37c7edf 100644
--- a/testing/lisp/test-org.el
+++ b/testing/lisp/test-org.el
@@ -5997,6 +5997,53 @@ Paragraph<point>"
(org-show-set-visibility 'minimal)
(org-invisible-p2))))
+(defun test-org/copy-visible ()
+ "Test `org-copy-visible' specifications."
+ (should
+ (equal "Foo"
+ (org-test-with-temp-text "Foo"
+ (let ((kill-ring nil))
+ (org-copy-visible (point-min) (point-max))
+ (current-kill 0 t)))))
+ ;; Skip invisible characters by text property.
+ (should
+ (equal "Foo"
+ (org-test-with-temp-text #("F<hidden>oo" 1 7 (invisible t))
+ (let ((kill-ring nil))
+ (org-copy-visible (point-min) (point-max))
+ (current-kill 0 t)))))
+ ;; Skip invisible characters by overlay.
+ (should
+ (equal "Foo"
+ (org-test-with-temp-text "F<hidden>oo"
+ (let ((o (make-overlay 2 10)))
+ (overlay-put o 'invisible t))
+ (let ((kill-ring nil))
+ (org-copy-visible (point-min) (point-max))
+ (current-kill 0 t)))))
+ ;; Handle invisible characters at the beginning and the end of the
+ ;; buffer.
+ (should
+ (equal "Foo"
+ (org-test-with-temp-text #("<hidden>Foo" 0 8 (invisible t))
+ (let ((kill-ring nil))
+ (org-copy-visible (point-min) (point-max))
+ (current-kill 0 t)))))
+ (should
+ (equal "Foo"
+ (org-test-with-temp-text #("Foo<hidden>" 3 11 (invisible t))
+ (let ((kill-ring nil))
+ (org-copy-visible (point-min) (point-max))
+ (current-kill 0 t)))))
+ ;; Handle multiple visible parts.
+ (should
+ (equal "abc"
+ (org-test-with-temp-text
+ #("aXbXc" 1 2 (invisible t) 3 4 (invisible t))
+ (let ((kill-ring nil))
+ (org-copy-visible (point-min) (point-max))
+ (current-kill 0 t))))))
+
(provide 'test-org)