Emacs term-mode: прекратить установку удаленного каталога по умолчанию на некоторых хостах

Я использую term-mode для запуска оболочек Bash в Emacs. На удаленных хостах функция отслеживания каталогов term-mode помогает установить default-directory, чтобы в нем было имя хоста, так что завершение вкладки и доступ к файлам выполняются удаленно через Tramp. Однако иногда я использую удаленные хосты, которые в основном используют те же файловые системы, что и моя рабочая станция, поскольку они загружают одни и те же каталоги из NFS. В этих случаях Tramp слишком меня тормозит. Я бы хотел, чтобы при использовании этих систем Emacs устанавливал default-directory локально. Для этого я скопировал term-handle-ansi-terminal-messages из системы term.el в новый файл, загруженный моим .emacs. Заменяю эту деталь:

((= command-code ?h)
 (setq term-ansi-at-host argument))

с этим:

((= command-code ?h)
 (setq term-ansi-at-host-real argument)
 (setq term-ansi-at-host
       ;; if it has an equivalent filesystem group, set to system-name
       (if (term-equivalent-filesystem-host-group-p argument)
           (system-name)
         argument)))

Это вызывает функцию term-equivalent-filesystem-host-group-p, которая сообщает, следует ли рассматривать хост как имеющий эквивалентную файловую систему.

Этот метод дает желаемый эффект, но копирование и изменение системного кода Lisp не устойчиво к любым будущим изменениям в коде. Я не думаю, что советовать функцию можно было бы без дублирования половины ее функциональности (либо цикла сообщений, либо установки переменных default-directory и ange-ftp-).

Есть лучший способ сделать это?


person Michael Hoffman    schedule 05.07.2012    source источник


Ответы (1)


Думаю, советом можно чертовски подойти. Я бы определил совет следующим образом:

(defadvice term-handle-ansi-terminal-messages
   (before rewrite-remote-paths-to-local (message) activate)
   (when (and (string-match ".*\eAnSiTh.\\([^\r\n]+\\)\r?\n" message)
              (term-equivalent-filesystem-host-group-p (match-string 1 message)))
     (setq term-ansi-at-host-real (match-string 1 message))
     (setq message (replace-match (system-name) t t message 1))))

Все, что это делает, - это ищет подстроку ввода в term-handle-ansi-terminal-messages, которая попадет в рассматриваемый случай, и заранее переписывает путь. Теперь нет необходимости возиться с внутренним устройством term-handle-ansi-terminal-messages, поскольку он никогда не увидит удаленный путь.

Это отличается от изменения функции? Я бы сказал, что да, но это открыто для интерпретации. В частности, я думаю, что единственное, от чего зависит приведенный выше код, - это формат вложенного сообщения, которое term-long-function-name-you-already-know будет искать, которое на самом деле является атрибутом протокола терминала. а не внутренности term-now-i'm-just-being-silly. Есть некоторые потенциальные проблемы, такие как новый код, который изменяет поведение в зависимости от 7-го символа в совпадении. (Это единственный . в string-match выше.)

Излишне говорить, что я вообще не тестировал этот код.

person Craig Citro    schedule 11.07.2012
comment
Это убедительно - я думаю, что это более надежно, чем переписывать функцию. Я немного изменил регулярное выражение, чтобы оно работало. - person Michael Hoffman; 12.07.2012
comment
Потрясающе - я не удивлен, что потребовалась небольшая настройка. (Что это было, из любопытства?) Я также забыл упомянуть еще один бонус использования советов - если когда-нибудь произойдет что-то странное, вы можете просто (ad-deactivate 'term-handle-ansi-terminal-messages), и вы вернете исходное поведение. - person Craig Citro; 12.07.2012
comment
Я отредактировал ваш ответ, чтобы указать используемое регулярное выражение. У старого было две проблемы: круглые скобки не были экранированы двойной обратной косой чертой, а message может содержать много строк, поэтому совпадение .*\r?\n фактически приведет к потере всего многострочного ввода. Кроме того, я добавил .* в начале, чтобы совпадать только последний пример остальной части шаблона, в случае, если AnSiTh указан дважды в message. - person Michael Hoffman; 12.07.2012