emacs-orgmode
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [O] Outline cycling does not preserve point's position


From: Carsten Dominik
Subject: Re: [O] Outline cycling does not preserve point's position
Date: Fri, 13 Sep 2013 12:57:21 +0200

Hi Nicolas,

thanks for these.  Please see the two comments below.

On Sep 11, 2013, at 10:01 PM, Nicolas Goaziou <address@hidden> wrote:

> Jambunathan K <address@hidden> writes:
> 
>> I am happy with whatever is the latest version.  You may want to commit
>> it.
> 
> I copy here[fn:1] the current version, for the record, along with its backward
> counterpart. Some points are still to be discussed:
> 
>  1. What to do on node properties?

I think they should be covered with a single C-down, so treated like a single 
paragraph.

>  2. What to do on source blocks?

At the beginning of the block (at the src line)  I think it should jump over 
the full src block.
Inside the block, it can use text-modes forward paragraph.

At lease these would be my suggestions.
Thank you for all your work around this issue!

When the functions are done, please go ahead and commit them and bind them to 
C-up/down.

Regards

- Carsten

> 
> 
> [fn:1] Here is the code:
> 
> (defun org-forward-linear-element ()
>  "Move forward to beginning of next element, ignoring depth.
> The function implements some special moves for convenience:
>  - On an affiliated keyword, jump to the beginning of the
>    relative element.
>  - On an item or a footnote definition, move to the second
>    element inside, if any.
>  - On a table, jump after it.
>  - On a verse block, stop after each blank line."
>  (interactive)
>  (when (eobp) (user-error "Cannot move further down"))
>  (let* ((element (org-element-at-point))
>         (type (org-element-type element))
>         (post-affiliated (org-element-property :post-affiliated element))
>         (contents-begin (org-element-property :contents-begin element))
>         (contents-end (org-element-property :contents-end element))
>         (end (let ((end (org-element-property :end element)) (parent element))
>                (while (and (setq parent (org-element-property :parent parent))
>                            (= (org-element-property :contents-end parent) 
> end))
>                  (setq end (org-element-property :end parent)))
>                end)))
>    (cond ((not element)
>           (skip-chars-forward " \r\t\n")
>           (or (eobp) (beginning-of-line)))
>          ;; On affiliated keywords, move to element's beginning.
>          ((and post-affiliated (< (point) post-affiliated))
>           (goto-char post-affiliated))
>          ;; At a table row, move to the end of the table.
>          ((eq type 'table-row)
>           (goto-char (org-element-property
>                       :end (org-element-property :parent element))))
>          ((eq type 'table) (goto-char end))
>          ((not contents-begin) (goto-char end))
>          ;; If current element contents are invisible, skip the
>          ;; element altogether.
>          ((outline-invisible-p (line-end-position))
>           (case type
>             (headline
>              (org-with-limited-levels (outline-next-visible-heading 1)))
>             ;; At a plain list, make sure we move to the next item
>             ;; instead of skipping the whole list.
>             (plain-list (forward-char)
>                         (org-forward-linear-element))
>             (otherwise (goto-char end))))
>          ((>= (point) contents-end) (goto-char end))
>          ((>= (point) contents-begin)
>           ;; Handle special cases.  In all other situations, point is
>           ;; where it should be.
>           (case type
>             (paragraph (goto-char end))
>             ;; At a plain list, try to move to second element in
>             ;; first item, if possible.
>             (plain-list (end-of-line)
>                         (org-forward-linear-element))
>             ;; Consider blank lines as separators in verse blocks to
>             ;; ease editing.
>             (verse-block
>              (beginning-of-line)
>              (if (not (re-search-forward "^[ \t]*$" contents-end t))
>                  (goto-char end)
>                (skip-chars-forward " \r\t\n")
>                (if (= (point) contents-end) (goto-char contents)
>                  (beginning-of-line))))))
>          ;; When contents start on the middle of a line (e.g. in
>          ;; items and footnote definitions), try to reach first
>          ;; element starting after current line.
>          ((> (line-end-position) contents-begin)
>           (end-of-line)
>           (org-forward-linear-element))
>          (t (goto-char contents-begin)))))
> 
> (defun org-backward-linear-element ()
>  "Move backward to start of previous element, ignoring depth."
>  (interactive)
>  (when (bobp) (user-error "Cannot move further up"))
>  (let* ((element (org-element-at-point))
>         (type (org-element-type element))
>         (contents-begin (org-element-property :contents-begin element))
>         (contents-end (org-element-property :contents-end element))
>         (post-affiliated (org-element-property :post-affiliated element))
>         (begin (org-element-property :begin element)))
>    (cond ((not element) (goto-char (point-min)))
>          ((= (point) begin)
>           (backward-char)
>           (org-backward-linear-element))
>          ((and post-affiliated (<= (point) post-affiliated)) (goto-char 
> begin))
>          ((eq type 'table-row)
>           (goto-char (org-element-property
>                       :contents-begin (org-element-property :parent 
> element))))
>          ((eq type 'table) (goto-char begin))
>          ((not contents-begin)
>           (goto-char (or post-affiliated begin)))
>          ((eq type 'paragraph)
>           (goto-char contents-begin)
>           ;; When at first paragraph in an item or a footnote
>           ;; definition, move directly to beginning of line.
>           (let ((parent-contents
>                  (org-element-property
>                   :contents-begin (org-element-property :parent element))))
>             (when (and parent-contents (= parent-contents contents-begin))
>               (beginning-of-line))))
>          ((eq type 'verse-block)
>           (if (= (point) contents-begin)
>               (goto-char (or post-affiliated begin))
>             ;; Inside a verse block, see blank lines as paragraph
>             ;; separators.
>             (let ((origin (point)))
>               (skip-chars-backward " \r\t\n" contents-begin)
>               (when (re-search-backward "^[ \t]*$" contents-begin 'move)
>                 (skip-chars-forward " \r\t\n" origin)
>                 (if (= (point) origin) (goto-char contents-begin)
>                   (beginning-of-line))))))
>          ;; At the end of a greater element, move to the beginning of
>          ;; the last element within.
>          ((>= (point) contents-end)
>           (goto-char (1- contents-end))
>           (org-backward-linear-element))
>          (t (goto-char (or post-affiliated begin))))
>    ;; Ensure we never leave point invisible.
>    (when (outline-invisible-p (point)) (beginning-of-visual-line))))
> 
> 
> Regards,
> 
> -- 
> Nicolas Goaziou

Attachment: signature.asc
Description: Message signed with OpenPGP using GPGMail


reply via email to

[Prev in Thread] Current Thread [Next in Thread]