Saya mencoba untuk mendapatkan shell-command
dan async-shell-command
mengintegrasikan secara mulus dengan beberapa program dalam .bashrc
file saya , khususnya direnv dalam contoh ini.
Saya menemukan bahwa jika saya mengkustomisasi shell-command-switch
, saya bisa mendapatkan proses shell untuk memuat profil saya seolah-olah itu adalah shell login interaktif reguler:
(setq shell-command-switch (purecopy "-ic")) (setq eksplisit-bash-args '("-ic" "ekspor EMACS =; stty echo; bash"))
Saya juga menggunakan exec-path-from-shell .
Katakanlah saya punya ~/.bashrc
file dengan:
... eval "$ (direnv hook $ 0)" gema "foo"
Di dalam ~/code/foo
saya punya .envrc
file dengan:
export PATH = $ PWD / bin: $ PATH gema "bar"
Jika saya menjalankan M-x shell
dengan default-directory
set ke ~/code/foo
, bash shell akan memuat profil saya dengan benar dan menjalankan kait direnv untuk menambahkannya ke jalur saya:
direnv: memuat .envrc batang direnv: ekspor ~ PATH ~ / code / foo $ echo $ PATH / Pengguna / nama pengguna / kode / foo / bin: / usr / local / bin: ... # sisa dari $ PATH
Namun jika default-directory
masih ~/code/foo
dan saya jalankan M-! echo $PATH
, itu benar memuat .bashrc saya tetapi tidak menjalankan hook direnv dari direktori saat ini:
foo / usr / local / bin: ... # sisa $ PATH tanpa ./bin
Saya mendapatkan hasil yang sama jika saya berlari M-! cd ~/code/foo && echo $PATH
.
Apakah ada cara saya dapat menyarankan atau menghubungkan ke shell-command
atau start-process
untuk membuatnya berperilaku seolah-olah sedang dikirim dari buffer shell interaktif?
sumber
(setq shell-command-switch "-ic")
maka itu harus dievaluasi bersama dengan setiap perintah lain di ~ / .bashrc.eval "$(direnv hook $0)"
. Ini sedang dijalankan, tetapi mekanisme yang harus dipecat ketika Anda berada di direktori tertentu dengan.envrc
file tidak..envrc
file yang dievaluasi? Atau hanya variabel lingkungan yang tidak diekspor? Bisakah Anda memberikan contoh lengkap sehingga saya dapat mencoba mereproduksi ini?Jawaban:
Ini tampaknya tidak menjadi masalah dengan Emacs tetapi dengan bash.
shell-command
hanya mengeksekusicall-process
di shell dan melewati argumen. Saya mencoba ini pada shell biasa:~/.bashrc
bersumber, tetapi kait direnv tidak berjalan. Ketikadirenv hook bash
dieksekusi, suatu fungsi_direnv_hook
adalah output dan ditambahkan kePROMPT_COMMAND
.Saya menduga itu
PROMPT_COMMAND
tidak akan berhasil. Itu bukan masalah, karena_direnv_hook
ini sangat sederhana. Kami hanya bisa menambahkaneval $(direnv export bash)
ke perintah shell dan itu akan bekerja:Ini akan mencetak jalur yang ditambah ke buffer pesan. Atau, jalankan dengan
M-!
:Anda tidak perlu melakukan
(setq shell-command-switch "-ic")
ini untuk bekerja.sumber
eval "$(direnv export bash)"
di elisp, tetapi ini sangat membantu dan menempatkan saya di jalan yang benar.Menjalankan
eval "$(direnv hook $0)"
mendefinisikan fungsi yang terhubung$PROMPT_COMMAND
, yang tidak pernah dipanggil ketika bash dijalankanbash -ic
karena tidak ada prompt. Anda dapat mengubah baris:eval "$(direnv hook $0)"
untuk:
eval "$(direnv hook $0)" && _direnv_hook
untuk secara eksplisit memanggil fungsi hook.
Sunting: Baru sadar rekado memberikan jawaban yang sangat mirip.
sumber
$PROMPT_COMMAND
.Terima kasih kepada Rekado dan Erik karena menunjukkan bagaimana pengait direnv bekerja dengan menggunakan
$PROMPT_COMMAND
. Karenashell-command
tidak menggunakan prompt, ini tidak dijalankan.Sementara jawaban Erik bekerja dalam contoh saya memanggil perintah shell
M-!
dengandefault-directory
set, itu tidak akan berfungsi dalam contoh berikut:Setelah beberapa googling, saya menemukan cara untuk membuat preexec hook di bash untuk mengeksekusi sesuatu sebelum perintah dieksekusi. Saya mengambil ide ini dan dimodifikasi agar sesuai dengan kebutuhan saya untuk direnv. Inilah bagian yang relevan dari ~ / .bashrc saya sekarang:
sumber
saat ini Anda mungkin ingin menggunakan https://github.com/wbolster/emacs-direnv
ia bekerja mirip dengan hook yang direnv instal di shell Anda. lingkungan emacs diperbarui berdasarkan permintaan (atau secara otomatis saat mengganti buffer) untuk mencocokkan dengan status direnv apa yang merupakan lingkungan yang benar untuk direktori saat ini.
dengan memodifikasi
exec-path
danprocess-environment
emacs akan berperilaku seperti yang dilakukan shell Anda: jalankan program dari jalur yang benar dan dengan lingkungan yang benar.sumber