diff --git a/doc_src/cd.txt b/doc_src/cd.txt
index 3153c383d..a2cb95885 100644
--- a/doc_src/cd.txt
+++ b/doc_src/cd.txt
@@ -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 `/`).
-Fish also ships a wrapper function around `cd` that understands `cd -` as changing to the previous directory. See `prevd`.
+Fish also ships a wrapper function around the builtin `cd` that understands `cd -` as changing to the previous directory. See also `prevd`. This wrapper function maintains a history of the 25 most recently visited directories in the `$dirprev` and `$dirnext` global variables.
\subsection cd-example Examples
diff --git a/doc_src/dirh.txt b/doc_src/dirh.txt
index d25b9c2ad..77e03e185 100644
--- a/doc_src/dirh.txt
+++ b/doc_src/dirh.txt
@@ -10,3 +10,5 @@ dirh
`dirh` prints the current directory history. The current position in the history is highlighted using the color defined in the `fish_color_history_current` environment variable.
`dirh` does not accept any parameters.
+
+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.
diff --git a/doc_src/nextd.txt b/doc_src/nextd.txt
index 8d7c90350..e02598a9b 100644
--- a/doc_src/nextd.txt
+++ b/doc_src/nextd.txt
@@ -11,6 +11,7 @@ nextd [ -l | --list ] [POS]
If the `-l` or `--list` flag is specified, the current directory 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.
\subsection nextd-example Example
diff --git a/doc_src/prevd.txt b/doc_src/prevd.txt
index cd0c99ac4..f1e9e6cb3 100644
--- a/doc_src/prevd.txt
+++ b/doc_src/prevd.txt
@@ -11,6 +11,7 @@ prevd [ -l | --list ] [POS]
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.
\subsection prevd-example Example
diff --git a/share/functions/cd.fish b/share/functions/cd.fish
index 8faa469d7..a1b6b2ac9 100644
--- a/share/functions/cd.fish
+++ b/share/functions/cd.fish
@@ -1,36 +1,41 @@
#
-# The following functions add support for a directory history
+# Wrap the builtin cd command to maintain directory history.
#
-
function cd --description "Change directory"
+ set -l MAX_DIR_HIST 25
- # Skip history in subshells
- if status --is-command-substitution
- builtin cd $argv
- return $status
- end
+ if test (count $argv) -gt 1
+ printf "%s\n" (_ "Too many args for cd command")
+ return 1
+ end
- # Avoid set completions
- set -l previous $PWD
+ # Skip history in subshells.
+ if status --is-command-substitution
+ builtin cd $argv
+ return $status
+ end
- if test $argv[1] = - ^/dev/null
- if test "$__fish_cd_direction" = next ^/dev/null
- nextd
- else
- prevd
- end
- return $status
- end
+ # Avoid set completions
+ set -l previous $PWD
- builtin cd $argv[1]
- set -l cd_status $status
+ if test "$argv" = "-"
+ if test "$__fish_cd_direction" = "next"
+ nextd
+ else
+ prevd
+ end
+ return $status
+ end
- if test $cd_status = 0 -a "$PWD" != "$previous"
- set -g dirprev $dirprev $previous
- set -e dirnext
- set -g __fish_cd_direction prev
- end
+ builtin cd $argv
+ set -l cd_status $status
- return $cd_status
+ if test $cd_status -eq 0 -a "$PWD" != "$previous"
+ set -q dirprev[$MAX_DIR_HIST]; and set -e dirprev[1]
+ set -g dirprev $dirprev $previous
+ set -e dirnext
+ set -g __fish_cd_direction prev
+ end
+
+ return $cd_status
end
-