/vim-picker

A fuzzy picker for Neovim and Vim

Primary LanguageVim scriptISC LicenseISC

vim-picker Build Status

vim-picker is a fuzzy picker for Neovim and Vim.

vim-picker allows you to search for and select files, buffers, and tags using a fuzzy selector such as fzy, pick, or selecta. It has advantages over plugins with a similar purpose such as ctrlp.vim and Command-T:

  • It uses the embedded terminal emulator when available (this requires Neovim or Vim 8.1), so the fuzzy selector does not block the UI. Whilst selecting an item you can move to another buffer, edit that buffer, and return to the fuzzy selector to continue where you left off.
  • It adheres to the Unix philosophy, and does not reimplement existing tools. File listing is achieved using the best tool for the job: git in Git repositories and fd elsewhere, falling back to find if fd is not available. Fuzzy text selection is done with fzy by default: a fast, well behaved interactive filter.
  • It doesn't define default key mappings, allowing you to define your own mappings that best fit your workflow and don't conflict with your other plugins.

Installation

To use vim-picker you will first need a fuzzy selector such as fzy (recommended), pick, or selecta installed. See their respective homepages for installation instructions.

If you already use a plugin manager such as vim-plug, Dein.vim, or Vundle, install vim-picker in the normal manner. Otherwise, the recommended plugin manager is minpac. Add the following to your vimrc ($HOME/.vim/vimrc for Vim and ${XDG_CONFIG_HOME:-$HOME/.config}/nvim/init.vim for Neovim), restart Vim, and run :call minpac#update():

call minpac#add('srstevenson/vim-picker')

If you have Vim 7.4.1840 or newer, you can use the native package support instead of a plugin manager by cloning vim-picker into a directory under packpath. For Vim:

git clone https://github.com/srstevenson/vim-picker \
    ~/.vim/pack/plugins/start/vim-picker

For Neovim:

git clone https://github.com/srstevenson/vim-picker \
    ${XDG_DATA_HOME:-$HOME/.local/share}/nvim/site/pack/plugins/start/vim-picker

Commands

vim-picker provides the following commands:

  • :PickerEdit: Pick a file to edit in the current window.
  • :PickerSplit: Pick a file to edit in a new horizontal split.
  • :PickerTabedit: Pick a file to edit in a new tab.
  • :PickerVsplit: Pick a file to edit in a new vertical split.
  • :PickerBuffer: Pick a buffer to edit in the current window.
  • :PickerTag: Pick a tag to jump to in the current window.
  • :PickerStag: Pick a tag to jump to in a new horizontal split.
  • :PickerBufferTag: Pick a tag from the current buffer to jump to.
  • :PickerHelp: Pick a help tag to jump to in the current window.
  • :PickerListUserCommands: Show a list of user-defined commands (see below).

Key mappings

vim-picker defines the following <Plug> mappings:

  • <Plug>PickerEdit: Execute :PickerEdit.
  • <Plug>PickerSplit: Execute :PickerSplit.
  • <Plug>PickerTabedit: Execute :PickerTabedit.
  • <Plug>PickerVsplit: Execute :PickerVsplit.
  • <Plug>PickerBuffer: Execute :PickerBuffer.
  • <Plug>PickerTag: Execute :PickerTag.
  • <Plug>PickerStag: Execute :PickerStag.
  • <Plug>PickerBufferTag: Execute :PickerBufferTag.
  • <Plug>PickerHelp: Execute :PickerHelp.
  • <Plug>PickerListUserCommands: Execute :PickerListUserCommands.

These are not mapped to key sequences, to allow you to choose those that best fit your workflow and don't conflict with other plugins you use. However if you have no preference, the following snippet maps the main mappings to mnemonic key sequences:

nmap <unique> <leader>pe <Plug>PickerEdit
nmap <unique> <leader>ps <Plug>PickerSplit
nmap <unique> <leader>pt <Plug>PickerTabedit
nmap <unique> <leader>pv <Plug>PickerVsplit
nmap <unique> <leader>pb <Plug>PickerBuffer
nmap <unique> <leader>p] <Plug>PickerTag
nmap <unique> <leader>pw <Plug>PickerStag
nmap <unique> <leader>po <Plug>PickerBufferTag
nmap <unique> <leader>ph <Plug>PickerHelp

Configuration

In directories which are not inside a Git repository, vim-picker uses fd to list files, falling back to find if fd is not available. To use an alternative to fd, set g:picker_find_executable and g:picker_find_flags in your vimrc. For example, to use ripgrep set:

let g:picker_find_executable = 'rg'
let g:picker_find_flags = '--color never --files'

fzy is used as the default fuzzy selector. To use an alternative selector, set g:picker_selector_executable and g:picker_selector_flags in your vimrc. For example, to use pick set:

let g:picker_selector_executable = 'pick'
let g:picker_selector_flags = ''

vim-picker has been tested with fzy, pick, and selecta, but any well behaved command line filter should work. If your version of Vim does not contain an embedded terminal emulator, but you run Vim within tmux, setting g:picker_selector_executable to the fzy-tmux script distributed with fzy will open the fuzzy selector in a new tmux pane below Vim, providing an interface similar to using the embedded terminal emulator of Neovim or Vim 8.1.

By default, when an embedded terminal emulator is available vim-picker will run the fuzzy selector in a full width split at the bottom of the window, using :botright. You can change this by setting g:picker_split in your vimrc. For example, to open a full width split at the top of the window, set:

let g:picker_split = 'topleft'

See opening-window for other valid values.

To specify the height of the window in which the fuzzy selector is opened, set g:picker_height in your vimrc. The default is 10 lines:

let g:picker_height = 10

User-defined commands

Users may customise how vim-picker gathers search candidates and processes selections with user-defined commands.

A user-defined command consists of four parts:

  1. A unique identifier. This is used to register the command and later execute it.
  2. A shell command that generates a newline-separated list of candidates to pass to the fuzzy selector. The shell command can utilize pipes to chain commands together.
  3. A selection type of string or file. String selections are left unchanged when received from the fuzzy selector. File selections are treated as filenames: spaces and special characters are escaped.
  4. A Vim command, such as edit or tjump. The item selected by the user, after escaping as a filename if the selection type is file, is passed to this Vim command as a single argument.

User-defined commands are registered using the picker#Register() function, which takes an identifier, selection type, Vim command, and shell command as described above as arguments:

call picker#Register({id}, {selection_type}, {vim_command}, {shell_command})

For example, to register a user-defined command named notes to edit a Markdown file stored in ~/notes, add the following to your vimrc:

call picker#Register('notes', 'file', 'edit', 'find ~/notes -name "*.md"')

This command can then be executed using the picker#Execute() function, which takes the ID of the user-defined command as a single argument:

call picker#Execute('notes')

You may wish to define a mapping for this, such as:

nmap <leader>n :call picker#Execute('notes')<CR>

To show a list of all registered user-defined commands, execute :PickerListUserCommands.

Copyright

Copyright © 2016-2019 Scott Stevenson.

vim-picker is distributed under the terms of the ISC licence.