Saya telah melihat contoh online di mana orang menambahkan jalur ke jalur default di Emacs dengan:
(add-to-list 'exec-path "/usr/local/bin/")
Saya baru mengenal Elisp, dan saya pikir saya mengerti apa yang dilakukan pernyataan di atas, tetapi saya punya beberapa pertanyaan:
Dalam urutan apa Emacs mencari melalui jalur eksekusi? Misalnya, apakah ia menganggap nilai
$PATH
(variabel env) sama sekali (dan jika ya, sebelum atau sesudahexec-path
?)Bagaimana saya bisa menambahkan beberapa jalur seperti itu? Bisakah saya terus menyatukan mereka? misalnya
(add-to-list 'exec-path "PATH1", "PATH2")
atau yang harus saya lakukan:
(add-to-list 'exec-path "PATH1:PATH2:PATH3")
Saya juga menemukan paket menarik ini di GitHub: exec-path-from-shell . Mengapa ada kebutuhan untuk paket untuk ini?
Motivasi
Pernah menemukan bahwa perintah bekerja di shell Anda, tetapi tidak di Emacs?
Ini banyak terjadi pada OS X, di mana instance Emacs dimulai dari GUI mewarisi serangkaian variabel lingkungan default.
Pustaka ini berfungsi memecahkan masalah ini dengan menyalin variabel lingkungan penting dari shell pengguna: ia bekerja dengan meminta shell Anda untuk mencetak variabel yang diminati, lalu menyalinnya ke lingkungan Emacs.
(describe-function 'add-to-list)
(C-h f
) akan memberi Anda dokumen untukadd-to-list
fungsi tersebut, serta tautan ke sumbernya. Ada juga(describe-variable 'exec-path)
(C-h v
). Ini tidak dimaksudkan untuk menjadi komentar RTFM - dokumen ini tidak menjawab semua pertanyaan yang Anda daftarkan, hanya sesuatu yang bermanfaat.C-h v exec-path
, gunakan manual (Emacs dan Elisp). Dalam manual,i exec-path
mengarahkan Anda ke penjelasan yang bermanfaat. Tanyakan Emacs dulu - Anda tidak akan menyesal melakukannya.Jawaban:
1)
PATH
danexec-path
Emacs tidak ditentukan
exec-path
dari nilaiPATH
saat startup, tetapi tidak akan melihatnya lagi nanti. Tetapi jika Anda menjalankan perintah, itu akan mewarisiPATH
, tidakexec-path
, sehingga subproses dapat menemukan perintah yang berbeda dari yang Emacs lakukan.Seperti dikatakan Francesco, ini bisa sangat membingungkan
shell-command
, karena itu tidak menjalankan proses secara langsung, tetapi memanggil shell untuk menjalankannya, yang akan digunakanPATH
, bukanexec-path
.2) Menambahkan beberapa jalur ke
exec-path
Panggil saja
add-to-list
berulang kali:Perhatikan bahwa
add-to-list
menambahkan ke awal daftar, jadi ini akan berakhir dengan"PATH2"
berada diexec-path
sebelumnya"PATH1"
.Anda juga dapat menggunakan lebih banyak akses "tingkat rendah" ke daftar:
Ini akan menambah
"PATH1"
dan"PATH2"
ke Andaexec-path
, dalam urutan itu.3) PATH Mac OS
Masalah pada Mac OS X adalah bahwa Mac OS tidak mengatur lingkungan yang sama ketika Anda memanggil program dari UI global atau ketika Anda menyebutnya dari shell. Ini berarti menjalankan Emacs dari shell akan menghasilkan variabel lingkungan yang berbeda yang ditetapkan daripada ketika Anda menjalankannya dari finder. Ini sangat menjengkelkan jika Anda mengatur variabel lingkungan
.bashrc
atau sejenisnya, karena itu tidak akan memengaruhi Emacs "global".Paket tersebut tampaknya memulai sebuah shell dan mengimpor variabel lingkungan dari sana, meniru lingkungan yang Anda dapatkan dari sebuah shell di Emacs yang dimulai secara global.
sumber
PATH
didefinisikan untuk program yang dimulai dari UI global (lingkungan desktop)? Saya mengalami masalah yang sama denganPYTHONPATH
dielpy
:). Ketika saya memulai Emacs dari desktop, Emacs tidak mengetahuiPYTHONPATH
definisi saya dalam.zshenv
file saya (file init untukzsh
), yang sangat membuat frustrasi, karenaelpy
tidak tahu lalu ke mana menemukan paket Python saya. Saya senang memindahkanPYTHONPATH
definisi ini keinit
file shell yang berbeda (walaupun idealnya saya ingin Emacs menggunakan definisi dari saya.zshenv
)exec-path
danPATH
di Anda.emacs
. Anda dapat mengaturPATH
menggunakan(setenv "PATH" (format "%s:%s" "/new/path/element" (getenv "PATH")))
.PYTHONPATH
yangelpy
harus digunakan?process-environment
, misalnya menggunakansetenv
. Anda dapat melakukannyaelpy-mode-hook
, tetapi ini adalah variabel globsl dan menjadikannya buffer-local dapat dengan mudah menyebabkan perilaku membingungkan.Ketika emacs memulai proses eksternal baru menggunakan fungsi primitif seperti
call-process
ataustart-process
, executable dicariexec-path
(dan tidak$PATH
)Namun, fungsi seperti
shell-command
memulai shell sebagai subproses dan meneruskannya perintah yang ingin Anda jalankan. Untuk menjalankan perintah ini, shell kemudian akan mencoba untuk menemukan executable di$PATH
(dan bukan diexec-path
).Oleh karena itu,
exec-path
yang paling penting untuk proses eksternal yang dimulai oleh emacs itu sendiri, sedangkan$PATH
apa yang diperhitungkan untuk perintah yang Anda jalankan sendiri dengan fungsi tingkat yang lebih tinggi (menggunakan M-!misalnya)Jika Anda ingin menambahkan beberapa direktori
exec-path
, Anda harus menggunakanadd-to-list
beberapa kali.Anda dapat melakukannya secara manual
atau menggunakan loop
Mengenai pertanyaan ketiga Anda, jika emacs diluncurkan dari lingkungan desktop, itu mewarisi lingkungan dari itu, yang mungkin kurang lengkap dibandingkan dengan shell penuh.
Ini berarti bahwa kadang-kadang mungkin perlu untuk melengkapi nilai Emacs untuk
$PATH
menggunakan apa yang dilihat oleh shell biasa. Ini adalah tujuanexec-path-from-shell
perpustakaan yang Anda sebutkan.sumber