├── .editorconfig
├── .travis.yml
├── CHANGELOG.md
├── Makefile
├── README.md
├── commacd.sh
└── shpec
└── commacd_shpec.sh
/.editorconfig:
--------------------------------------------------------------------------------
1 | root = true
2 |
3 | [*]
4 | charset = utf-8
5 | end_of_line = lf
6 | indent_size = 2
7 | indent_style = space
8 | insert_final_newline = true
9 | trim_trailing_whitespace = true
10 |
11 | [Makefile]
12 | indent_size = 4
13 | indent_style = tab
14 |
15 | [*.md]
16 | trim_trailing_whitespace = false
17 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | # https://docs.travis-ci.com/user/languages/minimal-and-generic/
2 | language: generic
3 | install:
4 | - curl -sSL https://raw.github.com/rylnd/shpec/0.3.1/bin/shpec -o shpec.sh && chmod a+x shpec.sh && sudo mv shpec.sh /usr/local/bin/shpec
5 | - curl -sSL https://storage.googleapis.com/shellcheck/shellcheck-v0.6.0.linux-x86_64 -o shellcheck && chmod a+x shellcheck && sudo mv shellcheck /usr/local/bin/
6 | script: make
7 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # Changelog
2 | All notable changes to this project will be documented in this file.
3 |
4 | The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
5 | and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
6 |
7 | ## [1.0.0] - 2019-02-03
8 |
9 | ### Added
10 | - ZSH support ([#16](https://github.com/shyiko/commacd/pull/16)).
11 | - `COMMACD_MARKER` env variable to control exit condition for `,,`
12 | (by default `,,` stops when it finds parent dir with `.git/`, `.hg/` or `.svn/`)
13 |
14 | ```
15 | $ tree -A ~
16 | |- a
17 | |- b
18 | |- c
19 | |- projects # ,, should stop here (contains .git/)
20 | |- .commacdroot
21 | |- project_a # and here (contains .commacdroot)
22 | |- .git
23 | |- x
24 | |- y
25 | |- z # workdir
26 |
27 | $ export COMMACD_MARKER=".git/ .hg/ .svn/ .commacdroot"
28 |
29 | ~/a/b/c/projects/project_a/x/y/z$ ,,
30 | => cd ~/a/b/c/projects/project_a
31 |
32 | ~/a/b/c/projects/project_a$ ,,
33 | => cd ~/a/b/c/projects
34 | ```
35 |
36 | ### Changed
37 | - Default `COMMACD_CD` to print `commacd: no matches found` & exit with code 1 when there is no match.
38 |
39 | ## [0.4.0] - 2018-01-13
40 |
41 | ### Added
42 | - Selection without Enter (when number of options is less than 10) (to enable `export COMMACD_IMPLICITENTER="on"`) ([#15](https://github.com/shyiko/commacd/issues/15)).
43 |
44 | ## [0.3.4] - 2018-01-05
45 |
46 | ### Fixed
47 | - Error message is printed when `failglob` shell option is set and no matches are found ([#13](https://github.com/shyiko/commacd/pull/13)).
48 |
49 | ## [0.3.3] - 2017-10-07
50 |
51 | ### Fixed
52 | - Terminal in inconsistent state after interrupt signal (`^C`) ([#12](https://github.com/shyiko/commacd/issues/12)).
53 |
54 | ## [0.3.2] - 2016-05-29
55 |
56 | ### Fixed
57 | - COMMACD_CD handling [#10](https://github.com/shyiko/commacd/issues/10) (thanks to [@chilicuil](https://github.com/chilicuil)).
58 |
59 | ## [0.3.1] - 2015-08-29
60 |
61 | ### Fixed
62 | - VCS root lookup (`,,`) in case of nested checkouts (`/.../checkout_1/.../checkout_2`).
63 |
64 | ## [0.3.0] - 2015-07-14
65 |
66 | ### Added
67 | - A way to change enumeration of "multiple choices" to start from 1 (instead of default 0) (use `export COMMACD_SEQSTART=1` to activate) (thanks to [@skorochkin](https://github.com/skorochkin)).
68 |
69 | ## [0.2.1] - 2014-11-08
70 |
71 | ## Fixed
72 | - Order of `,,`'s prefix/substring matching.
73 |
74 | ## [0.2.0] - 2014-11-07
75 |
76 | ## Added
77 | - Substring (fuzzy) matching as a fallback to the default prefix lookup (can be turned off with `export COMMACD_NOFUZZYFALLBACK="on"`).
78 |
79 | ## 0.1.0 - 2014-11-07
80 |
81 | [1.0.0]: https://github.com/shyiko/commacd/compare/v0.4.0...v1.0.0
82 | [0.4.0]: https://github.com/shyiko/commacd/compare/v0.3.4...v0.4.0
83 | [0.3.4]: https://github.com/shyiko/commacd/compare/v0.3.3...v0.3.4
84 | [0.3.3]: https://github.com/shyiko/commacd/compare/v0.3.2...v0.3.3
85 | [0.3.2]: https://github.com/shyiko/commacd/compare/v0.3.1...v0.3.2
86 | [0.3.1]: https://github.com/shyiko/commacd/compare/v0.3.0...v0.3.1
87 | [0.3.0]: https://github.com/shyiko/commacd/compare/v0.2.1...v0.3.0
88 | [0.2.1]: https://github.com/shyiko/commacd/compare/v0.2.0...v0.2.1
89 | [0.2.0]: https://github.com/shyiko/commacd/compare/v0.1.0...v0.2.0
90 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | all: lint test
2 |
3 | lint:
4 | test -s `which shellcheck` || { echo "shellcheck (https://github.com/koalaman/shellcheck) wasn't found on the PATH. Please install it and try again."; exit 1; }
5 | shellcheck -s bash -e SC1117,SC2206,SC2207,SC2128,SC2162,SC2178 -f gcc commacd.sh
6 |
7 | test:
8 | test -s `which shpec` || { echo "shpec (https://github.com/rylnd/shpec) wasn't found on the PATH. Please install it and try again"; exit 1; }
9 | bash -i -c "shpec"
10 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # commacd [](https://travis-ci.org/shyiko/commacd)
2 |
3 | A faster way to move around (Bash 3+/Zsh).
4 |
5 | > `commacd` is NOT an [autojump](https://github.com/joelthelion/autojump)/[z](https://github.com/rupa/z)/[fasd](https://github.com/clvv/fasd) alternative nor they are mutually exclusive. Think of it as an improved `cd`.
6 |
7 | ## Installation
8 |
9 | #### Bash
10 |
11 | ```sh
12 | curl -sSL https://github.com/shyiko/commacd/raw/v1.0.0/commacd.sh -o ~/.commacd.sh && \
13 | echo "source ~/.commacd.sh" >> ~/.bashrc
14 | ```
15 |
16 | > macOS users: make sure [~/.bashrc is sourced from ~/.bash_profile](http://ss64.com/osx/syntax-bashrc.html).
17 |
18 | #### Zsh
19 |
20 | ```sh
21 | curl -sSL https://github.com/shyiko/commacd/raw/v1.0.0/commacd.sh -o ~/.commacd.sh && \
22 | echo "source ~/.commacd.sh" >> ~/.zshrc
23 | ```
24 |
25 | ## Upgrading to the latest version
26 |
27 | ```sh
28 | curl -sSL https://github.com/shyiko/commacd/raw/v1.0.0/commacd.sh -o ~/.commacd.sh
29 | ```
30 |
31 | ## Usage
32 |
33 | `commacd` exports three commands: `,` (for jumping forward), `,,` (backward) and `,,,` (backward+forward):
34 |
35 | ```sh
36 | ~$ , des
37 | => cd Desktop
38 |
39 | # move through multiple directories
40 | ~$ , /u/l/ce
41 | => cd /usr/local/Cellar
42 |
43 | # allow me to choose directory in case of ambiguous pattern (= multiple choices)
44 | ~$ , d
45 | => 1 Desktop
46 | 2 Downloads
47 | :
48 |
49 | # given two directories jdk7 and jdk8 on the Desktop, cd into jdk8 without hitting
50 | # interactive mode (the one shown above)
51 | ~/github$ , ~/d/j*8
52 | => cd ~/Desktop/jdk8
53 |
54 | # cd into directory having 'esk' somewhere in its name
55 | ~/github$ , ~/esk # in pre-0.2.0 that would be `, ~/*esk`
56 | => cd ~/Desktop
57 |
58 | # go all the way up to the project root (in this case, the one that has .git in it)
59 | ~/github/lorem/src/public$ ,,
60 | => cd ~/github/lorem
61 |
62 | # cd into to the first (closest) parent directory named g*
63 | ~/github/vimium/src/public$ ,, g
64 | => cd ~/github
65 |
66 | # substitute jekyll with ghost
67 | ~/github/jekyll/test$ ,, jekyll ghost
68 | => cd ~/github/ghost/test
69 |
70 | # jump to some other project (in this case, located in ~/github)
71 | ~/github/rook/src/public$ ,,, binlog # in pre-0.2.0 you would need to use `m*binlog`
72 | => cd ~/github/mysql-binlog-connector-java
73 | ```
74 |
75 | As a bonus, all three aliases support `` expansion (try `, /u/lo`) and can be combined with other tools (e.g. ``ls `, /u/lo` ``).
76 |
77 | For more information, please refer to http://shyiko.com/2014/10/10/commacd/.
78 |
79 | ## Development
80 |
81 | ```sh
82 | make # lint & test
83 | ```
84 |
85 | ## License
86 |
87 | [MIT License](http://opensource.org/licenses/mit-license.php)
88 |
89 |
--------------------------------------------------------------------------------
/commacd.sh:
--------------------------------------------------------------------------------
1 | # commacd - a faster way to move around (Bash 3+/Zsh).
2 | # https://github.com/shyiko/commacd
3 | #
4 | # ENV variables that can be used to control commacd:
5 | # COMMACD_CD - function to change the directory
6 | # (by default 'builtin cd "$1" && pwd' is used)
7 | # COMMACD_NOTTY - set it to "on" when you want to suppress user input
8 | # (print multiple matches and exit)
9 | # COMMACD_NOFUZZYFALLBACK - set it to "on" if you don't want commacd to use
10 | # "fuzzy matching" as a fallback for "no matches by prefix"
11 | # (introduced in 0.2.0)
12 | # COMMACD_SEQSTART - set it to 1 if you want "multiple choices" to start
13 | # from 1 instead of 0
14 | # (introduced in 0.3.0)
15 | # COMMACD_IMPLICITENTER - set it to "on" to avoid pressing when
16 | # number of options (to select from) is less than 10
17 | # (introduced in 0.4.0)
18 | # COMMACD_MARKER - space-separated project root "marker"s (for ,, to stop at)
19 | # (".git/ .hg/ .svn/" by default)
20 | # (introduced in 1.0.0)
21 | #
22 | # @version 1.0.0
23 | # @author Stanley Shyiko
24 | # @license MIT
25 |
26 | # turn on case-insensitive search by default
27 |
28 | if [ -n "$ZSH_VERSION" ]; then
29 | # CAUTION: if you name local variable "path" (when no_case_glob is set) it
30 | # will override $PATH
31 | setopt no_case_glob
32 | unsetopt nomatch
33 | elif [ -n "$BASH_VERSION" ]; then
34 | shopt -s nocaseglob
35 | else
36 | echo "commacd: unsupported shell" >&2
37 | return
38 | fi
39 |
40 | _commacd_split() {
41 | # shellcheck disable=SC2001
42 | echo "$1" | sed $'s|/|\\\n/|g'
43 | }
44 | _commacd_join() { local IFS="$1"; shift; echo "$*"; }
45 |
46 | _commacd_expand() (
47 | if [ -n "$ZSH_VERSION" ]; then
48 | setopt extended_glob null_glob
49 | # shellcheck disable=SC2086
50 | print -rl - ${~1}
51 | else
52 | shopt -s extglob nullglob
53 | shopt -u failglob
54 | local ex=($1)
55 | printf "%s\n" "${ex[@]}"
56 | fi
57 | )
58 |
59 | _command_cd() {
60 | local dir=$1 IFS=$' \t\n'
61 | if [[ -z "$COMMACD_CD" ]]; then
62 | if [[ "$PWD" != "$dir" ]]; then
63 | builtin cd "$dir" && pwd
64 | else
65 | echo "commacd: no matches found" >&2
66 | return 1
67 | fi
68 | else
69 | $COMMACD_CD "$dir"
70 | fi
71 | }
72 |
73 | # show match selection menu
74 | _commacd_choose_match() {
75 | local matches=("$@")
76 | local i=${COMMACD_SEQSTART:-0}
77 | for match in "${matches[@]}"; do
78 | printf "%s\t%s\n" "$((i++))" "$match" >&2
79 | done
80 | local selection
81 | local threshold=$((11-${COMMACD_SEQSTART:-0}))
82 | if [[ "$COMMACD_IMPLICITENTER" == "on" && \
83 | ${#matches[@]} -lt $threshold ]]; then
84 | if [ -n "$ZSH_VERSION" ]; then
85 | read -k1 "selection?: " >&2
86 | else
87 | read -n1 -e -p ': ' selection >&2
88 | fi
89 | else
90 | if [ -n "$ZSH_VERSION" ]; then
91 | read "selection?: " >&2
92 | else
93 | read -e -p ': ' selection >&2
94 | fi
95 | fi
96 | if [[ "$selection" =~ ^[0-9]+$ ]]; then
97 | local i=$((selection-${COMMACD_SEQSTART:-0}))
98 | if [ -n "$ZSH_VERSION" ]; then
99 | ((i++)) # zsh arrays are 1-based
100 | fi
101 | if [[ "${matches[i]}" != "" ]]; then
102 | echo -n "${matches[i]}"
103 | return
104 | fi
105 | fi
106 | echo -n "$PWD"
107 | }
108 |
109 | _commacd_prefix_glob() (
110 | set -f
111 | local pth="${*%/}/" IFS=$'\n'
112 | # shellcheck disable=SC2046
113 | echo -n "$(_commacd_join \* $(_commacd_split "$pth"))"
114 | )
115 |
116 | _commacd_glob() (
117 | set -f
118 | local pth="${*%/}" IFS=$'\n'
119 | if [[ "${pth/\/}" == "$pth" ]]; then
120 | pth="*$pth*/"
121 | else
122 | # shellcheck disable=SC2046
123 | pth="$(_commacd_join \* $(_commacd_split "$pth") | rev |
124 | sed 's/\//*\//' | rev)*/"
125 | fi
126 | echo -n "$pth"
127 | )
128 |
129 | _commacd_forward_by_prefix() {
130 | local matches=($(_commacd_expand "$(_commacd_prefix_glob "$*")"))
131 | if [[ "$COMMACD_NOFUZZYFALLBACK" != "on" && ${#matches[@]} -eq 0 ]]; then
132 | matches=($(_commacd_expand "$(_commacd_glob "$*")"))
133 | fi
134 | case ${#matches[@]} in
135 | 0) echo -n "$PWD";;
136 | *) printf "%s\n" "${matches[@]}"
137 | esac
138 | }
139 |
140 | # jump forward (`,`)
141 | _commacd_forward() {
142 | if [[ -z "$*" ]]; then return 1; fi
143 | local IFS=$'\n'
144 | local dir=($(_commacd_forward_by_prefix "$@"))
145 | if [[ "$COMMACD_NOTTY" == "on" ]]; then
146 | printf "%s\n" "${dir[@]}"
147 | return
148 | fi
149 | if [[ ${#dir[@]} -gt 1 ]]; then
150 | # https://github.com/shyiko/commacd/issues/12
151 | trap 'trap - SIGINT; stty '"$(stty -g)" SIGINT
152 |
153 | dir=$(_commacd_choose_match "${dir[@]}")
154 |
155 | # make sure trap is removed regardless of whether read -e ... was
156 | # interrupted or not
157 | trap - SIGINT
158 | if [[ -z "$dir" ]]; then return 1; fi
159 | fi
160 | _command_cd "$dir"
161 | }
162 |
163 | _commacd_marked() {
164 | local dir="${*%/}"
165 | local markers=(${COMMACD_MARKER:-.git/ .hg/ .svn/})
166 | if [ -n "$ZSH_VERSION" ]; then
167 | markers=("${=markers[1]}") # shwordsplit
168 | fi
169 | for marker in "${markers[@]}"; do
170 | if [[ -e "$dir/$marker" ]]; then
171 | return 0
172 | fi
173 | done
174 | return 1
175 | }
176 |
177 | # search backward for the vcs root (`,,`)
178 | _commacd_backward_vcs_root() {
179 | local dir="${PWD%/*}"
180 | while ! _commacd_marked "$dir"; do
181 | dir="${dir%/*}"
182 | if [[ -z "$dir" ]]; then
183 | echo -n "$PWD"
184 | return
185 | fi
186 | done
187 | echo -n "$dir"
188 | }
189 |
190 | # search backward for the directory whose name begins with $1 (`,, $1`)
191 | _commacd_backward_by_prefix() (
192 | local prev_dir dir="${PWD%/*}" matches match IFS=$'\n'
193 | while [[ -n "$dir" ]]; do
194 | prev_dir="$dir"
195 | dir="${dir%/*}"
196 | matches=($(_commacd_expand "$dir/${1}*/"))
197 | for match in "${matches[@]}"; do
198 | if [ -n "$ZSH_VERSION" ]; then
199 | if [[ "${match:l}" == "${prev_dir:l}/" ]]; then
200 | echo -n "$prev_dir"
201 | return
202 | fi
203 | else
204 | # ${var,,}/${var^^} are not available in BASH 3.2 (macOS 10.14)
205 | # hence nocasematch & ==
206 | shopt -s nocasematch
207 | if [[ "$match" == "$prev_dir/" ]]; then
208 | echo -n "$prev_dir"
209 | return
210 | fi
211 | fi
212 | done
213 | done
214 | # at this point there is still a possibility that $1 is an actual path
215 | # (e.g. passed by "complete"), so let's check that
216 | if [[ -d "$1" ]]; then echo -n "$1"; return; fi
217 | # otherwise fallback to pwd
218 | echo -n "$PWD"
219 | )
220 |
221 | # replace $1 with $2 in $PWD (`,, $1 $2`)
222 | _commacd_backward_substitute() {
223 | echo -n "${PWD/$1/$2}"
224 | }
225 |
226 | # choose `,,` strategy based on a number of arguments
227 | _commacd_backward() {
228 | local dir=
229 | case $# in
230 | 0) dir=$(_commacd_backward_vcs_root);;
231 | 1) dir=$(_commacd_backward_by_prefix "$*")
232 | if [[ "$COMMACD_NOFUZZYFALLBACK" != "on" && "$dir" == "$PWD" ]]; then
233 | dir=$(_commacd_backward_by_prefix "*$*")
234 | fi;;
235 | 2) dir=$(_commacd_backward_substitute "$@");;
236 | *) return 1
237 | esac
238 | if [[ "$COMMACD_NOTTY" == "on" ]]; then
239 | echo -n "${dir}"
240 | return
241 | fi
242 | _command_cd "$dir"
243 | }
244 |
245 | _commacd_backward_forward_by_prefix() {
246 | local dir="$PWD" pth="${*%/}/" matches match IFS=$'\n'
247 | if [[ "${pth:0:1}" == "/" ]]; then
248 | # assume that we've been brought here by the completion
249 | dir=(${pth%/}*)
250 | printf "%s\n" "${dir[@]}"
251 | return
252 | fi
253 | while [[ -n "$dir" ]]; do
254 | dir="${dir%/*}"
255 | matches=($(_commacd_expand "$dir/$(_commacd_prefix_glob "$*")"))
256 | if [[ "$COMMACD_NOFUZZYFALLBACK" != "on" && ${#matches[@]} -eq 0 ]]; then
257 | matches=($(_commacd_expand "$dir/$(_commacd_glob "$*")"))
258 | fi
259 | case ${#matches[@]} in
260 | 0) ;;
261 | *) printf "%s\n" "${matches[@]}"
262 | return;;
263 | esac
264 | done
265 | echo -n "$PWD"
266 | }
267 |
268 | # combine backtracking with `, $1` (`,,, $1`)
269 | _commacd_backward_forward() {
270 | if [[ -z "$*" ]]; then return 1; fi
271 | local IFS=$'\n'
272 | local dir=($(_commacd_backward_forward_by_prefix "$@"))
273 | if [[ "$COMMACD_NOTTY" == "on" ]]; then
274 | printf "%s\n" "${dir[@]}"
275 | return
276 | fi
277 | if [[ ${#dir[@]} -gt 1 ]]; then
278 | dir=$(_commacd_choose_match "${dir[@]}")
279 | fi
280 | _command_cd "$dir"
281 | }
282 |
283 | _commacd_completion_valid() {
284 | if [[ "$2" == "$PWD" || "${2// /\\ }" == "$1" ]]; then return 1; fi
285 | }
286 |
287 | _commacd_completion() {
288 | local pattern=${COMP_WORDS[COMP_CWORD]} IFS=$'\n'
289 | # shellcheck disable=SC2088
290 | if [[ "${pattern:0:2}" == "~/" ]]; then
291 | # shellcheck disable=SC2116
292 | pattern=$(echo ~/"${pattern:2}")
293 | fi
294 | local completion=($(COMMACD_NOTTY=on $1 "$pattern"))
295 | if ! _commacd_completion_valid "$pattern" "$completion"; then
296 | pattern="$pattern?"
297 | # retry with ? matching
298 | completion=($(COMMACD_NOTTY=on $1 "$pattern"))
299 | if ! _commacd_completion_valid "$pattern" "$completion"; then
300 | return
301 | fi
302 | fi
303 | # remove trailing / (if any)
304 | for i in "${!completion[@]}"; do
305 | completion[$i]="${completion[$i]%/}";
306 | done
307 | COMPREPLY=($(compgen -W "$(printf "%s\n" "${completion[@]}")" -- ''))
308 | }
309 |
310 | _commacd_forward_completion() {
311 | _commacd_completion _commacd_forward
312 | }
313 |
314 | _commacd_backward_completion() {
315 | _commacd_completion _commacd_backward
316 | }
317 |
318 | _commacd_backward_forward_completion() {
319 | _commacd_completion _commacd_backward_forward
320 | }
321 |
322 | alias ,=_commacd_forward
323 | alias ,,=_commacd_backward
324 | alias ,,,=_commacd_backward_forward
325 |
326 | if [ -n "$BASH_VERSION" ]; then
327 | complete -o filenames -F _commacd_forward_completion ,
328 | complete -o filenames -F _commacd_backward_completion ,,
329 | complete -o filenames -F _commacd_backward_forward_completion ,,,
330 | fi
331 |
--------------------------------------------------------------------------------
/shpec/commacd_shpec.sh:
--------------------------------------------------------------------------------
1 | shopt -s expand_aliases
2 | . commacd.sh
3 |
4 | ROOT=/tmp/commacd.shpec
5 | rm -rf $ROOT
6 | mkdir -p $ROOT/projects/{jekyll/node_modules/tj/src,ghost,mysql-binlog-connector-java/src/main/java,mappify/{.git,src/test}}
7 | mkdir -p $ROOT/space\ hell/{a\ a,b\ b,a\ b}
8 |
9 | COMMACD_CD=cd # supress pwd
10 |
11 | describe 'commacd'
12 |
13 | describe ','
14 | it 'does nothing in case of no arguments'
15 | cd $ROOT
16 | ,
17 | assert equal "$PWD" $ROOT
18 | end
19 | it 'stays in the same directory in case of no match'
20 | cd $ROOT
21 | , p/nonexisting
22 | assert equal "$PWD" $ROOT
23 | end
24 | it 'changes directory without asking anything in case of single (unique) match'
25 | cd $ROOT
26 | , p/m/s/m
27 | assert equal "$PWD" "$ROOT/projects/mysql-binlog-connector-java/src/main"
28 | end
29 | it 'supports patterns starting with /'
30 | cd $ROOT
31 | , $ROOT/p/j
32 | assert equal "$PWD" "$ROOT/projects/jekyll"
33 | end
34 | it 'asks for user input in case of multiple choices'
35 | cd $ROOT
36 | , $ROOT/p/m 2> /dev/null <<< $(echo 0)
37 | assert equal "$PWD" "$ROOT/projects/mappify"
38 | end
39 | it 'can be used in subshells'
40 | cd $ROOT
41 | commacd_to_restore=$COMMACD_CD
42 | COMMACD_CD=
43 | v=$(, p)
44 | COMMACD_CD=$commacd_to_restore
45 | assert equal "$v" "$ROOT/projects"
46 | end
47 | it 'does not break on spaces'
48 | cd $ROOT
49 | , s/b
50 | assert equal "$PWD" "$ROOT/space hell/b b"
51 | end
52 | it 'switches to fuzzy mode when there are no matches by prefix'
53 | cd $ROOT/projects
54 | , binlog
55 | assert equal "$PWD" "$ROOT/projects/mysql-binlog-connector-java"
56 | end
57 | it 'switches to fuzzy mode when there are no matches by prefix containing /'
58 | cd $ROOT
59 | , p/binlog
60 | assert equal "$PWD" "$ROOT/projects/mysql-binlog-connector-java"
61 | end
62 | end
63 |
64 | describe ',,'
65 | it 'goes to the project root directory in case of no arguments'
66 | cd $ROOT/projects/mappify/src/test
67 | ,,
68 | assert equal "$PWD" "$ROOT/projects/mappify"
69 | end
70 | it 'stays in the same directory in case of no match'
71 | cd $ROOT
72 | ,,
73 | ,, nonexisting
74 | assert equal "$PWD" $ROOT
75 | end
76 | it 'always switches to the closest match'
77 | cd $ROOT/projects/mysql-binlog-connector-java/src/main/java
78 | ,, m
79 | assert equal "$PWD" "$ROOT/projects/mysql-binlog-connector-java/src/main"
80 | end
81 | it 'performs substitution in case of two arguments'
82 | cd $ROOT/projects/jekyll
83 | ,, jekyll ghost
84 | assert equal "$PWD" $ROOT/projects/ghost
85 | end
86 | it 'supports patterns starting with /'
87 | cd $ROOT/projects/mappify/src/test
88 | ,, $ROOT/projects/mappify
89 | assert equal "$PWD" "$ROOT/projects/mappify"
90 | end
91 | it 'can be used in subshells'
92 | cd $ROOT/projects/jekyll
93 | commacd_to_restore=$COMMACD_CD
94 | COMMACD_CD=
95 | v=$(,, pro)
96 | COMMACD_CD=$commacd_to_restore
97 | assert equal "$v" "$ROOT/projects"
98 | end
99 | it 'does not break on spaces'
100 | cd "$ROOT/space hell/b b"
101 | ,, s
102 | assert equal "$PWD" "$ROOT/space hell"
103 | end
104 | it 'switches to fuzzy mode when there are no matches by prefix'
105 | cd $ROOT/projects/mysql-binlog-connector-java/src/main/java
106 | ,, binlog
107 | assert equal "$PWD" "$ROOT/projects/mysql-binlog-connector-java"
108 | end
109 | it 'switches to fuzzy mode only after full path scan'
110 | cd $ROOT/projects/jekyll/node_modules/tj/src
111 | ,, j
112 | assert equal "$PWD" "$ROOT/projects/jekyll"
113 | end
114 | end
115 |
116 | describe ',,,'
117 | it 'does nothing in case of no arguments'
118 | cd $ROOT
119 | ,,,
120 | assert equal "$PWD" $ROOT
121 | end
122 | it 'stays in the same directory in case of no match'
123 | cd $ROOT
124 | ,,, nonexisting
125 | assert equal "$PWD" $ROOT
126 | end
127 | it 'changes directory without asking anything in case of single (unique) match'
128 | cd $ROOT/projects/mappify/src/test
129 | ,,, mysql
130 | assert equal "$PWD" "$ROOT/projects/mysql-binlog-connector-java"
131 | end
132 | it 'supports patterns starting with /'
133 | cd $ROOT/projects/mappify
134 | ,,, $ROOT/projects/mysql
135 | assert equal "$PWD" "$ROOT/projects/mysql-binlog-connector-java"
136 | end
137 | it 'asks for user input in case of multiple choices'
138 | cd $ROOT/projects/jekyll
139 | ,,, m 2> /dev/null <<< $(echo 0)
140 | assert equal "$PWD" "$ROOT/projects/mappify"
141 | end
142 | it 'can be used in subshells'
143 | cd $ROOT/projects/jekyll
144 | commacd_to_restore=$COMMACD_CD
145 | COMMACD_CD=
146 | v=$(,,, mysql)
147 | COMMACD_CD=$commacd_to_restore
148 | assert equal "$v" "$ROOT/projects/mysql-binlog-connector-java"
149 | end
150 | it 'does not break on spaces'
151 | cd "$ROOT/space hell/a a"
152 | ,,, b
153 | assert equal "$PWD" "$ROOT/space hell/b b"
154 | end
155 | it 'switches to fuzzy mode when there are no matches by prefix'
156 | cd $ROOT/projects/mappify
157 | ,,, binlog
158 | assert equal "$PWD" "$ROOT/projects/mysql-binlog-connector-java"
159 | end
160 | end
161 |
162 | end
163 |
--------------------------------------------------------------------------------