changeset 70691:a69f2db3d3ae

(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.
author Stefan Monnier <monnier@iro.umontreal.ca>
date Wed, 17 May 2006 21:57:25 +0000
parents 8fd6ecfbe6ea
children f03812b51969
files lisp/ChangeLog lisp/shell.el
diffstat 2 files changed, 88 insertions(+), 83 deletions(-) [+]
line wrap: on
line diff
--- a/lisp/ChangeLog	Wed May 17 21:25:59 2006 +0000
+++ b/lisp/ChangeLog	Wed May 17 21:57:25 2006 +0000
@@ -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>
 
--- a/lisp/shell.el	Wed May 17 21:25:59 2006 +0000
+++ b/lisp/shell.el	Wed May 17 21:57:25 2006 +0000
@@ -150,7 +150,7 @@
   :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 @@
 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 @@
   :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 @@
       ; 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 @@
       ;; 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 @@
 			   (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 @@
   (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 @@
       (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 @@
 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 @@
 	       (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 @@
       ;; 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 @@
     (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 @@
   (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 @@
 		   (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 @@
 
 (provide 'shell)
 
-;;; arch-tag: bcb5f12a-c1f4-4aea-a809-2504bd5bd797
+;; arch-tag: bcb5f12a-c1f4-4aea-a809-2504bd5bd797
 ;;; shell.el ends here