mclear-tools / consult-notes

Use consult to search notes
GNU General Public License v3.0
164 stars 15 forks source link

Integrate Silos Directories [Feature request] #63

Open elge70 opened 4 months ago

elge70 commented 4 months ago

Currently consult-notes list notes according to the variable "denote-directory" in consult-notes-denote-mode. If we are in a silos directory, it list the notes in the silos directory and subdirectories correctly. If we add silos directory to "consult-notes-file-dir-source", it lists the notes in that directory but not the subdirectories. It does not follow the consult-notes-denote-mode listing of notes when it lists the notes in consult-notes-file-dir-source even though dir-locals.el is defined in that directory. It also does not show the notes in subdirectories when using consult-notes if we are not in silos directory,

if the user is using "denote-silo-extras" module, is it possible to use the silos directories in "denote-silo-extras-directories" and give a combined listing of notes when using "consult-notes-denote-mode" in the format "Title #keywords /directory size date modified". Directory could be silos/directory to make the differentiation.

leafarbelm commented 4 months ago

This would be a fantastic addition to the package. Currently, I do the following, but I would love to see something like this implemented directly in the package.


(use-package consult-notes
  :ensure t
  :defer t
  :custom-face
  (consult-notes-sep ((t (:inherit shadow))))
  :custom
  (consult-notes-denote-display-id nil)
  :config
  (require 'consult-notes-denote)
  (defun consult-notes-search-in-all-notes ()
    "Search in all notes using `grep' or `ripgrep'.
Which search function is used depends on the value of `consult-notes-use-rg'."
    (interactive)
    (let ((sources (delete-dups
                    (flatten-list
                     (append
                      ;; silos sources
                      (mapcar #'cddr consult-notes-denote-silos)
                      ;; dir sources
                      (mapcar #'cddr consult-notes-file-dir-sources)
                      ;; org roam
                      (when (bound-and-true-p consult-notes-org-roam-mode)
                        (list (expand-file-name org-roam-directory)))
                      ;; denote
                      (when (bound-and-true-p consult-notes-denote-mode)
                        (list (expand-file-name denote-directory)))
                      ;; org agenda files
                      (when (bound-and-true-p consult-notes-org-headings-mode)
                        (mapcar #'expand-file-name consult-notes-org-headings-files)))))))
      (if consult-notes-use-rg
          (consult-ripgrep sources)
        (consult-grep sources))))

  (defun consult-notes-denote-items (directory)
    (let* ((max-width 0)
           (denote-directory directory)
           (cands (mapcar (lambda (f)
                            (let* ((id (denote-retrieve-filename-identifier f))
                                   (title-1 (or (denote-retrieve-title-value f (denote-filetype-heuristics f)) (denote-retrieve-filename-title f)))
                                   (title (if consult-notes-denote-display-id
                                              (concat id " " title-1)
                                            title-1))
                                   (dir (file-relative-name (file-name-directory f) denote-directory))
                                   (keywords (denote-extract-keywords-from-path f)))
                              (let ((current-width (string-width title)))
                                (when (> current-width max-width)
                                  (setq max-width (+ 24 current-width))))
                              (propertize title 'denote-path f 'denote-keywords keywords)))
                          (funcall consult-notes-denote-files-function))))
      (mapcar (lambda (c)
                (let* ((keywords (get-text-property 0 'denote-keywords c))
                       (path (get-text-property 0 'denote-path c))
                       (dirs (directory-file-name (file-relative-name (file-name-directory path) denote-directory))))
                  (concat c
                          ;; align keywords
                          (propertize " " 'display `(space :align-to (+ left ,(+ 2 max-width))))
                          (format "%18s"
                                  (if keywords
                                      (concat (propertize "#" 'face 'consult-notes-name)
                                              (propertize (mapconcat 'identity keywords " ") 'face 'consult-notes-name))
                                    ""))
                          (when consult-notes-denote-dir (format "%18s" (propertize (concat "/" dirs) 'face 'consult-notes-name))))))
              cands)))

  (defun create-denote-source (name key directory)
    "Create a consult-notes source with NAME, KEY, and DIRECTORY."
    (list :name     (propertize name 'face 'consult-notes-sep)
          :narrow   key
          :category 'consult-notes-category
          :annotate #'consult-notes-denote--annotate
          :items    (lambda () (consult-notes-denote-items directory))
          ;; Custom preview
          :state  #'consult-notes-denote--state
          ;; Create new note on match fail
          :new     #'consult-notes-denote--new-note))

  (setq consult-notes-denote-silos
        '(("Personal" ?p "~/Documents/common-book/personal/")
          ("Work" ?w "~/Documents/common-book/work/")))

  (dolist (dir consult-notes-denote-silos)
    (let* ((name (nth 0 dir))
           (key (nth 1 dir))
           (directory (nth 2 dir))
           (source (create-denote-source name key directory)))
      (when source
        (add-to-list 'consult-notes-all-sources source 'append)))))
elge70 commented 4 months ago

I am getting following error "Symbol’s value as variable is void: directory".

I updated only '(("Personal" ?p "~/Documents/common-book/personal/") ("Work" ?w "~/Documents/common-book/work/"))) with my directories.

leafarbelm commented 4 months ago

Do you get this error when running the code without modifications? maybe the consult-notes-denote-silos is set with the wrong format? it should be ("Name" key "directory")

Edit: I don't know what's the issue but i did some testing end find out that when i run the code from the *scratch* buffer i also get this error but when i put it in my init.el it run just fine. maybe you could try that.

Edit2: You could try something like this:

(defun create-denote-source (name key items)
    "Create a consult-notes source with NAME, KEY, and DIRECTORY."
    (list :name     (propertize name 'face 'consult-notes-sep)
          :narrow   key
          :category 'consult-notes-category
          :annotate #'consult-notes-denote--annotate
          :items    items
          ;; Custom preview
          :state    #'consult-notes-denote--state
          ;; Create new note on match fail
          :new      #'consult-notes-denote--new-note))

  (setq consult-notes-all-sources nil)

  (dolist (dir consult-notes-denote-silos)
    (let* ((name (nth 0 dir))
           (key (nth 1 dir))
           (directory (nth 2 dir))
           (source (create-denote-source name key (consult-notes-denote-items directory))))
      (when source
        (add-to-list 'consult-notes-all-sources source 'append))))

From my tests it seems to work

elge70 commented 4 months ago

Thanks a lot. This is exactly what I want. Searching the notes and listing are working great!!!!

If this could be added to consult-notes, it will be helpful to users who would like to separate notes. E.g Work and Personal

leafarbelm commented 4 months ago

I'm glad it's working now! 😊

I agree, it would be fantastic to have this feature in the project.

I hope mclearc will consider including it.

mclearc commented 4 months ago

Thanks both for your feedback. I'm hoping to get time to focus on this issue next week.

mclearc commented 4 months ago

Hi @leafarbelm -- do you think you would have time to make a pull request? I'm not a silo user (nor a power user of Denote), but if you can make a pull request with the relevant changes I'll give it some testing.

leafarbelm commented 3 months ago

Hi @mclearc,

Sorry for the late reply. I can try to implement this functionality. I'm not very experienced with Elisp (I only make small changes in my init.el and write small functions), but I could try to create a PR based on the changes I posted here, if you wish.