zk-org / zk-nvim

Neovim extension for zk
https://github.com/zk-org/zk
GNU General Public License v3.0
503 stars 41 forks source link

Feature Request: list notes by multiple tags #50

Closed djromero closed 2 years ago

djromero commented 2 years ago

Filter notes by a multiple tags.

Example: imagine a zettelkasten about applications; invoke ZkTags to show the tag picker, type "editor" and now instead of hitting ENTER to show the notes tagged with "editor", you hit C-t (for example) to filter the tag list to show only tags appearing in notes tagged as "editor". The tag list now shows "modal", "hex", "latex", "markdown", you type "modal" and hit ENTER to open a picker of notes tagged "editor" AND "modal".

Equivalent to zk list --tag "editor AND modal"

Most pieces are there I think (Telescope seems to support custom mappings to run commands in the picker) except perhaps the list tags filtered by tags.

This will speed up finding a note in a large collection if you don't remember the title but has been consistently tagged using a small number of tags.

mickael-menu commented 2 years ago

You can already search by multiple tags with ZkTags, but it works a bit differently. After listing all the tags with ZkTags, you can select multiple tags to filter with using the Tab key, before hitting Enter.

djromero commented 2 years ago

Thanks for your quick reply! Your suggestion works perfectly, especially for a few tags where you can quickly mover over the list without filtering, otherwise it requires typing to filter, TAB to select, Ctrl-w to clear, type another tab, etc. Kind of slow.

With that in mind I've written an ad-hoc command for my use case. The idea is to hard-code the first tag as parameter, type to select the second tag and push ENTER to jump to the notes list filtered by both tags.

Sharing the code here if it helps someone: (non idiomatic, pretty much my first lines in lua)

commands.add("ZkRefineTags", function(options, filter)
   zk.pick_tags(options, { title = "Zk Tags", default_text = tag or "" }, function(tags)
     tags = vim.tbl_map(function(v)
       return v.name
     end, tags)
     refined = nil
     if type(filter) == "table" then
       refined = filter
     else
       refined = { filter }
     end
     for _, v in pairs(tags) do
       refined[#refined + 1] = v
     end
     zk.edit({ tags = refined }, { title = "Zk Tagged Notes" .. vim.inspect(refined) })
    end)
 end)

Usage: ZkRefineTags {}, "editor" or with multiple tags ZkRefineTags {}, {"vim", "neovim"}.

Then you can add mappings for your most used tags.