* [RFC] Org Num library @ 2018-11-20 18:22 Nicolas Goaziou 2018-11-20 22:29 ` Neil Jerram ` (2 more replies) 0 siblings, 3 replies; 8+ messages in thread From: Nicolas Goaziou @ 2018-11-20 18:22 UTC (permalink / raw) To: Org Mode List [-- Attachment #1: Type: text/plain, Size: 1267 bytes --] Hello, A few weeks ago, I posted on this ML a proof of concept about dynamic numbering of headlines in an Org buffer. Since then, I worked on it more seriously, improved it, and threw in some features. Here is an excerpt of its commentary section: This library provides dynamic numbering for Org headlines. Use <M-x org-num-mode> to toggle it. You can select what is numbered according to level, tags, COMMENT keyword, or UNNUMBERED property. You can also skip footnotes sections. See `org-num-max-level', `org-num-skip-tags', `org-num-skip-commented', `org-num-skip-unnumbered', and `org-skip-footnotes' for details. You can also control how the numbering is displayed by setting `org-num-face' and `org-num-format-function'. I tested it a bit, even in relatively large documents like the Org manual, without problem. I also wrote a test suite for that library. Since it is very much Org-specific, and a basic feature you could expect from Org, I'd like to add it in core. So, if there is no strong objection to it, it can go in Org 9.3. I attach the library for further testing, suggestions, remarks… Let me know what you think. Regards, -- Nicolas Goaziou [-- Attachment #2: Org Num library --] [-- Type: application/emacs-lisp, Size: 18971 bytes --] ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [RFC] Org Num library 2018-11-20 18:22 [RFC] Org Num library Nicolas Goaziou @ 2018-11-20 22:29 ` Neil Jerram 2018-11-21 6:31 ` Eric S Fraga 2019-01-31 15:27 ` Marco Wahl 2 siblings, 0 replies; 8+ messages in thread From: Neil Jerram @ 2018-11-20 22:29 UTC (permalink / raw) To: Nicolas Goaziou, Org Mode List Nicolas Goaziou <mail@nicolasgoaziou.fr> writes: > Since it is very much Org-specific, and a basic feature you could expect > from Org, I'd like to add it in core. So, if there is no strong > objection to it, it can go in Org 9.3. > > I attach the library for further testing, suggestions, remarks… Let me > know what you think. Well, with my Org 9.1.14, I can report that the code evaluates cleanly and the feature works. I can't see any objection to adding it into core. (I'd add that I'm not yet seeing a clear use case for it; but perhaps that will change in future.) Neil ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [RFC] Org Num library 2018-11-20 18:22 [RFC] Org Num library Nicolas Goaziou 2018-11-20 22:29 ` Neil Jerram @ 2018-11-21 6:31 ` Eric S Fraga 2019-01-31 15:27 ` Marco Wahl 2 siblings, 0 replies; 8+ messages in thread From: Eric S Fraga @ 2018-11-21 6:31 UTC (permalink / raw) To: Org Mode List On Tuesday, 20 Nov 2018 at 19:22, Nicolas Goaziou wrote: > Since it is very much Org-specific, and a basic feature you could expect > from Org, I'd like to add it in core. So, if there is no strong > objection to it, it can go in Org 9.3. No objection from me at all. I may or may not use this very often but see no reason it cannot be there for others to use. It does seem to work very well, by the way. thanks, eric -- Eric S Fraga via Emacs 27.0.50, Org release_9.1.14-1035-gfeb442 ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [RFC] Org Num library 2018-11-20 18:22 [RFC] Org Num library Nicolas Goaziou 2018-11-20 22:29 ` Neil Jerram 2018-11-21 6:31 ` Eric S Fraga @ 2019-01-31 15:27 ` Marco Wahl 2019-02-03 9:41 ` Nicolas Goaziou 2 siblings, 1 reply; 8+ messages in thread From: Marco Wahl @ 2019-01-31 15:27 UTC (permalink / raw) To: emacs-orgmode Hi Nicolas and all, @Nicolas: Thanks for org-num-mode. > A few weeks ago, I posted on this ML a proof of concept about dynamic > numbering of headlines in an Org buffer. Since then, I worked on it more > seriously, improved it, and threw in some features. Here is an excerpt > of its commentary section: > > This library provides dynamic numbering for Org headlines. Use > > <M-x org-num-mode> > > to toggle it. > > You can select what is numbered according to level, tags, COMMENT > keyword, or UNNUMBERED property. You can also skip footnotes > sections. See `org-num-max-level', `org-num-skip-tags', > `org-num-skip-commented', `org-num-skip-unnumbered', and > `org-skip-footnotes' for details. > > You can also control how the numbering is displayed by setting > `org-num-face' and `org-num-format-function'. > > I tested it a bit, even in relatively large documents like the Org > manual, without problem. I also wrote a test suite for that library. > > Since it is very much Org-specific, and a basic feature you could expect > from Org, I'd like to add it in core. So, if there is no strong > objection to it, it can go in Org 9.3. > > I attach the library for further testing, suggestions, remarks… Let me > know what you think. For some days I turned on org-num-mode for every Org file automatically with the setting (add-hook 'org-mode-hook #'org-num-mode) in my init file. org-num-mode worked fine for me. Just one idea came to my mind. What about adding an option to restart the numbering at 1 for the first heading in the case when narrowing is in effect? Ciao, Marco ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [RFC] Org Num library 2019-01-31 15:27 ` Marco Wahl @ 2019-02-03 9:41 ` Nicolas Goaziou 2019-02-04 6:35 ` stardiviner 0 siblings, 1 reply; 8+ messages in thread From: Nicolas Goaziou @ 2019-02-03 9:41 UTC (permalink / raw) To: Marco Wahl; +Cc: emacs-orgmode [-- Attachment #1: Type: text/plain, Size: 481 bytes --] Hello, Marco Wahl <marcowahlsoft@gmail.com> writes: > Just one idea came to my mind. What about adding an option to restart > the numbering at 1 for the first heading in the case when narrowing is > in effect? AFAICT, detecting narrowing changes requires using `post-command-hook'. Therefore an update to numbering, when such change happens, might get in the way, e.g., if it slows down input. Anyway, here is a POC, if anyone wants to test it. Regards, -- Nicolas Goaziou [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #2: Number headlinges according to buffer narrowing --] [-- Type: text/x-diff, Size: 6737 bytes --] From 1659484513fd4badb1fca867810a87756d1d46b5 Mon Sep 17 00:00:00 2001 From: Nicolas Goaziou <mail@nicolasgoaziou.fr> Date: Sun, 3 Feb 2019 10:33:47 +0100 Subject: [PATCH] org-num: Add an option to start numbering according to narrowing * lisp/org-num.el (org-num-visible-only): (org-num--start): New variables. (org-num--current-numbering): Change signature. (org-num--number-region): (org-num--update): Apply signature change. (org-num--check-narrowing): New function. (org-num-mode): Add, or remove, new function in `post-command-hook'. --- lisp/org-num.el | 80 ++++++++++++++++++++++++++++++++----------------- 1 file changed, 53 insertions(+), 27 deletions(-) diff --git a/lisp/org-num.el b/lisp/org-num.el index f062526a0..de0a4ad48 100644 --- a/lisp/org-num.el +++ b/lisp/org-num.el @@ -135,6 +135,12 @@ control tag inheritance." :type 'boolean :safe #'booleanp) +(defcustom org-num-visible-only nil + "Non-nil restricts numbering to the visible part of the buffer." + :group 'org-appearance + :type 'boolean + :safe #'booleanp) + \f ;;; Internal Variables @@ -154,6 +160,9 @@ inheritance of no-numbering attributes.") A numbering is a list of integers, in reverse order. So numbering for headline \"1.2.3\" is (3 2 1).") +(defvar-local org-num--start 1 + "Buffer position where headlines start to be numbered.") + (defvar-local org-num--missing-overlay nil "Buffer position signaling a headline without an overlay.") @@ -255,16 +264,22 @@ otherwise." (org-entry-get (point) "UNNUMBERED") t)))) -(defun org-num--current-numbering (level skip) +(defun org-num--current-numbering (pos level skip) "Return numbering for current headline. -LEVEL is headline's level, and SKIP its skip value. Return nil -if headline should be skipped." + +POS is headline's beginning position, LEVEL its level, and SKIP +its skip value. + +Numbering starts from `org-num--start' position. Return nil if +headline should not be numbered." (cond ;; Skipped by inheritance. ((and org-num--skip-level (> level org-num--skip-level)) nil) ;; Skipped by a non-nil skip value; set `org-num--skip-level' ;; to skip the whole sub-tree later on. (skip (setq org-num--skip-level level) nil) + ;; Skipped because it is before visible part of the buffer. + ((and org-num-visible-only (< pos org-num--start)) nil) (t (setq org-num--skip-level nil) ;; Compute next numbering, and update `org-num--numbering'. @@ -296,10 +311,12 @@ first." (let ((regexp (org-num--headline-regexp)) (new nil)) (while (re-search-forward regexp end t) - (let* ((level (org-reduced-level - (- (match-end 0) (match-beginning 0) 1))) - (skip (org-num--skip-value)) - (numbering (org-num--current-numbering level skip))) + (let* ((pos (line-beginning-position)) + (level (org-reduced-level + (- (match-end 0) (match-beginning 0) 1))) + (skip (org-num--skip-value)) + (numbering + (org-num--current-numbering pos level skip))) ;; Apply numbering to current headline. Store overlay for ;; the return value. (push (org-num--make-overlay numbering level skip) @@ -324,26 +341,26 @@ missing overlays to that list." ;; last known overlay, make sure to parse the buffer between ;; these two overlays. ((org-num--valid-overlay-p overlay) - (let ((next (overlay-start overlay)) - (last (and new-overlays (overlay-start (car new-overlays))))) - (cond - ((null org-num--missing-overlay)) - ((> org-num--missing-overlay next)) - ((or (null last) (> org-num--missing-overlay last)) - (setq org-num--missing-overlay nil) - (setq new-overlays (nconc (org-num--number-region last next) - new-overlays))) - ;; If it is already after the last known overlay, reset it: - ;; some previous invalid overlay already triggered the - ;; necessary parsing. - (t - (setq org-num--missing-overlay nil)))) - ;; Update OVERLAY's numbering. - (let* ((level (overlay-get overlay 'level)) - (skip (overlay-get overlay 'skip)) - (numbering (org-num--current-numbering level skip))) - (org-num--refresh-display overlay numbering) - (push overlay new-overlays))) + (let ((next (overlay-start overlay))) + (let ((last (and new-overlays (overlay-start (car new-overlays))))) + (cond + ((null org-num--missing-overlay)) + ((> org-num--missing-overlay next)) + ((or (null last) (> org-num--missing-overlay last)) + (setq org-num--missing-overlay nil) + (setq new-overlays (nconc (org-num--number-region last next) + new-overlays))) + ;; If it is already after the last known overlay, reset it: + ;; some previous invalid overlay already triggered the + ;; necessary parsing. + (t + (setq org-num--missing-overlay nil)))) + ;; Update OVERLAY's numbering. + (let* ((level (overlay-get overlay 'level)) + (skip (overlay-get overlay 'skip)) + (numbering (org-num--current-numbering next level skip))) + (org-num--refresh-display overlay numbering) + (push overlay new-overlays)))) ;; Invalid overlay. It indicates that the buffer needs to be ;; parsed again between the two surrounding valid overlays or ;; buffer boundaries. @@ -430,6 +447,13 @@ See this variable for the meaning of BEG and END." (when (or org-num--missing-overlay org-num--invalid-flag) (org-num--update)))) +(defun org-num--check-narrowing () + "Check buffer narrowing; update numbering if necessary. +This function is meant to be used in `post-command-hook'." + (when (and org-num-visible-only (/= org-num--start (point-min))) + (setq org-num--start (point-min)) + (org-num--update))) + \f ;;; Public Functions @@ -450,10 +474,12 @@ NUMBERING is a list of numbers." (setq org-num--numbering nil) (setq org-num--overlays (nreverse (org-num--number-region nil nil))) (add-hook 'after-change-functions #'org-num--verify nil t) + (add-hook 'post-command-hook #'org-num--check-narrowing nil t) (add-hook 'change-major-mode-hook #'org-num--clear nil t)) (t (org-num--clear) (remove-hook 'after-change-functions #'org-num--verify t) + (remove-hook 'post-command-hook #'org-num--check-narrowing t) (remove-hook 'change-major-mode-hook #'org-num--clear t)))) -- 2.20.1 ^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [RFC] Org Num library 2019-02-03 9:41 ` Nicolas Goaziou @ 2019-02-04 6:35 ` stardiviner 2019-02-04 11:23 ` Marco Wahl 0 siblings, 1 reply; 8+ messages in thread From: stardiviner @ 2019-02-04 6:35 UTC (permalink / raw) To: emacs-orgmode; +Cc: Marco Wahl Nicolas Goaziou <mail@nicolasgoaziou.fr> writes: > Hello, > > Marco Wahl <marcowahlsoft@gmail.com> writes: > >> Just one idea came to my mind. What about adding an option to restart >> the numbering at 1 for the first heading in the case when narrowing is >> in effect? > > AFAICT, detecting narrowing changes requires using > `post-command-hook'. Add more things into `post-command-hook' is not a good idea. Org will really getting slow! I saw many Org Mode newbie complain about Org Mode slow on big Org file. Myself has this experience often. I have to disable some features so speedup Org rendering. Well, I think this is just my personal opinion. I respect author's decision. > Therefore an update to numbering, when such change happens, might get in > the way, e.g., if it slows down input. > > Anyway, here is a POC, if anyone wants to test it. > > Regards, > > -- > Nicolas Goaziou > From 1659484513fd4badb1fca867810a87756d1d46b5 Mon Sep 17 00:00:00 2001 > From: Nicolas Goaziou <mail@nicolasgoaziou.fr> > Date: Sun, 3 Feb 2019 10:33:47 +0100 > Subject: [PATCH] org-num: Add an option to start numbering according to > narrowing > > * lisp/org-num.el (org-num-visible-only): > (org-num--start): New variables. > (org-num--current-numbering): Change signature. > (org-num--number-region): > (org-num--update): Apply signature change. > (org-num--check-narrowing): New function. > (org-num-mode): Add, or remove, new function in `post-command-hook'. > --- > lisp/org-num.el | 80 ++++++++++++++++++++++++++++++++----------------- > 1 file changed, 53 insertions(+), 27 deletions(-) > > diff --git a/lisp/org-num.el b/lisp/org-num.el > index f062526a0..de0a4ad48 100644 > --- a/lisp/org-num.el > +++ b/lisp/org-num.el > @@ -135,6 +135,12 @@ control tag inheritance." > :type 'boolean > :safe #'booleanp) > > +(defcustom org-num-visible-only nil > + "Non-nil restricts numbering to the visible part of the buffer." > + :group 'org-appearance > + :type 'boolean > + :safe #'booleanp) > + > \f > ;;; Internal Variables > > @@ -154,6 +160,9 @@ inheritance of no-numbering attributes.") > A numbering is a list of integers, in reverse order. So numbering > for headline \"1.2.3\" is (3 2 1).") > > +(defvar-local org-num--start 1 > + "Buffer position where headlines start to be numbered.") > + > (defvar-local org-num--missing-overlay nil > "Buffer position signaling a headline without an overlay.") > > @@ -255,16 +264,22 @@ otherwise." > (org-entry-get (point) "UNNUMBERED") > t)))) > > -(defun org-num--current-numbering (level skip) > +(defun org-num--current-numbering (pos level skip) > "Return numbering for current headline. > -LEVEL is headline's level, and SKIP its skip value. Return nil > -if headline should be skipped." > + > +POS is headline's beginning position, LEVEL its level, and SKIP > +its skip value. > + > +Numbering starts from `org-num--start' position. Return nil if > +headline should not be numbered." > (cond > ;; Skipped by inheritance. > ((and org-num--skip-level (> level org-num--skip-level)) nil) > ;; Skipped by a non-nil skip value; set `org-num--skip-level' > ;; to skip the whole sub-tree later on. > (skip (setq org-num--skip-level level) nil) > + ;; Skipped because it is before visible part of the buffer. > + ((and org-num-visible-only (< pos org-num--start)) nil) > (t > (setq org-num--skip-level nil) > ;; Compute next numbering, and update `org-num--numbering'. > @@ -296,10 +311,12 @@ first." > (let ((regexp (org-num--headline-regexp)) > (new nil)) > (while (re-search-forward regexp end t) > - (let* ((level (org-reduced-level > - (- (match-end 0) (match-beginning 0) 1))) > - (skip (org-num--skip-value)) > - (numbering (org-num--current-numbering level skip))) > + (let* ((pos (line-beginning-position)) > + (level (org-reduced-level > + (- (match-end 0) (match-beginning 0) 1))) > + (skip (org-num--skip-value)) > + (numbering > + (org-num--current-numbering pos level skip))) > ;; Apply numbering to current headline. Store overlay for > ;; the return value. > (push (org-num--make-overlay numbering level skip) > @@ -324,26 +341,26 @@ missing overlays to that list." > ;; last known overlay, make sure to parse the buffer between > ;; these two overlays. > ((org-num--valid-overlay-p overlay) > - (let ((next (overlay-start overlay)) > - (last (and new-overlays (overlay-start (car new-overlays))))) > - (cond > - ((null org-num--missing-overlay)) > - ((> org-num--missing-overlay next)) > - ((or (null last) (> org-num--missing-overlay last)) > - (setq org-num--missing-overlay nil) > - (setq new-overlays (nconc (org-num--number-region last next) > - new-overlays))) > - ;; If it is already after the last known overlay, reset it: > - ;; some previous invalid overlay already triggered the > - ;; necessary parsing. > - (t > - (setq org-num--missing-overlay nil)))) > - ;; Update OVERLAY's numbering. > - (let* ((level (overlay-get overlay 'level)) > - (skip (overlay-get overlay 'skip)) > - (numbering (org-num--current-numbering level skip))) > - (org-num--refresh-display overlay numbering) > - (push overlay new-overlays))) > + (let ((next (overlay-start overlay))) > + (let ((last (and new-overlays (overlay-start (car new-overlays))))) > + (cond > + ((null org-num--missing-overlay)) > + ((> org-num--missing-overlay next)) > + ((or (null last) (> org-num--missing-overlay last)) > + (setq org-num--missing-overlay nil) > + (setq new-overlays (nconc (org-num--number-region last next) > + new-overlays))) > + ;; If it is already after the last known overlay, reset it: > + ;; some previous invalid overlay already triggered the > + ;; necessary parsing. > + (t > + (setq org-num--missing-overlay nil)))) > + ;; Update OVERLAY's numbering. > + (let* ((level (overlay-get overlay 'level)) > + (skip (overlay-get overlay 'skip)) > + (numbering (org-num--current-numbering next level skip))) > + (org-num--refresh-display overlay numbering) > + (push overlay new-overlays)))) > ;; Invalid overlay. It indicates that the buffer needs to be > ;; parsed again between the two surrounding valid overlays or > ;; buffer boundaries. > @@ -430,6 +447,13 @@ See this variable for the meaning of BEG and END." > (when (or org-num--missing-overlay org-num--invalid-flag) > (org-num--update)))) > > +(defun org-num--check-narrowing () > + "Check buffer narrowing; update numbering if necessary. > +This function is meant to be used in `post-command-hook'." > + (when (and org-num-visible-only (/= org-num--start (point-min))) > + (setq org-num--start (point-min)) > + (org-num--update))) > + > \f > ;;; Public Functions > > @@ -450,10 +474,12 @@ NUMBERING is a list of numbers." > (setq org-num--numbering nil) > (setq org-num--overlays (nreverse (org-num--number-region nil nil))) > (add-hook 'after-change-functions #'org-num--verify nil t) > + (add-hook 'post-command-hook #'org-num--check-narrowing nil t) > (add-hook 'change-major-mode-hook #'org-num--clear nil t)) > (t > (org-num--clear) > (remove-hook 'after-change-functions #'org-num--verify t) > + (remove-hook 'post-command-hook #'org-num--check-narrowing t) > (remove-hook 'change-major-mode-hook #'org-num--clear t)))) -- [ stardiviner ] I try to make every word tell the meaning what I want to express. Blog: https://stardiviner.github.io/ IRC(freenode): stardiviner, Matrix: stardiviner GPG: F09F650D7D674819892591401B5DF1C95AE89AC3 ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [RFC] Org Num library 2019-02-04 6:35 ` stardiviner @ 2019-02-04 11:23 ` Marco Wahl 2019-02-04 19:36 ` Nicolas Goaziou 0 siblings, 1 reply; 8+ messages in thread From: Marco Wahl @ 2019-02-04 11:23 UTC (permalink / raw) To: emacs-orgmode Hello stardiviner, >>> Just one idea came to my mind. What about adding an option to restart >>> the numbering at 1 for the first heading in the case when narrowing is >>> in effect? >> >> AFAICT, detecting narrowing changes requires using >> `post-command-hook'. > > Add more things into `post-command-hook' is not a good idea. Org will > really getting slow! I saw many Org Mode newbie complain about Org Mode > slow on big Org file. Myself has this experience often. I have to > disable some features so speedup Org rendering. > > Well, I think this is just my personal opinion. I respect author's > decision. I also think it's a good idea to save resources. I tried out the patch from Nicolas (which works great BTW, thanks!) but I'm undecided if it adds much value to Org. So if there is no interest we could just not commit the patch. If there is interest in that patch, the code could be refined to only hook into the `post-command-hook' when local numbering of narrowed parts has been chosen. Best regards, Marco ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [RFC] Org Num library 2019-02-04 11:23 ` Marco Wahl @ 2019-02-04 19:36 ` Nicolas Goaziou 0 siblings, 0 replies; 8+ messages in thread From: Nicolas Goaziou @ 2019-02-04 19:36 UTC (permalink / raw) To: Marco Wahl; +Cc: emacs-orgmode Hello, Marco Wahl <marcowahlsoft@gmail.com> writes: > If there is interest in that patch, the code could be refined to only > hook into the `post-command-hook' when local numbering of narrowed parts > has been chosen. This is mostly already the case. If local numbering of narrowed parts is inactive, the code executed in `post-command-hook' is (when #f), which adds no overhead. Regards, -- Nicolas Goaziou ^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2019-02-04 19:41 UTC | newest] Thread overview: 8+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2018-11-20 18:22 [RFC] Org Num library Nicolas Goaziou 2018-11-20 22:29 ` Neil Jerram 2018-11-21 6:31 ` Eric S Fraga 2019-01-31 15:27 ` Marco Wahl 2019-02-03 9:41 ` Nicolas Goaziou 2019-02-04 6:35 ` stardiviner 2019-02-04 11:23 ` Marco Wahl 2019-02-04 19:36 ` Nicolas Goaziou
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).