-
Notifications
You must be signed in to change notification settings - Fork 1
/
go2x
executable file
·149 lines (127 loc) · 4 KB
/
go2x
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
#!/bin/bash
###############################################################################
##
## Quick navigation to anything
## ============================
##
## Brief: Script which provides a shortcut in navigating to a specific seach
## path
##
## Installation by adding an alias in the .bashrc file (Assuming binaries are
## in search path):
## `alias go2x='. go2x'`
##
## Author: Koen Hausmans
##
###############################################################################
# Default settings
SEARCH_PATH="./"
QUERY=""
## DO NOT CHANGE BELOW
# Argument parsing
function show_help() {
echo """
usage: $0 --search-path=PATH QUERY
arguments:
-s [PATH], --search-path=[PATH]
Sets the search path for which the fuzzy navigation will take place
-h, --help Shows this help
"""
exit
}
while [[ $# -ge 1 ]] ; do
case "$1" in
-h|--help)
show_help
exit
;;
-s|--search-path)
SEARCH_PATH="$2"
shift
;;
-s=*|--search-path=*)
SEARCH_PATH="${1#*=}"
;;
*)
[[ ! -z "$QUERY" ]] && show_help
QUERY="$1"
;;
esac
shift
done
# Check for valid arguments
ShouldStopSearch=""
if [[ -z "$QUERY" ]] ; then
echo -e "\e[31mPlease enter a query to be used!\e[0m"
ShouldStopSearch="true"
fi
SearchPathExists=`find ${SEARCH_PATH} -maxdepth 0 -type d 2>&1 > /dev/null`
if [[ -z "$SEARCH_PATH" || $? -ne 0 ]] ; then
echo -e "\e[31mInvalid search path entered!\e[0m"
ShouldStopSearch="true"
fi
## Helper functions
# convert_query_to_fuzzy: Adds wildcard (.*) between every character
function convert_query_to_fuzzy() {
echo "$1" | sed 's|.|\0.*|g'
}
# highlight_fuzzy_result: Highlights the character of the query in order with a bright color
function highlight_fuzzy_result() {
Result="$1"
Query="$2"
j=0
for (( i=0; i < ${#Result}; i++ )) ; do
# Use different substring for ZSH for compatibility issues, there might be an easier solution?
# Using shell tooling (cut / expr substr / etc.) is too slow...
if [[ -n "$ZSH_VERSION" ]] ; then
CurResultChar="$Result[(($i + 1))]"
CurQueryChar="$Query[(($j + 1))]"
else
CurResultChar="${Result:${i}:1}"
CurQueryChar="${Query:${j}:1}"
fi
if [[ "$CurResultChar" == "$CurQueryChar" ]] ; then
((j++))
echo -en "\e[31m$CurResultChar\e[0m"
else
echo -n "$CurResultChar"
fi
done
echo
}
if [[ "$ShouldStopSearch" != "true" ]] ; then
# Find locations given the search path and the query
FuzzyQuery=`convert_query_to_fuzzy "$QUERY"`
Locations=`find ${SEARCH_PATH} -maxdepth 1 -type d -exec basename {} \; | grep -i "$FuzzyQuery"`
NumberOfResults=`wc -w <<< "$Locations"`
# No results found, show error
if [[ "$NumberOfResults" -eq "0" ]] ; then
echo -e "\e[31mNo result found that matches query\e[0m"
fi
# Single result, navigate to directory
SelectedFolder=""
if [[ "$NumberOfResults" -eq "1" ]] ; then
SelectedFolder="$Locations"
fi
# Multiple results, show list and allow for a selection
if [[ "$NumberOfResults" -ge "2" ]] ; then
MatchCounter=0
while read -r location ; do
(( MatchCounter++ ))
echo -en "\e[34m$MatchCounter.\e[0m "
highlight_fuzzy_result "$location" "$QUERY"
done <<< "$Locations"
echo -n "Enter desired result: "
read selected
test "$selected" -ge 1 -a "$selected" -le "$NumberOfResults" 2>&-
if [[ $? -ne 0 ]] ; then
echo -e "\e[31mInvalid number entered\e[0m"
else
SelectedFolder=$(echo "$Locations" | sed -n "${selected}p")
fi
fi
# Navigate to the selected folder, if there was a selection
if [[ ! -z "$SelectedFolder" ]] ; then
cd $(find $SEARCH_PATH -maxdepth 1 -type d -iname "$SelectedFolder")
fi
fi