[Top][All Lists]

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

Directory tracking and completions in tramp remote shells

From: Christian Millour (AB TELA)
Subject: Directory tracking and completions in tramp remote shells
Date: Sat, 06 Nov 2010 01:14:30 +0100
User-agent: Mozilla/5.0 (Windows; U; Windows NT 6.1; fr; rv: Gecko/20101027 Thunderbird/3.1.6


consider a tramp remote shell obtained for instance by C-x C-f /plink:address@hidden: ~/foo, and then C-u M-x shell in this buffer.

currently directory tracking and completions do not work in tramp remote shells for absolute pathnames.

For instance if you open a tramp remote shell, and then type cd /<tab>, the suggested completions refer to the content of the local / directory. And once you have typed cd /<return>, directory tracking is f...d. In fact any cd to an absolute pathname will thrash directory tracking and you will need to resync using M-x cd /<method>:<user>@<host>:<current-remote-dir-name> (for instance if you are using plink as user on remote, and did a cd /etc, the resync command is M-x cd /plink:address@hidden:/etc).

This lossy behavior stems from the fact that tramp is currently not setting the (buffer-local) variable comint-file-name-prefix.

To see the difference, eval the following definition

(defun fix-comint-file-name-prefix ()
  (interactive "*")
  (with-parsed-tramp-file-name default-directory nil
    (set (make-local-variable 'comint-file-name-prefix)
     (tramp-make-tramp-file-name method user host ""))))

then go in the remote shell buffer (properly resync'ed if needed) and M-x fix-comint-file-name-prefix. Presto, everything works :-) : cd and pushd and completion for absolute pathnames ; and if directory tracking gets confused because you sourced a file or used an alias that changed directory, you can even resync using dirs at the shell prompt (or M-x dirs).

Actually, everything works *except* popd, but that is because of a bug in shell-process-popd, which should be
(defun shell-process-popd (arg)
  (let ((num (or (shell-extract-num arg) 0)))
    (cond ((and num (= num 0) shell-dirstack)
       ;(shell-cd (car shell-dirstack)) <<<<<< whoops!
(shell-cd (shell-prefixed-directory-name (car shell-dirstack))) ; << better
       (setq shell-dirstack (cdr shell-dirstack))
      ((and num (> num 0) (<= num (length shell-dirstack)))
       (let* ((ds (cons nil shell-dirstack))
          (cell (nthcdr (1- num) ds)))
         (rplacd cell (cdr (cdr cell)))
         (setq shell-dirstack (cdr ds))
       (error "Couldn't popd")))))
I will post the patch to emacs-devel as soon as I finish this message.

I have tried to upgrade tramp (latest version, but that should apply to 2.1.19-pre just as well) so that this variable would be set automatically. The logical place seems to be in tramp-sh-handle-start-file-process, as follows :
Taisha:~/tramp/tramp/lisp $ diff -c tramp-sh.el.~2.11.~  tramp-sh.el
*** tramp-sh.el.~2.11.~    Thu Oct 21 09:55:10 2010
--- tramp-sh.el    Sat Nov  6 01:15:42 2010
*** 2687,2693 ****
            (set-process-buffer (tramp-get-connection-process v) nil)
            (kill-buffer (current-buffer)))
!       (goto-char (point-max))))
        (tramp-set-connection-property v "process-name" nil)
        (tramp-set-connection-property v "process-buffer" nil))))

--- 2687,2695 ----
            (set-process-buffer (tramp-get-connection-process v) nil)
            (kill-buffer (current-buffer)))
!       (goto-char (point-max)))
!     (set (make-local-variable 'comint-file-name-prefix)
!          (tramp-make-tramp-file-name method user host "")))
        (tramp-set-connection-property v "process-name" nil)
        (tramp-set-connection-property v "process-buffer" nil))))

Taisha:~/tramp/tramp/lisp $

but unfortunately it seems that the value get reset by the final call to (shell-mode) in shell (the lisp funtion). This is weird because I don't see where shell-mode (actually "define-derived-mode shell") sets this variable, or why it should set it. At this point I have however reached the limit of my emacs savvyness (I don't know in depth how derived modes work, and how to instrument and step into a derived mode) and am at a loss as where to go next... Any idea ? Is this the right place or should I raise it on emacs-devel ?

Thanks in advance, and best regards, Christian.

reply via email to

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