Como posso avaliar o elisp em um arquivo orgmode quando ele é aberto?


13

Eu tenho o código elisp que gostaria de executar nos arquivos orgmode quando eles são carregados (diferentes para arquivos diferentes e definidos no próprio arquivo). Existe uma maneira de fazer isso? Não vi nada em http://orgmode.org/manual/In_002dbuffer-settings.html

Se eu puder adicionar algo à inicialização do emacs que executa um bloco de código especialmente nomeado sempre que um arquivo orgmode é carregado, isso pode ser uma solução, mas não tenho certeza de como fazer isso e, idealmente, há algo embutido.


11
Variáveis ​​de arquivo local, talvez?
Dan

Isso funciona! Deseja transformar em uma resposta que eu possa aceitar?
avv

Pensando melhor, que é um ambiente muito confuso para editar, portanto, uma boa solução teria a variável local do arquivo executando um bloco de código nomeado.
avv

Envolvê-lo em um progn ou lambda, talvez?
Dan

3
Você também pode usar, # -*- eval: (lisp code here) -*-mas também precisa estar ciente dos perigos. Mesmo que você não compartilhe esses documentos com mais ninguém, a natureza interpretada do Emacs Lisp significará que uma alteração pode resultar acidentalmente em perda de dados. Além disso, o gancho de modo soa como uma opção melhor se você deseja executar o mesmo código para mais de um arquivo.
wvxvw

Respostas:


9

Esta solução não requer alterações init.el(com pequenas modificações). Porém, envolve avaliações locais de arquivos - mas é exatamente isso que o OP solicitou. As vantagens da solução são:

  • pede confirmação para avaliar o código
  • O código elisp pode ser editado e testado no ambiente org-babel
  • como a solução não requer modificações init.elno arquivo orgmode, pode ser compartilhada entre usuários (confiáveis)

Estou reformulando a solução aqui.

Adicione um bloco src em algum lugar do seu arquivo:

#+NAME: startup
#+BEGIN_SRC emacs-lisp
(your-code-here)
#+END_SRC

Em seguida, coloque isso no final do seu arquivo orgmode:

# Local Variables:
# eval: (progn (org-babel-goto-named-src-block "startup") (org-babel-execute-src-block) (outline-hide-sublevels 1))
# End:

Eu adicionei (outline-hide-sublevels 1)porque gosto de ocultar o bloco src dentro de um cabeçalho e quero que os subníveis estejam ocultos na inicialização. Sem essa declaração, os subníveis serão expandidos por (org-babel-goto-named-src-block "startup").

Com esta solução, o emacs solicitará duas vezes a permissão para executar (1º: aplicar variáveis ​​locais; 2º: executar "startup" -src-block). Como tenho muitos blocos src no meu arquivo, configurei outro arquivo-local-variável org-confirm-babel-evaluate, como este:

# Local Variables:
# org-confirm-babel-evaluate: nil
# eval: (progn (org-babel-goto-named-src-block "startup") (org-babel-execute-src-block) (outline-hide-sublevels 1))
# End:

Aviso: Com essa adição, o emacs solicitará apenas uma vez a permissão para executar - todos os blocos src nesse arquivo agora podem ser executados sem confirmação adicional. Como outros já apontaram antes, esse comportamento pode ser perigoso e você deve ter muito cuidado com essa configuração.

No entanto, eu argumentaria que esta solução (especialmente a primeira versão) é mais segura do que a fornecida por Joe Corneli, porque pelo menos você será solicitado a confirmar a execução. A solução de Joe avaliará o bloco especial sem confirmação, se ele for encontrado no arquivo. Um atacante teria que adivinhar o nome do bloco especial, é claro ...

Estou usando essa abordagem para escrever documentos grandes que requerem, por exemplo, adaptações nos mecanismos de exportação da organização.


5

org-mode... Além de qualquer gancho que seu modo pai outline-modepossa ter executado, esse modo executa o gancho org-mode-hook, como a etapa final durante a inicialização.

Então, no seu init.el:

(defun function-that-finds-and-evaluates-special-block ()
;; DWIM :-)
)
(add-hook 'org-mode-hook 'function-that-finds-and-evaluates-special-block)

Isso me parece mais razoável do que os arquivos locais do arquivo, para esta tarefa. Mas talvez eu esteja perdendo alguma coisa.
Tirou

@ Joe Corneli E então o que você colocaria no arquivo organizacional real?
22415 incandescentman

Nada de especial, exceto o "bloco especial".
Joe Corneli 24/07

3

Desde que você pede

(diferente para arquivos diferentes e definido no próprio arquivo)

então, tente esta solução .


Importa-se de explicar por que o voto negativo?
Usuário Emacs

É porque as respostas que são apenas links para outras respostas são desencorajadas. Dito isto, talvez esta pergunta seja uma brincadeira com a qual você está vinculado?
Linus Arver

1

Concordo com a sugestão de Joe Corneli sobre o uso de um gancho.

Ocorre-me também que você pode aproveitar os favoritos aqui: coloque um marcador específico no gancho. Uma vantagem de um marcador para o bloco de código é que ele geralmente é realocado automaticamente (por exemplo, à medida que o conteúdo do arquivo é alterado); portanto, a localização do bloco deve ser cuidada automaticamente.

[Mas não está claro para mim porque você tem o código nos arquivos do modo Org, em vez de em outro lugar. Estamos tomando isso como um dado, de acordo com a declaração do problema, mas me pergunto por que você está fazendo isso. Informar-nos mais sobre o design a esse respeito pode levar a uma melhor ajuda.]


0

Eu tentei melhorar o código de Joe Corneli:

Você precisa disso no seu arquivo init.el:

  (defun tdh/eval-startblock ()
    (if (member "startblock" (org-babel-src-block-names))
      (save-excursion
        (org-babel-goto-named-src-block "startblock")
        (org-babel-execute-src-block))
      nil
      )
    )
  (add-hook 'org-mode-hook 'tdh/eval-startblock)

Cada vez que você abre um buffer de modo organizacional, ele procura um bloco de origem chamado startblock; se um for encontrado, ele será executado.

Nos seus arquivos de modo organizacional, você pode colocar:

#+NAME: startblock
#+BEGIN_SRC emacs-lisp
  ;; Any code you want
#+END_SRC
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.