__z.fish 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. function __z -d "Jump to a recent directory."
  2. function __print_help -d "Print z help."
  3. printf "Usage: $Z_CMD [-celrth] regex1 regex2...\n\n"
  4. printf " -c --clean Removes directories that no longer exist from $Z_DATA\n"
  5. printf " -d --dir Opens matching directory using system file manager.\n"
  6. printf " -e --echo Prints best match, no cd\n"
  7. printf " -l --list List matches and scores, no cd\n"
  8. printf " -p --purge Delete all entries from $Z_DATA\n"
  9. printf " -r --rank Search by rank\n"
  10. printf " -t --recent Search by recency\n"
  11. printf " -x --delete Removes the current directory from $Z_DATA\n"
  12. printf " -h --help Print this help\n\n"
  13. if type -q fisher
  14. printf "Run `fisher help z` for more information.\n"
  15. end
  16. end
  17. set -l options "h/help" "c/clean" "e/echo" "l/list" "p/purge" "r/rank" "t/recent" "d/directory" "x/delete"
  18. argparse $options -- $argv
  19. if set -q _flag_help
  20. __print_help
  21. return 0
  22. else if set -q _flag_clean
  23. __z_clean
  24. printf "%s cleaned!\n" $Z_DATA
  25. return 0
  26. else if set -q _flag_purge
  27. echo > $Z_DATA
  28. printf "%s purged!\n" $Z_DATA
  29. return 0
  30. else if set -q _flag_delete
  31. sed -i -e "\:^$PWD|.*:d" $Z_DATA
  32. return 0
  33. end
  34. set -l typ
  35. if set -q _flag_rank
  36. set typ "rank"
  37. else if set -q _flag_recent
  38. set typ "recent"
  39. end
  40. set -l z_script '
  41. function frecent(rank, time) {
  42. dx = t-time
  43. if( dx < 3600 ) return rank*4
  44. if( dx < 86400 ) return rank*2
  45. if( dx < 604800 ) return rank/2
  46. return rank/4
  47. }
  48. function output(matches, best_match, common) {
  49. # list or return the desired directory
  50. if( list ) {
  51. cmd = "sort -nr"
  52. for( x in matches ) {
  53. if( matches[x] ) {
  54. printf "%-10s %s\n", matches[x], x | cmd
  55. }
  56. }
  57. if( common ) {
  58. printf "%-10s %s\n", "common:", common > "/dev/stderr"
  59. }
  60. } else {
  61. if( common ) best_match = common
  62. print best_match
  63. }
  64. }
  65. function common(matches) {
  66. # find the common root of a list of matches, if it exists
  67. for( x in matches ) {
  68. if( matches[x] && (!short || length(x) < length(short)) ) {
  69. short = x
  70. }
  71. }
  72. if( short == "/" ) return
  73. for( x in matches ) if( matches[x] && index(x, short) != 1 ) {
  74. return
  75. }
  76. return short
  77. }
  78. BEGIN {
  79. gsub(" ", ".*", q)
  80. hi_rank = ihi_rank = -9999999999
  81. }
  82. {
  83. if( typ == "rank" ) {
  84. rank = $2
  85. } else if( typ == "recent" ) {
  86. rank = $3 - t
  87. } else rank = frecent($2, $3)
  88. if( $1 ~ q ) {
  89. matches[$1] = rank
  90. } else if( tolower($1) ~ tolower(q) ) imatches[$1] = rank
  91. if( matches[$1] && matches[$1] > hi_rank ) {
  92. best_match = $1
  93. hi_rank = matches[$1]
  94. } else if( imatches[$1] && imatches[$1] > ihi_rank ) {
  95. ibest_match = $1
  96. ihi_rank = imatches[$1]
  97. }
  98. }
  99. END {
  100. # prefer case sensitive
  101. if( best_match ) {
  102. output(matches, best_match, common(matches))
  103. } else if( ibest_match ) {
  104. output(imatches, ibest_match, common(imatches))
  105. }
  106. }
  107. '
  108. if set -q _flag_list
  109. # Handle list separately as it can print common path information to stderr
  110. # which cannot be captured from a subcommand.
  111. command awk -v t=(date +%s) -v list="list" -v typ="$typ" -v q="$argv" -F "|" $z_script "$Z_DATA"
  112. else
  113. set target (command awk -v t=(date +%s) -v typ="$typ" -v q="$argv" -F "|" $z_script "$Z_DATA")
  114. if test "$status" -gt 0
  115. return
  116. end
  117. if test -z "$target"
  118. printf "'%s' did not match any results\n" "$argv"
  119. return 1
  120. end
  121. if set -q _flag_list
  122. echo "$target" | tr ";" "\n" | sort -nr
  123. return 0
  124. end
  125. if set -q _flag_echo
  126. printf "%s\n" "$target"
  127. else if set -q _flag_directory
  128. type -q xdg-open;and xdg-open "$target"; and return $status;
  129. type -q open;and open "$target"; and return $status;
  130. echo "Not sure how to open file manager"; and return 1;
  131. else
  132. pushd "$target"
  133. end
  134. end
  135. end