Skip to content

feat: search for files or string in the specified directory#134

Closed
suitablebeard wants to merge 1 commit into
vim-fuzzbox:mainfrom
suitablebeard:bearded-branch
Closed

feat: search for files or string in the specified directory#134
suitablebeard wants to merge 1 commit into
vim-fuzzbox:mainfrom
suitablebeard:bearded-branch

Conversation

@suitablebeard
Copy link
Copy Markdown
Contributor

@suitablebeard suitablebeard commented May 20, 2026

Now you can fuzzy search in a different directory.

I find it very useful when I either want to take notes of something or find a note a have while not having to either start vim from the terminal in my notes folder or :cd into it. With the new commands, I can easily create a mapping for it similar to this one:

nnoremap <my_keys> :FuzzyFilesDir '/my/notes/dir'

Now regarding the code itself, I made a ParsePath helper function to both expand and simplify the path given. I thought it was needed after noticing two things:

  1. the Start() function of both 'grep' and 'files' uses getcwd() which gives the full path of the cwd;
  2. giving as argument a path ending with a slash (e.g. '~/Documents/Notes/') returns no results since the path used for search would end up like '~/Documents/Notes//' (idk why tho)

For point 1, the path given has to be expanded. And for point 2, it has to be simplified so that it'll accept a path with as many slashes a user might give.

Still about the helper, I wasn't sure where to place it since there were both 'internal/helpers.vim' and 'builtin/help.vim' and I didn't really understand the difference.

About the commands :FuzzyFilesDir and :FuzzyGrepDir , I chose to let them have only one argument (the path) since I thought the implementation would be easier.

Also updated the README.

Now you can fuzzy search in a different directory. Otherwise you would
need to cd into it.
@suitablebeard
Copy link
Copy Markdown
Contributor Author

suitablebeard commented May 20, 2026

Actually I just noticed that I was mistaken about simplification solving the slash-at-end issue I mentioned.

I believe the simplest way to fix it is with substitute(), removing a / or a \ at the end after the path is simplified.

here's how I think the ParsePath function should look like:

export def ParsePath(path: string): string
    return path
        ->expand()
        ->simplify()
        ->substitute('\\\|\/$', '', '')
enddef

@suitablebeard
Copy link
Copy Markdown
Contributor Author

suitablebeard commented May 20, 2026

Another correction, the regex pattern should be [\\\/]$ instead of \\\|\/$

Comment thread plugin/fuzzbox.vim

command! -nargs=? FuzzyGrep launcher.Start('grep', { prompt_text: <q-args> })
command! -nargs=? FuzzyGrepRoot launcher.Start('grep', { cwd: helpers.GetRootDir(), prompt_text: <q-args> })
command! -nargs=1 FuzzyGrepDir launcher.Start('grep', { cwd: <q-args> })
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You probably want -complete=dir here too

@mmrwoods
Copy link
Copy Markdown
Member

mmrwoods commented May 21, 2026

Hi,

Thanks for the PR, it made me realise there was a bug in the relative path handling of grep results. That code originated from a time before it was possible to pass the working directory as an arg, and didn't allow for arbitrary paths (only worked for ancestors, like one generated by :FuzzyGrepRoot). This is now fixed in main.

I'm not sure about adding these commands to the plugin, I think what's probably lacking here is documentation showing how easy it is to add custom commands, custom selectors, and even fully fledged extensions to Fuzzbox.

For example, something like this in your vimrc probably gives you what you want:

command! FuzzyFindNotes call fuzzbox#Launch('grep', #{ cwd: '/my/notes/dir', title: 'Find Notes' })
command! FuzzyGrepNotes call fuzzbox#Launch('files', #{ cwd: '/my/notes/dir', title: 'Grep Notes' })

internal/helpers.vim is basically utility functions, it's called "helpers" because at the time there was a poorly named "utils" directory. I'll rename it, it's about time!

builtin/help.vim is the selector for searching Vim help documentation (help tags).

@mmrwoods mmrwoods force-pushed the main branch 3 times, most recently from 173db9b to c25ec74 Compare May 27, 2026 17:02
@suitablebeard
Copy link
Copy Markdown
Contributor Author

Hi Mark!

I agree with you that the documentation needs a few improvements however I'm also partially to blame since I just noticed that you do explain how to make new commands and selectors in the autoload/fuzzbox.vim file but I just didn't see it.

But still, adding that section about creating custom commands and selectors to the README would be very useful, especially if you also explain what keys the opts dict can take (from what I saw it takes quite a few such as 'dropdown', 'preview_cb', etc).

To be honest with you, I didn't know you could access internal functions of a plugin from your vimrc when they're not global functions. Only after asking AI and reading :help autoload did I understand how it works (which basically is done by accessing the autoload folder).

About the custom selectors, it would also be a good idea to explain it thoroughly since IMO trying to understand how exactly it works by reading the code is a bit overwhelming since you have to jump through a couple files. But to be fair I just skimmed it.

Anyways thank you for explaining how I can create the commands I need to solve my problems.

I'll also close this PR since there's already a built-in way to implement what I was trying to do.

@suitablebeard
Copy link
Copy Markdown
Contributor Author

I just tried to understand the example you gave for a custom selector and it became a lot clearer to me how it works. Tho that's only for the select_cb. But again, I still have to read it for real.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants