He visto ejemplos en línea donde las personas agregan rutas a la ruta predeterminada en Emacs con:
(add-to-list 'exec-path "/usr/local/bin/")
Soy nuevo en Elisp y creo que entiendo lo que hace la declaración anterior, pero tengo algunas preguntas:
¿ En qué orden Emacs busca a través de las rutas de ejecución? Por ejemplo, ¿considera el valor de
$PATH
(variable de entorno) en absoluto (y si es así, antes o despuésexec-path
?)¿Cómo puedo anteponer múltiples rutas de este tipo? ¿Puedo seguir concatándolos? p.ej
(add-to-list 'exec-path "PATH1", "PATH2")
o debería hacer:
(add-to-list 'exec-path "PATH1:PATH2:PATH3")
También encontré este paquete interesante en GitHub: exec-path-from-shell . ¿Por qué hay una necesidad de un paquete para esto?
Motivación
¿Alguna vez encontró que un comando funciona en su shell, pero no en Emacs?
Esto sucede mucho en OS X, donde una instancia de Emacs iniciada desde la GUI hereda un conjunto predeterminado de variables de entorno.
Esta biblioteca funciona resuelve este problema copiando variables de entorno importantes del shell del usuario: funciona pidiéndole al shell que imprima las variables de interés y luego las copie en el entorno Emacs.
(describe-function 'add-to-list)
(C-h f
) le dará el documento para laadd-to-list
función, así como enlaces a la fuente. También hay(describe-variable 'exec-path)
(C-h v
). Esto no pretende ser un comentario RTFM: estos documentos no responden todas las preguntas que enumeró, solo algo útil.C-h v exec-path
, use los manuales (Emacs y Elisp). En un manual, loi exec-path
dirige a una explicación útil. Pregúntale a Emacs primero , no te arrepentirás de haberlo hecho.Respuestas:
1)
PATH
yexec-path
Emacs establece
exec-path
desde el valor dePATH
inicio, pero no volverá a verlo más tarde. Pero si ejecuta un comando, heredaráPATH
, noexec-path
, por lo que los subprocesos pueden encontrar comandos diferentes que Emacs.Como dice Francesco, esto puede ser especialmente confuso
shell-command
, ya que no ejecuta un proceso directamente, sino que llama a un shell para ejecutarlo, que usaráPATH
, noexec-path
.2) Agregar múltiples rutas a
exec-path
Solo llame
add-to-list
repetidamente:Tenga en cuenta que se
add-to-list
agrega al comienzo de la lista, por lo que esto terminará"PATH2"
en elexec-path
antes"PATH1"
.También puede usar más acceso de "bajo nivel" a las listas:
Esto agregará
"PATH1"
y"PATH2"
a suexec-path
, en ese orden.3) RUTA de Mac OS
El problema en Mac OS X es que Mac OS no configura el entorno de la misma manera cuando llama a un programa desde la IU global o cuando lo llama desde un shell. Esto significa que ejecutar Emacs desde un shell dará como resultado que se establezcan diferentes variables de entorno que cuando se ejecuta desde el buscador. Esto es especialmente molesto si configura variables de entorno en
.bashrc
o similares, ya que eso no afectará a los Emacs "globales".Aparentemente, el paquete inicia un shell e importa variables de entorno desde allí, imitando el entorno que se obtiene de un shell en un Emacs iniciado globalmente.
fuente
PATH
se define el valor predeterminado para los programas iniciados desde la IU global (entorno de escritorio)? Estoy teniendo el mismo problema conPYTHONPATH
enelpy
:). Cuando inicio Emacs desde el escritorio, Emacs no conoce misPYTHONPATH
definiciones en mi.zshenv
archivo (un archivo init parazsh
), lo cual es muy frustrante, yaelpy
que no sabe dónde encontrar mis paquetes de Python. Estoy feliz de mover estasPYTHONPATH
definiciones a uninit
archivo de shell diferente (aunque idealmente me gustaría que Emacs use las definiciones de mi.zshenv
)exec-path
yPATH
en su.emacs
. Puedes configurarloPATH
usando(setenv "PATH" (format "%s:%s" "/new/path/element" (getenv "PATH")))
.PYTHONPATH
queelpy
debería usar?process-environment
, por ejemplo, utilizandosetenv
. Puede hacerloelpy-mode-hook
, pero es una variable global y hacer que sea local en el búfer puede conducir fácilmente a un comportamiento confuso.Cuando emacs inicia un nuevo proceso externo utilizando funciones primitivas como
call-process
ostart-process
, se busca el ejecutableexec-path
(y no$PATH
)Sin embargo, una función como
shell-command
inicia el shell como un subproceso y le pasa el comando que desea ejecutar. Para ejecutar este comando, el shell intentará encontrar el ejecutable en$PATH
(y no enexec-path
).Por
exec-path
lo tanto, es lo que más cuenta para los procesos externos que se inician por emacs, mientras que$PATH
es lo que cuenta para los comandos que ejecuta usted mismo con una función de nivel superior (usando, M-!por ejemplo)Si desea agregar múltiples directorios
exec-path
, debe usarlosadd-to-list
varias veces.Puedes hacerlo manualmente
o usando un bucle
Con respecto a su tercera pregunta, si emacs se lanzó desde el entorno de escritorio, hereda el entorno del mismo, que podría ser menos completo que el de un shell completo.
Esto significa que a veces puede ser necesario completar el valor de Emacs para
$PATH
usar lo que ve un shell normal. Este es el propósito de laexec-path-from-shell
biblioteca que mencionas.fuente