package Psh
::Builtins
::Cd
;
require Psh
::Support
::Dirs
;
Change the working directory to DIR or home if DIR is not specified.
The special DIR "-" is interpreted as "return to the previous
C<cd %num> will jump to a certain directory in the stack (See also
C<cd +num> and C<cd -num> will go forward/backward in the directory
my $in_dir = shift || Psh
::OS
::get_home_dir
();
unless (@Psh::Support
::Dirs
::stack
) {
push @Psh::Support
::Dirs
::stack
, $ENV{PWD
};
if ($in_dir=~/^[+-](\d+)$/) {
my $tmp_pos=$Psh::Support
::Dirs
::stack_pos
-int($in_dir);
} elsif ($tmp_pos>$#Psh::Support
::Dirs
::stack
) {
$in_dir=$Psh::Support
::Dirs
::stack
[$tmp_pos];
$Psh::Support
::Dirs
::stack_pos
=$tmp_pos;
} elsif ($in_dir eq '-') {
if (@Psh::Support
::Dirs
::stack
>1) {
if ($Psh::Support
::Dirs
::stack_pos
==0) {
$in_dir=$Psh::Support
::Dirs
::stack
[1];
$Psh::Support
::Dirs
::stack_pos
=1;
$in_dir=$Psh::Support
::Dirs
::stack
[0];
$Psh::Support
::Dirs
::stack_pos
=0;
} elsif ($in_dir=~ /^\%(\d+)$/) {
if ($tmp_pos>$#Psh::Support
::Dirs
::stack
) {
$in_dir=$Psh::Support
::Dirs
::stack
[$tmp_pos];
$Psh::Support
::Dirs
::stack_pos
=$tmp_pos;
$explicit=1 unless $in_dir eq $Psh::Support
::Dirs
::stack
[0];
# Don't push the same value again
$Psh::Support
::Dirs
::stack_pos
=0;
if ($ENV{CDPATH
} && !Psh
::OS
::file_name_is_absolute
($in_dir)) {
foreach my $cdbase (split $Psh::OS
::PATH_SEPARATOR
,$dirpath) {
$dir = Psh
::Util
::abs_path
($dir);
$dir = Psh
::Util
::abs_path
(Psh
::OS
::catdir
($cdbase,$dir));
if ($dir and (-e
$dir) and (-d _
)) {
unshift @Psh::Support
::Dirs
::stack
, $dir if $explicit;
Psh
::Util
::print_error_i18n
('perm_denied',$in_dir,$Psh::bin
);
Psh
::Util
::print_error_i18n
('no_such_dir',$in_dir,$Psh::bin
);
my( $text, $pre, $start, $line, $startchar) = @_;
return 1,Psh
::Completion
::cmpl_directories
($pre.$text);