Próbuję dostać shell-command
i async-shell-command
do integracji z kilku programów w moim .bashrc
pliku, specjalnie direnv w tym przykładzie.
Przekonałem się, że jeśli dostosuję shell-command-switch
, mogę uzyskać procesy powłoki ładujące mój profil, tak jakby to była zwykła interaktywna powłoka logowania:
(setq shell-command-switch (purecopy „-ic”)) (setq express-bash-args '(„-ic” „export EMACS =; stty echo; bash”))
Używam również exec-path-from-shell .
Powiedz, że mam ~/.bashrc
plik z:
... eval „$ (hak direnv 0 $)” echo „foo”
W środku ~/code/foo
mam .envrc
plik z:
eksport PATH = $ PWD / bin: $ PATH „pasek” echa
Jeśli uruchomię M-x shell
z default-directory
ustawioną na ~/code/foo
, powłoka bash poprawnie załaduje mój profil i uruchomi direnv hook, aby dodać go do mojej ścieżki:
direnv: ładowanie .envrc bar direnv: eksport ~ ŚCIEŻKA ~ / code / foo $ echo $ PATH / Users / nazwa użytkownika / kod / foo / bin: / usr / local / bin: ... # reszta $ PATH
Jednak jeśli default-directory
nadal jest ~/code/foo
uruchomiony M-! echo $PATH
, to poprawnie ładuje mój plik .bashrc, ale nie wykonuje haka direnv bieżącego katalogu:
bla / usr / local / bin: ... # reszta $ PATH bez ./bin
Otrzymuję ten sam wynik, jeśli biegnę M-! cd ~/code/foo && echo $PATH
.
Czy istnieje sposób, w jaki mogę doradzić, podpiąć się shell-command
lub start-process
sprawić, by zachowywał się tak, jakby był wysyłany z interaktywnego bufora powłoki?
źródło
(setq shell-command-switch "-ic")
, powinien zostać oceniony wraz z każdym innym poleceniem w ~ / .bashrc.eval "$(direnv hook $0)"
. Jest to wykonywane, ale nie działa mechanizm, który powinien zostać uruchomiony, gdy jesteś w określonym katalogu z.envrc
plikiem..envrc
pliku nie jest oceniane? Czy to tylko zmienne środowiskowe, które nie są eksportowane? Czy możesz podać pełny przykład, abym mógł spróbować to odtworzyć?Odpowiedzi:
To nie wydaje się być problemem w Emacsie, ale w bashu.
shell-command
po prostu wykonujecall-process
się na powłoce i przekazuje argumenty. Próbowałem tego na zwykłej powłoce:~/.bashrc
jest pozyskiwany, ale hak direnv nie jest uruchamiany. Podirenv hook bash
uruchomieniu funkcja_direnv_hook
jest wyprowadzana i dodawana doPROMPT_COMMAND
.Podejrzewam, że
PROMPT_COMMAND
po prostu nie zadziała. Nie stanowi to jednak problemu, ponieważ_direnv_hook
jest naprawdę prosty. Możemy po prostu poprzedzićeval $(direnv export bash)
polecenie powłoki i zadziała:Spowoduje to wydrukowanie rozszerzonej ścieżki do bufora komunikatów. Alternatywnie wykonaj za pomocą
M-!
:Nie musisz
(setq shell-command-switch "-ic")
tego robić .źródło
eval "$(direnv export bash)"
elisp, ale było to niezwykle pomocne i skierowało mnie na właściwą ścieżkę.Uruchomienie
eval "$(direnv hook $0)"
definiuje funkcję, która się zaczepia$PROMPT_COMMAND
, która nigdy nie jest wywoływana podczas uruchamiania bash,bash -ic
ponieważ nie pojawia się monit. Możesz zmienić linię:eval "$(direnv hook $0)"
do:
eval "$(direnv hook $0)" && _direnv_hook
jawnie wywołać funkcję hook.
Edycja: Właśnie zrealizowane rekado dało bardzo podobną odpowiedź.
źródło
$PROMPT_COMMAND
.Podziękowania dla Rekado i Erika za wskazanie, jak działa hak direnv za pomocą
$PROMPT_COMMAND
. Ponieważshell-command
nie korzysta z monitu, nie można go było wykonać.Podczas gdy odpowiedź Erika działa w moim przykładzie wywołania polecenia powłoki
M-!
zdefault-directory
ustawieniem, nie zadziała w następującym przykładzie:Po pewnym googlingu znalazłem sposób, aby utworzyć hak prexec w bash, aby wykonać coś przed wykonaniem polecenia. Przyjąłem ten pomysł i zmodyfikowałem go, aby pasował do mojej potrzeby direnv. Oto jak teraz wygląda odpowiednia część mojego ~ / .bashrc:
źródło
w dzisiejszych czasach prawdopodobnie będziesz chciał skorzystać z https://github.com/wbolster/emacs-direnv
działa podobnie do haka, który direnv instaluje w twojej powłoce. środowisko emacs jest aktualizowane na żądanie (lub automatycznie podczas przełączania buforów) w celu dopasowania do stanów direnv, które są poprawnym środowiskiem dla bieżącego katalogu.
modyfikując
exec-path
iprocess-environment
emacs będzie zachowywał się tak, jak zrobiłaby to twoja powłoka: uruchamiaj programy z właściwych ścieżek i we właściwym środowisku.źródło