From d04c20deece7b1d0eb40f7b8365a87484f26db6a Mon Sep 17 00:00:00 2001 From: Rasmus Date: Thu, 21 Dec 2017 14:37:06 +0100 Subject: [PATCH 5/6] org: Change structure insertion * lisp/org.el (org-insert-structure-template): Change newline behavior. * testing/lisp/test-org.el (test-org/insert-template): New tests. `org-insert-structure-template' considers indentation and also insert newlines between the beginning and the end of the block. --- lisp/org.el | 81 +++++++++++++++++++++++++++------------- testing/lisp/test-org.el | 35 +++++++++++++++-- 2 files changed, 87 insertions(+), 29 deletions(-) diff --git a/lisp/org.el b/lisp/org.el index bcf8b5986..4fd5dce51 100644 --- a/lisp/org.el +++ b/lisp/org.el @@ -11762,33 +11762,62 @@ insert an empty block." (`("\t" . ,_) (read-string "Structure type: ")) (`(,_ ,choice . ,_) choice)))) (let* ((region? (use-region-p)) - (s (if region? (region-beginning) (point))) - (e (copy-marker (if region? (region-end) (point)) t)) - column) - (when (string-match-p - (concat "\\`" (regexp-opt '("example" "export" "src"))) - type) - (org-escape-code-in-region s e)) - (goto-char s) - (setq column (current-indentation)) - (beginning-of-line) - (indent-to column) - (insert (format "#+begin_%s%s\n" type (if (string-equal "src" type) " " ""))) - (goto-char e) - (if (bolp) - (progn - (skip-chars-backward " \n\t") - (forward-line)) - (end-of-line) + (col (current-indentation)) + (indent (make-string col ?\s)) + (special? (string-match-p "\\(src\\|export\\)\\'" type)) + (region-string (and region? + (buffer-substring (region-beginning) + (region-end)))) + (region-end-blank (and region? + (save-excursion + (goto-char (region-end)) + (when (looking-at "[ \t]*$") + (replace-match "") + t)))) + s) + (when region? (delete-region (region-beginning) (region-end))) + (unless (save-excursion (skip-chars-backward "[ \t]") (bolp)) (insert "\n")) - (indent-to column) - (insert (format "#+end_%s\n" - (car (split-string type)))) - (when (or (not region?) - (string-match-p "src\\|\\`export\\'" type)) - (goto-char s) - (end-of-line)) - (set-marker e nil))) + (beginning-of-line) + (save-excursion + (insert + (with-temp-buffer + (when region? + (insert region-string "\n") + (when (string-match-p + (concat "\\`" (regexp-opt '("example" "export" "src"))) + type) + (org-escape-code-in-region (point-min) (point-max)))) + (goto-char (point-min)) + ;; Delete trailing white-lines. + (when region? + (while (looking-at-p "^[ \t]*$") + (delete-region (line-beginning-position) + (line-beginning-position 2)))) + (save-excursion + (while (not (eobp)) + (unless (looking-at-p indent) + (insert indent)) + (forward-line))) + (insert + indent + (format "#+begin_%s%s\n" type (if special? " " ""))) + (unless region? (indent-to col)) + (setq s (point)) + (goto-char (point-max)) + (skip-chars-backward "[ \t\n]" s) + (delete-region (line-end-position) (point-max)) + (insert "\n" indent + (format "#+end_%s" (car (split-string type))) + (if region-end-blank "" "\n")) + (buffer-substring (point-min) (point)))) + (when (and (eobp) (not (bolp))) (insert "\n"))) + (cond (special? + (end-of-line)) + (t + (forward-line) + (skip-chars-forward "[ \t]*"))))) + ;;;; TODO, DEADLINE, Comments diff --git a/testing/lisp/test-org.el b/testing/lisp/test-org.el index 8d8b36f86..5ab35f7de 100644 --- a/testing/lisp/test-org.el +++ b/testing/lisp/test-org.el @@ -4047,17 +4047,35 @@ Text. "Test `org-insert-structure-template'." ;; Test in empty buffer. (should - (string= "#+begin_foo\n#+end_foo\n" + (string= "#+begin_foo\n\n#+end_foo\n" (org-test-with-temp-text "" (org-insert-structure-template "foo") (buffer-string)))) ;; Test with multiple lines in buffer. (should - (string= "#+begin_foo\nI'm a paragraph\n#+end_foo\n\nI'm a second paragraph" + (string= "#+begin_foo\nI'm a paragraph\n#+end_foo\nI'm a second paragraph" (org-test-with-temp-text "I'm a paragraph\n\nI'm a second paragraph" (org-mark-element) (org-insert-structure-template "foo") (buffer-string)))) + ;; Mark only the current line. + (should + (string= "#+begin_foo\nI'm a paragraph\n#+end_foo\n\nI'm a second paragraph" + (org-test-with-temp-text "I'm a paragraph\n\nI'm a second paragraph" + (set-mark (point-min)) + (end-of-line) + (activate-mark) + (org-insert-structure-template "foo") + (buffer-string)))) + ;; Middle of paragraph + (should + (string= "p1\n#+begin_foo\np2\n#+end_foo\np3" + (org-test-with-temp-text "p1\np2\np3" + (set-mark (line-beginning-position)) + (end-of-line) + (activate-mark) + (org-insert-structure-template "foo") + (buffer-string)))) ;; Test with text in buffer, no region, no final newline. (should (string= "#+begin_foo\nI'm a paragraph.\n#+end_foo\n" @@ -4086,7 +4104,18 @@ Text. (org-test-with-temp-text " This is a paragraph" (org-mark-element) (org-insert-structure-template "foo") - (buffer-string))))) + (buffer-string)))) + ;; Test point location. + (should + (eq (length "#\\+begin_foo\n") + (org-test-with-temp-text "" + (org-insert-structure-template "foo") + (point)))) + (should + (eq (length "#\\+begin_src ") + (org-test-with-temp-text "" + (org-insert-structure-template "src") + (point))))) (ert-deftest test-org/previous-block () "Test `org-previous-block' specifications." -- 2.17.0