summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicolas Goaziou <mail@nicolasgoaziou.fr>2017-03-13 22:45:54 +0100
committerNicolas Goaziou <mail@nicolasgoaziou.fr>2017-03-14 09:03:59 +0100
commit92ee4d06a2a88b26a3fe33acbf6abb40f6944dbe (patch)
tree4f1f88cd5b2d01e58cc62f8eba4310d86a494f76
parentad194846760a8fcde598b8de21ab3e51c4ed394b (diff)
downloadorg-mode-92ee4d06a2a88b26a3fe33acbf6abb40f6944dbe.tar.gz
org-capture: Fix escaping characters in template embedded S-exps
* lisp/org-capture.el (org-capture-fill-template): Escape backslash characters in %i contents when those are inserted within a S-exp. Also prevent adding any prefix to %i contents spanning over multiple lines when they are inserted within a S-exp. * testing/lisp/test-org-capture.el (test-org-capture/fill-template): Add tests. Reported-by: Samuel Wales <samologist@gmail.com> <http://permalink.gmane.org/gmane.emacs.orgmode/112232>
-rw-r--r--lisp/org-capture.el59
-rw-r--r--testing/lisp/test-org-capture.el13
2 files changed, 46 insertions, 26 deletions
diff --git a/lisp/org-capture.el b/lisp/org-capture.el
index 9003b2f..7a2007e 100644
--- a/lisp/org-capture.el
+++ b/lisp/org-capture.el
@@ -1654,34 +1654,41 @@ The template may still contain \"%?\" for cursor positioning."
(delete-region pos end)
(set-marker pos nil)
(set-marker end nil)
- (let ((replacement
- (pcase (string-to-char value)
- (?< (format-time-string time-string))
- (?:
- (or (plist-get org-store-link-plist (intern value))
- ""))
- (?i (let ((lead (buffer-substring-no-properties
+ (let* ((inside-sexp? (org-capture-inside-embedded-elisp-p))
+ (replacement
+ (pcase (string-to-char value)
+ (?< (format-time-string time-string))
+ (?:
+ (or (plist-get org-store-link-plist (intern value))
+ ""))
+ (?i
+ (if inside-sexp? v-i
+ ;; Outside embedded Lisp, repeat leading
+ ;; characters before initial place holder
+ ;; every line.
+ (let ((lead (buffer-substring-no-properties
(line-beginning-position) (point))))
- (mapconcat #'identity
- (split-string v-i "\n")
- (concat "\n" lead))))
- (?a v-a)
- (?A v-A)
- (?c v-c)
- (?f v-f)
- (?F v-F)
- (?k v-k)
- (?K v-K)
- (?l v-l)
- (?n v-n)
- (?t v-t)
- (?T v-T)
- (?u v-u)
- (?U v-U)
- (?x v-x))))
+ (replace-regexp-in-string "\n\\(.\\)"
+ (concat lead "\\1")
+ v-i nil nil 1))))
+ (?a v-a)
+ (?A v-A)
+ (?c v-c)
+ (?f v-f)
+ (?F v-F)
+ (?k v-k)
+ (?K v-K)
+ (?l v-l)
+ (?n v-n)
+ (?t v-t)
+ (?T v-T)
+ (?u v-u)
+ (?U v-U)
+ (?x v-x))))
(insert
- (if (org-capture-inside-embedded-elisp-p)
- (replace-regexp-in-string "\"" "\\\\\"" replacement)
+ (if inside-sexp?
+ ;; Escape sensitive characters.
+ (replace-regexp-in-string "[\\\"]" "\\\\\\&" replacement)
replacement))))))))
;; Expand %() embedded Elisp. Limit to Sexp originally marked.
diff --git a/testing/lisp/test-org-capture.el b/testing/lisp/test-org-capture.el
index 3f477b2..c630142 100644
--- a/testing/lisp/test-org-capture.el
+++ b/testing/lisp/test-org-capture.el
@@ -35,6 +35,13 @@
(should
(equal "success!\n"
(org-capture-fill-template "%(concat \"success\" \"!\")")))
+ ;; It is possible to include other place holders in %(sexp). In
+ ;; that case properly escape \ and " characters.
+ (should
+ (equal "Nested string \"\\\"\\\"\"\n"
+ (let ((org-store-link-plist nil))
+ (org-capture-fill-template "%(concat \"%i\")"
+ "Nested string \"\\\"\\\"\""))))
;; %<...> placeholder.
(should
(equal (concat (format-time-string "%Y") "\n")
@@ -66,6 +73,12 @@
(let ((org-store-link-plist nil))
(org-capture-fill-template
"%i" "%(concat \"no \" \"evaluation\")"))))
+ ;; When %i contents span over multiple line, repeat initial leading
+ ;; characters over each line.
+ (should
+ (equal "> line 1\n> line 2\n"
+ (let ((org-store-link-plist nil))
+ (org-capture-fill-template "> %i" "line 1\nline 2"))))
;; Test %-escaping with \ character.
(should
(equal "%i\n"