Hi. I've been using this for a while and find it very handy. If people like this and want it in Org Mode, I'll do the rest of the work to package it up as a patch, with ChangeLog entry, NEWS, etc, and post it here for review before committing. To try it out, just evaluate both functions and then run `M-x org-display-headings-to-point' from somewhere deep in an org subtree. Comments/feedback welcome. Best regards, -Karl (defun org-headings-to-point () "Return all the Org Mode headings leading to point." (when (not (eq major-mode 'org-mode)) (error "ERROR: this only works in Org Mode")) (let ((headings (list (org-heading-components)))) (save-excursion (save-match-data (save-restriction (widen) (while (org-up-heading-safe) (setq headings (cons (org-heading-components) headings))))) headings))) (defun org-display-headings-to-point () "Display Org Mode heading titles from level 1 to current subtree. Display each title on its own line, indented proportionally to its level." (interactive) (let* ((heading-titles (mapcar (lambda (heading) (nth 4 heading)) (org-headings-to-point))) (level 0) (hierarchy (mapcar (lambda (title) (prog1 (if (zerop level) (concat "• " title) (concat "\n" (make-string (* level 2) ? ) "→ " title)) (setq level (1+ level)))) heading-titles))) (display-message-or-buffer (string-join hierarchy))))
[-- Attachment #1: Type: text/plain, Size: 2113 bytes --] Very nice! It works also in Narrow mode, which makes it even more useful for me. Thanks! --Diego On Tue, Dec 3, 2019 at 3:58 AM Karl Fogel <kfogel@red-bean.com> wrote: > Hi. I've been using this for a while and find it very handy. > > If people like this and want it in Org Mode, I'll do the rest of the work > to package it up as a patch, with ChangeLog entry, NEWS, etc, and post it > here for review before committing. > > To try it out, just evaluate both functions and then run > > `M-x org-display-headings-to-point' > > from somewhere deep in an org subtree. Comments/feedback welcome. > > Best regards, > -Karl > > (defun org-headings-to-point () > "Return all the Org Mode headings leading to point." > (when (not (eq major-mode 'org-mode)) > (error "ERROR: this only works in Org Mode")) > (let ((headings (list (org-heading-components)))) > (save-excursion > (save-match-data > (save-restriction > (widen) > (while (org-up-heading-safe) > (setq headings (cons (org-heading-components) headings))))) > headings))) > > (defun org-display-headings-to-point () > "Display Org Mode heading titles from level 1 to current subtree. > Display each title on its own line, indented proportionally to its level." > (interactive) > (let* ((heading-titles (mapcar (lambda (heading) > (nth 4 heading)) > (org-headings-to-point))) > (level 0) > (hierarchy (mapcar (lambda (title) > (prog1 > (if (zerop level) > (concat "• " title) > (concat "\n" > (make-string (* level 2) ? ) > "→ " title)) > (setq level (1+ level)))) > heading-titles))) > (display-message-or-buffer (string-join hierarchy)))) > > [-- Attachment #2: Type: text/html, Size: 2826 bytes --]
This is really useful. Thanks!
Yiufung
On Tue, Dec 3, 2019, at 10:56 AM, Karl Fogel wrote:
> Hi. I've been using this for a while and find it very handy.
>
> If people like this and want it in Org Mode, I'll do the rest of the
> work to package it up as a patch, with ChangeLog entry, NEWS, etc, and
> post it here for review before committing.
>
> To try it out, just evaluate both functions and then run
>
> `M-x org-display-headings-to-point'
>
> from somewhere deep in an org subtree. Comments/feedback welcome.
>
> Best regards,
> -Karl
>
> (defun org-headings-to-point ()
> "Return all the Org Mode headings leading to point."
> (when (not (eq major-mode 'org-mode))
> (error "ERROR: this only works in Org Mode"))
> (let ((headings (list (org-heading-components))))
> (save-excursion
> (save-match-data
> (save-restriction
> (widen)
> (while (org-up-heading-safe)
> (setq headings (cons (org-heading-components) headings)))))
> headings)))
>
> (defun org-display-headings-to-point ()
> "Display Org Mode heading titles from level 1 to current subtree.
> Display each title on its own line, indented proportionally to its level."
> (interactive)
> (let* ((heading-titles (mapcar (lambda (heading)
> (nth 4 heading))
> (org-headings-to-point)))
> (level 0)
> (hierarchy (mapcar (lambda (title)
> (prog1
> (if (zerop level)
> (concat "• " title)
> (concat "\n"
> (make-string (* level 2) ? )
> "→ " title))
> (setq level (1+ level))))
> heading-titles)))
> (display-message-or-buffer (string-join hierarchy))))
>
>
This seems to duplicate functionality from org-get-outline-path. As well, org-eldoc displays in the minibuffer the outline path for the heading at point.
On 03 Dec 2019, Adam Porter wrote:
>This seems to duplicate functionality from org-get-outline-path. As
>well, org-eldoc displays in the minibuffer the outline path for the
>heading at point.
Thank you, Adam -- I didn't know about those. I had searched for something like that before implementing my own, but I think I searched using the term "heading" or something instead of "outline", unfortunately, so I never found them.
Now that I know about `org-display-outline-path', the one improvement I'd like to make is to enable it to display the headings with per-level indentation, and treat the first level specially (with an anchoring dot instead of a directional arrow), as my code did. It's a lot more readable that way displayed in the minibuffer.
I suppose I would implement this by adding two new optional arguments to `org-display-outline-path':
* `per-level-indentation': add a newline followed by <this string LEVEL-1 times> in front of each SEPARATOR
* `level-1-prefix': a special prefix for the first level's heading
...and make corresponding changes to the helper functions of course. There should also be some way to access the new functionality interactively; the solution might be a new interactive wrapper function with its own name, or maybe some new variables? I don't know; I haven't thought it all the way through yet.
Is there any interest in or opposition to such a patch? I'd like to get a sense of whether it would be able to land in Org Mode before I start working on it.
Best regards,
-Karl
On 03 Dec 2019, Adam Porter wrote:
>This seems to duplicate functionality from org-get-outline-path. As
>well, org-eldoc displays in the minibuffer the outline path for the
>heading at point.
By the way, when I run `M-x eldoc-mode' in a Org Mode buffer, I get this message:
"There is no ElDoc support in this buffer"
Am I doing it wrong?
Karl Fogel <kfogel@red-bean.com> writes:
> By the way, when I run `M-x eldoc-mode' in a Org Mode buffer, I get this message:
>
> "There is no ElDoc support in this buffer"
>
> Am I doing it wrong?
You need org-eldoc.el from /contrib.
[-- Attachment #1: Type: text/plain, Size: 929 bytes --] Karl Fogel <kfogel@red-bean.com> writes: > Thank you, Adam -- I didn't know about those. I had searched for > something like that before implementing my own, but I think I searched > using the term "heading" or something instead of "outline", > unfortunately, so I never found them. Org is like Emacs in that it has many nooks and crannies that even experienced users are unfamiliar with. There's always something more to discover. > Now that I know about `org-display-outline-path', the one improvement > I'd like to make is to enable it to display the headings with > per-level indentation, and treat the first level specially (with an > anchoring dot instead of a directional arrow), as my code did. It's a > lot more readable that way displayed in the minibuffer. You might consider adjusting your fontification settings. The single-line outline path can be quite readable with the right faces (see attached example). [-- Attachment #2: example --] [-- Type: image/png, Size: 25545 bytes --] [-- Attachment #3: Type: text/plain, Size: 2038 bytes --] > I suppose I would implement this by adding two new optional arguments to `org-display-outline-path': > > * `per-level-indentation': add a newline followed by <this string LEVEL-1 times> in front of each SEPARATOR > > * `level-1-prefix': a special prefix for the first level's heading I'd recommend against adding more optional arguments to that function, because it already has four. Emacs/Org already have enough problems with code like (org-whatever nil t nil t nil nil t). > ...and make corresponding changes to the helper functions of course. Please consider such changes very carefully, because those functions are used by a number of other packages. It's already difficult, and often frustrating, for package authors to maintain code that works across Org versions, which persist in the wild for years. Today Org 9.3 was released with more breaking changes, and I'm just waiting for the bug reports to roll in on my packages so I can add more conditional definitions and aliases to meet the needs of the variety of users out there. > There should also be some way to access the new functionality > interactively; the solution might be a new interactive wrapper > function with its own name, or maybe some new variables? I don't > know; I haven't thought it all the way through yet. > Is there any interest in or opposition to such a patch? I'd like to > get a sense of whether it would be able to land in Org Mode before I > start working on it. I'd recommend simply making a new interactive function, putting it in your personal config, and sharing it publicly (e.g. here and on /r/orgmode). Use it "in anger" for a while, and solicit feedback from other users for a while. Then, if it still seems widely useful enough to deserve being added to Org proper, apply what you've learned in the meantime to improve and simplify its implementation before proposing a patch. You might also consider sending it to my "unpackaged.el" repo, which might make a good home for it: http://github.com/alphapapa/unpackaged.el
On 03 Dec 2019, Adam Porter wrote: >You might consider adjusting your fontification settings. The >single-line outline path can be quite readable with the right faces (see >attached example). That's a useful hint generally, thank you. However, for most of the Org Mode files I work with, the heading lengths are pretty long, so I need vertical stacking in the minibuffer when displaying all the headings down to point. >I'd recommend against adding more optional arguments to that function, >because it already has four. Emacs/Org already have enough problems >with code like (org-whatever nil t nil t nil nil t). Sure, I can see how that tradeoff might not be worth it. >> There should also be some way to access the new functionality >> interactively; the solution might be a new interactive wrapper >> function with its own name, or maybe some new variables? I don't >> know; I haven't thought it all the way through yet. > >> Is there any interest in or opposition to such a patch? I'd like to >> get a sense of whether it would be able to land in Org Mode before I >> start working on it. > >I'd recommend simply making a new interactive function, putting it in >your personal config, and sharing it publicly (e.g. here and on >/r/orgmode). Use it "in anger" for a while, and solicit feedback from >other users for a while. Then, if it still seems widely useful enough >to deserve being added to Org proper, apply what you've learned in the >meantime to improve and simplify its implementation before proposing a >patch. Well, I already posted it here, so that's done. Those functions are publicly packaged (albeit with the `ots-' prefix) here: https://github.com/OpenTechStrategies/ots-tools/blob/master/emacs-tools/ots.el Unless you meant make a new interactive function to display a vertical hierarchy and base it on the existing Org Mode functions you informed me of the existence of? But I don't think there's a way to do that without adding some new parameters to those existing functions, and, as you point out, that's probably not worth the extra complexity. >You might also consider sending it to my "unpackaged.el" repo, which >might make a good home for it: http://github.com/alphapapa/unpackaged.el That's a nice collection! I'm enjoying browsing through it. I effectively already have a personal unpackaged-elisp repository at https://svn.red-bean.com/repos/kfogel/trunk/.emacs (if these functions weren't already in 'ots-tools', they'd be there). Best regards, -Karl
Karl Fogel <kfogel@red-bean.com> writes:
> Unless you meant make a new interactive function to display a vertical
> hierarchy and base it on the existing Org Mode functions you informed
> me of the existence of? But I don't think there's a way to do that
> without adding some new parameters to those existing functions, and,
> as you point out, that's probably not worth the extra complexity.
I'm not sure what you mean about having to add new parameters to
existing functions. For example, if I understand correctly what you're
wanting, this code does approximately that:
(defun ap/org-display-olp-lines ()
(interactive)
(thread-first
(cl-loop for heading in (org-get-outline-path t)
for i from 0
for indent = (make-string (* i 2) ? )
collect (concat indent "* " heading))
(string-join "\n")
message))
Which displays, e.g.
* Computers
* Software
* Emacs
* Org-mode
* Articles
* Orgmode for GTD
Karl Fogel <kfogel@red-bean.com> writes:
> Unless you meant make a new interactive function to display a vertical
> hierarchy and base it on the existing Org Mode functions you informed
> me of the existence of? But I don't think there's a way to do that
> without adding some new parameters to those existing functions, and,
> as you point out, that's probably not worth the extra complexity.
Forgive me, I think I misunderstood you. Yes, I meant to make a new
interactive function for displaying the vertical hierarchy.
BTW, you might also find the org-sticky-header package helpful.
On 05 Dec 2019, Adam Porter wrote: >Karl Fogel <kfogel@red-bean.com> writes: >> Unless you meant make a new interactive function to display a vertical >> hierarchy and base it on the existing Org Mode functions you informed >> me of the existence of? But I don't think there's a way to do that >> without adding some new parameters to those existing functions, and, >> as you point out, that's probably not worth the extra complexity. > >Forgive me, I think I misunderstood you. Yes, I meant to make a new >interactive function for displaying the vertical hierarchy. Oh, I still learned things from the code you posted in your previous message, though, thanks. (I didn't know about `thread-first', for example, even though it's been around for a while.) Yes, what I'd meant was that ideally this would just be an interactive wrapper around `org-format-outline-path'. Unfortunately there's no way to get the behavior I want from that function currently. This is not a showstopper -- I agree with you that adding yet more arguments to that function is not a complexity cost worth paying here. Another thing is that `org-get-outline-path' returns only the title portion of each heading, rather than the full heading. Even though the titles are all I need right now, I still would normally prefer that the underlying function provide more generality (i.e., return the full headings) and then the caller would use `(nth 4 heading)' or whatever to get the part it needs. That way if one wants to do something more sophisticated when displaying headings -- involving tags, for example -- the necessary information would be available. Again, these are not things that need to be "solved" in Org Mode; I'm not even sure we should consider them to be problems. I'm just explaining my earlier comment about how the existing functions in Org Mode don't provide quite the substrate I was hoping for for this particular task. >BTW, you might also find the org-sticky-header package helpful. Ah, very nice -- thank you! (https://github.com/alphapapa/org-sticky-header, for those who want the convenience of the a quick link.) Best regards, -Karl