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

Я использую term-mode запускать оболочки Bash в Emacs. На удаленных хостах, term-modeфункция отслеживания каталогов default-directory чтобы в нем было имя хоста, чтобы заполнение вкладок и доступ к файлам осуществлялся удаленно через Tramp. Однако иногда я использую удаленные хосты, которые в основном используют те же файловые системы, что и моя рабочая станция, так как они загружают те же каталоги из NFS. В этих случаях Бродяга слишком сильно меня тормозит. Я хотел бы, чтобы при использовании этих систем 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-... переменные).

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

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 выше.)

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

Другие вопросы по тегам