jgru / consult-org-roam

A bunch of convenience functions for operating org-roam with the help of consult
GNU General Public License v3.0
121 stars 6 forks source link

Feature Request / Idea #11

Closed jsilve24 closed 2 years ago

jsilve24 commented 2 years ago

I personally love consult-org-agenda. I used it 50 times a day. Now I am moving some stuff into org-roam and I would love an analogous function for org-roam. Basically, its just a restriction to headlines with nice faces and fontifying coolness that makes it easy to quickly see the level of a headline.

Currently I am using consult-org-roam-search and just starting searches with * [search] and that works ok but it has some false positives and nowhere near the cleanliness of consult-org-agenda. The alter also has nice features like showing tags and such.

Just an idea. If I get a chance one day I will try to put it together myself.

Thanks for the great package!

jsilve24 commented 2 years ago

Alright, I just solved my own problem.

(defun jds/consult-org-roam-and-agenda (&optional match)
  "Like consult-org-agenda but also search org-roam directory."
  (interactive)
  (unless org-agenda-files
    (user-error "No agenda files"))
  (unless org-roam-directory
    (user-error "org-roam-directory is not set"))
  (let* ((files (org-agenda-files))
     (files (cl-union files
            (mapcar (lambda (x) (file-name-concat org-roam-directory x))
                (seq-remove (lambda (x) (string-match "^.#" x))
                        (cl-remove-if (lambda (x) (member x '("." "..")))
                              (directory-files org-roam-directory)))))))
    (consult-org-heading match files)))

I will leave this issue open in case you want to use this. If this seems like a ~me~ problem only, feel free to close.

jsilve24 commented 2 years ago

Slightly improved version:

(defun jds/consult-org-roam-and-agenda (&optional match)
  "Like consult-org-agenda but also search org-roam directory."
  (interactive)
  (unless org-agenda-files
    (user-error "No agenda files"))
  (unless org-roam-directory
    (user-error "org-roam-directory is not set"))
  (let* ((files (org-agenda-files))
     (files (cl-union files
              (directory-files-recursively org-roam-directory "\\.org$"))))
    (consult-org-heading match files)))
jgru commented 2 years ago

Hi @jsilve24,

this is extremely interesting! Thank you for providing this snippet. I will look closely at it as soon as time permits, but that looks already really good. I think of a defcustom to allow users to choose whether they want to include or exclude org-agenda-files

Thanks again.

Best regards, jgru

jgru commented 2 years ago

Hi @jsilve24,

I tested your code snippet in the meantim. Unfortunately, this opens all files in org-roam-directory, which is, at least for me, not desirable at all consult-org-heading seems to be designed to use the org-map-elements with the specified scope, so this is probably not the best way to go, is it? After thinking about it, I would suggest to keep org-roam-directory contents and org-agenda-files separate since it is a rather specific use case in my opinion; however, the displaying (fontified) headline levels would be a general improvement, don't you think so?

A first step into this direction could be the following snippet that displays the headline level (and the todo-state and priority eventually):

(cl-defmethod org-roam-node-level-title ((node org-roam-node))
  (let ((lvl (org-roam-node-level node)))
  (if (> lvl 0)
    (concat
      (make-string  (org-roam-node-level node) ?*)
      " "
      (when (org-roam-node-todo node)
       (print (org-roam-node-todo node))
       (concat (org-roam-node-todo node)
         " "))
      (when (org-roam-node-priority node)
        (concat "[#" (string (org-roam-node-priority node))
          "] "))
      (org-roam-node-title node))
    (org-roam-node-title node))))

(setq org-roam-node-display-template
      (concat
        "${level-title:80} "
        (propertize
          "${tags:20}" 'face 'org-tag)))

I think this could be fontified as well. Can you or maybe someone else think of a better solution, here?

Best regards, jgru

jgru commented 2 years ago

Hi @jsilve24,

I looked into "fontifying" the headlines. Assuming you are using org-bullets-mode, you could achieve a rather similar display to consult-org-heading with the following snippet extending the code in my previous reply:

(defcustom consult-org-roam-bullets-convert #'consult-org-roam--bullets-convert
  "This variable allows to display asterisk as another symbol"
  :group 'consult-org-roam
  :type 'function)

(defun consult-org-roam--bullets-convert (level)
  (if (boundp 'org-bullets-mode)
    (progn
      (nth level org-bullets-bullet-list))
    ""))

(cl-defmethod org-roam-node-level-title ((node org-roam-node))
  (let ((lvl (org-roam-node-level node))
         (title-str nil))
  (if (> lvl 0)
    (setq title-str (concat " "
      ;; Display nice bullet symbol
      (if (fboundp consult-org-roam-bullets-convert)
         (concat
           ;; Prefix with lvl * space (ASCII 32)
           (make-string (org-roam-node-level node) 32)
           ;; Convert asterisk to nicer symbol
           (consult-org-roam--bullets-convert lvl))
        ;; Display plain asterisks
        (make-string (org-roam-node-level node) ?*))
      " "
      (when (org-roam-node-todo node)
       (print (org-roam-node-todo node))
       (concat (org-roam-node-todo node)
         " "))
      (when (org-roam-node-priority node)
        (concat "[#" (string (org-roam-node-priority node))
          "] "))
      (org-roam-node-title node)))
    (setq title-str (org-roam-node-title node)))
    ;; Propertize the headline
    (propertize title-str 'face
      ;; Retriev org-level-? face-symbol via intern
      (intern (concat "org-level-" (number-to-string lvl))))))

(setq org-roam-node-display-template
      (concat
        "${level-title:80} "
        (propertize
          "${tags:20}" 'face 'org-tag)))

One remaining issue, however, is that nodes are not grouped by their parent file and are displayed therefore out of order. Do you think that this is required? Do you have any good idea how to group nodes to files?

Best regards, jgru

jsilve24 commented 2 years ago

Thanks for this! Let me take a deep dive into this this week and try it out.

Re separation of files. It's definitely a nice feature. Re org bullets. I don't use it but I think you have given a really good starting point.

Re my version. I never thought of that but your right for a lot of files that would suck. I am just getting started with org roam so that was no issue in my testing. Thanks!

Sent From My Mobile Device


From: Jan @.> Sent: Sunday, September 25, 2022 2:17:53 AM To: jgru/consult-org-roam @.> Cc: Justin Silverman @.>; Mention @.> Subject: Re: [jgru/consult-org-roam] Feature Request / Idea (Issue #11)

Hi @jsilve24https://github.com/jsilve24,

I looked into "fontifying" the headlines. Assuming you are using org-bullets-mode, you could achieve a rather similar display to consult-org-heading with the following snippet extending the code in my previous reply:

(defcustom consult-org-roam-bullets-convert #'consult-org-roam--bullets-convert "This variable allows to display asterisk as another symbol" :group 'consult-org-roam :type 'function)

(defun consult-org-roam--bullets-convert (level) (if (boundp 'org-bullets-mode) (progn (nth level org-bullets-bullet-list)) ""))

(cl-defmethod org-roam-node-level-title ((node org-roam-node)) (let ((lvl (org-roam-node-level node)) (title-str nil)) (if (> lvl 0) (setq title-str (concat " " ;; Display nice bullet symbol (if (fboundp consult-org-roam-bullets-convert) (concat ;; Prefix with lvl space (ASCII 32) (make-string (org-roam-node-level node) 32) ;; Convert asterisk to nicer symbol (consult-org-roam--bullets-convert lvl)) ;; Display plain asterisks (make-string (org-roam-node-level node) ?)) " " (when (org-roam-node-todo node) (print (org-roam-node-todo node)) (concat (org-roam-node-todo node) " ")) (when (org-roam-node-priority node) (concat "[#" (string (org-roam-node-priority node)) "] ")) (org-roam-node-title node))) (setq title-str (org-roam-node-title node))) ;; Propertize the headline (propertize title-str 'face ;; Retriev org-level-? face-symbol via intern (intern (concat "org-level-" (number-to-string lvl))))))

(setq org-roam-node-display-template (concat "${level-title:80} " (propertize "${tags:20}" 'face 'org-tag)))

One remaining issue, however, is that nodes are not grouped by their parent file and are displayed therefore out of order. Do you think that this is required? Do you have any good idea how to group nodes to files?

Best regards, jgru

— Reply to this email directly, view it on GitHubhttps://github.com/jgru/consult-org-roam/issues/11#issuecomment-1257130320, or unsubscribehttps://github.com/notifications/unsubscribe-auth/AADOORSUOHZ4S5NFAPEF4STV77VBDANCNFSM6AAAAAAQSTAWIU. You are receiving this because you were mentioned.Message ID: @.***>

jsilve24 commented 2 years ago

Ok so I looked over what you suggested and I am ashamed to say I didn't understand how to use it :)

I get the idea of what each function is doing just not how to tie it all together. As a result I am not sure I can really evaluate what you are suggesting. That said, I do have a potentially different approach that builds off of consult-ripgrep instead.

So limitations first:

Benefits:

(defun jds/consult-org-roam-and-agenda-search-headlines (&optional initial)
  "Run Ripgrep on ~/Dropbox/org/ only in *.org files."
  (interactive)
  (let* ((heading-regexp "^*+\\  ")
     (consult-ripgrep-args "rg --null --line-buffered --color=never --max-columns=1000 --path-separator /   --smart-case --no-heading --line-number -g \"*.org\" ."))
    (if initial
    (funcall consult-org-roam-grep-func "~/Dropbox/org/" (format "%s" (concat heading-regexp initial)))
      (funcall consult-org-roam-grep-func "~/Dropbox/org/"  (format "%s" heading-regexp)))))
jgru commented 2 years ago

Hi @jsilve24,

Ok so I looked over what you suggested and I am ashamed to say I didn't understand how to use it :)

That's unfortunate. If you have any specific question, please do not hesitate to pose it and I'll try to answer it.

I get the idea of what each function is doing just not how to tie it all together. As a result I am not sure I can really evaluate what you are suggesting. That said, I do have a potentially different approach that builds off of consult-ripgrep instead.

Good to hear!

So limitations first:

* my solution currently has a hard-coded directory "~/Dropbox/org/" which for me is a directory that just has agenda and org-roam files nested inside. This solution would not work if roam and agenda items are not together under some natural parent folder. This seems like a limitations of ripgrep? Perhaps best approach would be to run two ripgrep commands and use consult to peice them together (it can do that right?)

That is no problem to make this a defcustom or even fallback to org-roam-directory or so.

* There is no fontification (but I bet something on that front could be done)

* Unlike consult-org-agenda, this function does not allow you to search for a filename (which was a really nice feature for when I give up and just start looking for the filename instead or want to further restrict matches by filename)

Here, you might fall back to the already existing function consult-org-roam-file-find. Not super convenient, but does the job.

Benefits:

* fast

* does group by filename

* does alow previewing (some other solutions I explored did not)

Cool. The code snippet posted by me does a similar thing but does not group by housing file, so if you need that your solution seems the way to go. Do you think this should be added to consult-org-roam?

Best regards, jgru

jsilve24 commented 2 years ago

Honestly, it feels more like solid "wiki" material. Something that is written down somewhere and even potentially iterated on but not core package material. Maybe in the future. That said, of course its up to you.

Justin

jgru commented 2 years ago

Hi @jsilve24,

great. I added a wiki page here. Feel free to make any changes if you like to do so.

Thanks for discussing this.

Best regards, jgru