mirror of
https://github.com/fish-shell/fish-shell
synced 2024-12-25 20:33:08 +00:00
parent
6b92f830ff
commit
8cc4639ea6
9 changed files with 139 additions and 1 deletions
|
@ -8,6 +8,7 @@
|
||||||
- `string unescape` has been implemented to reverse the effects of `string escape` (#3543).
|
- `string unescape` has been implemented to reverse the effects of `string escape` (#3543).
|
||||||
- The history file can now be specified by setting the `FISH_HISTORY` variable (#102).
|
- The history file can now be specified by setting the `FISH_HISTORY` variable (#102).
|
||||||
- Read history is now controlled by the `FISH_HISTORY` variable rather than the `--mode-name` flag (#1504).
|
- Read history is now controlled by the `FISH_HISTORY` variable rather than the `--mode-name` flag (#1504).
|
||||||
|
- Implement a `cdh` (change directory using recent history) command to provide a more friendly alternative to prevd/nextd and pushd/popd (#2847).
|
||||||
|
|
||||||
## Other significant changes
|
## Other significant changes
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,7 @@ If `DIRECTORY` is a relative path, the paths found in the `CDPATH` environment v
|
||||||
|
|
||||||
Note that the shell will attempt to change directory without requiring `cd` if the name of a directory is provided (starting with `.`, `/` or `~`, or ending with `/`).
|
Note that the shell will attempt to change directory without requiring `cd` if the name of a directory is provided (starting with `.`, `/` or `~`, or ending with `/`).
|
||||||
|
|
||||||
Fish also ships a wrapper function around the builtin `cd` that understands `cd -` as changing to the previous directory. See also <a href="commands.html#prevd">`prevd`</a>. This wrapper function maintains a history of the 25 most recently visited directories in the `$dirprev` and `$dirnext` global variables.
|
Fish also ships a wrapper function around the builtin `cd` that understands `cd -` as changing to the previous directory. See also <a href="commands.html#prevd">`prevd`</a>. This wrapper function maintains a history of the 25 most recently visited directories in the `$dirprev` and `$dirnext` global variables. If you make those universal variables your `cd` history is shared among all fish instances.
|
||||||
|
|
||||||
\subsection cd-example Examples
|
\subsection cd-example Examples
|
||||||
|
|
||||||
|
@ -25,3 +25,7 @@ cd
|
||||||
cd /usr/src/fish-shell
|
cd /usr/src/fish-shell
|
||||||
# changes the working directory to /usr/src/fish-shell
|
# changes the working directory to /usr/src/fish-shell
|
||||||
\endfish
|
\endfish
|
||||||
|
|
||||||
|
\subsection cd-see-also See Also
|
||||||
|
|
||||||
|
See also the <a href="commands.html#cdh">`cdh`</a> command for changing to a recently visited directory.
|
||||||
|
|
16
doc_src/cdh.txt
Normal file
16
doc_src/cdh.txt
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
\section cdh cdh - change to a recently visited directory
|
||||||
|
|
||||||
|
\subsection cdh-synopsis Synopsis
|
||||||
|
\fish{synopsis}
|
||||||
|
cdh [ directory ]
|
||||||
|
\endfish
|
||||||
|
|
||||||
|
\subsection cdh-description Description
|
||||||
|
|
||||||
|
`cdh` with no arguments presents a list of recently visited directories. You can then select one of the entries by letter or number. You can also press @key{tab} to use the completion pager to select an item from the list. If you give it a single argument it is equivalent to `cd directory`.
|
||||||
|
|
||||||
|
Note that the `cd` command limits directory history to the 25 most recently visited directories. The history is stored in the `$dirprev` and `$dirnext` variables which this command manipulates. If you make those universal variables your `cd` history is shared among all fish instances.
|
||||||
|
|
||||||
|
\subsection cdh-see-also See Also
|
||||||
|
|
||||||
|
See also the <a href="commands.html#prevd">`prevd`</a> and <a href="commands.html#pushd">`pushd`</a> commands which also work with the recent `cd` history and are provided for compatibility with other shells.
|
|
@ -13,6 +13,8 @@ If the `-l` or `--list` flag is specified, the current directory history is also
|
||||||
|
|
||||||
Note that the `cd` command limits directory history to the 25 most recently visited directories. The history is stored in the `$dirprev` and `$dirnext` variables which this command manipulates.
|
Note that the `cd` command limits directory history to the 25 most recently visited directories. The history is stored in the `$dirprev` and `$dirnext` variables which this command manipulates.
|
||||||
|
|
||||||
|
You may be interested in the <a href="commands.html#cdh">`cdh`</a> command which provides a more intuitive way to navigate to recently visited directories.
|
||||||
|
|
||||||
\subsection nextd-example Example
|
\subsection nextd-example Example
|
||||||
|
|
||||||
\fish
|
\fish
|
||||||
|
|
|
@ -9,6 +9,7 @@ popd
|
||||||
|
|
||||||
`popd` removes the top directory from the directory stack and changes the working directory to the new top directory. Use <a href="#pushd">`pushd`</a> to add directories to the stack.
|
`popd` removes the top directory from the directory stack and changes the working directory to the new top directory. Use <a href="#pushd">`pushd`</a> to add directories to the stack.
|
||||||
|
|
||||||
|
You may be interested in the <a href="commands.html#cdh">`cdh`</a> command which provides a more intuitive way to navigate to recently visited directories.
|
||||||
|
|
||||||
\subsection popd-example Example
|
\subsection popd-example Example
|
||||||
|
|
||||||
|
|
|
@ -13,6 +13,8 @@ If the `-l` or `--list` flag is specified, the current history is also displayed
|
||||||
|
|
||||||
Note that the `cd` command limits directory history to the 25 most recently visited directories. The history is stored in the `$dirprev` and `$dirnext` variables which this command manipulates.
|
Note that the `cd` command limits directory history to the 25 most recently visited directories. The history is stored in the `$dirprev` and `$dirnext` variables which this command manipulates.
|
||||||
|
|
||||||
|
You may be interested in the <a href="commands.html#cdh">`cdh`</a> command which provides a more intuitive way to navigate to recently visited directories.
|
||||||
|
|
||||||
\subsection prevd-example Example
|
\subsection prevd-example Example
|
||||||
|
|
||||||
\fish
|
\fish
|
||||||
|
|
|
@ -17,6 +17,8 @@ Without arguments, it exchanges the top two directories in the stack.
|
||||||
|
|
||||||
See also `dirs` and `dirs -c`.
|
See also `dirs` and `dirs -c`.
|
||||||
|
|
||||||
|
You may be interested in the <a href="commands.html#cdh">`cdh`</a> command which provides a more intuitive way to navigate to recently visited directories.
|
||||||
|
|
||||||
\subsection pushd-example Example
|
\subsection pushd-example Example
|
||||||
|
|
||||||
\fish
|
\fish
|
||||||
|
|
23
share/completions/cdh.fish
Normal file
23
share/completions/cdh.fish
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
function __fish_cdh_args
|
||||||
|
set -l all_dirs $dirprev $dirnext
|
||||||
|
set -l uniq_dirs
|
||||||
|
|
||||||
|
# This next bit of code doesn't do anything useful at the moment since the fish pager always
|
||||||
|
# sorts, and eliminates duplicate, entries. But we do this to mimic the modal behavor of `cdh`
|
||||||
|
# and in hope that the fish pager behavior will be changed to preserve the order of entries.
|
||||||
|
for dir in $all_dirs[-1..1]
|
||||||
|
if not contains $dir $uniq_dirs
|
||||||
|
set uniq_dirs $uniq_dirs $dir
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
for dir in $uniq_dirs
|
||||||
|
set -l home_dir (string match -r "$HOME(/.*|\$)" "$dir")
|
||||||
|
if set -q home_dir[2]
|
||||||
|
set dir "~$home_dir[2]"
|
||||||
|
end
|
||||||
|
echo $dir
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
complete -c cdh -xa '(__fish_cdh_args)'
|
87
share/functions/cdh.fish
Normal file
87
share/functions/cdh.fish
Normal file
|
@ -0,0 +1,87 @@
|
||||||
|
# Provide a menu of the directories recently navigated to and ask the user to
|
||||||
|
# choose one to make the new current working directory (cwd).
|
||||||
|
|
||||||
|
function cdh --description "Menu based cd command"
|
||||||
|
# See if we've been invoked with an argument. Presumably from the `cdh` completion script.
|
||||||
|
# If we have just treat it as `cd` to the specified directory.
|
||||||
|
if set -q argv[1]
|
||||||
|
cd $argv
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
if set -q argv[2]
|
||||||
|
echo (_ "cdh: Expected zero or one arguments") >&2
|
||||||
|
return 1
|
||||||
|
end
|
||||||
|
|
||||||
|
set -l all_dirs $dirprev $dirnext
|
||||||
|
if not set -q all_dirs[1]
|
||||||
|
echo (_ 'No previous directories to select. You have to cd at least once.') >&2
|
||||||
|
return 0
|
||||||
|
end
|
||||||
|
|
||||||
|
# Reverse the directories so the most recently visited is first in the list.
|
||||||
|
# Also, eliminate duplicates; i.e., we only want the most recent visit to a
|
||||||
|
# given directory in the selection list.
|
||||||
|
set -l uniq_dirs
|
||||||
|
for dir in $all_dirs[-1..1]
|
||||||
|
if not contains $dir $uniq_dirs
|
||||||
|
set uniq_dirs $uniq_dirs $dir
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
set -l letters a b c d e f g h i j k l m n o p q r s t u v w x y z
|
||||||
|
set -l dirc (count $uniq_dirs)
|
||||||
|
if test $dirc -gt (count $letters)
|
||||||
|
set -l msg (_ 'This should not happen. Have you changed the cd function?')
|
||||||
|
printf "$msg\n"
|
||||||
|
set -l msg (_ 'There are %s unique dirs in your history but I can only handle %s')
|
||||||
|
printf "$msg\n" $dirc (count $letters)
|
||||||
|
return 1
|
||||||
|
end
|
||||||
|
|
||||||
|
# Print the recent directories, oldest to newest. Since we previously
|
||||||
|
# reversed the list, making the newest entry the first item in the array,
|
||||||
|
# we count down rather than up.
|
||||||
|
for i in (seq $dirc -1 1)
|
||||||
|
set -l dir $uniq_dirs[$i]
|
||||||
|
set -l label_color normal
|
||||||
|
set -q fish_color_cwd; and set label_color $fish_color_cwd
|
||||||
|
set -l dir_color_reset (set_color normal)
|
||||||
|
set -l dir_color
|
||||||
|
if test "$dir" = "$PWD"
|
||||||
|
set dir_color (set_color $fish_color_history_current)
|
||||||
|
end
|
||||||
|
|
||||||
|
set -l home_dir (string match -r "$HOME(/.*|\$)" "$dir")
|
||||||
|
if set -q home_dir[2]
|
||||||
|
set dir "~$home_dir[2]"
|
||||||
|
end
|
||||||
|
printf '%s %s %2d) %s %s%s%s\n' (set_color $label_color) $letters[$i] \
|
||||||
|
$i (set_color normal) $dir_color $dir $dir_color_reset
|
||||||
|
end
|
||||||
|
|
||||||
|
# Ask the user which directory from their history they want to cd to.
|
||||||
|
set -l msg (_ 'Select directory by letter or number: ')
|
||||||
|
read -l -p "echo '$msg'" choice
|
||||||
|
if test "$choice" = ""
|
||||||
|
return 0
|
||||||
|
else if string match -q -r '^[a-z]$' $choice
|
||||||
|
# Convert the letter to an index number.
|
||||||
|
set choice (contains -i $choice $letters)
|
||||||
|
end
|
||||||
|
|
||||||
|
set -l msg (_ 'Error: expected a number between 1 and %d or letter in that range, got "%s"')
|
||||||
|
if string match -q -r '^\d+$' $choice
|
||||||
|
if test $choice -ge 1 -a $choice -le $dirc
|
||||||
|
cd $uniq_dirs[$choice]
|
||||||
|
return
|
||||||
|
else
|
||||||
|
printf "$msg\n" $dirc $choice
|
||||||
|
return 1
|
||||||
|
end
|
||||||
|
else
|
||||||
|
printf "$msg\n" $dirc $choice
|
||||||
|
return 1
|
||||||
|
end
|
||||||
|
end
|
Loading…
Reference in a new issue