forked from mirrors/org-mode
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>
This commit is contained in:
parent
ad19484676
commit
92ee4d06a2
|
@ -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.
|
||||
|
|
|
@ -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"
|
||||
|
|
Loading…
Reference in New Issue