aboutsummaryrefslogtreecommitdiffhomepage
path: root/share/functions/pushd.fish
diff options
context:
space:
mode:
authorGravatar Derek Harland <donkopotamus@users.noreply.github.com>2015-07-09 14:20:43 +1200
committerGravatar ridiculousfish <corydoras@ridiculousfish.com>2015-07-12 11:57:14 -0700
commitf07d59c55df1b6ea51f49c9fef0411c1d02e1a27 (patch)
tree751d1feefea09546217482f72f85388d91ce4e6c /share/functions/pushd.fish
parentb057efdb37a931633b5791339364d5c074b14eb0 (diff)
Alter pushd to add more bash-like behaviour
The following behaviour is added: - an empty pushd exchanges the top two directories in the stack; - pushd +<n> rotates the stack so that the n-th directory (counting from the left of the list shown by dirs, starting with zero) is at the top; - pushd -<n> rotates the stack so that the nth directory (counting from the right of the list shown by dirs, starting with zero) is at the top.
Diffstat (limited to 'share/functions/pushd.fish')
-rw-r--r--share/functions/pushd.fish63
1 files changed, 61 insertions, 2 deletions
diff --git a/share/functions/pushd.fish b/share/functions/pushd.fish
index 7829e16b..0b60c470 100644
--- a/share/functions/pushd.fish
+++ b/share/functions/pushd.fish
@@ -1,16 +1,75 @@
-function pushd --description "Push directory to stack"
+function pushd --description 'Push directory to stack'
if count $argv >/dev/null
+ # check for --help
switch $argv[1]
case -h --h --he --hel --help
__fish_print_help pushd
return 0
end
+
+ # emulate bash by checking if argument of form +n or -n
+ set rot_l (echo $argv[1] | sed -n '/^+\([0-9]\)$/ s//\1/g p')
+ set rot_r (echo $argv[1] | sed -n '/^-\([0-9]\)$/ s//\1/g p')
+ end
+
+ # emulate bash: an empty pushd should switch the top of dirs
+ if test (count $argv) -eq 0
+ # check that the stack isn't empty
+ if test (count $dirstack) -eq 0
+ echo "pushd: no other directory"
+ return 1
+ end
+
+ # get the top two values of the dirs stack ... the first is pwd
+ set -l top_dir (command pwd)
+ set -l next_dir $dirstack[1]
+
+ # alter the top of dirstack and move to directory
+ set -g dirstack[1] $top_dir
+ cd $next_dir
+ return
+ end
+
+ # emulate bash: check for rotations
+ if test -n "$rot_l" -o -n "$rot_r"
+ # grab the current stack
+ set -l stack (command pwd) $dirstack
+
+ # translate a right rotation to a left rotation
+ if test -n "$rot_r"
+ # check the rotation in range
+ if test $rot_r -gt (math (count $stack) - 1)
+ echo "pushd: -$rot_r: directory stack index out of range"
+ return 1
+ end
+
+ set rot_l (math (count $stack) - 1 - $rot_r)
+ end
+
+ # check the rotation in range
+ if test $rot_l -gt (math (count $stack) - 1)
+ echo "pushd: +$rot_l: directory stack index out of range"
+ return 1
+ else
+ # rotate stack unless rot_l is 0
+ if test $rot_l -gt 0
+ set stack $stack[(math $rot_l + 1)..(count $stack)] $stack[1..$rot_l]
+ end
+
+ # now reconstruct dirstack and change directory
+ set -g dirstack $stack[2..(count $stack)]
+ cd $stack[1]
+ end
+
+ # print the new stack
+ dirs
+ return
end
# Comment to avoid set completions
set -g dirstack (command pwd) $dirstack
cd $argv[1]
-end
+end