From: Nicolas <n.goaziou@gmail.com>
To: Linus Arver <linusarver@gmail.com>
Cc: emacs-orgmode@gnu.org, Bastien <bastien.guerry@wikimedia.fr>
Subject: Re: [PATCH] indentation for section headings vs bulleted lists
Date: Mon, 21 Feb 2011 00:26:30 +0100 [thread overview]
Message-ID: <874o7yz3rt.fsf_-_@gmail.com> (raw)
In-Reply-To: <20110220195133.GA28370@aether.rnxn4ps> (Linus Arver's message of "Sun, 20 Feb 2011 11:51:35 -0800")
[-- Attachment #1: Type: text/plain, Size: 112 bytes --]
Hello,
Here is an attempt to solve the problem at hand.
Linus, would you mind testing it and reporting back?
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: patch to integrate lists with org-indent-mode --]
[-- Type: text/x-patch, Size: 10938 bytes --]
From 77aad13b9a322032763148b17dd9cb3073bdbf23 Mon Sep 17 00:00:00 2001
From: Nicolas Goaziou <n.goaziou@gmail.com>
Date: Sun, 20 Feb 2011 13:44:00 +0100
Subject: [PATCH] Integrate lists with org-indent-mode and visual-line-mode
* lisp/org-list.el (org-list-insert-item): keep prefix properties when
inserting a new item.
(org-list-struct-apply-struct): keep prefix properties when
modifying an item.
* lisp/org-indent.el (org-indent-mode): promoting and demoting should
refresh subtree.
(org-indent-add-properties): Add lists support. Refactor and comment
code.
(org-indent-refresh-subtree): No need to remove properties before
refreshing. Also, make sure beg is at beginning of line.
(org-indent-refresh-to, org-indent-refresh-section): Refactor. No
need to remove properties before refreshing either.
---
lisp/org-indent.el | 132 ++++++++++++++++++++++-----------------------------
lisp/org-list.el | 18 ++++++-
2 files changed, 73 insertions(+), 77 deletions(-)
diff --git a/lisp/org-indent.el b/lisp/org-indent.el
index a177a6f..4411cd2 100644
--- a/lisp/org-indent.el
+++ b/lisp/org-indent.el
@@ -39,6 +39,7 @@
(require 'cl))
(defvar org-inlinetask-min-level)
+(declare-function org-in-item-p "org-list" ())
(declare-function org-inlinetask-get-task-level "org-inlinetask" ())
(declare-function org-inlinetask-in-task-p "org-inlinetask" ())
@@ -161,13 +162,12 @@ FIXME: How to update when broken?"
(add-to-list 'buffer-substring-filters
'org-indent-remove-properties-from-string)
(org-add-hook 'org-after-demote-entry-hook
- 'org-indent-refresh-section nil 'local)
+ 'org-indent-refresh-subtree nil 'local)
(org-add-hook 'org-after-promote-entry-hook
- 'org-indent-refresh-section nil 'local)
+ 'org-indent-refresh-subtree nil 'local)
(org-add-hook 'org-font-lock-hook
'org-indent-refresh-to nil 'local)
- (and font-lock-mode (org-restart-font-lock))
- )
+ (and font-lock-mode (org-restart-font-lock)))
(t
;; mode was turned off (or we refused to turn it on)
(save-excursion
@@ -181,9 +181,9 @@ FIXME: How to update when broken?"
(delq 'org-indent-remove-properties-from-string
buffer-substring-filters))
(remove-hook 'org-after-promote-entry-hook
- 'org-indent-refresh-section 'local)
+ 'org-indent-refresh-subtree 'local)
(remove-hook 'org-after-demote-entry-hook
- 'org-indent-refresh-section 'local)
+ 'org-indent-refresh-subtree 'local)
(and font-lock-mode (org-restart-font-lock))
(redraw-display))))))
@@ -222,82 +222,66 @@ useful to make it ever so slightly different."
(defun org-indent-add-properties (beg end)
"Add indentation properties between BEG and END.
-Assumes that BEG is at the beginning of a line."
+Assume BEG is at an headline, inline task, or at beginning of buffer."
(let* ((inhibit-modification-hooks t)
(inlinetaskp (featurep 'org-inlinetask))
- (get-real-level (lambda (pos lvl)
- (save-excursion
- (goto-char pos)
- (if (and inlinetaskp (org-inlinetask-in-task-p))
- (org-inlinetask-get-task-level)
- lvl))))
- (b beg)
- (e end)
- (level 0)
- (n 0)
- exit nstars)
+ (m end))
(with-silent-modifications
+ ;; 1. Starting from END, move to each headline and inline task,
+ ;; and set prefixes point and the headline/inline task below
+ ;; (saved in M). `line-prefix' property is only set on inner
+ ;; part of that area, not on headlines.
(save-excursion
+ (goto-char end)
+ (while (re-search-backward org-indent-outline-re beg 'move)
+ (let ((pf (aref org-indent-strings
+ (if (and inlinetaskp (org-inlinetask-at-task-p))
+ (1+ (org-inlinetask-get-task-level))
+ (1+ (org-current-level))))))
+ (add-text-properties (point) m `(wrap-prefix ,pf))
+ (add-text-properties (point-at-eol) m `(line-prefix ,pf))
+ (setq m (point))))
+ ;; Special case for area before first headline.
+ (when (bobp)
+ (add-text-properties (point) m '(wrap-prefix nil line-prefix nil)))
+ ;; 2. Set `wrap-prefix' in lists between BEG and END. For each
+ ;; item, length of prefix is the sum of length of
+ ;; `line-prefix', indentation and size of bullet.
(goto-char beg)
- (while (not exit)
- (setq e end)
- (if (not (re-search-forward org-indent-outline-re nil t))
- (setq e (point-max) exit t)
- (setq e (match-beginning 0))
- (if (>= e end) (setq exit t))
- (unless (and inlinetaskp (org-inlinetask-in-task-p))
- (setq level (- (match-end 0) (match-beginning 0) 1)))
- (setq nstars (* (1- (funcall get-real-level e level))
- (1- org-indent-indentation-per-level)))
- (add-text-properties
- (point-at-bol) (point-at-eol)
- (list 'line-prefix
- (aref org-indent-stars nstars)
- 'wrap-prefix
- (aref org-indent-strings
- (* (funcall get-real-level e level)
- org-indent-indentation-per-level)))))
- (when (> e b)
- (add-text-properties
- b e (list 'line-prefix (aref org-indent-strings n)
- 'wrap-prefix (aref org-indent-strings n))))
- (setq b (1+ (point-at-eol))
- n (* (funcall get-real-level b level)
- org-indent-indentation-per-level)))))))
+ (while (org-list-search-forward (org-item-beginning-re) end t)
+ (let ((struct (org-list-struct)))
+ (mapc (lambda (itm)
+ (let ((pf (aref org-indent-strings
+ (+ (length (get-text-property
+ (car itm) 'line-prefix))
+ (nth 1 itm)
+ (length (nth 2 itm))))))
+ (add-text-properties (car itm) (1- (nth 6 itm))
+ `(wrap-prefix ,pf))))
+ struct)
+ (goto-char (org-list-get-bottom-point struct))))))))
(defvar org-inlinetask-min-level)
(defun org-indent-refresh-section ()
- "Refresh indentation properties in the current outline section.
-Point is assumed to be at the beginning of a headline."
+ "Refresh indentation properties between point and end next outline section."
(interactive)
(when org-indent-mode
- (let (beg end)
- (save-excursion
- (when (ignore-errors (let ((outline-regexp (format "\\*\\{1,%s\\}[ \t]+"
- (if (featurep 'org-inlinetask)
- (1- org-inlinetask-min-level)
- ""))))
- (org-back-to-heading)))
- (setq beg (point))
- (setq end (or (save-excursion (or (outline-next-heading) (point)))))
- (org-indent-remove-properties beg end)
- (org-indent-add-properties beg end))))))
+ (save-excursion
+ (org-with-limited-levels
+ (let ((beg (or (ignore-errors (org-back-to-heading))
+ (point-min)))
+ (end (progn (outline-next-heading) (point))))
+ (org-indent-add-properties beg end))))))
(defun org-indent-refresh-to (limit)
- "Refresh indentation properties in the current outline section.
-Point is assumed to be at the beginning of a headline."
+ "Refresh indentation properties in the current outline section."
(interactive)
(when org-indent-mode
- (let ((beg (point)) (end limit))
- (save-excursion
- (and (ignore-errors (let ((outline-regexp (format "\\*\\{1,%s\\}[ \t]+"
- (if (featurep 'org-inlinetask)
- (1- org-inlinetask-min-level)
- ""))))
- (org-back-to-heading)))
- (setq beg (point))))
- (org-indent-remove-properties beg end)
- (org-indent-add-properties beg end)))
+ (save-excursion
+ (org-with-limited-levels
+ (let ((beg (or (and (ignore-errors (org-back-to-heading)) (point))
+ (point-min))))
+ (org-indent-add-properties beg limit)))))
(goto-char limit))
(defun org-indent-refresh-subtree ()
@@ -306,15 +290,13 @@ Point is assumed to be at the beginning of a headline."
(interactive)
(when org-indent-mode
(save-excursion
- (let (beg end)
- (setq beg (point))
- (setq end (save-excursion (org-end-of-subtree t t)))
- (org-indent-remove-properties beg end)
- (org-indent-add-properties beg end)))))
+ (org-with-limited-levels
+ (let ((beg (point-at-bol))
+ (end (save-excursion (org-end-of-subtree t t))))
+ (org-indent-add-properties beg end))))))
(defun org-indent-refresh-buffer ()
- "Refresh indentation properties in the current outline subtree.
-Point is assumed to be at the beginning of a headline."
+ "Refresh indentation properties in the current outline subtree."
(interactive)
(when org-indent-mode
(org-indent-mode -1)
diff --git a/lisp/org-list.el b/lisp/org-list.el
index 4700477..8ffe4d0 100644
--- a/lisp/org-list.el
+++ b/lisp/org-list.el
@@ -1156,9 +1156,12 @@ This function modifies STRUCT."
;; functions, position of point with regards to item start
;; (BEFOREP), blank lines number separating items (BLANK-NB),
;; position of split (POS) if we're allowed to (SPLIT-LINE-P).
+ ;; Also, save prefix properties for `org-indent-mode'.
(let* ((item (goto-char (org-list-get-item-begin)))
(item-end (org-list-get-item-end item struct))
(item-end-no-blank (org-list-get-item-end-before-blank item struct))
+ (wrap (get-text-property (point) 'wrap-prefix))
+ (line (get-text-property (point) 'line-prefix))
(beforep (and (looking-at org-list-full-item-re)
(<= pos (match-end 0))))
(split-line-p (org-get-alist-option org-M-RET-may-split-line 'item))
@@ -1194,6 +1197,9 @@ This function modifies STRUCT."
(goto-char item)
(org-indent-to-column ind)
(insert body)
+ (when (and (featurep 'org-indent) org-indent-mode)
+ (add-text-properties item (point)
+ `(line-prefix ,line wrap-prefix ,wrap)))
(insert item-sep)
;; 5. Add new item to STRUCT.
(mapc (lambda (e)
@@ -1628,7 +1634,9 @@ Initial position of cursor is restored after the changes."
(new-bul (org-list-bullet-string
(org-list-get-bullet item struct)))
(old-bul (org-list-get-bullet item old-struct))
- (new-box (org-list-get-checkbox item struct)))
+ (new-box (org-list-get-checkbox item struct))
+ (wrap (get-text-property (point) 'wrap-prefix))
+ (line (get-text-property (point) 'line-prefix)))
(looking-at org-list-full-item-re)
;; a. Replace bullet
(unless (equal old-bul new-bul)
@@ -1652,7 +1660,13 @@ Initial position of cursor is restored after the changes."
(unless (= new-ind old-ind)
(delete-region (goto-char (point-at-bol))
(progn (skip-chars-forward " \t") (point)))
- (indent-to new-ind)))))))
+ (indent-to new-ind))
+ ;; d. If `org-indent-mode' is on, keep prefix
+ ;; properties.
+ (when (and (featurep 'org-indent) org-indent-mode)
+ (add-text-properties
+ (point-at-bol) (point-at-eol)
+ `(line-prefix ,line wrap-prefix ,wrap))))))))
;; 1. First get list of items and position endings. We maintain
;; two alists: ITM-SHIFT, determining indentation shift needed
;; at item, and END-POS, a pseudo-alist where key is ending
--
1.7.4.1
[-- Attachment #3: Type: text/plain, Size: 23 bytes --]
Regards,
--
Nicolas
[-- Attachment #4: Type: text/plain, Size: 201 bytes --]
_______________________________________________
Emacs-orgmode mailing list
Please use `Reply All' to send replies to the list.
Emacs-orgmode@gnu.org
http://lists.gnu.org/mailman/listinfo/emacs-orgmode
next prev parent reply other threads:[~2011-02-20 23:26 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-02-18 6:39 indentation for section headings vs bulleted lists Linus Arver
2011-02-18 8:52 ` Bastien
2011-02-19 2:34 ` Linus Arver
2011-02-19 9:35 ` Bastien
2011-02-20 7:22 ` Linus Arver
2011-02-20 12:19 ` Nicolas
2011-02-20 12:39 ` Carsten Dominik
2011-02-20 13:27 ` Nicolas
2011-02-20 19:51 ` Linus Arver
2011-02-20 23:26 ` Nicolas [this message]
2011-02-21 1:04 ` [PATCH] " Linus Arver
2011-02-21 10:59 ` Giovanni Ridolfi
2011-02-21 17:32 ` Nicolas
2011-02-18 18:18 ` Darlan Cavalcante Moreira
2011-02-19 2:46 ` Linus Arver
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: https://www.orgmode.org/
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=874o7yz3rt.fsf_-_@gmail.com \
--to=n.goaziou@gmail.com \
--cc=bastien.guerry@wikimedia.fr \
--cc=emacs-orgmode@gnu.org \
--cc=linusarver@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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).