emacs-orgmode@gnu.org archives
 help / color / mirror / code / Atom feed
From: Rasmus <rasmus@gmx.us>
To: emacs-orgmode@gnu.org
Subject: [patch] extend org-meta-return to keywords
Date: Sat, 22 Nov 2014 02:23:48 +0100	[thread overview]
Message-ID: <87wq6o3u57.fsf@gmx.us> (raw)
In-Reply-To: 87egszw8ui.fsf@gmx.us

[-- Attachment #1: Type: text/plain, Size: 961 bytes --]

Hi,

Rasmus <rasmus@gmx.us> writes:

> Something I have wanted for a while is to have M-RET work "as
> expected"(?)  on keyword lines such as #+LATEX_HEADER, #+CAPTION etc.
> [...]
> Attached is a quick patch that works surprisingly well.  I would work
> more on it if you guys agree this would be useful.  It probably need
> much more work for corner-cases (any ideas what these are)?

Attached is a new version of the patch that will respect the variables
that also govern `org-insert-headline'.  It's smarter and preserves the
layout better.

E.g. (where | is the cursor)

   #+CAP|TION: foo

After M-RET it becomes

   #+CAPTION: foo
   #+CAPTION: |

A keyword-line is inserted above when one press M-RET between BOL and "#".

Keywords that an element can only have one of will not be inserted.
E.g.

    #+NAME: foo|

After M-RET it becomes    

    #+NAME: foo
    * |     

Any opinions? 

—Rasmus

-- 
I hear there's rumors on the, uh, Internets. . .

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-org.el-Add-keyword-support-to-M-RET.patch --]
[-- Type: text/x-diff, Size: 5207 bytes --]

From 1981d0b0a324565659629438ea253cc3e284e0bf Mon Sep 17 00:00:00 2001
From: rasmus <rasmus@gmx.us>
Date: Wed, 19 Nov 2014 15:39:19 +0100
Subject: [PATCH] org.el: Add keyword-support to M-RET

* org.el (org-insert-keyword): New function.
(org-meta-return): May call `org-insert-keyword'.
(org-M-RET-may-split-line): Add keyword.
---
 lisp/org.el | 79 ++++++++++++++++++++++++++++++++++++++++++++++++++++---------
 1 file changed, 68 insertions(+), 11 deletions(-)

diff --git a/lisp/org.el b/lisp/org.el
index 6ab13f4..e8e6b58 100755
--- a/lisp/org.el
+++ b/lisp/org.el
@@ -1601,6 +1601,7 @@ contexts.  Valid contexts are:
 headline  when creating a new headline
 item      when creating a new item
 table     in a table field
+keyword   when creating a new keyword
 default   the value to be used for all contexts not explicitly
           customized"
   :group 'org-structure
@@ -1614,6 +1615,7 @@ default   the value to be used for all contexts not explicitly
 			   (const headline)
 			   (const item)
 			   (const table)
+			   (const keyword)
 			   (const default))
 		   (boolean)))))
 
