fzf

While creating the my custom search commands, I learned a lot about Vimscript and how fzf works. Here are a couple of important notes:

  • fzf#vim#files is the function that kicks off an fzf search over file names. It takes a path string as input.
  • fzf#vim#grep is the functions that executes some search command like grep or rg and kicks of a fzf session on the output. It takes as input a command to execute (i.e. one involving rg and a few other commands.
  • To enable fzf preview on searches, you need to pass the fzf#vim#with_preview function into the files or grep functions. Inside of this function you can pass an options dictionary, which specifies how fzf will be run and with what parameters. These parameters simply must be wrapped by the preview function if you end up using it.
    • Note that fzf#vim#with_preview takes an fzf spec dictionary like every normal fzf function, because internally everything uses fzf#wrap to extend a given spec dict with global user options and whatever else. So the with_preview function takes a given spec dict so that it can extend it in its own way using proper preview options. So with_preview returns a new spec dictionary with properly configured preview options, which is usually then passed immediately to a core fzf function that uses the spec to initialize a search session.
  • rg is fine to search all lines with a basic regex like .*. I was running into some problems here with the nth and with-nth options in fzf, which were ruining my output. The important thing here is that with-nth actually modifies the line according to the set delimiter. So nth needs to accomodate for this. For example, if with-nth=4.., then fzf is going to cut out all but the 4th delimited section from each line. Then a nth=1.. will restrict the search scope to that remaining section previously cut out. So with-nth1 does not just affect the displayed lines, it actually affects the lines content and ultimately what can be searched.
    • One thing I realized from this was that my file with a colon in it (Roam: How to… something) was actually being affected by this. So I need to figure a better pipeline for naming files, which is on the list anyway.
  • fzf has a -q option which allows you to fill the search with a query before entering interactive mode. This was useful for my unlinked references where I wanted to prepopulate the search field, but leave room for the fuzzy interactive session.
  • In order to get the preview working with color, you need to install bat. I didn’t realize until seeing it was used as a dependency, and now it works. Note that you’ll have to customize bat to work with whatever color scheme you prefer.
  • fzf will search command history when <ctrl-r> is pressed
  • bang is a command argument specified by a “!” after the command. If used, an “!” populates the bang argument and can be accessed in the command with <bang>. In the context of fzf, this tells the command whether or not to open up in fullscreen mode, i.e. act like a real shell command, since <bang>0 is used to negate 0 to a boolean value of 1 for fullscreen.

Was toying around with modifying autocomplete results so I can define my own “omnicomplete” pipeline for wiki file names. Using Vim’s <expr>, you can map a key sequence to execute a function and use it’s output in the current location. For example,

inoremap <expr> [[ fzf#vim#complete('cat /usr/share/dict/word')

will start an interactive fzf session when I type “[[” and place the output in the current cursor location. Basically I want this with fzf file completion, but I need to modify the output so that the result is wrapped in proper link syntax. After digging around a little, I found that fzf#vim#complete calls an “fzf trigger,” which triggers an interactive fzf session. It then writes the results of this session using a function called feedkeys(), which I believe gets used in conjunction with the <expr> to write text the current cursor location. So I can manually inject text before and after this result using feedkeys myself, but the current problem is how I might actually get the result text, modify it, and place it in multiple locations.