1
0
mirror of https://git.savannah.gnu.org/git/emacs.git synced 2024-11-23 07:19:15 +00:00

(shell-dirtrack-mode): Make it into a proper minor mode, so

we can explicitly enable/disable rather than toggle.
(shell-mode): Use it.
(shell-cd): Don't try to reproduce what `cd' does.
This commit is contained in:
Stefan Monnier 2006-05-17 21:57:25 +00:00
parent 2d38f869f6
commit 05327ca972
2 changed files with 88 additions and 83 deletions

View File

@ -1,6 +1,14 @@
2006-05-17 Stefan Monnier <monnier@iro.umontreal.ca>
* shell.el (shell-dirtrack-mode): Make it into a proper minor mode, so
we can explicitly enable/disable rather than toggle.
(shell-mode): Use it.
(shell-cd): Don't try to reproduce what `cd' does.
2006-05-17 Kim F. Storm <storm@cua.dk>
* ido.el (ido-read-internal): Use only nondirectory part of default item.
* ido.el (ido-read-internal): Use only nondirectory part of
default item.
2006-05-17 Thien-Thi Nguyen <ttn@gnu.org>

View File

@ -150,7 +150,7 @@ This is a fine thing to set in your `.emacs' file."
:group 'shell)
(defcustom shell-completion-fignore nil
"*List of suffixes to be disregarded during file/command completion.
"List of suffixes to be disregarded during file/command completion.
This variable is used to initialize `comint-completion-fignore' in the shell
buffer. The default is nil, for compatibility with most shells.
Some people like (\"~\" \"#\" \"%\").
@ -199,19 +199,19 @@ shell buffer.
This is a fine thing to set in your `.emacs' file.")
(defcustom shell-command-regexp "[^;&|\n]+"
"*Regexp to match a single command within a pipeline.
"Regexp to match a single command within a pipeline.
This is used for directory tracking and does not do a perfect job."
:type 'regexp
:group 'shell)
(defcustom shell-command-separator-regexp "[;&|\n \t]*"
"*Regexp to match a single command within a pipeline.
"Regexp to match a single command within a pipeline.
This is used for directory tracking and does not do a perfect job."
:type 'regexp
:group 'shell)
(defcustom shell-completion-execonly t
"*If non-nil, use executable files only for completion candidates.
"If non-nil, use executable files only for completion candidates.
This mirrors the optional behavior of tcsh.
Detecting executability of files may slow command completion considerably."
@ -219,35 +219,35 @@ Detecting executability of files may slow command completion considerably."
:group 'shell)
(defcustom shell-popd-regexp "popd"
"*Regexp to match subshell commands equivalent to popd."
"Regexp to match subshell commands equivalent to popd."
:type 'regexp
:group 'shell-directories)
(defcustom shell-pushd-regexp "pushd"
"*Regexp to match subshell commands equivalent to pushd."
"Regexp to match subshell commands equivalent to pushd."
:type 'regexp
:group 'shell-directories)
(defcustom shell-pushd-tohome nil
"*If non-nil, make pushd with no arg behave as \"pushd ~\" (like cd).
"If non-nil, make pushd with no arg behave as \"pushd ~\" (like cd).
This mirrors the optional behavior of tcsh."
:type 'boolean
:group 'shell-directories)
(defcustom shell-pushd-dextract nil
"*If non-nil, make \"pushd +n\" pop the nth dir to the stack top.
"If non-nil, make \"pushd +n\" pop the nth dir to the stack top.
This mirrors the optional behavior of tcsh."
:type 'boolean
:group 'shell-directories)
(defcustom shell-pushd-dunique nil
"*If non-nil, make pushd only add unique directories to the stack.
"If non-nil, make pushd only add unique directories to the stack.
This mirrors the optional behavior of tcsh."
:type 'boolean
:group 'shell-directories)
(defcustom shell-cd-regexp "cd"
"*Regexp to match subshell commands equivalent to cd."
"Regexp to match subshell commands equivalent to cd."
:type 'regexp
:group 'shell-directories)
@ -256,19 +256,19 @@ This mirrors the optional behavior of tcsh."
; NetWare allows the five chars between upper and lower alphabetics.
"[]a-zA-Z^_`\\[\\\\]:"
nil)
"*If non-nil, is regexp used to track drive changes."
"If non-nil, is regexp used to track drive changes."
:type '(choice regexp
(const nil))
:group 'shell-directories)
(defcustom shell-dirtrack-verbose t
"*If non-nil, show the directory stack following directory change.
"If non-nil, show the directory stack following directory change.
This is effective only if directory tracking is enabled."
:type 'boolean
:group 'shell-directories)
(defcustom explicit-shell-file-name nil
"*If non-nil, is file name to use for explicitly requested inferior shell."
"If non-nil, is file name to use for explicitly requested inferior shell."
:type '(choice (const :tag "None" nil) file)
:group 'shell)
@ -278,7 +278,7 @@ This is effective only if directory tracking is enabled."
;; than us about what terminal modes to use.
'("-i" "-T")
'("-i"))
"*Args passed to inferior shell by M-x shell, if the shell is csh.
"Args passed to inferior shell by \\[shell], if the shell is csh.
Value is a list of strings, which may be nil."
:type '(repeat (string :tag "Argument"))
:group 'shell)
@ -296,13 +296,13 @@ Value is a list of strings, which may be nil."
(shell-command-to-string (concat prog " --noediting"))))
'("-i")
'("--noediting" "-i")))
"*Args passed to inferior shell by M-x shell, if the shell is bash.
"Args passed to inferior shell by \\[shell], if the shell is bash.
Value is a list of strings, which may be nil."
:type '(repeat (string :tag "Argument"))
:group 'shell)
(defcustom shell-input-autoexpand 'history
"*If non-nil, expand input command history references on completion.
"If non-nil, expand input command history references on completion.
This mirrors the optional behavior of tcsh (its autoexpand and histlit).
If the value is `input', then the expansion is seen on input.
@ -433,9 +433,7 @@ buffer."
(setq shell-dirstack nil)
(make-local-variable 'shell-last-dir)
(setq shell-last-dir nil)
(make-local-variable 'shell-dirtrackp)
(setq shell-dirtrackp t)
(add-hook 'comint-input-filter-functions 'shell-directory-tracker nil t)
(shell-dirtrack-mode 1)
(setq comint-input-autoexpand shell-input-autoexpand)
;; This is not really correct, since the shell buffer does not really
;; edit this directory. But it is useful in the buffer list and menus.
@ -558,48 +556,48 @@ Otherwise, one argument `-i' is passed to the shell.
(shell-mode)))
buffer)
;;; Don't do this when shell.el is loaded, only while dumping.
;; Don't do this when shell.el is loaded, only while dumping.
;;;###autoload (add-hook 'same-window-buffer-names "*shell*")
;;; 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, although it's more accurate than
;;; the version in Emacs 18's shell.el. 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.
;;
;; 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, although it's more accurate than
;; the version in Emacs 18's shell.el. 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.
(defun shell-directory-tracker (str)
"Tracks cd, pushd and popd commands issued to the shell.
@ -607,8 +605,8 @@ This function is called on each input passed to the shell.
It watches for cd, pushd and popd commands and sets the buffer's
default directory to track these commands.
You may toggle this tracking on and off with M-x dirtrack-mode.
If Emacs gets confused, you can resync with the shell with M-x dirs.
You may toggle this tracking on and off with \\[dirtrack-mode].
If Emacs gets confused, you can resync with the shell with \\[dirs].
See variables `shell-cd-regexp', `shell-chdrive-regexp', `shell-pushd-regexp',
and `shell-popd-regexp', while `shell-pushd-tohome', `shell-pushd-dextract',
@ -677,7 +675,7 @@ Environment variables are expanded, see function `substitute-in-file-name'."
(setq string (replace-match "" nil nil string)))))
string)))
;;; popd [+n]
;; popd [+n]
(defun shell-process-popd (arg)
(let ((num (or (shell-extract-num arg) 0)))
(cond ((and num (= num 0) shell-dirstack)
@ -703,7 +701,7 @@ Environment variables are expanded, see function `substitute-in-file-name'."
;; For relative name we assume default-directory already has the prefix.
(expand-file-name dir))))
;;; cd [dir]
;; cd [dir]
(defun shell-process-cd (arg)
(let ((new-dir (cond ((zerop (length arg)) (concat comint-file-name-prefix
"~"))
@ -713,7 +711,7 @@ Environment variables are expanded, see function `substitute-in-file-name'."
(shell-cd new-dir)
(shell-dirstack-message)))
;;; pushd [+n | dir]
;; pushd [+n | dir]
(defun shell-process-pushd (arg)
(let ((num (shell-extract-num arg)))
(cond ((zerop (length arg))
@ -762,26 +760,25 @@ Environment variables are expanded, see function `substitute-in-file-name'."
(and (string-match "^\\+[1-9][0-9]*$" str)
(string-to-number str)))
(defun shell-dirtrack-mode ()
(defvaralias 'shell-dirtrack-mode 'shell-dirtrackp)
(define-minor-mode shell-dirtrack-mode
"Turn directory tracking on and off in a shell buffer."
(interactive)
(if (setq shell-dirtrackp (not shell-dirtrackp))
(setq list-buffers-directory default-directory)
(setq list-buffers-directory nil))
(message "Directory tracking %s" (if shell-dirtrackp "ON" "OFF")))
nil nil nil
(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)))
;;; For your typing convenience:
(defalias 'shell-dirtrack-toggle 'shell-dirtrack-mode)
;; For your typing convenience:
(defalias 'shell-dirtrack-toggle 'shell-dirtrack-mode) ;??Convenience??
(defalias 'dirtrack-toggle 'shell-dirtrack-mode)
(defalias 'dirtrack-mode 'shell-dirtrack-mode)
(defun shell-cd (dir)
"Do normal `cd' to DIR, and set `list-buffers-directory'."
(cd dir)
(if shell-dirtrackp
(setq list-buffers-directory (file-name-as-directory
(expand-file-name dir))))
(cd dir))
(setq list-buffers-directory default-directory)))
(defun shell-resync-dirs ()
"Resync the buffer's idea of the current directory stack.
@ -841,15 +838,15 @@ command again."
(shell-dirstack-message))
(error (message "Couldn't cd")))))))
;;; For your typing convenience:
;; For your typing convenience:
(defalias 'dirs 'shell-resync-dirs)
;;; Show the current dirstack on the message line.
;;; Pretty up dirs a bit by changing "/usr/jqr/foo" to "~/foo".
;;; (This isn't necessary if the dirlisting is generated with a simple "dirs".)
;;; All the commands that mung the buffer's dirstack finish by calling
;;; this guy.
;; Show the current dirstack on the message line.
;; Pretty up dirs a bit by changing "/usr/jqr/foo" to "~/foo".
;; (This isn't necessary if the dirlisting is generated with a simple "dirs".)
;; All the commands that mung the buffer's dirstack finish by calling
;; this guy.
(defun shell-dirstack-message ()
(when shell-dirtrack-verbose
(let* ((msg "")
@ -1076,5 +1073,5 @@ Returns t if successful."
(provide 'shell)
;;; arch-tag: bcb5f12a-c1f4-4aea-a809-2504bd5bd797
;; arch-tag: bcb5f12a-c1f4-4aea-a809-2504bd5bd797
;;; shell.el ends here