@@ -7725,8 +7727,8 @@ split the line and create a new headline with the text in the
 current line after point \(see `org-M-RET-may-split-line' on how
 to modify this behavior).
 
-If point is at the beginning of a normal line, turn this line
-into a heading.
+If point is at the beginning of a normal line, excluding some
+keywords, turn this line into a heading.
 
 When INVISIBLE-OK is set, stop at invisible headlines when going
 back.  This is important for non-interactive uses of the
@@ -21291,10 +21293,57 @@ number of stars to add."
 	       (forward-line)))))))
     (unless toggled (message "Cannot toggle heading from here"))))
 
+(defun org-insert-keyword (&optional arg)
+  "Insert a new keyword-line.
+
+If point is between the beginning of the line and the start of
+the keyword, a keyword-line is inserted above the current one.
+
+If point is in the middle of a keyword-line, split the line
+depending on the value of `org-M-RET-may-split-line'.  See the
+docstring of this variable for further details.
+
+If point is within the keyword a new keyword-line is inserted
+below.
+
+Currently arg is ignored and the keyword is determined from the
+context.
+
+The function is used by `org-meta-return'.  Note that keywords
+that can only occur once per element are ignored (through
+`org-meta-return')."
+  (interactive "P")
+  (let* ((may-split (org-get-alist-option
+		     org-M-RET-may-split-line 'keyword))
+	 (point-at-bol-p (looking-back "^[[:space:]]*"))
+	 (end-of-keyword
+	  (save-excursion
+	    (beginning-of-line)
+	    (search-forward-regexp
+	     org-element--affiliated-re (point-at-eol) t)
+	    (point)))
+	 (elm (org-element-at-point))
+	 (key (and (eq 'keyword (org-element-type elm))
+		   (org-element-property :key elm))))
+    (when key
+      (when point-at-bol-p (open-line 1)
+	    ;; Open-line makes sometimes ruins indention of the
+	    ;; previous line.
+	    (save-excursion (forward-line 1)
+			    (org-indent-line)))
+      (unless may-split (end-of-line))
+      (unless point-at-bol-p
+	(when (< (point) end-of-keyword)
+	  (goto-char end-of-keyword))
+	(insert "\n"))
+      (insert (format "#+%s: " key))
+      (org-indent-line))))
+
 (defun org-meta-return (&optional arg)
-  "Insert a new heading or wrap a region in a table.
-Calls `org-insert-heading' or `org-table-wrap-region', depending
-on context.  See the individual commands for more information."
+  "Insert a new heading, a new keyword or wrap a region in a table.
+Calls `org-insert-heading', `org-insert-keyword' or
+`org-table-wrap-region', depending on context.  See the
+individual commands for more information."
   (interactive "P")
   (org-check-before-invisible-edit 'insert)
   (or (run-hook-with-args-until-success 'org-metareturn-hook)
@@ -21303,12 +21352,20 @@ on context.  See the individual commands for more information."
         (when (eq type 'table-row)
           (setq element (org-element-property :parent element))
           (setq type 'table))
-        (if (and (eq type 'table)
-                 (eq (org-element-property :type element) 'org)
-                 (>= (point) (org-element-property :contents-begin element))
-                 (< (point) (org-element-property :contents-end element)))
-            (call-interactively 'org-table-wrap-region)
-          (call-interactively 'org-insert-heading)))))
+        (cond  ((and (eq type 'table)
+		      (eq (org-element-property :type element) 'org)
+		      (>= (point) (org-element-property :contents-begin element))
+		      (< (point) (org-element-property :contents-end element)))
+		(call-interactively 'org-table-wrap-region))
+	       ((and (eq type 'keyword)
+		     ;; Keyword such as LATEX, ATTR_LATEX, CAPTION, and HEADER,
+		     ;; LATEX_HEADER, LATEX etc. can occur multiple times.
+		     (let ((key (org-element-property :key element)))
+		       (if (member key org-element-affiliated-keywords)
+			   (member key org-element-multiple-keywords)
+			 t)))
+		(call-interactively 'org-insert-keyword))
+	       (t (call-interactively 'org-insert-heading))))))
 
 ;;; Menu entries
 
-- 
2.1.3


  reply	other threads:[~2014-11-22  1:24 UTC|newest]

Thread overview: 26+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-11-19 14:41 [Prelim. patch] extend org-meta-return to keywords Rasmus
2014-11-22  1:23 ` Rasmus [this message]
2014-11-22  9:52   ` [patch] " Nicolas Goaziou
2014-11-22 12:19     ` Rasmus Pank Roulund
2014-11-22 19:26       ` Rasmus
2014-11-22 21:57         ` Thierry Banel
2014-11-22 23:20         ` Nicolas Goaziou
2014-11-23 11:08           ` Thierry Banel
2014-11-23 16:54             ` Nicolas Goaziou
2014-11-23 17:15               ` Rasmus
2014-11-23 17:54                 ` Nicolas Goaziou
2014-11-23 18:11                   ` Rasmus
2014-11-23 21:13                     ` Nicolas Goaziou
2014-11-23 21:54                       ` Rasmus
2014-11-25  9:00                         ` Nicolas Goaziou
2014-11-25 10:12                           ` M-RET vs C-RET Sebastien Vauban
2014-11-25 11:09                             ` Nicolas Goaziou
2014-11-25 11:16                             ` Rasmus
2014-11-26 23:50                               ` Nicolas Goaziou
2014-11-27  0:55                                 ` Rasmus
2014-11-27  9:19                                   ` Andreas Leha
2014-11-23 17:00           ` [patch] extend org-meta-return to keywords Rasmus
2014-11-23 17:46             ` Nicolas Goaziou
2014-11-22 13:53 ` [Prelim. patch] " Thierry Banel
2014-11-22 14:31   ` Rasmus
2014-11-22 17:09     ` Thierry Banel

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.orgmode.org/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=87wq6o3u57.fsf@gmx.us \
    --to=rasmus@gmx.us \
    --cc=emacs-orgmode@gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).