]> git.eshelyaron.com Git - emacs.git/commitdiff
* lisp/shell.el (shell-dir-cookie-re): New custom variable.
authorStefan Monnier <monnier@iro.umontreal.ca>
Fri, 12 Nov 2010 14:13:48 +0000 (09:13 -0500)
committerStefan Monnier <monnier@iro.umontreal.ca>
Fri, 12 Nov 2010 14:13:48 +0000 (09:13 -0500)
(shell-dir-cookie-watcher): New function.

etc/NEWS
lisp/ChangeLog
lisp/shell.el

index aab6cf98eb0306d356a50e549d5b2451b17dd980..4ab97b32b16282654565030d6a83ced9d89614df 100644 (file)
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -289,6 +289,9 @@ set `x-select-enable-clipboard' to nil.
 \f
 * Changes in Specialized Modes and Packages in Emacs 24.1
 
+** shell-mode can track your cwd by reading it from your prompt.
+Just set shell-dir-cookie-re to an appropriate regexp.
+
 ** Modula-2 mode provides auto-indentation.
 
 ** latex-electric-env-pair-mode keeps \begin..\end matched on the fly.
@@ -529,8 +532,6 @@ system or session bus.
 
 ** pcase.el provides the ML-style pattern matching macro `pcase'.
 
-** smie.el is a package providing a simple generic indentation engine.
-
 ** secrets.el is an implementation of the Secret Service API, an
 interface to password managers like GNOME Keyring or KDE Wallet.  The
 Secret Service API requires D-Bus for communication.  The command
index d7388d5b4f89937e2b6f2db094f7f0a7e1e96601..822af9becc3fb3a02d982b62bfc95acc18ef643e 100644 (file)
@@ -1,5 +1,8 @@
 2010-11-12  Stefan Monnier  <monnier@iro.umontreal.ca>
 
+       * shell.el (shell-dir-cookie-re): New custom variable.
+       (shell-dir-cookie-watcher): New function.
+
        * vc/vc.el (vc-deduce-backend): Use default-directory in shell-mode
        and compilation-mode (bug#7350).
 
index 7504030552849597e3736677bed9282af9b03deb..7771c0d1c4fbb898f9b216e12a1fc57a6427195d 100644 (file)
@@ -472,6 +472,10 @@ buffer."
       (when (string-equal shell "bash")
         (add-hook 'comint-output-filter-functions
                   'shell-filter-ctrl-a-ctrl-b nil t)))
+    (when shell-dir-cookie-re
+      ;; Watch for magic cookies in the output to track the current dir.
+      (add-hook 'comint-output-filter-functions
+               'shell-dir-cookie-watcher nil t))
     (comint-read-input-ring t)))
 
 (defun shell-filter-ctrl-a-ctrl-b (string)
@@ -619,6 +623,31 @@ Otherwise, one argument `-i' is passed to the shell.
 ;; replace it with a process filter that watches for and strips out
 ;; these messages.
 
+(defcustom shell-dir-cookie-re nil
+  "Regexp matching your prompt, including some part of the current directory.
+If your prompt includes the current directory or the last few elements of it,
+set this to a pattern that matches your prompt and whose subgroup 1 matches
+the directory part of it.
+This is used by `shell-dir-cookie-watcher' to try and use this info
+to track your current directory.  It can be used instead of or in addition
+to `dirtrack-mode'."
+  :type '(choice (const nil) regexp))
+
+(defun shell-dir-cookie-watcher (text)
+  ;; This is fragile: the TEXT could be split into several chunks and we'd
+  ;; miss it.  Oh well.  It's a best effort anyway.  I'd expect that it's
+  ;; rather unusual to have the prompt split into several packets, but
+  ;; I'm sure Murphy will prove me wrong.
+  (when (and shell-dir-cookie-re (string-match shell-dir-cookie-re text))
+    (let ((dir (match-string 1 text)))
+      (cond
+       ((file-name-absolute-p dir) (shell-cd dir))
+       ;; Let's try and see if it seems to be up or down from where we were.
+       ((string-match "\\`\\(.*\\)\\(?:/.*\\)?\n\\(.*/\\)\\1\\(?:/.*\\)?\\'"
+                     (setq text (concat dir "\n" default-directory)))
+       (shell-cd (concat (match-string 2 text) dir)))))))
+       
+
 (defun shell-directory-tracker (str)
   "Tracks cd, pushd and popd commands issued to the shell.
 This function is called on each input passed to the shell.