summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicolas Goaziou <n.goaziou@gmail.com>2010-12-24 00:54:48 +0100
committerNicolas Goaziou <n.goaziou@gmail.com>2011-02-18 12:45:08 +0100
commite865ce445a2061d02da75c38d222fe04cb1b54c0 (patch)
treec8617eb361853c1cdfd956a6a0f8a3599e1dced9
parentb2c369725adbf14cf490bd6811f37d3ee706ef13 (diff)
downloadorg-mode-e865ce445a2061d02da75c38d222fe04cb1b54c0.tar.gz
org-list: interactive navigation functions use accessors
* lisp/org-list.el (org-list-in-item-p): unify methods for this predicate. (org-list-in-item-p-with-indent): removed function (org-list-ending-between): removed function (org-list-maybe-skip-block): removed function (org-list-in-item-p-with-regexp): removed function (org-list-top-point-with-regexp): removed function (org-list-top-point-with-indent): removed function (org-list-bottom-point-with-indent): removed function (org-list-bottom-point-with-regexp): removed function (org-list-get-item-same-level): removed function (org-list-top-point): removed function (org-list-bottom-point): removed function (org-get-item-beginning): renamed to org-list-get-item-begin to be consistent with naming policy of non-interactive functions. (org-get-beginning-of-list): removed function (org-beginning-of-item-list): use new accessors (org-get-end-of-list): removed function (org-end-of-list): use new accessors (org-get-end-of-item): removed function (org-end-of-item): use new accessors (org-get-previous-item): removed function (org-previous-item): use new accessors (org-get-next-item): removed function (org-next-item): use new accessors (org-end-of-item-before-blank): renamed to (org-list-get-item-end-before-blank): Use new accessors.
-rw-r--r--lisp/org-list.el522
1 files changed, 133 insertions, 389 deletions
diff --git a/lisp/org-list.el b/lisp/org-list.el
index c7d897e..cc98cad 100644
--- a/lisp/org-list.el
+++ b/lisp/org-list.el
@@ -419,40 +419,6 @@ Symbols `block' and `invalid' refer to `org-list-blocks'."
;; Return the closest context around
(assq (apply 'max (mapcar 'car context-list)) context-list)))))))
-(defun org-list-ending-between (min max &optional firstp)
- "Find the position of a list ending between MIN and MAX, or nil.
-This function looks for `org-list-end-re' outside a block.
-
-If FIRSTP in non-nil, return the point at the beginning of the
-nearest valid terminator from MIN. Otherwise, return the point at
-the end of the nearest terminator from MAX."
- (save-excursion
- (let* ((start (if firstp min max))
- (end (if firstp max min))
- (search-fun (if firstp
- #'org-search-forward-unenclosed
- #'org-search-backward-unenclosed))
- (list-end-p (progn
- (goto-char start)
- (funcall search-fun (org-list-end-re) end t))))
- ;; Is there a valid list ending somewhere ?
- (and list-end-p
- ;; we want to be on the first line of the list ender
- (match-beginning 0)))))
-
-(defun org-list-maybe-skip-block (search limit)
- "Return non-nil value if point is in a block, skipping it on the way.
-It looks for the boundary of the block in SEARCH direction,
-stopping at LIMIT."
- (save-match-data
- (let ((case-fold-search t)
- (boundary (if (eq search 're-search-forward) 3 5)))
- (when (save-excursion
- (and (funcall search "^[ \t]*#\\+\\(begin\\|end\\)_" limit t)
- (= (length (match-string 1)) boundary)))
- ;; We're in a block: get out of it
- (goto-char (match-beginning 0))))))
-
(defun org-list-search-unenclosed-generic (search re bound noerr)
"Search a string outside blocks and protected places.
Arguments SEARCH, RE, BOUND and NOERR are similar to those in
@@ -485,171 +451,6 @@ Arguments REGEXP, BOUND and NOERROR are similar to those used in
(org-list-search-unenclosed-generic
#'re-search-forward regexp (or bound (point-max)) noerror))
-(defun org-list-in-item-p-with-indent (limit)
- "Is the cursor inside a plain list?
-Plain lists are considered ending when a non-blank line is less
-indented than the previous item within LIMIT."
- (save-excursion
- (beginning-of-line)
- (cond
- ;; do not start searching inside a block...
- ((org-list-maybe-skip-block #'re-search-backward limit))
- ;; ... or at a blank line
- ((looking-at "^[ \t]*$")
- (skip-chars-backward " \r\t\n")
- (beginning-of-line)))
- (beginning-of-line)
- (or (org-at-item-p)
- (let* ((case-fold-search t)
- (ind-ref (org-get-indentation))
- ;; Ensure there is at least an item above
- (up-item-p (save-excursion
- (org-search-backward-unenclosed
- org-item-beginning-re limit t))))
- (and up-item-p
- (catch 'exit
- (while t
- (cond
- ((org-at-item-p)
- (throw 'exit (< (org-get-indentation) ind-ref)))
- ((looking-at "^[ \t]*$")
- (skip-chars-backward " \r\t\n")
- (beginning-of-line))
- ((looking-at "^[ \t]*#\\+end_")
- (re-search-backward "^[ \t]*#\\+begin_"))
- (t
- (setq ind-ref (min (org-get-indentation) ind-ref))
- (forward-line -1))))))))))
-
-(defun org-list-in-item-p-with-regexp (limit)
- "Is the cursor inside a plain list?
-Plain lists end when `org-list-end-regexp' is matched, or at a
-blank line if `org-empty-line-terminates-plain-lists' is true.
-
-Argument LIMIT specifies the upper-bound of the search."
- (save-excursion
- (let* ((actual-pos (goto-char (point-at-eol)))
- ;; Moved to eol so current line can be matched by
- ;; `org-item-re'.
- (last-item-start (save-excursion
- (org-search-backward-unenclosed
- org-item-beginning-re limit t)))
- (list-ender (org-list-ending-between
- last-item-start actual-pos)))
- ;; We are in a list when we are on an item line or when we can
- ;; find an item before point and there is no valid list ender
- ;; between it and the point.
- (and last-item-start (not list-ender)))))
-
-(defun org-list-top-point-with-regexp (limit)
- "Return point at the top level item in a list.
-Argument LIMIT specifies the upper-bound of the search.
-
-List ending is determined by regexp. See
-`org-list-ending-method'. for more information."
- (save-excursion
- (let ((pos (point-at-eol)))
- ;; Is there some list above this one ? If so, go to its ending.
- ;; Otherwise, go back to the heading above or bob.
- (goto-char (or (org-list-ending-between limit pos) limit))
- ;; From there, search down our list.
- (org-search-forward-unenclosed org-item-beginning-re pos t)
- (point-at-bol))))
-
-(defun org-list-bottom-point-with-regexp (limit)
- "Return point just before list ending.
-Argument LIMIT specifies the lower-bound of the search.
-
-List ending is determined by regexp. See
-`org-list-ending-method'. for more information."
- (save-excursion
- (let ((pos (org-get-item-beginning)))
- ;; The list ending is either first point matching
- ;; `org-list-end-re', point at first white-line before next
- ;; heading, or eob.
- (or (org-list-ending-between (min pos limit) limit t) limit))))
-
-(defun org-list-top-point-with-indent (limit)
- "Return point at the top level in a list.
-Argument LIMIT specifies the upper-bound of the search.
-
-List ending is determined by indentation of text. See
-`org-list-ending-method'. for more information."
- (save-excursion
- (let ((case-fold-search t))
- (let ((item-ref (goto-char (org-get-item-beginning)))
- (ind-ref 10000))
- (forward-line -1)
- (catch 'exit
- (while t
- (let ((ind (+ (or (get-text-property (point) 'original-indentation) 0)
- (org-get-indentation))))
- (cond
- ((looking-at "^[ \t]*:END:")
- (throw 'exit item-ref))
- ((<= (point) limit)
- (throw 'exit
- (if (and (org-at-item-p) (< ind ind-ref))
- (point-at-bol)
- item-ref)))
- ((looking-at "^[ \t]*$")
- (skip-chars-backward " \r\t\n")
- (beginning-of-line))
- ((looking-at "^[ \t]*#\\+end_")
- (re-search-backward "^[ \t]*#\\+begin_"))
- ((not (org-at-item-p))
- (setq ind-ref (min ind ind-ref))
- (forward-line -1))
- ((>= ind ind-ref)
- (throw 'exit item-ref))
- (t
- (setq item-ref (point-at-bol) ind-ref 10000)
- (forward-line -1))))))))))
-
-(defun org-list-bottom-point-with-indent (limit)
- "Return point just before list ending or nil if not in a list.
-Argument LIMIT specifies the lower-bound of the search.
-
-List ending is determined by the indentation of text. See
-`org-list-ending-method' for more information."
- (save-excursion
- (let ((ind-ref (progn
- (goto-char (org-get-item-beginning))
- (org-get-indentation)))
- (case-fold-search t))
- ;; do not start inside a block
- (org-list-maybe-skip-block #'re-search-forward limit)
- (beginning-of-line)
- (catch 'exit
- (while t
- (skip-chars-forward " \t")
- (let ((ind (+ (or (get-text-property (point) 'original-indentation) 0)
- (org-get-indentation))))
- (cond
- ((or (>= (point) limit)
- (looking-at ":END:"))
- (throw 'exit (progn
- ;; Ensure bottom is just after a
- ;; non-blank line.
- (skip-chars-backward " \r\t\n")
- (min (point-max) (1+ (point-at-eol))))))
- ((= (point) (point-at-eol))
- (skip-chars-forward " \r\t\n")
- (beginning-of-line))
- ((org-at-item-p)
- (setq ind-ref ind)
- (forward-line 1))
- ((<= ind ind-ref)
- (throw 'exit (progn
- ;; Again, ensure bottom is just after a
- ;; non-blank line.
- (skip-chars-backward " \r\t\n")
- (min (point-max) (1+ (point-at-eol))))))
- ((looking-at "#\\+begin_")
- (re-search-forward "[ \t]*#\\+end_")
- (forward-line 1))
- (t (forward-line 1)))))))))
-
(defun org-list-at-regexp-after-bullet-p (regexp)
"Is point at a list item with REGEXP after bullet?"
(and (org-at-item-p)
@@ -660,23 +461,6 @@ List ending is determined by the indentation of text. See
(goto-char (match-end 0)))
(looking-at regexp))))
-(defun org-list-get-item-same-level (search-fun pos limit pre-move)
- "Return point at the beginning of next item at the same level.
-Search items using function SEARCH-FUN, from POS to LIMIT. It
-uses PRE-MOVE before search. Return nil if no item was found."
- (save-excursion
- (goto-char pos)
- (let* ((start (org-get-item-beginning))
- (ind (progn (goto-char start) (org-get-indentation))))
- ;; We don't want to match the current line.
- (funcall pre-move)
- ;; Skip any sublist on the way
- (while (and (funcall search-fun org-item-beginning-re limit t)
- (> (org-get-indentation) ind)))
- (when (and (/= (point-at-bol) start) ; Have we moved ?
- (= (org-get-indentation) ind))
- (point-at-bol)))))
-
(defun org-list-separating-blank-lines-number (pos top bottom)
"Return number of blank lines that should separate items in list.
POS is the position of point to be considered.
@@ -744,7 +528,7 @@ function ends."
(let* ((true-pos (point))
(top (org-list-top-point))
(bottom (copy-marker (org-list-bottom-point)))
- (bullet (and (goto-char (org-get-item-beginning))
+ (bullet (and (goto-char (org-list-get-item-begin))
(org-list-bullet-string (org-get-bullet))))
(ind (org-get-indentation))
(before-p (progn
@@ -761,7 +545,7 @@ function ends."
(lambda (text)
;; insert bullet above item in order to avoid bothering
;; with possible blank lines ending last item.
- (goto-char (org-get-item-beginning))
+ (goto-char (org-list-get-item-begin))
(org-indent-to-column ind)
(insert (concat bullet (when checkbox "[ ] ") after-bullet))
;; Stay between after-bullet and before text.
@@ -773,7 +557,7 @@ function ends."
(setq bottom (marker-position bottom))
(let ((col (current-column)))
(org-list-exchange-items
- (org-get-item-beginning) (org-get-next-item (point) bottom)
+ (org-list-get-item-begin) (org-get-next-item (point) bottom)
bottom)
;; recompute next-item: last sexp modified list
(goto-char (org-get-next-item (point) bottom))
@@ -910,32 +694,50 @@ Return t if successful."
(defun org-in-item-p ()
"Is the cursor inside a plain list?
This checks `org-list-ending-method'."
- (unless (let ((outline-regexp org-outline-regexp)) (org-at-heading-p))
- (let* ((prev-head (save-excursion (outline-previous-heading)))
- (bound (if prev-head
- (or (save-excursion
- (let ((case-fold-search t))
- (re-search-backward "^[ \t]*:END:" prev-head t)))
- prev-head)
- (point-min))))
- (cond
- ((eq org-list-ending-method 'regexp)
- (org-list-in-item-p-with-regexp bound))
- ((eq org-list-ending-method 'indent)
- (org-list-in-item-p-with-indent bound))
- (t (and (org-list-in-item-p-with-regexp bound)
- (org-list-in-item-p-with-indent bound)))))))
-
-(defun org-list-first-item-p (top)
- "Is this item the first item in a plain list?
-Assume point is at an item.
-
-TOP is the position of list's top-item."
(save-excursion
(beginning-of-line)
- (let ((ind (org-get-indentation)))
- (or (not (org-search-backward-unenclosed org-item-beginning-re top t))
- (< (org-get-indentation) ind)))))
+ (unless (or (let ((outline-regexp org-outline-regexp)) (org-at-heading-p))
+ (and (not (eq org-list-ending-method 'indent))
+ (looking-at (org-list-end-re))
+ (progn (forward-line -1) (looking-at (org-list-end-re)))))
+ (or (and (org-at-item-p) (point-at-bol))
+ (let* ((case-fold-search t)
+ (context (org-list-context))
+ (lim-up (car context))
+ (inlinetask-re (and (featurep 'org-inlinetask)
+ (org-inlinetask-outline-regexp)))
+ (ind-ref (if (looking-at "^[ \t]*$")
+ 10000
+ (org-get-indentation))))
+ (catch 'exit
+ (while t
+ (let ((ind (org-get-indentation)))
+ (cond
+ ((<= (point) lim-up)
+ (throw 'exit (and (org-at-item-p) (< ind ind-ref))))
+ ((and (not (eq org-list-ending-method 'indent))
+ (looking-at (org-list-end-re)))
+ (throw 'exit nil))
+ ;; Skip blocks, drawers, inline-tasks, blank lines
+ ((looking-at "^[ \t]*#\\+end_")
+ (re-search-backward "^[ \t]*#\\+begin_" nil t))
+ ((looking-at "^[ \t]*:END:")
+ (re-search-backward org-drawer-regexp nil t)
+ (beginning-of-line))
+ ((and inlinetask-re (looking-at inlinetask-re))
+ (org-inlinetask-goto-beginning)
+ (forward-line -1))
+ ((looking-at "^[ \t]*$")
+ (forward-line -1))
+ ((< ind ind-ref)
+ (if (org-at-item-p)
+ (throw 'exit (point))
+ (setq ind-ref ind)
+ (forward-line -1)))
+ (t (if (and (eq org-list-ending-method 'regexp)
+ (org-at-item-p))
+ (throw 'exit (point))
+ (forward-line -1))))))))))))
(defun org-at-item-p ()
"Is point in a line starting a hand-formatted item?"
@@ -963,178 +765,86 @@ TOP is the position of list's top-item."
;;; Navigate
-;; Every interactive navigation function is derived from a
-;; non-interactive one, which doesn't move point, assumes point is
-;; already in a list and doesn't compute list boundaries.
-
-;; If you plan to use more than one org-list function is some code,
-;; you should therefore first check if point is in a list with
-;; `org-in-item-p' or `org-at-item-p', then compute list boundaries
-;; with `org-list-top-point' and `org-list-bottom-point', and make use
-;; of non-interactive forms.
-
-(defun org-list-top-point ()
- "Return point at the top level in a list.
-Assume point is in a list."
- (let* ((prev-head (save-excursion (outline-previous-heading)))
- (bound (if prev-head
- (or (save-excursion
- (let ((case-fold-search t))
- (re-search-backward "^[ \t]*:END:" prev-head t)))
- prev-head)
- (point-min))))
- (cond
- ((eq org-list-ending-method 'regexp)
- (org-list-top-point-with-regexp bound))
- ((eq org-list-ending-method 'indent)
- (org-list-top-point-with-indent bound))
- (t (let ((top-re (org-list-top-point-with-regexp bound)))
- (org-list-top-point-with-indent (or top-re bound)))))))
-
-(defun org-list-bottom-point ()
- "Return point just before list ending.
-Assume point is in a list."
- (let* ((next-head (save-excursion
- (and (let ((outline-regexp org-outline-regexp))
- ;; Use default regexp because folding
- ;; changes OUTLINE-REGEXP.
- (outline-next-heading)))))
- (limit (or (save-excursion
- (and (re-search-forward "^[ \t]*:END:" next-head t)
- (point-at-bol)))
- next-head
- (point-max))))
- (cond
- ((eq org-list-ending-method 'regexp)
- (org-list-bottom-point-with-regexp limit))
- ((eq org-list-ending-method 'indent)
- (org-list-bottom-point-with-indent limit))
- (t (let ((bottom-re (org-list-bottom-point-with-regexp limit)))
- (org-list-bottom-point-with-indent (or bottom-re limit)))))))
-
-(defun org-get-item-beginning ()
- "Return position of current item beginning."
- (save-excursion
- ;; possibly match current line
- (end-of-line)
- (org-search-backward-unenclosed org-item-beginning-re nil t)
- (point-at-bol)))
+(defalias 'org-list-get-item-begin 'org-in-item-p)
(defun org-beginning-of-item ()
"Go to the beginning of the current hand-formatted item.
If the cursor is not in an item, throw an error."
(interactive)
- (if (org-in-item-p)
- (goto-char (org-get-item-beginning))
- (error "Not in an item")))
-
-(defun org-get-beginning-of-list (top)
- "Return position of the first item of the current list or sublist.
-TOP is the position at list beginning."
- (save-excursion
- (let (prev-p)
- (while (setq prev-p (org-get-previous-item (point) top))
- (goto-char prev-p))
- (point-at-bol))))
+ (let ((begin (org-in-item-p)))
+ (if begin (goto-char begin) (error "Not in an item"))))
(defun org-beginning-of-item-list ()
"Go to the beginning item of the current list or sublist.
Return an error if not in a list."
(interactive)
- (if (org-in-item-p)
- (goto-char (org-get-beginning-of-list (org-list-top-point)))
- (error "Not in an item")))
-
-(defun org-get-end-of-list (bottom)
- "Return position at the end of the current list or sublist.
-BOTTOM is the position at list ending."
- (save-excursion
- (goto-char (org-get-item-beginning))
- (let ((ind (org-get-indentation)))
- (while (and (/= (point) bottom)
- (>= (org-get-indentation) ind))
- (org-search-forward-unenclosed org-item-beginning-re bottom 'move))
- (if (= (point) bottom) bottom (point-at-bol)))))
+ (let ((begin (org-in-item-p)))
+ (if (not begin)
+ (error "Not in an item")
+ (goto-char begin)
+ (let ((struct (org-list-struct)))
+ (goto-char (org-list-get-list-begin begin (org-list-struct)))))))
(defun org-end-of-item-list ()
"Go to the end of the current list or sublist.
If the cursor in not in an item, throw an error."
(interactive)
- (if (org-in-item-p)
- (goto-char (org-get-end-of-list (org-list-bottom-point)))
- (error "Not in an item")))
-
-(defun org-get-end-of-item (bottom)
- "Return position at the end of the current item.
-BOTTOM is the position at list ending."
- (or (org-get-next-item (point) bottom)
- (org-get-end-of-list bottom)))
+ (let ((begin (org-in-item-p)))
+ (if (not begin)
+ (error "Not in an item")
+ (goto-char begin)
+ (let ((struct (org-list-struct)))
+ (goto-char (org-list-get-list-end begin (org-list-struct)))))))
(defun org-end-of-item ()
"Go to the end of the current hand-formatted item.
If the cursor is not in an item, throw an error."
(interactive)
- (if (org-in-item-p)
- (goto-char (org-get-end-of-item (org-list-bottom-point)))
- (error "Not in an item")))
-
-(defun org-end-of-item-or-at-child (bottom)
- "Move to the end of the item, stops before the first child if any.
-BOTTOM is the position at list ending."
- (end-of-line)
- (goto-char
- (if (org-search-forward-unenclosed org-item-beginning-re bottom t)
- (point-at-bol)
- (org-get-end-of-item bottom))))
-
-(defun org-end-of-item-before-blank (bottom)
- "Return point at end of item, before any blank line.
-Point returned is at eol.
-
-BOTTOM is the position at list ending."
- (save-excursion
- (goto-char (org-get-end-of-item bottom))
- (skip-chars-backward " \r\t\n")
- (point-at-eol)))
-
-(defun org-get-previous-item (pos limit)
- "Return point of the previous item at the same level as POS.
-Stop searching at LIMIT. Return nil if no item is found."
- (org-list-get-item-same-level
- #'org-search-backward-unenclosed pos limit #'beginning-of-line))
+ (let ((begin (org-in-item-p)))
+ (if (not begin)
+ (error "Not in an item")
+ (goto-char begin)
+ (let ((struct (org-list-struct)))
+ (goto-char (org-list-get-item-end begin struct))))))
(defun org-previous-item ()
"Move to the beginning of the previous item.
Item is at the same level in the current plain list. Error if not
in a plain list, or if this is the first item in the list."
(interactive)
- (if (not (org-in-item-p))
- (error "Not in an item")
- (let ((prev-p (org-get-previous-item (point) (org-list-top-point))))
- (if prev-p (goto-char prev-p) (error "On first item")))))
-
-(defun org-get-next-item (pos limit)
- "Return point of the next item at the same level as POS.
-Stop searching at LIMIT. Return nil if no item is found."
- (org-list-get-item-same-level
- #'org-search-forward-unenclosed pos limit #'end-of-line))
+ (let ((begin (org-in-item-p)))
+ (if (not begin)
+ (error "Not in an item")
+ (goto-char begin)
+ (let* ((struct (org-list-struct))
+ (prevs (org-list-struct-prev-alist struct))
+ (prevp (org-list-get-prev-item begin struct prevs)))
+ (if prevp (goto-char prevp) (error "On first item"))))))
(defun org-next-item ()
"Move to the beginning of the next item.
Item is at the same level in the current plain list. Error if not
in a plain list, or if this is the last item in the list."
(interactive)
- (if (not (org-in-item-p))
- (error "Not in an item")
- (let ((next-p (org-get-next-item (point) (org-list-bottom-point))))
- (if next-p (goto-char next-p) (error "On last item")))))
+ (let ((begin (org-in-item-p)))
+ (if (not begin)
+ (error "Not in an item")
+ (goto-char begin)
+ (let* ((struct (org-list-struct))
+ (prevs (org-list-struct-prev-alist struct))
+ (prevp (org-list-get-next-item begin struct prevs)))
+ (if prevp (goto-char prevp) (error "On last item"))))))
;;; Manipulate
(defun org-list-exchange-items (beg-A beg-B struct)
- "Swap item starting at BEG-A with item starting at BEG-B.
-Blank lines at the end of items are left in place. Assume BEG-A
-is lesser than BEG-B."
+ "Swap item starting at BEG-A with item starting at BEG-B in STRUCT.
+Blank lines at the end of items are left in place.
+
+Assume BEG-A is lesser than BEG-B and that BEG-A and BEG-B
+belong to the same sub-list.
+
+This function modifies STRUCT."
(save-excursion
(let* ((end-of-item-no-blank
(lambda (pos)
@@ -1146,7 +856,21 @@ is lesser than BEG-B."
(between-A-no-blank-and-B (buffer-substring end-A-no-blank beg-B)))
(goto-char beg-A)
(delete-region beg-A end-B-no-blank)
- (insert (concat body-B between-A-no-blank-and-B body-A)))))
+ (insert (concat body-B between-A-no-blank-and-B body-A))
+ ;; Now modify struct. No need to re-read the list, the
+ ;; transformation is just a shift of positions
+ (let* ((sub-A (cons beg-A (org-list-get-subtree beg-A struct)))
+ (sub-B (cons beg-B (org-list-get-subtree beg-B struct)))
+ (end-A (org-list-get-item-end beg-A struct))
+ (end-B (org-list-get-item-end beg-B struct))
+ (inter-A-B (- beg-B end-A))
+ (size-A (- end-A beg-A))
+ (size-B (- end-B beg-B)))
+ (mapc (lambda (e) (org-list-set-pos e struct (+ e size-B inter-A-B)))
+ sub-A)
+ (mapc (lambda (e) (org-list-set-pos e struct (- e size-A inter-A-B)))
+ sub-B)
+ (sort struct (lambda (e1 e2) (< (car e1) (car e2))))))))
(defun org-move-item-down ()
"Move the plain list item at point down, i.e. swap with following item.
@@ -1164,12 +888,17 @@ so this really moves item trees."
(progn
(goto-char pos)
(error "Cannot move this item further down"))
- (let ((next-item-size (- (org-list-get-item-end next-item struct)
- next-item)))
- (org-list-exchange-items actual-item next-item struct)
- (org-list-repair)
- (goto-char (+ (point) next-item-size))
- (org-move-to-column col)))))
+ (org-list-exchange-items actual-item next-item struct)
+ ;; Use a short variation of `org-list-struct-fix-struct' as
+ ;; there's no need to go through all the steps.
+ (let ((old-struct (mapcar (lambda (e) (copy-alist e)) struct))
+ (prevs (org-list-struct-prev-alist struct))
+ (parents (org-list-struct-parent-alist struct)))
+ (org-list-struct-fix-bul struct prevs)
+ (org-list-struct-fix-ind struct parents)
+ (org-list-struct-apply-struct struct old-struct)
+ (goto-char (org-list-get-next-item (point-at-bol) struct prevs)))
+ (org-move-to-column col))))
(defun org-move-item-up ()
"Move the plain list item at point up, i.e. swap with previous item.
@@ -1188,7 +917,14 @@ so this really moves item trees."
(goto-char pos)
(error "Cannot move this item further up"))
(org-list-exchange-items prev-item actual-item struct)
- (org-list-repair)
+ ;; Use a short variation of `org-list-struct-fix-struct' as
+ ;; there's no need to go through all the steps.
+ (let ((old-struct (mapcar (lambda (e) (copy-alist e)) struct))
+ (prevs (org-list-struct-prev-alist struct))
+ (parents (org-list-struct-parent-alist struct)))
+ (org-list-struct-fix-bul struct prevs)
+ (org-list-struct-fix-ind struct parents)
+ (org-list-struct-apply-struct struct old-struct))
(org-move-to-column col))))
(defun org-insert-item (&optional checkbox)
@@ -1205,13 +941,13 @@ item is invisible."
(goto-char (org-get-item-beginning))
(outline-invisible-p)))
(if (save-excursion
- (goto-char (org-get-item-beginning))
+ (goto-char (org-list-get-item-begin))
(org-at-item-timer-p))
;; Timer list: delegate to `org-timer-item'.
(progn (org-timer-item) t)
;; if we're in a description list, ask for the new term.
(let ((desc-text (when (save-excursion
- (and (goto-char (org-get-item-beginning))
+ (and (goto-char (org-list-get-item-begin))
(org-at-item-description-p)))
(concat (read-string "Term: ") " :: "))))
;; Don't insert a checkbox if checkbox rule is applied and it
@@ -1612,6 +1348,14 @@ previous items. See `org-list-struct-prev-alist'."
"Return end position of ITEM in STRUCT."
(org-list-get-nth 5 item struct))
+(defun org-list-get-item-end-before-blank (item struct)
+ "Return point at end of item, before any blank line.
+Point returned is at end of line."
+ (save-excursion
+ (goto-char (org-list-get-item-end item struct))
+ (skip-chars-backward " \r\t\n")
+ (point-at-eol)))
+
(defun org-list-struct-fix-bul (struct prevs)
"Verify and correct bullets for every association in STRUCT.
\nThis function modifies STRUCT."