use str use ./list use ./map var search-type = [ &exact= {|m| ls $m 2>/dev/null } &match= {|m| put *$m* } &prefix= {|m| put $m* } &suffix= {|m| put *$m } &deep-match= {|m| put **$m** } &deep-prefix= {|m| put $m** } &deep-suffix= {|m| put **$m } ] fn comp {|f1 f2| var fl1 fl2 = (str:to-lower $f1) (str:to-lower $f2) var c = (str:compare $fl1 $fl2) if (!= $c 0) { put $c } else { str:compare $f1 $f2 } } fn -r {|sort result| if $sort { keys $result | list:sort $comp~ } else { keys $result } } fn -s {|&sort=$false &type=exact @motive| var f result = $search-type[$type] [&] if (list:is-empty $motive) { set result = (put * | map:to-set) } else { peach {|m| try { $f $m | peach {|e| set result[$e] = $nil } } except e { } } $motive } -r $sort $result } fn match {|&sort=$false &type=prefix @motive| -s &sort=$sort &type=$type $@motive } fn match-extensions {|&sort=$false &type=deep-prefix motive @extensions| var result = [&] -s &type=$type $motive | peach {|f| if (list:contains {|e| str:has-suffix $f .$e } $extensions) { set result[$f] = $nil } } -r $sort $result }