help-gnu-emacs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: file name Completion in Shell (cmd.exe) on Emacs (MS Windows)


From: Sandip Chitale
Subject: Re: file name Completion in Shell (cmd.exe) on Emacs (MS Windows)
Date: Fri, 23 Jul 2004 09:51:26 -0700

<address@hidden> wrote in message news:address@hidden
>
> "SC" == Sandip Chitale <address@hidden> writes:
>  SC> Date: Wed, 21 Jul 2004 10:47:14 -0700
>
> 8<--------------------------------------------------------------------
>
>  SC> The shell.el has a concept of shell-chdrive-regexp which is used to
detect
>  SC> drive switching commands. However it seems that its use is not being
fully
>  SC> implemented. Kind of makes sense...people use emacs on Windows to get
away
>  SC> from Windows ;)
>
> hi,
>
> i stepped through the relevant function shell-directory-tracker with
> edebug.
>
> it finally calls the function error an returns "Couldn't cd".
>
> martin

Yes. I had traced the problem to that also. It seems to be a problem with:

file-name-absolute-p

which returns false for "<drive letter>:". Thus cd fails with "Couldn't cd"
error.

Even if "cd" had worked correctly it would still be wrong because it would
have made
default-directory as the root of that drive and not the last "current"
directory on that drive.
So basically what need to happen is that shell.el needs to keep track for
current directory before
switching the drive in some kind of buffer local association list e.g.

(("d:" . "d:/") ("x:" . "x:/") ("c:" . "c:/emacs/lisp/"))

And, after switching the drive set the default-directory to the value (dir)
for the drive key in the association list.
Of course, if the value is not found in the association list
default-directory is set to root of the drive.

This is what I have done in my locally hacked shell.el and it works great.

Here are relevant functions:

(defvar shell-drive-to-directory-map nil "The variable keeps track of drive
and directory mapping.")

(defun shell-get-directory-for-drive (drive)
"Get directory for drive."
(let ((dir (cdr (assoc drive shell-drive-to-directory-map))))
  (if dir
      dir
      (shell-set-directory-for-drive drive (concat (expand-file-name
drive)))
      (cdr (assoc drive shell-drive-to-directory-map))
      )))

(defun shell-set-directory-for-drive-from-dir (dir)
  "Add the drive to directory mapping from dir."
  (setq dir (expand-file-name dir))
  (if (string-match (concat "\\`\\(" shell-chdrive-regexp
   "\\)\\(.*\\)\\'")
  dir)
      (shell-set-directory-for-drive (match-string 1 dir) (match-string 0
dir))
      (error "Could not set directory for drive based on dir.")))

(defun shell-set-directory-for-drive (drive dir)
  "Add the drive to directory mapping."
  (setq shell-drive-to-directory-map (delq drive
shell-drive-to-directory-map))
  (let ((mapping (assoc drive shell-drive-to-directory-map)))
 (if mapping
     (setcdr mapping dir)
     (add-to-list 'shell-drive-to-directory-map (cons drive dir)))))

(defun shell-directory-tracker (str)
  "..."
:
:
      ((and shell-chdrive-regexp
     (string-match (concat "\\`\\(" shell-chdrive-regexp
      "\\)\\($\\|[ \t]\\)")
     cmd))
       (shell-set-directory-for-drive-from-dir default-directory) ;; record
current dir for later recovery
       (shell-process-cd (shell-get-directory-for-drive
(comint-substitute-in-file-name cmd)))))
:
:
:)

(define-derived-mode shell-mode comint-mode "Shell"
"..."
:
:
:
(make-local-variable 'shell-dirtrackp)
  (setq shell-dirtrackp t)
(make-local-variable 'shell-drive-to-directory-map)
  (setq shell-drive-to-directory-map nil)
:
:)

Sandip






reply via email to

[Prev in Thread] Current Thread [Next in Thread]