05 May 2014

One of my favorite things about my vim setup is the way I open files. For a little while I used ctrlp and then I switched to Gary Bernhardt’s selecta script.

selecta is cool in part because of how it’s designed to be more than a vim plugin, although that’s mainly what I use it for. The readme gives a few examples of how else it could be used and other people come up with weirder stuff.

Also cool is the means of distribution. Recently someone added it as a homebrew formula, making it easy to install and keep it up-to-date on a Mac, but until then, the recommended move was to download a raw ruby script, make it executable, and put it on your PATH, and then I guess hope to remember to update it occasionally. If you want to use it in vim, you can copy and paste a vimscript function from the readme into your vimrc.

Here’s the code from the readme:

" Run a given vim command on the results of fuzzy selecting from a given shell
" command. See usage below.
function! SelectaCommand(choice_command, selecta_args, vim_command)
    silent let selection = system(a:choice_command . " | selecta " . a:selecta_args)
  catch /Vim:Interrupt/
    " Swallow the ^C so that the redraw below happens; otherwise there will be
    " leftovers from selecta on the screen
  exec a:vim_command . " " . selection

" Find all files in all non-dot directories starting in the working directory.
" Fuzzy select one of those. Open the selected file with :e.
nnoremap <leader>f :call SelectaCommand("find * -type f", "", ":e")<cr>

I made one change, which was to use ctrl+p instead of leader+f, because I’d trained my fingers on ctrl+p and didn’t have the reserves of peace & discipline to consider changing. Other than that I left it as-is, until today.

I wanted to edit my .gitignore file, and noticed that it wasn’t opening. Not a big deal, I wrote :e .gitignore and survived.

The comment says it opens all files in all non-dot directories. It’s kind of true but not exactly, as it ignores dotfiles regardless of their location. I definitely want it to ignore files in dot directories (.git and .sass-cache come to mind), but I don’t want it to ignore most dotfiles.

selecta works like this: you pipe some list of information into it, it breaks it apart, lets you select one line from the list, and then pipes that selection out to the next command. This vim plugin runs the bash command find * -type f, which prints the list of non-dot files (-type f excludes directories, * excludes dots) and then pipes it to the vim edit command :e.

Since setting this up months ago I’ve learned and used the find command a few times but had no idea it was powering my fuzzy opener thing! Something opaque opened up a little. So I edited that last part like this:

" Find all files and all non-dot directories
" starting in the working directory
" and edit the chosen thing
nnoremap <c-p> :call SelectaCommand("find . -not -path './.*/*'", "", ":e")<cr>

The main changes:

I made a before and after gif.

I think I like this! But actually what if it sorted the files by last modified date?