OS X GUI access to a shared directory stack
gdirs
pushd
just doesn't
cut it in a multi-terminal session GUI environment. I never could
get used to the directory stack idea, especially when each shell
session is isolated from all of the others. But I wanted a
way of returning to previously visited directories with a minimum
of typing. I also wanted a way of getting there easily with
the finder. Hence gdirs
which is very
loosly modelled after the dirs command associated with pushd.
Along the way I had to make several functions and aliases to get it
all to work properly.
If
you want to use this with zsh on OS X, by FAR the easiest thing to
do is to install my zsh template
scripts, as this will work right out of the box (starting with
version 0.4.0). This page is to explain a bit of what I made,
so that you can understand it and hopefully modify and improve
it.
How to use it:
Type
gdirs and you will get a pop-up window that displays up to
twenty previoiusly visited directories. Pick whatever
directory you want and hit "OK" and the terminal will cd to that
directory. Type
gdirs -f and both the terminal and Finder will change to the
newly selected directory. Type
gdirs -F and only the Finder will change to the newly
selected directory.
The non-gui version is (at present) a bit more flexible and
fully-featured. Type
dirstack [n] where n is an integer [defaults to 20] and you
will get the n most recent directories visited, listed with numbers
next to them. The command
cd? is the same. Then you can type (eg)
cd7 and the terminal will change directory to that listed on
line 7 of the dirstack output.
cp7 or
cpath7 copies the directory path in line 7 into the
clipboard copy/paste buffer.
I
have defined the following aliases in my
aliases.local file:
alias
dirstack="dirdump; typeset -U dirs_shared ;
dirstack"
alias
cd\?="dirdump; typeset -U dirs_shared; dirstack"
alias
gdirs="dirdump; typeset -U dirs_shared; dirstack > /dev/null ;
_guidirs"
I
also autoload the following functions in my
functions.local file:
dirdump:
#!/bin/zsh
# use this in
conjunction with the local functions
# called chpwd and
dirstack
# In an attempt to
have a shared directory stack (i.e.,
# shared between
different shell sessions), this appends
# the pwd onto the
bottom of a file called ~/.zdirdump
print $PWD | perl -pi
-e 's| |_SPACE_|g' >>|
~/.zdirdump
# Now create an array
called global_dirs. It is generated
# from the entries in
the above file.
junk=()
junk=( $(cat
~/.zdirdump ) )
lines=${#junk}
for (( i = 1; i
<=$lines; i++ )) do
if
[[ -n $junk[i] ]];then
invjunk[i]=$junk[-i]
fi
done
dirs_shared=(
$invjunk )
export
dirs_shared
dirstack:
#!/bin/zsh
#
usage: dirsize [n]
# n = #
of lines of directory stack printed
# if n is
not given, default to 20
# command
to update and then print out the shared directory
stack
# aliases
a series of cd-type commands corresponding to the
line
# number
in the directory stack printout
#
eg:
#
cd7 will cd to the directory in line #7 of the dirstack
printout
#
cd? is aliased to the dirstack command (in the file
aliases.local)
#
The commands cp7 and cpath7 are aliases to the same string of
commands
#
that copies the directory in line #7 into the clipboard cut/paste
buffer
#
cd# and cp# / cpath# are updated dynamically each time this
function is invoked,
#
so always invoke it first with cd? or dirstack
# Here
you can change the default 20 most recent directories
to
#
whatever number suits you.
if [[ -n
$1 ]]; then
GLOBALDIRSIZE=$1
else
GLOBALDIRSIZE=20
fi
global_dirs=()
global_dirs=(
$dirs_shared[1,$GLOBALDIRSIZE] )
export
global_dirs
for ((i =
1; i <= $GLOBALDIRSIZE; i++ ))
do
if [[ -n $global_dirs[i] ]];then
print $i $global_dirs[i] | perl -pi -e 's|_SPACE_|\\\
|g'
dir_index=$(print $global_dirs[i] | perl -pi -e 's|_SPACE_|\\\ |g'
)
alias cd$i="cd $dir_index ; command pwd "
dir_index_chomp=$(print -n $global_dirs[i] | perl -pi -e
's|_SPACE_|\\\ |g' )
alias cp$i="echo -n $dir_index_chomp |perl -pi -e 's; ;\\\ ;g' |
pbcopy "
alias cpath$i="echo -n $dir_index_chomp |perl -pi -e 's; ;\\\ ;g' |
pbcopy "
else
return 0
fi
done
#!/bin/zsh
-f
#
usage: gdirs [-fF]
# gdirs -f cd's
both terminal and finder to chosen
directory
# gdirs -F cd's
only the Finder to the chosen directory
# gdirs with no
argument changes only the terminal
directory
if
[[ $1 == '-f' ]];then
CDD=ON
elif [[ $1 == '-F'
]];then
CDF=ON
fi
#
function ChooseFile allows picking from filtered list of files in
$PWD
#
returns name of chosen file as a string
function
ChooseFromStack {
#
#
Change this first line for particular filtering
needs:
#
#
=========>
#
filelist=($(print $global_dirs | perl -pi -e 's| |\n|g' | perl -pi
-e 's|_SPACE_|\*|g' ) )
item_list=""
for item in "${filelist[@]}"
do
item_list="$item_list""\"${item}\","
done
function filepicker {
osascript << eof
tell app "Finder"
activate
choose from list {${item_list%,}} with prompt "Choose a recent
directory: "
end tell
eof
}
SelectedFile=$(filepicker)
if [[ $CDD ==
ON ]];then
cd
"$SelectedFile"; open . ; pwd
elif [[ $CDF
== ON ]];then
cd
"$SelectedFile"; open . ; cd $OLDPWD
else
cd "$SelectedFile"; pwd
fi
}
ChooseFromStack