Есть ли способ заставить мои emacs распознавать мои псевдонимы bash и пользовательские функции, когда я запускаю команду оболочки?

В моей оболочке у меня есть псевдонимы и пользовательские функции. Когда я нахожусь в экземпляре emacs (я всегда использую emacs -nw) и выполняю команду оболочки (Mx!), Я не могу их использовать. Это имеет смысл, поскольку я представляю, что запускает свой собственный подоболочек, чтобы сделать это... но есть ли способ (может быть, в моем.emacs), чтобы заставить это работать? Возможно, даже если это связано с поиском среды по умолчанию перед выполнением какой-либо команды оболочки?

6 ответов

Решение

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

Я думаю, что и Mx shell-command, и Mx compile выполняют команды в нижней оболочке через call-process. Попробуйте следующее в вашем.emacs (или просто оцените):

(setq shell-file-name "bash")
(setq shell-command-switch "-ic")

Я заметил, что после оценки вышеизложенного псевдонимы.bashrc подобраны для использования как командой Mx shell, так и Mx compile, т.е.

Mx скомпилируйте RET your_alias RET

должен тогда работать.

Моя среда: Emacs 24.1 (pretest rc1), OSX 10.7.3

Источник

Нам нужно включить расширение псевдонимов в неинтерактивных оболочках, желательно только тогда, когда они вызываются из emacs (чтобы избежать тонких различий при запуске других оболочек). Для меня сработало создание двух файлов: ~/.alias содержит все мои псевдонимы, например

alias python python27

и ~/.aliasExpand имеет

source ~/.alias
shopt -s expand_aliases

Я также, конечно, заменил все свои псевдонимы в.bashrc на

source ~/.alias

Наконец, я добавил это в свой.emacs:

(setenv "BASH_ENV" "~/.aliasExpand")

Я попробовал решение Кейта Флауэра (по созданию интерактивных оболочек) и получил

bash: невозможно установить группу процессов терминала (-1): неподходящий ioctl для устройства bash: нет управления заданиями в этой оболочке

Обратите внимание, что я получил это через намеки Гленна Джекмана и Николаса Дудебау.

Если вы готовы рискнуть, если у всех ваших оболочек есть расширение псевдонимов, и вы не против запускать весь свой.bashrc для каждой оболочки emacs, вы можете упростить это, добавив

shopt -s expand_aliases

в ваш.bashrc и

(setenv "BASH_ENV" "~/.bashrc")

в ваш.emacs

Прочитайте http://www.gnu.org/software/bash/manual/bashref.html

Для неинтерактивных оболочек единственным источником файла является значение переменной среды BASH_ENV. Вы вызываете Emacs как BASH_ENV=~/.bashrc emacs если emacs будет использовать bash для команд оболочки - некоторые программы специально используют "/bin/sh"

Получить shell-command читать ~/.bashrc перед выполнением команды в соответствии с методикой, описанной в /questions/1056437/est-li-sposob-zastavit-moi-emacs-raspoznavat-moi-psevdonimyi-bash-i-polzovatelskie-funktsii-kogda-ya-zapuskayu-komandu-obolochki/1056458#1056458, без потенциальных побочных эффектов из-за $BASH_ENV будучи определенным для всей вашей сессии Emacs, попробуйте это в вашем ~/.emacs.d/init.el (или же .emacs) файл:

;; I want M-! (shell-command) to pick up my aliases and so run .bashrc:
(setq shell-file-name "bash-for-emacs.sh")  ; Does this: BASH_ENV="~/.bashrc" exec bash "$@"
(setq shell-command-switch "-c")

Как описано в комментарии во второй строке, также установите (в вашем $PATH) скрипт с именем bash-for-emacs.sh который содержит:

#!/bin/bash

BASH_ENV="~/.bashrc" exec bash "$@"

Обратите внимание, что ваш ~/.bashrc может потребоваться изменить, чтобы определить неинтерактивные псевдонимы, даже если [ -z "$PS1" ] Значение true (что указывает на неинтерактивную оболочку). Это подход, который я использую для моей собственной среды (такой, как она есть), которая находится по адресу https://github.com/jcburley/UnixHome.

Кроме того, это предполагает, что вы хотите использовать Bash в качестве созданной в Emacs оболочки, как и я.

Параметр shell-command-switch напрямую значительно замедлит работу (если вы используете много (ba|z)sh плагины), который вызывается различными неинтерактивными функциями, такими как shell-command-to-string, eshell-remote-command, ... и его многочисленные вызовы из других функций, которые никогда не потребуются .bashrc или же .zshrc

Например, на моей машине (и, вероятно, вашей тоже):

      (benchmark-elapse (let ((shell-command-switch "-c")) (shell-command "")))
0.005170422
(benchmark-elapse (let ((shell-command-switch "-ic")) (shell-command "")))
0.242628824
;; Empty ~/.zshrc: 0.168341049

Следовательно, мы должны выбрать способ использовать интерактивную оболочку только тогда, когда shell-command называется интерактивно

      ;;;###autoload
(defun my-shell-command-interactive-a (fn &rest args)
  "Use interactive shell for `shell-command' when invoked interactively.
Setting the \"-i\" switch all the time will significantly slow
down `shell-command' because there may too many files to source."
  (let ((shell-command-switch (if (called-interactively-p 'interactive)
                                  ;; Replace the first "-"
                                  (replace-regexp-in-string
                                   "\\(-\\).*\\'"
                                   "-i"
                                   shell-command-switch
                                   nil
                                   nil
                                   1)
                                shell-command-switch)))
    (apply fn args)))

(advice-add #'shell-command :around #'my-shell-command-interactive-a)

Поместите псевдонимы и функции в .bashrcне .bash_profile, Последний выполняется только в логинах, первый - во всех оболочках.

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