Skip to content

rschmitt/heatseeker

Repository files navigation

Linux Build Status Windows Build Status

Heatseeker is a rewrite of Gary Bernhardt's selecta, a general-purpose fuzzy selector. It looks like this:

ps-readline-demo

The purpose of the rewrite is to combine the simplicity and generality of Selecta with the speed and portability of native code.

Installation

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

Use

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

PowerShell

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 " ")
    }

Vim

With a bit of Vimscript, you can use Heatseeker to open files in Vim, without any need for a special plugin.

vim-demo

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>

Project Status

  • 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.

Building

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