dotfiles/private_dot_config/private_fish/functions/fcd_ffdir.fish
2023-04-30 01:21:51 +03:00

93 lines
2.5 KiB
Fish

function fcd_ffdir -d "fuzzy find a directory, pass root dir and sequential search strings"
set -l options "c/case-sensitive" "i/case-insensitive" "m/menu" "multi" "d/depth=" "shortest"
argparse $options -- $argv
set -l max_depth 2
set -l new_path
set -l args
if test (count $argv) -gt 1
set new_path $argv[1]
set args $argv[2..-1]
else
set new_path '.'
set args $argv
end
if set -q _flag_depth
set max_depth $_flag_depth
end
if test (count $args) -gt 0
# allow traversing to number of args * max count
set max_depth (math (count $args)" * $max_depth")
test $max_depth -gt 4 && set max_depth 4
set -l found "."
# if search string contains uppercase, make search case sensitive
if string match -q --regex [A-Z] $args or set -q _flag_c
set case_sensitive "regex"
else
set case_sensitive "iregex"
end
# search for directory containing string up to 2 levels deeper
set -l regex (fcd_dir_regex $args)
# start by looking for directories starting with first char of search
# string, ignoring dot directories
set -l results (find -EL -s "$new_path" -$case_sensitive ".*/[^.]*$regex.*" -type d -maxdepth $max_depth -mindepth 1 2> /dev/null)
# choose shortest result
if set -q _flag_menu
set found (echo -e (string join "\n" $results) | fzf -1 -0)
if test -z "$found"
return
end
else
if set -q _flag_multi
set found $results
else
set found (fcd_shortest $results)
end
end
# if we found a result, clean it up
if test -n "$found"
if set -q _flag_multi
if set -q _flag_shortest
set found (fcd_shortest_common $found)
end
fcd_return_array $found
return
end
set found (echo -n "$found" | sed -e 's/^\.\///')
set new_path $found
else # if not, try again without the first char/dot requirement
set results (find -EL -s "$new_path" -$case_sensitive ".*$regex.*" -type d -maxdepth $max_depth -mindepth 1 2> /dev/null)
if set -q _flag_shortest
set results (fcd_shortest_common $results)
end
if set -q _flag_menu
set found (fcd_return_array $results | fzf -1 -0)
if test -z "$found"
return
end
else
if set -q _flag_multi
set found $results
else
set found (fcd_shortest $results)
end
end
if test -n "$found"
if set -q _flag_multi
echo -e (string join "\n" $found)
return
end
set found (echo "$found" | sed -e 's/^\.\///')
set new_path $found
else
set -e new_path
end
end
end
echo "$new_path"
end