Variable: shell-dirtrack-mode
shell-dirtrack-mode is a buffer-local variable defined in shell.el.gz.
Documentation
Non-nil if Shell-Dirtrack mode is enabled.
Use the command shell-dirtrack-mode(var)/shell-dirtrack-mode(fun) to change this variable.
Probably introduced at or before Emacs version 22.2.
Key Bindings
Aliases
Source Code
;; Defined in /usr/src/emacs/lisp/shell.el.gz
;;; Directory tracking
;;
;; This code provides the shell mode input sentinel
;; SHELL-DIRECTORY-TRACKER
;; that tracks cd, pushd, and popd commands issued to the shell, and
;; changes the current directory of the shell buffer accordingly.
;;
;; This is basically a fragile hack. It has the following failings:
;; 1. It doesn't know about the cdpath shell variable.
;; 2. It cannot infallibly deal with command sequences, though it does well
;; with these and with ignoring commands forked in another shell with ()s.
;; 3. More generally, any complex command is going to throw it. Otherwise,
;; you'd have to build an entire shell interpreter in Emacs Lisp. Failing
;; that, there's no way to catch shell commands where cd's are buried
;; inside conditional expressions, aliases, and so forth.
;;
;; The whole approach is a crock. Shell aliases mess it up. File sourcing
;; messes it up. You run other processes under the shell; these each have
;; separate working directories, and some have commands for manipulating
;; their w.d.'s (e.g., the lcd command in ftp). Some of these programs have
;; commands that do *not* affect the current w.d. at all, but look like they
;; do (e.g., the cd command in ftp). In shells that allow you job
;; control, you can switch between jobs, all having different w.d.'s. So
;; simply saying %3 can shift your w.d..
;;
;; The solution is to relax, not stress out about it, and settle for
;; a hack that works pretty well in typical circumstances. Remember
;; that a half-assed solution is more in keeping with the spirit of Unix,
;; anyway. Blech.
;;
;; One good hack not implemented here for users of programmable shells
;; is to program up the shell w.d. manipulation commands to output
;; a coded command sequence to the tty. Something like
;; ESC | <cwd> |
;; where <cwd> is the new current working directory. Then trash the
;; directory tracking machinery currently used in this package, and
;; replace it with a process filter that watches for and strips out
;; these messages.
(define-minor-mode shell-dirtrack-mode
"Toggle directory tracking in this shell buffer (Shell Dirtrack mode).
This assigns a buffer-local non-nil value to `shell-dirtrackp'.
The `dirtrack' package provides an alternative implementation of
this feature; see the function `dirtrack-mode'. Also see
`comint-osc-directory-tracker' for an escape-sequence based
solution."
:lighter nil
:interactive (shell-mode)
(setq list-buffers-directory (if shell-dirtrack-mode default-directory))
(if shell-dirtrack-mode
(add-hook 'comint-input-filter-functions #'shell-directory-tracker nil t)
(remove-hook 'comint-input-filter-functions #'shell-directory-tracker t)))