Heatseeker is a rewrite of Gary Bernhardt's selecta, a general-purpose fuzzy selector. It looks like this:
The purpose of the rewrite is to combine the simplicity and generality of Selecta with the speed and portability of native code.
Compiled binaries for the latest version can be downloaded from GitHub.
To install on Windows using Chocolatey, run:
choco install heatseeker
To install on OS X using Homebrew, run:
brew tap rschmitt/heatseeker
brew install heatseeker
To install on Linux, run:
wget -q -O - https://github.com/rschmitt/heatseeker/releases/download/v1.7.2/heatseeker-v1.7.2-x86_64-unknown-linux-musl.tar.gz | tar -zxf - hs
# To install globally:
sudo install hs /usr/local/bin/
# To install in your home directory:
install -D hs ~/bin/hs
Heatseeker supports basically the same keys as Selecta, along with a few others to support multi-select:
- ^T to select or deselect the currently highlighted match
- Enter to select the currently highlighted match, or any matches previously highlighted with ^T
- ^G, ^C, or Escape to quit without selecting a match
- Backspace to delete the last query character typed
- ^U to delete the entire query
- ^N, down arrow, or tab to highlight the next match
- ^P or up arrow to highlight the previous match
With PSReadLine, Heatseeker can be integrated directly into the Windows command line. Add this code to your $profile
. The file selector can be summoned with Ctrl-S.
$ps = $null
try {
# On Windows 10, PSReadLine ships with PowerShell
$ps = [Microsoft.PowerShell.PSConsoleReadline]
} catch [Exception] {
# Otherwise, it can be installed from the PowerShell Gallery:
# https://github.com/lzybkr/PSReadLine#installation
Import-Module PSReadLine
$ps = [PSConsoleUtilities.PSConsoleReadLine]
}
Set-PSReadlineKeyHandler `
-Chord 'Ctrl+s' `
-BriefDescription "InsertHeatseekerPathInCommandLine" `
-LongDescription "Run Heatseeker in the PWD, appending any selected paths to the current command" `
-ScriptBlock {
$choices = $(Get-ChildItem -Name -Attributes !D -Recurse | hs)
$ps::Insert($choices -join " ")
}
With a bit of Vimscript, you can use Heatseeker to open files in Vim, without any need for a special plugin.
The Vimscript samples from the Selecta README basically work, but it is preferable to modify them for use with Heatseeker in order to add support for Windows and multi-select.
function! HeatseekerCommand(choice_command, hs_args, first_command, rest_command)
try
let selections = system(a:choice_command . " | hs " . a:hs_args)
catch /Vim:Interrupt/
redraw!
return
endtry
redraw!
let first = 1
for selection in split(selections, "\n")
if first
exec a:first_command . " " . selection
let first = 0
else
exec a:rest_command . " " . selection
endif
endfor
endfunction
if has('win32')
nnoremap <leader>f :call HeatseekerCommand("dir /a-d /s /b", "", ':e', ':tabe')<CR>
else
nnoremap <leader>f :call HeatseekerCommand("find . ! -path '*/.git/*' -type f -follow", "", ':e', ':tabe')<cr>
endif
The same goes for buffer selection. This is a bit trickier on Windows, because the most straightforward way to send the list of buffers to Heatseeker is to write a temp file.
function! HeatseekerBuffer()
let bufnrs = filter(range(1, bufnr("$")), 'buflisted(v:val)')
let buffers = map(bufnrs, 'bufname(v:val)')
let named_buffers = filter(buffers, '!empty(v:val)')
if has('win32')
let filename = tempname()
call writefile(named_buffers, filename)
call HeatseekerCommand("type " . filename, "", ":b", ":b")
silent let _ = system("del " . filename)
else
call HeatseekerCommand('echo "' . join(named_buffers, "\n") . '"', "", ":b", ":b")
endif
endfunction
" Fuzzy select a buffer. Open the selected buffer with :b.
nnoremap <leader>b :call HeatseekerBuffer()<cr>
- Heatseeker is fully implemented. It works smoothly on all supported platforms, including Windows; it has even been successfully smoke tested (both building and running) on Windows 10 Technical Preview.
- Heatseeker requires no unstable language features and can be compiled with the stable Rust toolchain.
Perform the build by invoking:
$ cargo build --release
The resulting binary will be located in the target/release
directory. (Note that omitting the --release
flag will cause compiler optimizations to be skipped; this speeds up compilation but results in a remarkably sluggish program.) The unit tests can be invoked by running:
$ cargo test