vim-select
vim-select copied to clipboard
Vim fuzzy file/buffer/mru selector plugin
= vim-select: fuzzy select file/buffer/MRU/etc
NOTE: Plugin works with recent (nightly) vim having matchfuzzypos()
function and
prompt-buffer
feature implemented.
For project files, buffers and MRU it lets you narrow down the list with fuzzy
matching and select with <CR>
or <Tab>
if only 1 candidate is in the list.
For files it will let you go to parent directory with <BS>
and to selected
directory with <CR>
.
Project file search uses either fd
or ripgrep
(with fallback to find
on non-windows) tool so be sure you have one of them installed on your system.
By default it uses vim current working directory as a project root.
image::https://user-images.githubusercontent.com/234774/99876845-bac99400-2c0a-11eb-87cf-e881690b20c7.gif[]
link:showcase.adoc[More animated gifs]
NOTE: Extensions are available: https://github.com/habamax/vim-select-more
== Installation
If you use package/plugin manager, consult their documentation.
For manual installation clone this repository to your
~/.vim/pack/plugins/start/
path, where plugins
subdirectory is arbitrary.
NOTE: for windows users replace ~/.vim
to ~/vimfiles
.
== Mappings
There are no default global mappings -- create your own.
.Safe (will not create mappings if plugin was not loaded) [source,vim]
" add it to ~/.vim/after/plugin/select.vim
if exists("g:loaded_select")
nmap fe <Plug>(SelectFile)
nmap ff <Plug>(SelectProjectFile)
nmap fp <Plug>(SelectProject)
nmap b <Plug>(SelectBuffer)
nmap m <Plug>(SelectMRU)
endif
or
.Regular [source,vim]
" add it to your vimrc
nmap fe <Plug>(SelectFile)
nmap ff <Plug>(SelectProjectFile)
nmap fp <Plug>(SelectProject)
nmap b <Plug>(SelectBuffer)
nmap m <Plug>(SelectMRU)
Select window has default mappings:
-
<CR>
to open/execute current item. -
<S-CR>
or<C-s>
to open current item in split. -
<C-v>
to open current item in vertical split. -
<C-t>
to open current item in a tab. -
<C-j>
to create a new file out of prompt value. Only available for:Select file
. -
<ESC>
to close the select window. -
<TAB>
select next item in the list, for a single item it will open/execute it. -
<BS>
open parent directory. Only forSelect file
. -
<C-n>
or<Down>
select next item. -
<C-p>
or<Up>
select previous item. -
<PageUp>
scroll up select window. -
<PageDown>
scroll down select window.
== Commands
-
:Select
file from current file directory. -
:Select file
from current file directory. Or from directory passed as an argument. -
:Select projectfile
from current working directory(and sub-directories). Or from directory passed as an argument.
NOTE: External tool fd
or ripgrep
is required. On non-windows find
would
be used if none is installed.
-
:Select project
from the list of projects and run:Select projectfile
on it. Each project is a current working directory where:Select projectfile
was run and a file was selected. The list is persisted in~/.vim/.selectprojects
or~/.selectprojects
file. -
:Select buffer
from buffer list. -
:Select mru
fromv:oldfiles
.
== Extending
First of all create an "extension point":
[source,vim]
let g:select_info = get(g:, "select_info", {})
And then...
=== Basic example
Let's select something from the list and echo it in vim:
[source,vim]
let g:select_info.test = {} let g:select_info.test.data = {-> ['hello', 'from', 'vim-select', 'plugin']} let g:select_info.test.sink = "echomsg '%s'"
Then with the command :Select test
you can select a value from the list and
see it was echoed as a vim message.
%s
would be substituted with the selected value in the sink
string
parameter.
You can also provide a dict with action there, like:
[source,vim]
func! ShowMessage(msg) abort echom a:msg endfunc
let g:select_info.test = {} let g:select_info.test.data = {-> ['hello', 'from', 'vim-select', 'plugin']} let g:select_info.test.sink = {"action": {v -> ShowMessage(v)}}
=== Show highlight group
[source,vim]
let g:select_info.highlight = {} let g:select_info.highlight.data = {-> getcompletion('', 'highlight')} let g:select_info.highlight.sink = {"action": {v -> feedkeys(':hi '..v.."<CR>", "nt")}}
Then use :Select highlight
to select and show syntax highlight group
parameters.
=== Loading sessions
Imagine you have all your sessions saved in ~/.vimdata/sessions
folder.
I do have them there and usually create session with a helper command:
[source,vim]
command! -nargs=1 S :mksession! ~/.vimdata/sessions/
Then just a simple :S my_another_project
to persist a session.
Now to narrow down and source/apply a session you can setup select plugin with:
[source,vim]
let g:select_info.session = {}
let g:select_info.session.data = {-> map(glob("~/.vimdata/sessions/*", 1, 1), {_, v -> fnamemodify(v, ":t")})}
let g:select_info.session.sink = "%%bd | source ~/.vimdata/sessions/%s"
nnoremap fs :Select session<CR>
=== Play mp3. Yes, mp3s.
Funny thing, vim can play mp3s, so just for fun we can select a music file and play it:
[source,vim]
let g:select_info.sound = {} let g:select_info.sound.data = {"job": "rg --files --glob *.mp3"} let g:select_info.sound.sink = {"transform": {p, v -> p..v}, "action": {v -> sound_playfile(v)}}
Having this you can :Select sound ~/Music
, select and play mp3 file.
A new key "transform"
is to apply additional logic for a value to be passed
for an action. It receives a current working directory path and a selected
value. In this example the value is transformed to be a full path to a mp3
file.
=== Filetype specific example
There is b:select_info
you can use in the same way as g:select_info
.
For example I would like to be able to select and run https://godotengine.org/[Godot] scene and it should only be availble in https://github.com/habamax/vim-godot[gdscript] files.
Just add to ~/.vim/after/ftplugin/gdscript.vim
: