Closed mikepqr closed 10 months ago
This would be great to have. At the moment implementing this is over my head but I'll keep it mind as a larger goal to work towards.
For reference for anyone looking into implementing this (including maybe me!), fzf
can echo the search term if there is no match with this invocation (ref):
fzf --bind=enter:replace-query+print-query
Let's talk about the desired UX before writing code. 😉
I think the idea of an explicit keybind within the fuzzy finder chooser is the way to go. I like this because it eliminates a lot of edge cases with the fuzzy matching by avoiding complex logic around partial matches. Creating a new note, rather than matching and selecting an existing note, would be totally deterministic this way.
As a practical example, the Telescope Project plugin binds <C-a>
to "add cwd as a project" and it ignores your search query. In our case, we would instead use the search query as a parameter to make a new note.
But a tradeoff would be inconsistent behavior with the official Obsidian app. This is a bit weird because the user could have different fuzzy finders configured, so even if we matched the "Open Quickly" workflow, the actual search results may be different between NeoVim and Obsidian. I think this should be configurable so that the user can decide on the tradeoff in their workflow.
What are your thoughts here, @mikepqr and @epwalsh ?
I don't have a strong opinion on exactly how the user would indicate a particular "search" is actually a request for a new file with that name.
Telescope's <C-a>
sounds good, modulo the fact that cnoremap <C-A> <Home>
). How does Telescope handle that?
Corpus doesn't clobber a readline binding, but ends up with a system that has several options that are a bit of a mouthful to explain, and presumably has more edge cases in its implementation (tldr: :Corpus!
or append .md
to the search, but see the docs for details).
One other data point is Notational Velocity. AFAIK, this is where the idea of unified search/create in a notes app comes from. In nvALT your input is presumed to be the title of a new note, even if it matches search results. If you hit enter, you get a new note. But the search results are shown, and you can use C-J or C-K to page into them and then select them. I'm not sure if fzf (or telescope) could be used to reproduce this UX, and given "search for existing" is probably a more common task than "create new", I think I prefer the approaches above, which select search results by default.
I would not try to emulate the keyboard interface (or wider UX) of the Obsidian app. The goals/expectations there are very different.
@mikepqr how about the :ObsidianQuickSwitch
command? Shouldn't such binding belong to this command, rather than to :ObsidianSearch
? The first one is actually searching note names, so maybe it should be its responsibility to eventually create notes.
For my note taking system I have a command OrgNote
which
ObsidianQuickSwitch
),C-l
),C-c
).
Usability wise this is great IMO.This is implemented using custom telescope actions. Not too complex.
But obsidian.nvim
would require implementations for the different fuzzy finders if I'm not mistaken.
Just as reference, my implementation looks something like this.
function Orgnote.search_or_link_or_create()
-- FIXME: prep_link_selected_entry is messy; refactor this.
local link_info_tb = prep_link_selected_entry()
require("telescope.builtin").find_files({
prompt_title = "ORGNOTE | CR open | C-x create | C-l link",
default_text = link_info_tb.selection or "",
cwd = root,
search_file = "*.org",
attach_mappings = function(_, map)
map("i", "<C-x>", create_note_from_query)
map("i", "<C-l>", function(prompt_bufnr)
link_selected_entry(prompt_bufnr, link_info_tb)
end)
return true
end,
})
end
@sotte even if we can't implement that for other finders it would be great to have for our telescope integration. In general I recommend people use telescope as it has the best Lua API, so it's the easiest for us to work with. Are you interested in making a PR with that?
I actually wanted to say that I don't have the time. But then I looked at the code and drafted an implementation.
Here is the MR: https://github.com/epwalsh/obsidian.nvim/pull/296
There are still some things to address (see MR).
If somebody else wants to bring this over the finish line I'm more than happy to hand this over.
I think with #296 merged, we can close this issue.
🚀 The feature, motivation and pitch
It would be great if the fuzzy finder launched by
:ObsidianSearch
could be a unified UI to search and create notes, such that, if there is no match for the search term in the picker when the user hits enter, obsidian.nvim invokes :ObsidianNew with the search string as the argument.This reduces cognitive overhead when creating a note, and is how the "Open Quickly" UI in Obsidian itself works.
I'm not sure if this is possible with fzf or telescope, however!
Alternatives
You could take this further and allow the user to invoke :ObsidianNew from the picker even if there are matches, e.g. if the user selects the match with something other than enter, or the search term ends in
!
, then create a new note.Additional context
This is also how Corpus works (the
:Corpus
command provides a unified way to search and create).