From mboxrd@z Thu Jan 1 00:00:00 1970 From: Eric Abrahamsen Subject: Re: function for inserting a block Date: Tue, 14 Nov 2017 13:36:40 -0800 Message-ID: <87mv3osftj.fsf@ericabrahamsen.net> References: <877exghblx.fsf@ericabrahamsen.net> <87k1zsbizs.fsf@ericabrahamsen.net> <87k1zp4rxj.fsf@ericabrahamsen.net> <871slx4j6p.fsf@ericabrahamsen.net> <87376btslq.fsf@nicolasgoaziou.fr> <87vaj7oyxb.fsf@ericabrahamsen.net> <871sl9ow44.fsf@gnu.org> <87fu9pgfkj.fsf@nicolasgoaziou.fr> <87375ouanr.fsf@gmx.us> <871sl8e76c.fsf@nicolasgoaziou.fr> <87y3nfse6m.fsf@gmx.us> <87tvy3sa7m.fsf@gmx.us> <87bmkbflbc.fsf@ericabrahamsen.net> <87po8qscmq.fsf@gmx.us> <87mv3um4c7.fsf@ericabrahamsen.net> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" Return-path: Received: from eggs.gnu.org ([2001:4830:134:3::10]:58275) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eEiux-0007tj-Rc for emacs-orgmode@gnu.org; Tue, 14 Nov 2017 16:38:53 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eEiup-00046U-Hl for emacs-orgmode@gnu.org; Tue, 14 Nov 2017 16:38:47 -0500 Received: from [195.159.176.226] (port=51160 helo=blaine.gmane.org) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1eEiup-00045j-4x for emacs-orgmode@gnu.org; Tue, 14 Nov 2017 16:38:43 -0500 Received: from list by blaine.gmane.org with local (Exim 4.84_2) (envelope-from ) id 1eEiud-0005Of-TX for emacs-orgmode@gnu.org; Tue, 14 Nov 2017 22:38:31 +0100 List-Id: "General discussions about Org-mode." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-orgmode-bounces+geo-emacs-orgmode=m.gmane.org@gnu.org Sender: "Emacs-orgmode" To: emacs-orgmode@gnu.org --=-=-= Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit "Thomas S. Dye" writes: > Eric Abrahamsen writes: > >> Rasmus writes: >> >>> Hi Eric, >>> >>> Eric Abrahamsen writes: >>> >>>>> Also, Eric, it seems that org-structure-template-alist only supports a >>>>> single letter for short-hands (the car of an entry in >>>>> org-structure-template-alist is a char). I used to have blocks like ">>>> expanding to an "abstract" special-block, which I guess isn’t possible >>>>> anymore? >>>> >>>> I hadn't thought of that. Really, all I ever wanted was to wrap things >>>> in blocks... >>>> >>>> I don't see any reason why org-structure-template-alist couldn't go back >>>> to using string keys. Then we could use read-string, and wouldn't have >>>> to have special behavior -- a string that didn't exist in the >>>> alist could just be used literally to make a block. >>> >>> I’d prefer that. For some special blocks, a few characters might makes it >>> more intuitive, e.g. "def" → "definition", "hyp" → "hypothesis" etc. >> >> Here's the simplest solution. >> >> There still remains the fact that `org-structure-template-alist' has >> changed format, and `org-try-structure-completion' no longer exists. >> That may still annoy some people who were using the internals of the >> process, but... > > Would something like this work? > > (defun org-try-structure-completion () > (tempo-complete-tag)) Here's the newest version! It incorporates Rasmus' org-tempo.el file, with modifications, and Thomas' suggestion to re-instate `org-try-structure-completion', and, erm, stardiviner's request to honor `org-babel-uppercase-example-markers'. Remaining issues: 1. The "org-include" tempo template doesn't work, for reasons I don't understand (I've never used tempo before). Nothing happens when I hit . 2. Now it seems like there should be completion when prompting for a string key. Feature creep! But likely worthwhile feature creep. 3. I've rather rashly renamed the relevant customization options `org-structure-block-alist' (for blocks added via `org-insert-structure-template') and `org-structure-keyword-alist' (for keywords insertable via the tempo system). Perhaps this was a bad idea. If it's not a bad idea, maybe `org-insert-structure-template' should be renamed `org-insert-block' or something like that. 3. Docs need to be updated. Comments welcome! Eric --=-=-= Content-Type: text/x-diff Content-Disposition: attachment; filename=tempostructure.diff diff --git a/lisp/org-tempo.el b/lisp/org-tempo.el new file mode 100644 index 000000000..ebe5a26c2 --- /dev/null +++ b/lisp/org-tempo.el @@ -0,0 +1,118 @@ +;;; org-tempo.el --- Tempo-style templates for Org -*- lexical-binding: t; -*- + +;; Copyright (C) 2017 Free Software Foundation, Inc. +;; +;; Author: Rasmus Pank Roulund +;; Keywords: outlines, hypermedia, calendar, wp +;; Homepage: http://orgmode.org +;; +;; This file is part of GNU Emacs. +;; +;; GNU Emacs is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; GNU Emacs is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs. If not, see . +;; +;;; Commentary: + +;; Block and structure templates, to replace the previous Org-specific +;; system. The old function `org-try-structure-completion' is +;; provided as a thin wrapper around `tempo-complete-tag', for +;; backwards compatibility. + +;;; Code: + +(require 'tempo) +(require 'cl-lib) + +(defvar org-tempo-tags nil + "Tempo tags for org-mode") + +(defcustom org-structure-keyword-alist + '(("L" . "latex") + ("H" . "html") + ("A" . "ascii") + ("i" . "index")) + "Keyword templates expanded using the tempo package." + :group 'org-tempo + :type '(repeat + (cons (string :tag "Key") + (string :tag "Template"))) + :package-version '(Org . "9.2")) + +(defun org-tempo-setup () + (tempo-use-tag-list 'org-tempo-tags) + (setq tempo-match-finder "^ *\\(<[[:word:]]\\)\\=")) + +(add-hook 'org-mode-hook 'org-tempo-setup) + +(defun org-tempo-add-templates () + "Update all org-tempo templates. +Goes through `org-structure-block-alist' and +`org-structure-keyword-alist'." + (let ((keys (mapcar (apply-partially #'format "<%s") + (mapcar #'car (append org-structure-block-alist + org-structure-keyword-alist))))) + (if (> (length keys) + (length (delete-dups keys))) + (user-error "Duplicate keys in `org-structure-template-alist' and `org-structure-template-alist-keywords'")) + (dolist (key keys) + (if (assoc-string key org-tempo-tags) + (setq org-tempo-tags + (delete (assoc-string key org-tempo-tags) + org-tempo-tags)))) + (mapc #'org-tempo-add-block org-structure-block-alist) + (mapc #'org-tempo-add-keyword org-structure-keyword-alist)) + (setq tempo-dirty-collection t)) + +(defun org-tempo-add-block (entry) + "Add block entry from `org-structure-block-alist'." + (let* ((key (format "<%s" (car entry))) + (name (cdr entry))) + (tempo-define-template + (format "org-%s" (replace-regexp-in-string " " "-" name)) + `(,(format "#+begin_%s " name) p '> n n + ,(format "#+end_%s" (car (org-split-string name " "))) + >) + key + (format "Insert a %s block" name) + 'org-tempo-tags))) + +(defun org-tempo-add-keyword (entry) + "Add keyword entry from `org-structure-keyword-alist'." + (let* ((key (format "<%s" (car entry))) + (name (cdr entry))) + (tempo-define-template + (format "org-%s" (replace-regexp-in-string " " "-" name)) + `(,(format "#+%s: " name) p '>) + key + (format "Insert a %s keyword" name) + 'org-tempo-tags))) + +;; Additional keywords + +(tempo-define-template + "org-include" + '("#+include: " + (ignore-errors + (format "\"%s\" " (file-relative-name (read-file-name "Include file: ")))) + p >) + ", prompt the -user for a string to use. With an active region, wrap the region -in the block. Otherwise, insert an empty block." +First read a string, which is used as a lookup key in +`org-structure-block-alist' or, failing that, used literally. +With an active region, wrap the region in the block. Otherwise, +insert an empty block." (interactive (list - (let* ((key (read-key "Key: ")) + (let* ((key (read-string "Block type: ")) (struct-string - (or (cdr (assq key org-structure-template-alist)) - (and (= key ?\t) - (read-string "Structure type: ")) - (user-error "`%c' has no structure definition" key)))) + (or (cdr (assoc-string key org-structure-block-alist)) + key))) struct-string))) (let* ((region? (use-region-p)) (s (if region? (region-beginning) (point))) @@ -11923,6 +11921,10 @@ in the block. Otherwise, insert an empty block." (end-of-line)) (set-marker e nil))) +;; For backward compatibility with the previous system. +(defun org-try-structure-completion () + (tempo-complete-tag)) + ;;;; TODO, DEADLINE, Comments (defun org-toggle-comment () --=-=-=--