2012-12-01 2 views
2

Если я использую консоль или другой терминал, имя тега терминала может изменяться на основе PWD. Но в многорежимном состоянии имя буфера *terminal<number>*. Это не очень приятно. Потому что, когда я переключаюсь между ними, имя не очень информативно. Поэтому я хочу переименовать его на основе PWD.Обновление многоуровневого имени буфера на основе PWD

Я считаю, что Введите ключ будет связываться с термином-отправить-сырец, так что я пишу функцию

(defadvice term-send-raw (around rename-term-name activate) 
    (progn 
    (rename-buffer 
    (concat "⇒ " 
      (shell-command-to-string "pwd | xargs basename | tr -d '\n'") 
      (format-time-string " [%M ∞ %S]"))) 
    ad-do-it)) 

Но проблема pwd команды возвращают PWD терминального буфера, в то время как он а не PWDSHELL в этом терминале.

Оконечный буфер PWD установлен на defcustom multi-term-default-dir. И это не изменяется, когда PWD изменяется на SHELL.

(defcustom multi-term-default-dir "~/" 
    "The default directory for terms if current directory doesn't exist." 
    :type 'string 
    :group 'multi-term) 

Как я могу получить PWD SHELL в терминале?

С уважением.

ответ

2

AFAIK нет простого способа получить информацию из работающего процесса.

Но если вы хотите, чтобы получить текущий каталог вы можете:

  1. задать оболочку для печати его
  2. разобраны и проследить командную строку для функций, таких как компакт-диск, Pushd, Popd ...
  3. опрос/Proc/PID/CWD

Первый метод описан в заголовке term.el (Mxfind-libraryRETtermRET).

И теперь, спасибо за ваш вопрос, вы дали мне возможность сделать это:

(defadvice term-send-input (after update-current-directory) 
    (let* ((pid (process-id (get-buffer-process (current-buffer)))) 
     (cwd (file-truename (format "/proc/%d/cwd" pid)))) 
    (cd cwd))) 

(ad-activate 'term-send-input) 

Это наивная реализация третьего метода, и он не будет работать, если пользователь использует su или ssh , Тем не менее, я не знаю, возможно ли это с использованием первого или второго метода.

В вашем случае вы можете просто заменить команду cd тем, что хотите.

+0

Хороший метод. Я попробовал второй вариант, это немного сложно. Большое спасибо. :-) – louxiu

+0

Функция совета отлично работает при привязке к 'term-send-raw' (который отправляется при нажатии Enter в режиме char). Единственный недостаток заключается в том, что после нажатия Enter, 'update-current-directory' запускается до того, как оболочка получит шанс фактически изменить каталоги. Обходной путь - нажать Enter дважды. –

0

Завершение ответа Даймрода на опрос/proc/PID/cwd, я нашел способ обойти проблему, которую указал Рид, где совет не забирает обновленный CWD немедленно, и вам нужно дважды нажать Enter.

Если вы переместите код обновления CWD в свою собственную функцию и используете время выполнения, чтобы вызвать его из совета в более позднее время, он правильно подберет обновленный CWD. К сожалению, я не знаю достаточно о планировании Emacs, чтобы объяснить, почему это работает (любое просвещение будет оценено).

Вот мой код, основанный на Daimrod's.Примечание. Я посоветовал term-send-input для линейного режима и term-send-return для char-mode. Я проверил это с использованием многоразового использования на Emacs 24.3.1:

(defadvice term-send-input (after update-current-directory) 
    (run-at-time "0.1 sec" nil 'term-update-dir) 
) 

(ad-activate 'term-send-input) 

(defadvice term-send-return (after update-current-directory) 
    (run-at-time "0.1 sec" nil 'term-update-dir) 
) 

(ad-activate 'term-send-return) 

(defun term-update-dir() 
    (let* ((pid (process-id (get-buffer-process (current-buffer)))) 
     (cwd (file-truename (format "/proc/%d/cwd" pid)))) 
    (unless (equal (file-name-as-directory cwd) default-directory) 
     (message (concat "Switching dir to " cwd)) 
     (cd cwd))) 
) 
Смежные вопросы