* Re: how can I insert a new heading after all at this level?
2013-02-19 19:53 how can I insert a new heading after all at this level? David Naumann
@ 2013-02-19 22:36 ` Nick Dokos
2013-02-25 16:28 ` Jonathan Leech-Pepin
2013-03-03 17:08 ` Bastien
2 siblings, 0 replies; 4+ messages in thread
From: Nick Dokos @ 2013-02-19 22:36 UTC (permalink / raw)
To: David Naumann; +Cc: emacs-orgmode
David Naumann <naumann@cs.stevens.edu> wrote:
> I'm a happy, frequent user of org mode but there's something I can't
> figure out from the manual.
>
> What I would like to be able to do is insert a new heading at the same
> level as current, _following_ all the others. For example, with the
> cursor on the A in this tree:
>
> * top
> -> ** A
> ** B
> ** C
> * next
>
> I would like to insert a last sibling and move to it:
>
> * top
> ** A
> ** B
> ** C
> -> **
> * next
>
> Use case: adding to a very long chronological list. I have not seen a
> quick way to do this using the structure motion/editing commands in
> the manual, without scrolling in one way or another.
>
> If you have a hint, please reply to my address; I'm not on this
> mailing list.
>
From somewhere in the second level (but not in the third or higher levels, if such
exist), you can go up to the higher-level heading (what you call top), then to the
next heading at the same level (next), open a line before that and insert a heading:
C-c C-u
C-c C-f
C-o
M-RET
If typing all that is objectionable, you can define a keyboard macro to
do it.
Or you can define a command to do it (I just looked up the
above key bindings to find the functions to call and looked up the docs
of the various functions for the arguments):
(defun my-org-insert-heading-at-end-of-current-level ()
(interactive)
(outline-up-heading 1)
(org-forward-heading-same-level 1)
(open-line 1)
(org-meta-return))
and either call it with M-x my-org-insert-heading-at-end-of-current-level RET
or bind it to a key.
Nick
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: how can I insert a new heading after all at this level?
2013-02-19 19:53 how can I insert a new heading after all at this level? David Naumann
2013-02-19 22:36 ` Nick Dokos
@ 2013-02-25 16:28 ` Jonathan Leech-Pepin
2013-03-03 17:08 ` Bastien
2 siblings, 0 replies; 4+ messages in thread
From: Jonathan Leech-Pepin @ 2013-02-25 16:28 UTC (permalink / raw)
To: David Naumann; +Cc: emacs-orgmode
[-- Attachment #1: Type: text/plain, Size: 5678 bytes --]
Hello David,
On 19 February 2013 14:53, David Naumann <naumann@cs.stevens.edu> wrote:
> I'm a happy, frequent user of org mode but there's something I can't
> figure out from the manual.
>
> What I would like to be able to do is insert a new heading at the same
> level as current, _following_ all the others. For example, with the
> cursor on the A in this tree:
>
> * top
> -> ** A
> ** B
> ** C
> * next
>
> I would like to insert a last sibling and move to it:
>
> * top
> ** A
> ** B
> ** C
> -> **
> * next
>
> Use case: adding to a very long chronological list. I have not seen a
> quick way to do this using the structure motion/editing commands in
> the manual, without scrolling in one way or another.
>
> If you have a hint, please reply to my address; I'm not on this
> mailing list.
>
The following is a little long, however only one function is actually
interactive.
#+begin_src emacs-lisp
(require 'org-element)
(defun zin/org-next-element ()
"Move to the end of the current element (start of next)."
(let ((end (org-element-property :end (org-element-at-point))))
(goto-char end)))
(defun zin/org-element-check-element (type &optional name)
"Check if current element is of type TYPE.
If not move to next element using `zin/org-next-element'.
If NAME is non-nil, verify that the :name or :drawer-name
property matches it."
(save-excursion
(save-restriction
(save-excursion
(org-up-element)
(org-narrow-to-element))
(catch 'element
(while (not (eobp))
(let ((cur-type (car (org-element-at-point)))
;; Allows for adaptation to non-headline cases.
(cur-name (or (org-element-property
:name (org-element-at-point))
(org-element-property
:drawer-name (org-element-at-point)))))
(if (and (string= type cur-type)
(string= name cur-name))
(throw 'element (point))
(zin/org-next-element))))))))
(defun zin/org-element-start-or-end (start &optional level)
"Find start or ending point of an element's content.
If START is non-nil, return the beginning of the content, if nil
return the end.
If LEVEL is equal to 1, parse the buffer for level 1 headlines.
Any other value is ignored."
;; If level is 1, looking at top level headlines, there is no
;; containing element.
(if (and level
(= 1 level))
(let* ((map (org-element-map (org-element-parse-buffer) 'headline
(lambda (hl)
;; return a list of beginning and ending
;; points of all level 1 headlines.
(list
(org-element-property :begin hl)
(org-element-property :end hl))) 'nil 'nil
'headline))
;; Find smallest (when start is 't) or largest (when
;; start is 'nil) point.
(point (if start
(apply 'min (mapcar 'car map))
(apply 'max (mapcar 'cadr map)))))
point)
;; Not in a top level headline, deal with contents directly.
(let ((top (org-element-property :contents-begin
(org-element-at-point)))
(bottom (org-element-property :contents-end
(org-element-at-point))))
(if start
top
bottom))))
(defun zin/org-add-heading (start &optional title)
"Create a new heading at the before or after all headings of current
level.
If START is non-nil, the new heading will be the first in the
list. If nil it will be created after all the others.
With optional TITLE, automatically insert the desired title,
leaving the point on the following line."
(interactive "P")
(org-back-to-heading)
(let* ((level (org-element-property :level (org-element-at-point)))
(point (save-excursion
(ignore-errors (org-up-element))
(zin/org-element-start-or-end start level)))
;; Org-element minimal version of a headline at LEVEL with
;; TITLE (or blank)
(headline `(headline (:level ,level :title ,(or title "")))))
(if start
;; If placing headline above existing headlines, ensure you do
;; not place it above the content of the parent headline.
(progn
;; Search from top of content of parent headline. Without
;; this it will put it above the current headline.
(goto-char point)
;; Do not check to make sure content is skipped if in a
;; level 1 headline, just return the start of the top
;; headline.
(unless
(= 1 level)
(goto-char (zin/org-element-check-element "headline"))))
(goto-char point))
(org-save-outline-visibility 't
;; Insert a parsed version of the headline
(newline)
(delete-char -1)
(insert (org-element-interpret-data headline))
;; If there is a title provided, put point on start of next line,
;; otherwise return point to headline to insert title.
(if title
(open-line 1)
(backward-char 1)))))
#+end_src
Calling zin/org-add-heading will insert a new heading at the bottom of
the current set of headlines (of the current level). Calling it with
the prefix argument: C-u M-x zin/org-add-heading will insert it as the
first headline at that level.
Regards,
Jon
[-- Attachment #2: Type: text/html, Size: 7551 bytes --]
^ permalink raw reply [flat|nested] 4+ messages in thread