J'ai vu des exemples en ligne où les gens ajoutent des chemins au chemin par défaut dans Emacs avec:
(add-to-list 'exec-path "/usr/local/bin/")
Je suis nouveau chez Elisp, et je pense que je comprends ce que fait la déclaration ci-dessus, mais j'ai quelques questions:
Dans quel ordre Emacs recherche-t-il les chemins d'exécution? Par exemple, prend-il en compte la valeur de
$PATH
(variable env.) (Et si oui, avant ou aprèsexec-path
?)Comment puis-je ajouter plusieurs de ces chemins? Puis-je continuer à les concaténer? par exemple
(add-to-list 'exec-path "PATH1", "PATH2")
ou devrais-je faire:
(add-to-list 'exec-path "PATH1:PATH2:PATH3")
J'ai également trouvé ce package intéressant sur GitHub: exec-path-from-shell . Pourquoi a-t-on besoin d'un package pour cela?
Motivation
Avez-vous déjà constaté qu'une commande fonctionne dans votre shell, mais pas dans Emacs?
Cela se produit souvent sous OS X, où une instance Emacs démarrée à partir de l'interface graphique hérite d'un ensemble par défaut de variables d'environnement.
Cette bibliothèque fonctionne résout ce problème en copiant les variables d'environnement importantes du shell de l'utilisateur: elle fonctionne en demandant à votre shell d'imprimer les variables d'intérêt, puis en les copiant dans l'environnement Emacs.
(describe-function 'add-to-list)
(C-h f
) vous donnera le document pour laadd-to-list
fonction, ainsi que des liens vers la source. Il y a aussi(describe-variable 'exec-path)
(C-h v
). Ce n'est pas censé être un commentaire RTFM - ces documents ne répondent pas à toutes les questions que vous avez énumérées, juste quelque chose d'utile.C-h v exec-path
, utilisez le ou les manuels (Emacs et Elisp). Dans un manuel,i exec-path
vous dirige vers une explication utile. Demandez d'abord à Emacs - vous ne le regretterez pas.Réponses:
1)
PATH
etexec-path
Emacs est défini à
exec-path
partir de la valeur dePATH
au démarrage, mais ne le réexaminera pas plus tard. Mais si vous exécutez une commande, elle hériteraPATH
, nonexec-path
, donc les sous-processus peuvent trouver des commandes différentes d'Emacs.Comme Francesco le dit, cela peut être particulièrement déroutant
shell-command
, car cela n'exécute pas directement un processus, mais appelle un shell pour l'exécuter, qui l'utiliseraPATH
, nonexec-path
.2) Ajout de plusieurs chemins à
exec-path
Appelez simplement à
add-to-list
plusieurs reprises:Notez que cela
add-to-list
s'ajoute au début de la liste, donc cela finira par"PATH2"
être dans l'exec-path
avant"PATH1"
.Vous pouvez également utiliser un accès plus "bas niveau" aux listes:
Cela ajoutera
"PATH1"
et"PATH2"
à votreexec-path
, dans cet ordre.3) CHEMIN DE Mac OS
Le problème sur Mac OS X est que Mac OS ne définit pas l'environnement de la même manière lorsque vous appelez un programme à partir de l'interface utilisateur globale ou lorsque vous l'appelez à partir d'un shell. Cela signifie que l'exécution d'Emacs à partir d'un shell entraînera la définition de différentes variables d'environnement que lorsque vous l'exécutez à partir du Finder. Ceci est particulièrement gênant si vous définissez des variables d'environnement dans
.bashrc
ou similaire, car cela n'affectera pas les Emacs "globaux".Le paquet démarre apparemment un shell et importe des variables d'environnement à partir de là, imitant l'environnement que vous obtenez à partir d'un shell dans un Emacs lancé à l'échelle mondiale.
la source
PATH
est définie pour les programmes démarrés à partir de l'interface utilisateur globale (environnement de bureau)? Je suis le même problème avecPYTHONPATH
danselpy
:). Lorsque je démarre Emacs à partir du bureau, Emacs n'a pas connaissance de mesPYTHONPATH
définitions dans mon.zshenv
fichier (un fichier init pourzsh
), ce qui est très frustrant, carelpy
il ne sait pas alors où trouver mes packages Python. Je suis heureux de déplacer cesPYTHONPATH
définitions vers un autreinit
fichier shell (bien que, dans l'idéal, j'aimerais qu'Emacs utilise les définitions de mon.zshenv
)exec-path
etPATH
dans votre.emacs
. Vous pouvez définir à l'PATH
aide de(setenv "PATH" (format "%s:%s" "/new/path/element" (getenv "PATH")))
.PYTHONPATH
quielpy
devrait être utilisé?process-environment
, par exemple en utilisantsetenv
. Vous pouvez le faire danselpy-mode-hook
, mais c'est une variable globsl et la rendre locale au tampon peut facilement conduire à un comportement déroutant.Quand emacs démarre un nouveau processus externe en utilisant des fonctions primitives telles que
call-process
oustart-process
, l'exécutable est recherché dansexec-path
(et non$PATH
)Cependant, une fonction telle que
shell-command
démarre le shell en tant que sous-processus et lui transmet la commande que vous souhaitez exécuter. Afin d'exécuter cette commande, le shell essaiera alors de trouver l'exécutable dans$PATH
(et non dansexec-path
).Par conséquent,
exec-path
c'est ce qui compte le plus pour les processus externes qui sont démarrés par emacs lui-même, alors que$PATH
c'est ce qui compte pour les commandes que vous exécutez vous-même avec une fonction de niveau supérieur (en utilisant M-!par exemple)Si vous souhaitez ajouter plusieurs répertoires à
exec-path
, vous devez utiliseradd-to-list
plusieurs fois.Vous pouvez le faire soit manuellement
ou en utilisant une boucle
Concernant votre troisième question, si emacs a été lancé à partir de l'environnement de bureau, il en hérite, ce qui pourrait être moins complet que celui d'un shell complet.
Cela signifie qu'il peut parfois être nécessaire de compléter la valeur d'Emacs pour
$PATH
utiliser ce que voit un shell standard. C'est le but de laexec-path-from-shell
bibliothèque que vous mentionnez.la source