diff options
author | Carsten Dominik <carsten.dominik@gmail.com> | 2010-04-21 15:52:01 +0200 |
---|---|---|
committer | Carsten Dominik <carsten.dominik@gmail.com> | 2010-04-23 10:26:15 +0200 |
commit | 11baa7cf77245cc2a5f44dd55e034157896ad08d (patch) | |
tree | c53fe6962fa602f6589513e3126af567e667cfe7 | |
parent | 9b6eeb4d2d7799fa35d4454f889f28199dea26e9 (diff) | |
download | org-mode-11baa7cf77245cc2a5f44dd55e034157896ad08d.tar.gz |
Make M-left and M-right affect only the item, not its children
This behavior is now parallel to the treatment of outline nodes.
This commit also introduces another change. When an outline node or a
plain list item is folded by outline and contains hidden children,
M-left/right will refuse to act on this item. You must either open
the tree, or use the subtree commands M-S-left and M-S-right.
Based on a patch by Matti De Craene, but significantly modified after
a discussion involving Bernt Hansen and others.
-rw-r--r-- | doc/ChangeLog | 5 | ||||
-rw-r--r-- | doc/org.texi | 5 | ||||
-rwxr-xr-x | lisp/ChangeLog | 17 | ||||
-rw-r--r-- | lisp/org-list.el | 61 | ||||
-rw-r--r-- | lisp/org.el | 40 |
5 files changed, 112 insertions, 16 deletions
diff --git a/doc/ChangeLog b/doc/ChangeLog index 971454d..41ff00b 100644 --- a/doc/ChangeLog +++ b/doc/ChangeLog @@ -1,3 +1,8 @@ +2010-04-23 Carsten Dominik <carsten.dominik@gmail.com> + + * org.texi (Plain lists): Document the commands to promote/demote + an item without affecting children. + 2010-04-22 Carsten Dominik <carsten.dominik@gmail.com> * org.texi (Sitemap): Document sitemap sorting. diff --git a/doc/org.texi b/doc/org.texi index fe443bf..69e23e0 100644 --- a/doc/org.texi +++ b/doc/org.texi @@ -1321,6 +1321,11 @@ similar effect. Move the item including subitems up/down (swap with previous/next item of same indentation). If the list is ordered, renumbering is automatic. +@kindex M-@key{left} +@kindex M-@key{right} +@item M-@key{left} +@itemx M-@key{right} +Decrease/increase the indentation of an item, leaving children alone. @kindex M-S-@key{left} @kindex M-S-@key{right} @item M-S-@key{left} diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 0b45639..a14a75d 100755 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -1,5 +1,22 @@ 2010-04-23 Carsten Dominik <carsten.dominik@gmail.com> + * org.el (org-shiftmetaleft, org-shiftmetaright): Call the subtree + indentation commands. + (org-hidden-tree-error): New defsubst. + (org-metaleft, org-metaright): Check for hidden stuff and throw an + error. + (org-check-for-hidden): New function. + + * org-list.el (org-item-re): New function. + (org-at-item-p): Use `org-item-re'. + (org-end-of-item-text-before-children): New function. + (org-outdent-item, org-indent-item): Arrange for leaving the + subtree alone. + (org-outdent-item-tree, org-indent-item-tree): New argument + NO-SUBTREE. + (org-indent-item-tree): Use `org-end-of-item-text-before-children' + to find the end for processing while ignoring the subtree. + * org-publish.el (org-publish-sitemap-sort-alphabetically) (org-publish-sitemap-sort-folders) (org-publish-sitemap-sort-ignore-case): New options. diff --git a/lisp/org-list.el b/lisp/org-list.el index 79c939c..212d172 100644 --- a/lisp/org-list.el +++ b/lisp/org-list.el @@ -197,17 +197,25 @@ list, obtained by prompting the user." ;;; Plain list items +(defun org-item-re (&optional general) + "Return the correct regular expression for plain lists. +If GENERAL is non-nil, return the general regexp independent of the value +of `org-plain-list-ordered-item-terminator'." + (cond + ((or general (eq org-plain-list-ordered-item-terminator t)) + "\\([ \t]*\\([-+]\\|\\([0-9]+[.)]\\)\\)\\|[ \t]+\\*\\)\\( \\|$\\)") + ((= org-plain-list-ordered-item-terminator ?.) + "\\([ \t]*\\([-+]\\|\\([0-9]+\\.\\)\\)\\|[ \t]+\\*\\)\\( \\|$\\)") + ((= org-plain-list-ordered-item-terminator ?\)) + "\\([ \t]*\\([-+]\\|\\([0-9]+)\\)\\)\\|[ \t]+\\*\\)\\( \\|$\\)") + (t (error "Invalid value of `org-plain-list-ordered-item-terminator'")))) + (defun org-at-item-p () "Is point in a line starting a hand-formatted item?" - (let ((llt org-plain-list-ordered-item-terminator)) - (save-excursion - (goto-char (point-at-bol)) - (looking-at - (cond - ((eq llt t) "\\([ \t]*\\([-+]\\|\\([0-9]+[.)]\\)\\)\\|[ \t]+\\*\\)\\( \\|$\\)") - ((= llt ?.) "\\([ \t]*\\([-+]\\|\\([0-9]+\\.\\)\\)\\|[ \t]+\\*\\)\\( \\|$\\)") - ((= llt ?\)) "\\([ \t]*\\([-+]\\|\\([0-9]+)\\)\\)\\|[ \t]+\\*\\)\\( \\|$\\)") - (t (error "Invalid value of `org-plain-list-ordered-item-terminator'"))))))) + + (save-excursion + (goto-char (point-at-bol)) + (looking-at (org-item-re)))) (defun org-at-item-bullet-p () "Is point at the bullet of a plain list item?" @@ -590,6 +598,16 @@ If the cursor is not in an item, throw an error." (goto-char pos) (error "Not in an item")))) +(defun org-end-of-item-text-before-children () + "Move to the end of the item text, stops before the first child if any. +Assumes that the cursor is in the first ine of an item." + (goto-char + (min (save-excursion (org-end-of-item) (point)) + (save-excursion + (goto-char (point-at-eol)) + (re-search-forward (concat "^" (org-item-re t)) nil t) + (match-beginning 0))))) + (defun org-next-item () "Move to the beginning of the next item in the current plain list. Error if not at a plain list, or if this is the last item in the list." @@ -961,12 +979,24 @@ I.e. to the text after the last item." (defvar org-last-indent-end-marker (make-marker)) (defun org-outdent-item (arg) - "Outdent a local list item." + "Outdent a local list item, but not its children." (interactive "p") - (org-indent-item (- arg))) + (org-indent-item-tree (- arg) 'no-subtree)) (defun org-indent-item (arg) - "Indent a local list item." + "Indent a local list item, but not its children." + (interactive "p") + (org-indent-item-tree arg 'no-subtree)) + +(defun org-outdent-item-tree (arg &optional no-subtree) + "Outdent a local list item including its children. +If NO-SUBTREE is set, only outdend the item itself, not its children." + (interactive "p") + (org-indent-item-tree (- arg) no-subtree)) + +(defun org-indent-item-tree (arg &optional no-subtree) + "Indent a local list item including its children. +If NO-SUBTREE is set, only indent the item itself, not its children." (interactive "p") (and (org-region-active-p) (org-cursor-to-region-beginning)) (unless (org-at-item-p) @@ -975,12 +1005,15 @@ I.e. to the text after the last item." (setq firstp (org-first-list-item-p)) (save-excursion (setq end (and (org-region-active-p) (region-end))) - (if (memq last-command '(org-shiftmetaright org-shiftmetaleft)) + (if (and (memq last-command '(org-shiftmetaright org-shiftmetaleft)) + (memq this-command '(org-shiftmetaright org-shiftmetaleft))) (setq beg org-last-indent-begin-marker end org-last-indent-end-marker) (org-beginning-of-item) (setq beg (move-marker org-last-indent-begin-marker (point))) - (org-end-of-item) + (if no-subtree + (org-end-of-item-text-before-children) + (org-end-of-item)) (setq end (move-marker org-last-indent-end-marker (or end (point))))) (goto-char beg) (setq ind-bul (org-item-indent-positions) diff --git a/lisp/org.el b/lisp/org.el index 0eaf326..f21e5bb 100644 --- a/lisp/org.el +++ b/lisp/org.el @@ -15970,7 +15970,7 @@ See the individual commands for more information." ((run-hook-with-args-until-success 'org-shiftmetaleft-hook)) ((org-at-table-p) (call-interactively 'org-table-delete-column)) ((org-on-heading-p) (call-interactively 'org-promote-subtree)) - ((org-at-item-p) (call-interactively 'org-outdent-item)) + ((org-at-item-p) (call-interactively 'org-outdent-item-tree)) (t (org-modifier-cursor-error)))) (defun org-shiftmetaright () @@ -15983,7 +15983,7 @@ See the individual commands for more information." ((run-hook-with-args-until-success 'org-shiftmetaright-hook)) ((org-at-table-p) (call-interactively 'org-table-insert-column)) ((org-on-heading-p) (call-interactively 'org-demote-subtree)) - ((org-at-item-p) (call-interactively 'org-indent-item)) + ((org-at-item-p) (call-interactively 'org-indent-item-tree)) (t (org-modifier-cursor-error)))) (defun org-shiftmetaup (&optional arg) @@ -16012,6 +16012,10 @@ commands for more information." ((org-at-item-p) (call-interactively 'org-move-item-down)) (t (org-modifier-cursor-error)))) +(defsubst org-hidden-tree-error () + (error + "Hidden subtree, open with TAB or use subtree command M-S-<left>/<right>")) + (defun org-metaleft (&optional arg) "Promote heading or move table column to left. Calls `org-do-promote' or `org-table-move-column', depending on context. @@ -16026,12 +16030,14 @@ See the individual commands for more information." (save-excursion (goto-char (region-beginning)) (org-on-heading-p)))) + (when (org-check-for-hidden 'headlines) (org-hidden-tree-error)) (call-interactively 'org-do-promote)) ((or (org-at-item-p) (and (org-region-active-p) (save-excursion (goto-char (region-beginning)) (org-at-item-p)))) + (when (org-check-for-hidden 'items) (org-hidden-tree-error)) (call-interactively 'org-outdent-item)) (t (call-interactively 'backward-word)))) @@ -16049,15 +16055,45 @@ See the individual commands for more information." (save-excursion (goto-char (region-beginning)) (org-on-heading-p)))) + (when (org-check-for-hidden 'headlines) (org-hidden-tree-error)) (call-interactively 'org-do-demote)) ((or (org-at-item-p) (and (org-region-active-p) (save-excursion (goto-char (region-beginning)) (org-at-item-p)))) + (when (org-check-for-hidden 'items) (org-hidden-tree-error)) (call-interactively 'org-indent-item)) (t (call-interactively 'forward-word)))) +(defun org-check-for-hidden (what) + "Check if there are hidden headlines/items in the current visual line. +WHAT can be either `headlines' or `items'. If the current line is +an outline or item heading and it has a folded subtree below it, +this fucntion returns t, nil otherwise." + (let ((re (cond + ((eq what 'headlines) (concat "^" org-outline-regexp)) + ((eq what 'items) (concat "^" (org-item-re t))) + (t (error "This should not happen")))) + beg end) + (save-excursion + (catch 'exit + (if (org-region-active-p) + (setq beg (region-beginning) end (region-end)) + (setq beg (point-at-bol)) + (beginning-of-line 2) + (while (and (not (eobp)) ;; this is like `next-line' + (get-char-property (1- (point)) 'invisible)) + (beginning-of-line 2)) + (setq end (point))) + (goto-char beg) + (goto-char (point-at-eol)) + (setq end (max end (point))) + (while (re-search-forward re end t) + (if (get-char-property (match-beginning 0) 'invisible) + (throw 'exit t))) + nil)))) + (defun org-metaup (&optional arg) "Move subtree up or move table row up. Calls `org-move-subtree-up' or `org-table-move-row' or |