emacs-orgmode@gnu.org archives
 help / color / mirror / code / Atom feed
* how can I insert a new heading after all at this level?
@ 2013-02-19 19:53 David Naumann
  2013-02-19 22:36 ` Nick Dokos
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: David Naumann @ 2013-02-19 19:53 UTC (permalink / raw)
  To: emacs-orgmode

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.

^ 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: 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

* 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: Bastien @ 2013-03-03 17:08 UTC (permalink / raw)
  To: David Naumann; +Cc: emacs-orgmode

Hi David,

David Naumann <naumann@cs.stevens.edu> writes:

> 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

From current git repo (master branch), you can now use C-u C-u M-RET
to insert a headline after all siblings.

Thanks for suggesting this,

-- 
 Bastien

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2013-03-03 17:08 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
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

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).