diff options
author | Rasmus <rasmus@gmx.us> | 2017-12-21 12:59:36 +0100 |
---|---|---|
committer | Rasmus <rasmus@gmx.us> | 2018-04-08 12:47:12 +0200 |
commit | e5f6cb6c8b6c26772a92410a657b6986842dd23e (patch) | |
tree | ce579ce3b38f7693b9f4ccdb90bc813632949c57 | |
parent | b56df737b7392845c6e00d4cc52801e64c105f8b (diff) | |
download | org-mode-e5f6cb6c8b6c26772a92410a657b6986842dd23e.tar.gz |
org-tempo: Various improvements
* lisp/org-tempo.el (org-tempo-keywords-alist): Improve docstring.
(org-tempo--update-maybe):
(org-tempo--keys): New function.
(org-tempo-complete-tag):
(org-tempo-setup):
(org-tempo-add-templates): Use new functions.
(org-tempo-add-block): Smarter position of point.
* testing/lisp/test-org-tempo.el (test-org-tempo/cursor-placement):
(test-org-tempo/space-first-line): New tests.
* testing/lisp/test-org-tempo.el (test-org-tempo/completion): Adapt
test to changes.
Org Tempo more carefully checks for new definitions. When inserting
blocks point will differ depending on whether it is source block.
-rw-r--r-- | lisp/org-tempo.el | 38 | ||||
-rw-r--r-- | testing/lisp/test-org-tempo.el | 41 |
2 files changed, 67 insertions, 12 deletions
diff --git a/lisp/org-tempo.el b/lisp/org-tempo.el index a41c994..e1268b8 100644 --- a/lisp/org-tempo.el +++ b/lisp/org-tempo.el @@ -34,7 +34,7 @@ ;; ;; `tempo' can also be used to define more sophisticated keywords ;; completions. See the section "Additional keywords" below for -;; additional details. +;; examples. ;; ;;; Code: @@ -65,7 +65,9 @@ and KEYWORD. The tempo snippet \"<KEY\" is expand to the KEYWORD value. For example \"<l\" at the beginning of a line is expanded to -#+latex:" +\"#+latex:\". + +Note: the tempo function for \"#+include\" is defined elsewhere." :group 'org-tempo :type '(repeat (cons (string :tag "Key") (string :tag "Keyword"))) @@ -76,23 +78,35 @@ For example \"<l\" at the beginning of a line is expanded to ;;; Org Tempo functions and setup. (defun org-tempo-setup () - (org-tempo-add-templates) + (org-tempo--update-maybe) (tempo-use-tag-list 'org-tempo-tags) (setq-local tempo-match-finder "^ *\\(<[[:word:]]+\\)\\=")) +(defun org-tempo--keys () + "Return a list of all Org Tempo expansion strings, like \"<s\"." + (mapcar (lambda (pair) (format "<%s" (car pair))) + (append org-structure-template-alist + org-tempo-keywords-alist))) + +(defun org-tempo--update-maybe () + "Check and add new Org Tempo templates if necessary. +In particular, if new entries were added to +`org-structure-template-alist' or `org-tempo-keywords-alist', new +Tempo templates will be added." + (unless (cl-every (lambda (key) (assoc key org-tempo-tags)) + (org-tempo--keys)) + (org-tempo-add-templates))) + (defun org-tempo-add-templates () "Update all Org Tempo templates. Goes through `org-structure-template-alist' and `org-tempo-keywords-alist'." - (let ((keys (mapcar (lambda (pair) (format "<%c" (car pair))) - (append org-structure-template-alist - org-tempo-keywords-alist)))) + (let ((keys (org-tempo--keys))) ;; Check for duplicated snippet keys and warn if any are found. (when (> (length keys) (length (delete-dups keys))) (warn "Duplicated keys in `org-structure-template-alist' and `org-tempo-keywords-alist'")) - ;; Remove any keys already defined in case they have been updated. (setq org-tempo-tags (cl-remove-if (lambda (tag) (member (car tag) keys)) org-tempo-tags)) @@ -102,9 +116,11 @@ Goes through `org-structure-template-alist' and (defun org-tempo-add-block (entry) "Add block entry from `org-structure-template-alist'." (let* ((key (format "<%s" (car entry))) - (name (cdr entry))) + (name (cdr entry)) + (special (member name '("src" "export")))) (tempo-define-template (format "org-%s" (replace-regexp-in-string " " "-" name)) - `(,(format "#+begin_%s " name) p '> n n + `(,(format "#+begin_%s%s" name (if special " " "")) + ,(when special 'p) '> n '> ,(unless special 'p) n ,(format "#+end_%s" (car (split-string name " "))) >) key @@ -126,10 +142,12 @@ Goes through `org-structure-template-alist' and Unlike to `tempo-complete-tag', do not give a signal if a partial completion or no match at all is found. Return nil if expansion didn't succeed." + (org-tempo--update-maybe) ;; `tempo-complete-tag' returns its SILENT argument when there is no ;; completion available at all. (not (eq 'fail (tempo-complete-tag 'fail)))) + ;;; Additional keywords (defun org-tempo--include-file () @@ -160,8 +178,6 @@ didn't succeed." (add-hook 'org-mode-hook 'org-tempo-setup) (add-hook 'org-tab-before-tab-emulation-hook 'org-tempo-complete-tag) -(org-tempo-add-templates) - ;; Enable Org Tempo in all open Org buffers. (dolist (b (org-buffer-list 'files)) (with-current-buffer b (org-tempo-setup))) diff --git a/testing/lisp/test-org-tempo.el b/testing/lisp/test-org-tempo.el index 6c751d4..1840b35 100644 --- a/testing/lisp/test-org-tempo.el +++ b/testing/lisp/test-org-tempo.el @@ -41,7 +41,7 @@ (org-tempo-setup) (call-interactively 'org-cycle) (buffer-string)) - "#+begin_export latex \n\n#+end_export")) + "#+begin_export latex\n\n#+end_export")) ;; Tab should work for expansion. (should (equal (org-test-with-temp-text "<L<point>" @@ -59,6 +59,45 @@ (buffer-string)) "<k")) +(ert-deftest test-org-tempo/space-first-line () + "Test space on first line after expansion." + ;; Normal blocks should have no space at the end of the first line. + (should (zerop + (org-test-with-temp-text "<l<point>" + (org-tempo-setup) + (tempo-complete-tag) + (goto-char (point-min)) + (end-of-line) + (skip-chars-backward " ")))) + ;; src blocks, export blocks and keywords should have one space at + ;; the end of the first line. + (should (cl-every (apply-partially 'eq 1) + (mapcar (lambda (s) + (org-test-with-temp-text (format "<%s<point>" s) + (org-tempo-setup) + (tempo-complete-tag) + (goto-char (point-min)) + (end-of-line) + (abs (skip-chars-backward " ")))) + '("s" "E" "L"))))) + +(ert-deftest test-org-tempo/cursor-placement () + "Test the placement of the cursor after tempo expand" + ;; Normal blocks place point "inside" block. + (should + (eq (org-test-with-temp-text "<l<point>" + (org-tempo-setup) + (tempo-complete-tag) + (point)) + (length "#\\+begin_export latex\n"))) + ;; Special block stop at end of #+begin line. + (should + (eq (org-test-with-temp-text "<s<point>" + (org-tempo-setup) + (tempo-complete-tag) + (point)) + (length "#\\+begin_src ")))) + (ert-deftest test-org-tempo/add-new-templates () "Test that new structures and keywords are added correctly." ;; New blocks should be added. |