1
###########################################################################
6
# ############################################
7
# Latest version of this script available from
8
# http://freshmeat.net/projects/cd/
9
# ############################################
13
# An enhancement of the Unix cd command
15
# There are unlimited stack entries and special entries. The stack
16
# entries keep the last cd_maxhistory
17
# directories that have been used. The special entries can be
18
# assigned to commonly used directories.
20
# The special entries may be pre-assigned by setting the environment
21
# variables CDSn or by using the -u or -U command.
23
# The following is a suggestion for the .profile file:
25
# . cdll # Set up the cd command
26
# alias cd='cd_new' # Replace the cd command
27
# cd -U # Upload pre-assigned entries for
28
# #+ the stack and special entries
29
# cd -D # Set non-default mode
30
# alias @="cd_new @" # Allow @ to be used to get history
38
###########################################################################
42
# Written by Phil Braham - Realtime Software Pty Ltd
43
# (realtime@mpx.com.au)
44
# Please send any suggestions or enhancements to the author (also at
47
############################################################################
51
${PRINTF} "%s" "cd [dir] [0-9] [@[s|h] [-g [<dir>]] [-d] \
52
[-D] [-r<n>] [dir|0-9] [-R<n>] [<dir>|0-9]
53
[-s<n>] [-S<n>] [-u] [-U] [-f] [-F] [-h] [-H] [-v]
54
<dir> Go to directory
55
0-n Go to previous directory (0 is previous, 1 is last but 1 etc)
56
n is up to max history (default is 50)
57
@ List history and special entries
58
@h List history entries
59
@s List special entries
60
-g [<dir>] Go to literal name (bypass special names)
61
This is to allow access to dirs called '0','1','-h' etc
62
-d Change default action - verbose. (See note)
63
-D Change default action - silent. (See note)
64
-s<n> Go to the special entry <n>*
65
-S<n> Go to the special entry <n>
66
and replace it with the current dir*
67
-r<n> [<dir>] Go to directory <dir>
68
and then put it on special entry <n>*
69
-R<n> [<dir>] Go to directory <dir>
70
and put current dir on special entry <n>*
71
-a<n> Alternative suggested directory. See note below.
72
-f [<file>] File entries to <file>.
73
-u [<file>] Update entries from <file>.
74
If no filename supplied then default file
75
(${CDPath}${2:-"$CDFile"}) is used
76
-F and -U are silent versions
77
-v Print version number
81
*The special entries (0 - 9) are held until log off, replaced by another
82
entry or updated with the -u command
84
Alternative suggested directories:
85
If a directory is not found then CD will suggest any
86
possibilities. These are directories starting with the same letters
87
and if any are found they are listed prefixed with -a<n>
88
where <n> is a number.
89
It's possible to go to the directory by entering cd -a<n>
92
The directory for -r<n> or -R<n> may be a number.
94
$ cd -r3 4 Go to history entry 4 and put it on special entry 3
95
$ cd -R3 4 Put current dir on the special entry 3
96
and go to history entry 4
97
$ cd -s3 Go to special entry 3
99
Note that commands R,r,S and s may be used without a number
101
$ cd -s Go to special entry 0
102
$ cd -S Go to special entry 0 and make special
104
$ cd -r 1 Go to history entry 1 and put it on special entry 0
105
$ cd -r Go to history entry 0 and put it on special entry 0
107
if ${TEST} "$CD_MODE" = "PREV"
109
${PRINTF} "$cd_mnset"
119
The previous directories (0-$cd_maxhistory) are stored in the
120
environment variables CD[0] - CD[$cd_maxhistory]
121
Similarly the special directories S0 - $cd_maxspecial are in
122
the environment variable CDS[0] - CDS[$cd_maxspecial]
123
and may be accessed from the command line
125
The default pathname for the -f and -u commands is $CDPath
126
The default filename for the -f and -u commands is $CDFile
128
Set the following environment variables:
129
CDL_PROMPTLEN - Set to the length of prompt you require.
130
Prompt string is set to the right characters of the
132
If not set then prompt is left unchanged
133
CDL_PROMPT_PRE - Set to the string to prefix the prompt.
135
non-root: \"\\[\\e[01;34m\\]\" (sets colour to blue).
136
root: \"\\[\\e[01;31m\\]\" (sets colour to red).
137
CDL_PROMPT_POST - Set to the string to suffix the prompt.
139
non-root: \"\\[\\e[00m\\]$\"
140
(resets colour and displays $).
141
root: \"\\[\\e[00m\\]#\"
142
(resets colour and displays #).
143
CDPath - Set the default path for the -f & -u options.
144
Default is home directory
145
CDFile - Set the default filename for the -f & -u options.
155
printf "Version: ${VERSION_MAJOR}.${VERSION_MINOR} Date: ${VERSION_DATE}\n"
163
# p2 - length to truncate to
165
# returns string in tcd
174
if ${TEST} ${plen} -le ${tlen}
178
let diff=${plen}-${tlen}
180
if ${TEST} ${diff} -le 2
185
let tlen=${tlen}+${elen}
186
tcd=${filler:0:elen}${str:tlen}
191
# Three versions of do history:
192
# cd_dohistory - packs history and specials side by side
193
# cd_dohistoryH - Shows only hstory
194
# cd_dohistoryS - Shows only specials
199
${PRINTF} "History:\n"
200
local -i count=${cd_histcount}
201
while ${TEST} ${count} -ge 0
203
cd_right_trunc "${CD[count]}" ${cd_lchar}
204
${PRINTF} "%2d %-${cd_lchar}.${cd_lchar}s " ${count} "${tcd}"
206
cd_right_trunc "${CDS[count]}" ${cd_rchar}
207
${PRINTF} "S%d %-${cd_rchar}.${cd_rchar}s\n" ${count} "${tcd}"
215
${PRINTF} "History:\n"
216
local -i count=${cd_maxhistory}
217
while ${TEST} ${count} -ge 0
219
${PRINTF} "${count} %-${cd_flchar}.${cd_flchar}s\n" ${CD[$count]}
227
${PRINTF} "Specials:\n"
228
local -i count=${cd_maxspecial}
229
while ${TEST} ${count} -ge 0
231
${PRINTF} "S${count} %-${cd_flchar}.${cd_flchar}s\n" ${CDS[$count]}
238
cd_flchar=$(stty -a | awk -F \;
239
'/rows/ { print $2 $3 }' | awk -F \ '{ print $4 }')
240
if ${TEST} ${cd_flchar} -ne 0
242
cd_lchar=${cd_flchar}/2-5
243
cd_rchar=${cd_flchar}/2-5
244
cd_flchar=${cd_flchar}-5
246
cd_flchar=${FLCHAR:=75}
247
# cd_flchar is used for for the @s & @h history
248
cd_lchar=${LCHAR:=35}
249
cd_rchar=${RCHAR:=35}
257
if ${TEST} "${CD_MODE}" = "PREV"
259
if ${TEST} -z "$cd_npwd"
264
tm=$(echo "${cd_npwd}" | cut -b 1)
265
if ${TEST} "${tm}" = "-"
267
pm=$(echo "${cd_npwd}" | cut -b 2)
268
nm=$(echo "${cd_npwd}" | cut -d $pm -f2)
270
a) cd_npwd=${cd_sugg[$nm]} ;;
271
s) cd_npwd="${CDS[$nm]}" ;;
272
S) cd_npwd="${CDS[$nm]}" ; CDS[$nm]=`pwd` ;;
273
r) cd_npwd="$2" ; cd_specDir=$nm ; cd_doselection "$1" "$2";;
274
R) cd_npwd="$2" ; CDS[$nm]=`pwd` ; cd_doselection "$1" "$2";;
278
if ${TEST} "${cd_npwd}" != "." -a "${cd_npwd}" \
279
!= ".." -a "${cd_npwd}" -le ${cd_maxhistory} >>/dev/null 2>&1
281
cd_npwd=${CD[$cd_npwd]}
284
@) cd_dohistory ; cd_doflag="FALSE" ;;
285
@h) cd_dohistoryH ; cd_doflag="FALSE" ;;
286
@s) cd_dohistoryS ; cd_doflag="FALSE" ;;
287
-h) cd_hm ; cd_doflag="FALSE" ;;
288
-H) cd_Hm ; cd_doflag="FALSE" ;;
289
-f) cd_fsave "SHOW" $2 ; cd_doflag="FALSE" ;;
290
-u) cd_upload "SHOW" $2 ; cd_doflag="FALSE" ;;
291
-F) cd_fsave "NOSHOW" $2 ; cd_doflag="FALSE" ;;
292
-U) cd_upload "NOSHOW" $2 ; cd_doflag="FALSE" ;;
294
-d) cd_chdefm 1; cd_doflag="FALSE" ;;
295
-D) cd_chdefm 0; cd_doflag="FALSE" ;;
296
-r) cd_npwd="$2" ; cd_specDir=0 ; cd_doselection "$1" "$2";;
297
-R) cd_npwd="$2" ; CDS[0]=`pwd` ; cd_doselection "$1" "$2";;
298
-s) cd_npwd="${CDS[0]}" ;;
299
-S) cd_npwd="${CDS[0]}" ; CDS[0]=`pwd` ;;
300
-v) cd_version ; cd_doflag="FALSE";;
307
if ${TEST} "${CD_MODE}" = "PREV"
312
${PRINTF} "${cd_mset}"
318
${PRINTF} "${cd_mnset}"
325
local sfile=${CDPath}${2:-"$CDFile"}
326
if ${TEST} "$1" = "SHOW"
328
${PRINTF} "Saved to %s\n" $sfile
332
while ${TEST} ${count} -le ${cd_maxhistory}
334
echo "CD[$count]=\"${CD[$count]}\"" >> ${sfile}
338
while ${TEST} ${count} -le ${cd_maxspecial}
340
echo "CDS[$count]=\"${CDS[$count]}\"" >> ${sfile}
347
local sfile=${CDPath}${2:-"$CDFile"}
348
if ${TEST} "${1}" = "SHOW"
350
${PRINTF} "Loading from %s\n" ${sfile}
362
cd_doselection "${1}" "${2}"
364
if ${TEST} ${cd_doflag} = "TRUE"
366
if ${TEST} "${CD[0]}" != "`pwd`"
369
while ${TEST} $count -gt 0
371
CD[$count]=${CD[$count-1]}
376
command cd "${cd_npwd}" 2>/dev/null
379
${PRINTF} "Unknown dir: %s\n" "${cd_npwd}"
381
for i in "${cd_npwd}"*
385
if ${TEST} ${ftflag} -eq 0
387
${PRINTF} "Suggest:\n"
390
${PRINTF} "\t-a${choose} %s\n" "$i"
391
cd_sugg[$choose]="${i}"
398
if ${TEST} ${cd_specDir} -ne -1
400
CDS[${cd_specDir}]=`pwd`
403
if ${TEST} ! -z "${CDL_PROMPTLEN}"
405
cd_right_trunc "${PWD}" ${CDL_PROMPTLEN}
406
cd_rp=${CDL_PROMPT_PRE}${tcd}${CDL_PROMPT_POST}
407
export PS1="$(echo -ne ${cd_rp})"
410
#########################################################################
412
# Initialisation here #
414
#########################################################################
418
VERSION_DATE="24-MAY-2003"
425
PRINTF=printf # Use builtin printf
427
#########################################################################
429
# Change this to modify the default pre- and post prompt strings. #
430
# These only come into effect if CDL_PROMPTLEN is set. #
432
#########################################################################
433
if ${TEST} ${EUID} -eq 0
435
# CDL_PROMPT_PRE=${CDL_PROMPT_PRE:="$HOSTNAME@"}
436
CDL_PROMPT_PRE=${CDL_PROMPT_PRE:="\\[\\e[01;31m\\]"} # Root is in red
437
CDL_PROMPT_POST=${CDL_PROMPT_POST:="\\[\\e[00m\\]#"}
439
CDL_PROMPT_PRE=${CDL_PROMPT_PRE:="\\[\\e[01;34m\\]"} # Users in blue
440
CDL_PROMPT_POST=${CDL_PROMPT_POST:="\\[\\e[00m\\]$"}
442
#########################################################################
444
# cd_maxhistory defines the max number of history entries allowed.
445
typeset -i cd_maxhistory=50
447
#########################################################################
449
# cd_maxspecial defines the number of special entries.
450
typeset -i cd_maxspecial=9
453
#########################################################################
455
# cd_histcount defines the number of entries displayed in
456
#+ the history command.
457
typeset -i cd_histcount=9
459
#########################################################################
460
export CDPath=${HOME}/
461
# Change these to use a different #
462
#+ default path and filename #
463
export CDFile=${CDFILE:=cdfile} # for the -u and -f commands #
465
#########################################################################
467
typeset -i cd_lchar cd_rchar cd_flchar
468
# This is the number of chars to allow for the #
469
cd_flchar=${FLCHAR:=75} #+ cd_flchar is used for for the @s & @h history#
473
cd_mset="\n\tDefault mode is now set - entering cd with no parameters \
474
has the default action\n\tUse cd -d or -D for cd to go to \
475
previous directory with no parameters\n"
476
cd_mnset="\n\tNon-default mode is now set - entering cd with no \
477
parameters is the same as entering cd 0\n\tUse cd -d or \
478
-D to change default cd action\n"
480
# ==================================================================== #
484
: <<DOCUMENTATION
486
Written by Phil Braham. Realtime Software Pty Ltd.
487
Released under GNU license. Free to use. Please pass any modifications
488
or comments to the author Phil Braham:
491
=======================================================================
493
cdll is a replacement for cd and incorporates similar functionality to
494
the bash pushd and popd commands but is independent of them.
496
This version of cdll has been tested on Linux using Bash. It will work
497
on most Linux versions but will probably not work on other shells without
503
cdll allows easy moving about between directories. When changing to a new
504
directory the current one is automatically put onto a stack. By default
505
50 entries are kept, but this is configurable. Special directories can be
506
kept for easy access - by default up to 10, but this is configurable. The
507
most recent stack entries and the special entries can be easily viewed.
509
The directory stack and special entries can be saved to, and loaded from,
510
a file. This allows them to be set up on login, saved before logging out
511
or changed when moving project to project.
513
In addition, cdll provides a flexible command prompt facility that allows,
514
for example, a directory name in colour that is truncated from the left
521
Copy cdll to either your local home directory or a central directory
522
such as /usr/bin (this will require root access).
524
Copy the file cdfile to your home directory. It will require read and
525
write access. This a default file that contains a directory stack and
528
To replace the cd command you must add commands to your login script.
529
The login script is one or more of:
536
/etc/bash.bashrc.local
538
To setup your login, ~/.bashrc is recommended, for global (and root) setup
539
add the commands to /etc/bash.bashrc.local
541
To set up on login, add the command:
543
For example if cdll is in your local home directory:
548
If you want to use this instead of the buitin cd command then add:
550
We would also recommend the following commands:
555
If you want to use cdll's prompt facilty then add the following:
557
Where nn is a number described below. Initially 99 would be suitable
560
Thus the script looks something like this:
562
######################################################################
564
######################################################################
565
CDL_PROMPTLEN=21 # Allow a prompt length of up to 21 characters
566
. /usr/bin/cdll # Initialise cdll
567
alias cd='cd_new' # Replace the built in cd command
568
alias @='cd_new @' # Allow @ at the prompt to display history
569
cd -U # Upload directories
570
cd -D # Set default action to non-posix
571
######################################################################
573
The full meaning of these commands will become clear later.
575
There are a couple of caveats. If another program changes the directory
576
without calling cdll, then the directory won't be put on the stack and
577
also if the prompt facility is used then this will not be updated. Two
578
programs that can do this are pushd and popd. To update the prompt and
583
Note that if the previous entry on the stack is the current directory
584
then the stack is not updated.
588
cd [dir] [0-9] [@[s|h] [-g <dir>] [-d] [-D] [-r<n>]
589
[dir|0-9] [-R<n>] [<dir>|0-9] [-s<n>] [-S<n>]
590
[-u] [-U] [-f] [-F] [-h] [-H] [-v]
592
<dir> Go to directory
593
0-n Goto previous directory (0 is previous,
594
1 is last but 1, etc.)
595
n is up to max history (default is 50)
596
@ List history and special entries (Usually available as $ @)
597
@h List history entries
598
@s List special entries
599
-g [<dir>] Go to literal name (bypass special names)
600
This is to allow access to dirs called '0','1','-h' etc
601
-d Change default action - verbose. (See note)
602
-D Change default action - silent. (See note)
603
-s<n> Go to the special entry <n>
604
-S<n> Go to the special entry <n>
605
and replace it with the current dir
606
-r<n> [<dir>] Go to directory <dir>
607
and then put it on special entry <n>
608
-R<n> [<dir>] Go to directory <dir>
609
and put current dir on special entry <n>
610
-a<n> Alternative suggested directory. See note below.
611
-f [<file>] File entries to <file>.
612
-u [<file>] Update entries from <file>.
613
If no filename supplied then default file (~/cdfile) is used
614
-F and -U are silent versions
615
-v Print version number
624
These examples assume non-default mode is set (that is, cd with no
625
parameters will go to the most recent stack directory), that aliases
626
have been set up for cd and @ as described above and that cd's prompt
627
facility is active and the prompt length is 21 characters.
630
# List the entries with the @
632
# Output of the @ command
634
# Skipped these entries for brevity
635
1 /home/phil/ummdev S1 /home/phil/perl
636
# Most recent two history entries
637
0 /home/phil/perl/eg S0 /home/phil/umm/ummdev
638
# and two special entries are shown
640
/home/phil$ cd /home/phil/utils/Cdll
641
# Now change directories
642
/home/phil/utils/Cdll$ @
643
# Prompt reflects the directory.
647
1 /home/phil/perl/eg S1 /home/phil/perl
648
# History entry 0 has moved to 1
649
0 /home/phil S0 /home/phil/umm/ummdev
650
# and the most recent has entered
652
To go to a history entry:
654
/home/phil/utils/Cdll$ cd 1
655
# Go to history entry 1.
657
# Current directory is now what was 1
659
To go to a special entry:
661
/home/phil/perl/eg$ cd -s1
662
# Go to special entry 1
663
/home/phil/umm/ummdev$
664
# Current directory is S1
666
To go to a directory called, for example, 1:
669
# -g ignores the special meaning of 1
672
To put current directory on the special list as S1:
674
cd -R1 . # These have the same effect if the directory is
675
#+ . (the current directory)
677
To go to a directory and add it as a special
678
The directory for -r<n> or -R<n> may be a number.
680
$ cd -r3 4 Go to history entry 4 and put it on special entry 3
681
$ cd -R3 4 Put current dir on the special entry 3 and go to
683
$ cd -s3 Go to special entry 3
685
Note that commands R,r,S and s may be used without a number and
687
$ cd -s Go to special entry 0
688
$ cd -S Go to special entry 0 and make special entry 0
690
$ cd -r 1 Go to history entry 1 and put it on special entry 0
691
$ cd -r Go to history entry 0 and put it on special entry 0
694
Alternative suggested directories:
696
If a directory is not found, then CD will suggest any
697
possibilities. These are directories starting with the same letters
698
and if any are found they are listed prefixed with -a<n>
699
where <n> is a number. It's possible to go to the directory
700
by entering cd -a<n> on the command line.
702
Use cd -d or -D to change default cd action. cd -H will show
705
The history entries (0-n) are stored in the environment variables
707
Similarly the special directories S0 - 9 are in the environment
708
variable CDS[0] - CDS[9]
709
and may be accessed from the command line, for example:
712
cat ${CD[8]}/file.txt
714
The default pathname for the -f and -u commands is ~
715
The default filename for the -f and -u commands is cdfile
721
The following environment variables can be set:
723
CDL_PROMPTLEN - Set to the length of prompt you require.
724
Prompt string is set to the right characters of the current
725
directory. If not set, then prompt is left unchanged. Note
726
that this is the number of characters that the directory is
727
shortened to, not the total characters in the prompt.
729
CDL_PROMPT_PRE - Set to the string to prefix the prompt.
731
non-root: "\\[\\e[01;34m\\]" (sets colour to blue).
732
root: "\\[\\e[01;31m\\]" (sets colour to red).
734
CDL_PROMPT_POST - Set to the string to suffix the prompt.
736
non-root: "\\[\\e[00m\\]$"
737
(resets colour and displays $).
738
root: "\\[\\e[00m\\]#"
739
(resets colour and displays #).
742
CDL_PROMPT_PRE & _POST only t
744
CDPath - Set the default path for the -f & -u options.
745
Default is home directory
746
CDFile - Set the default filename for the -f & -u options.
750
There are three variables defined in the file cdll which control the
751
number of entries stored or displayed. They are in the section labeled
752
'Initialisation here' towards the end of the file.
754
cd_maxhistory - The number of history entries stored.
756
cd_maxspecial - The number of special entries allowed.
758
cd_histcount - The number of history and special entries
759
displayed. Default is 9.
761
Note that cd_maxspecial should be >= cd_histcount to avoid displaying
762
special entries that can't be set.
765
Version: 1.2.1 Date: 24-MAY-2003