rschmitt / heatseeker

A high-performance Selecta clone, written in Rust.
MIT License
214 stars 10 forks source link

Feature Request :: Maintain directory index #30

Open bradphelan opened 5 years ago

bradphelan commented 5 years ago

Currently I have the below setup. My folder heirachy is about 200k files and the suggested solution has a 10 to 15 second response time. To make hs respond immediately I have a cache of the directory contents which I can rebuild with ctrl-alt-s.

It's not the ideal solution. What would be nice is a companion tool that keeps the cache up to date by monitoring the file system. Not sure if this is possible in a general way. Just though I'd throw this out to you. Great tool by the way. Even with rebuilding the cache manually it's awesome.

# Trigger fuzzy search
Set-PSReadlineKeyHandler `
     -Chord 'Ctrl+s' `
     -BriefDescription "InsertHeatseekerPathInCommandLine" `
     -LongDescription "Run Heatseeker in the PWD, appending any selected paths to the current command" `
     -ScriptBlock {
         $choices = [IO.File]::ReadAllText($(Resolve-Path .hscache)) | hs
         $ps::Insert($choices -join " ")
    }

# Rebuild cache
Set-PSReadlineKeyHandler `
     -Chord 'Ctrl+Alt+s' `
     -BriefDescription "RebuildHeatseekerPathInCommandLineCache" `
     -LongDescription "Rebuilds the heatseaker cache" `
     -ScriptBlock {
         $job = start-job {
             param($path)
             Get-ChildItem -Name -Attributes !D -Recurse $path > $path/.hscache
         } -arg $(pwd) 
         while( $job.State -ne "Completed") {
                Write-Progress -Activity ".hscache-build " -Status $(get-childitem .hscache).length
                sleep -m 200
         }

        Write-Progress -Activity ".hscache-build" -Completed
    }

2019-02-28_09-21-26

bradphelan commented 5 years ago

I've updated my script.

####################################################
# This is a fuzzy finder for powershell. It works
# by building a cache in a root directory and
# then allows you to query that cache using simple keystrokes
#
# Keystrokes
# ------------
# <ctrl-shift-s>
# will rebuild an index '.hscache' in the current directory
#
# <ctrl-s>
# will start the fuzzy finder with the current word as the intial search string. Once
# the file has been selected by refining the pattern or using the arrow keys hit
# returns and the initial string will be replaced by the selected string
#
# Requirements
# ------------
# Install and setup heat seeker
# https://github.com/rschmitt/heatseeker
###################################################
$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]
}

function PerformFuzzy {
    param([bool]$absolute=$false)

    if(!(test-path .hscache)){
     write-warning "Please press <ctrl-shift-s> to build an index for this directory before trying to use the fuzzy finder"
     return

    }
    $line = $null
    $cursor0 = $null
    $cursor1 = $null
    $ps::NextWord()
    $ps::GetBufferState([ref]$line, [ref]$cursor0)
    $ps::BackwardWord()
    $ps::GetBufferState([ref]$line, [ref]$cursor1)
    $search = $line.SubString($cursor1,$cursor0-$cursor1)
    $choices = [IO.File]::ReadAllText($(Resolve-Path .hscache)) | hs -s $search
    $ps::KillWord()
    $insert = $choices -join " " 
    if($absolute){
       $insert = Resolve-Path $insert
    }
    if($cursor1 -eq 0){
         $ps::Insert($insert) 
    }else{
         $ps::Insert("'" + $insert + "'" ) 
    }

}

# Trigger fuzzy search and replace with relative path
Set-PSReadlineKeyHandler `
     -Chord 'Ctrl+s' `
     -BriefDescription "InsertHeatseekerPathInCommandLine" `
     -LongDescription "Run Heatseeker in the PWD, appending any selected paths to the current command" `
     -ScriptBlock { PerformFuzzy($false) }

# Trigger fuzzy search and replace with absolute path
Set-PSReadlineKeyHandler `
     -Chord 'Ctrl+S' `
     -BriefDescription "InsertHeatseekerPathInCommandLine" `
     -LongDescription "Run Heatseeker in the PWD, appending any absolute selected paths to the current command" `
     -ScriptBlock { PerformFuzzy($true) }

# Rebuild cache
Set-PSReadlineKeyHandler `
     -Chord 'Ctrl+Alt+s' `
     -BriefDescription "RebuildHeatseekerPathInCommandLineCache" `
     -LongDescription "Rebuilds the heatseaker cache" `
     -ScriptBlock {
         $job = start-job {
             param($path)
             Get-ChildItem -Name -Attributes !D -Recurse $path > $path/.hscache
         } -arg $(pwd) 
         while( $job.State -ne "Completed") {
                Write-Progress -Activity ".hscache-build " -Status $(get-childitem .hscache).length
                sleep -m 200
         }

        Write-Progress -Activity ".hscache-build" -Completed
    }