Recarregar variáveis ​​de ambiente

10

Esta pergunta foi feita no superusuário existe uma maneira de recarregar variáveis ​​de ambiente no emacs , mas nenhuma boa solução foi fornecida.

Estou usando o EmacsClient com frequentemente mais de 30 buffers abertos; se eu alterar uma variável de ambiente no shell, preciso sair do EmacsClient (e reabrir todos os buffers) ou preciso definir manualmente a variável de ambiente também no Emacs. Acho irritante não poder atualizar facilmente as variáveis ​​de ambiente no Emacs. Alguma sugestão?

Håkon Hægland
fonte
Não há uma maneira direta de fazer isso, porque alterar uma variável de ambiente no processo pai não atualizará seu valor conforme exportado para um filho.
Erik Hetzner

Respostas:

7

exec-path-from-shell fornece o exec-path-from-shell-copy-envcomando, que permite copiar o valor das variáveis ​​de ambiente nas sessões do Emacs. Por exemplo, M-x exec-path-from-shell-copy-env RET FOOdefine o valor de $FOOno Emacs também.

Observe que exec-path-from-shell-copy-envgera um novo shell para extrair o valor da variável de ambiente. Portanto, ele funcionará apenas para variáveis ​​definidas nos arquivos de configuração do shell (por exemplo .bashrc), mas não para variáveis ​​definidas apenas em uma sessão do shell em execução export. Extrair essas variáveis ​​geralmente é impossível sem hacks complicados que inspecionam /proc/ou API semelhante para processos em execução.

lunaryorn
fonte
Com relação aos últimos valores / transitórios, se o Emacs estiver em execução como servidor, será fácil passar os valores atualizados para o emacsclient diretamente desse shell.
Phill
@phils Graças, veja a minha resposta atualizados ..
Håkon Hægland
5

Como solução alternativa, é possível usar o seguinte (Linux, Bash):

  • Primeiro execute a printenv -0 > env.txtpartir da janela do terminal Bash,
  • Então, no Emacs, execute
(defun my-update-env ()
  (interactive)
  (let ((str 
         (with-temp-buffer
           (insert-file-contents "env.txt")
           (buffer-string))) lst)
    (setq lst (split-string str "\000"))
    (while lst
      (setq cur (car lst))
      (when (string-match "^\\(.*?\\)=\\(.*\\)" cur)
        (setq var (match-string 1 cur))
        (setq value (match-string 2 cur))
        (setenv var value))
      (setq lst (cdr lst)))))

Atualizar

Acontece que isso pode ser feito de maneira mais elegante usando a --evalopção do emacsclientcomando: Define a Bash script update_emacs_env:

#! /bin/bash

fn=tempfile
printenv -0 > "$fn" 
emacsclient -s server_name -e '(my-update-env "'"$fn"'")' >/dev/null

Onde server_nameestá o nome do servidor Emacs e my-update-envé uma função definida pelo seu ~/.emacsarquivo:

(defun my-update-env (fn)
  (let ((str 
         (with-temp-buffer
           (insert-file-contents fn)
           (buffer-string))) lst)
    (setq lst (split-string str "\000"))
    (while lst
      (setq cur (car lst))
      (when (string-match "^\\(.*?\\)=\\(.*\\)" cur)
        (setq var (match-string 1 cur))
        (setq value (match-string 2 cur))
        (setenv var value))
      (setq lst (cdr lst)))))

Agora você pode simplesmente digitar update_emacs_envna linha de comando do shell para atualizar as variáveis ​​de ambiente do Emacs.

Håkon Hægland
fonte
E você pode executar o "printenv" a partir de dentro da função também ...
Mankoff
@mankoff Na verdade, eu acho que você não podia .. :) (Seria imprimir os valores antigos então)
Håkon Hægland
Você não pode gerar um shell com o sinalizador de login? Ou sourceo .bashrc, .bash_profile etc.?
Mankoff
Sim .. mas não ajudaria no caso especial se eu exportar no shell diretamente da linha de comando, usandoexport VAR=value
Håkon Hægland
Sim, eu não pensei nesse caso. Solução elegante com o cliente!
Mankoff
3

Eu costumava usar isso:

function export-emacs {
    if [ "$(emacsclient -e t)" != 't' ]; then
        return 1
    fi

    for name in "${@}"; do
        value=$(eval echo \"\$${name}\")
        emacsclient -e "(setenv \"${name}\" \"${value}\")" >/dev/null
    done
}

Permite exportar uma variável nomeada, EG:

export EDITOR=vim
export-emacs EDITOR
Phil Jackson
fonte