From 78835dd0546b7c724e82826b7a0897f9497e6ad4 Mon Sep 17 00:00:00 2001 From: Stefan Monnier Date: Fri, 12 Nov 2010 09:13:48 -0500 Subject: [PATCH] * lisp/shell.el (shell-dir-cookie-re): New custom variable. (shell-dir-cookie-watcher): New function. --- etc/NEWS | 5 +++-- lisp/ChangeLog | 3 +++ lisp/shell.el | 29 +++++++++++++++++++++++++++++ 3 files changed, 35 insertions(+), 2 deletions(-) diff --git a/etc/NEWS b/etc/NEWS index aab6cf98eb0..4ab97b32b16 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -289,6 +289,9 @@ set `x-select-enable-clipboard' to nil. * 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 diff --git a/lisp/ChangeLog b/lisp/ChangeLog index d7388d5b4f8..822af9becc3 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -1,5 +1,8 @@ 2010-11-12 Stefan Monnier + * 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). diff --git a/lisp/shell.el b/lisp/shell.el index 75040305528..7771c0d1c4f 100644 --- a/lisp/shell.el +++ b/lisp/shell.el @@ -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. -- 2.11.4.GIT