Emacs como daemon no OS X com sistema de janelas

13

Estou executando o gnu emacs 23.3.1 cacau build no OS X 10.6.
Eu adicionei o seguinte a ~ / Library / LaunchAgents / gnu.emacs.daemon.plist para que ele inicie um daemon e reinicie automaticamente o emacs se eu inadvertidamente o matar.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" 
    "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> 
 <plist version="1.0">
  <dict> 
    <key>Label</key>
    <string>gnu.emacs.daemon</string>
    <key>ProgramArguments</key>
    <array>
      <string>/Applications/Emacs.app/Contents/MacOS/Emacs</string>
      <string>--daemon</string>
    </array>
   <key>RunAtLoad</key>
   <true/>
   <key>KeepAlive</key>
   <true/>
   <key>ServiceDescription</key>
   <string>Gnu Emacs Daemon</string>
  </dict>
</plist>

Esta sorta funciona, mas notei que o meu tema de cores não estava funcionando corretamente. Então eu lembrei que tinha adicionado o seguinte ao meu arquivo init:

(when window-system 
  (require 'alpha)
  (require 'color-theme-ir-black)
  (modify-frame-parameters (selected-frame) '((alpha . 85)))
  (color-theme-ir-black))

Quando iniciado como um daemon window-system é falso aparentemente e isso faz sentido, no entanto a razão pela qual eu adicionei isso é porque eu ocasionalmente gosto de iniciar o emacs normal em um terminal do ssh etc e este esquema de cores é completamente ilegível iTerm assim o (quando o sistema de janela ...). Existe uma maneira de forçar o emacs a iniciar o modo de janela ao iniciar com --daemon?

Outro problema que eu notei é que quando eu executo pressiono s-w (delete-frame) no modo dameon eu não recebo a tentativa de erro de deletar o único frame visível ou iconificado e o emacs continua rodando em segundo plano. Eu gosto disso na maior parte do tempo, mas notei que uma vez que o último quadro é morto eu não posso mais reabrir emacs do doc e, embora emacs irá ativar e menus são exibidos eles não funcionam e eu não posso criar um novo quadro exceto usando o emacsclient na linha de comando. Alguém mais tem esse problema e / ou recomendação sobre solução alternativa? talvez eu possa ligar s-w para detectar se o último frame e o iconify-frame em vez disso, mas não tenho certeza porque ele acha que não é a última janela e me permitiu matá-lo em primeiro lugar.

ATUALIZAÇÃO:

Eu encontrei um comentário no seguinte blog por Steve Purcell com uma correção para um problema muito semelhante: link

O segredo que parece é usar o hook after-make-frame-functions para configurar o frame recém-criado e também para (setq color-theme-is-global nil) para que cada frame possa ter seu próprio tema de cores. Então, as seções relevantes do meu init agora se parecem com isso:

(defvar after-make-console-frame-hooks '()
"Hooks to run after creating a new TTY frame")
(defvar after-make-window-system-frame-hooks '()
"Hooks to run after creating a new window-system frame")

(defun run-after-make-frame-hooks (frame)
"Selectively run either 'after-make-console-frame-hooks' or
'after-make-window-system-frame-hooks'"
  (select-frame frame)
  (run-hooks (if window-system
               'after-make-window-system-frame-hooks
               'after-make-console-frame-hooks)))

(add-hook 'after-make-frame-functions 'run-after-make-frame-hooks)
(add-hook 'after-init-hook (lambda ()
  (run-after-make-frame-hooks (selected-frame))))


(setq color-theme-is-global nil)

(add-hook 'after-make-window-system-frame-hooks
          '(lambda ()
             (require 'alpha)
             (require 'color-theme-ir-black)
             (modify-frame-parameters (selected-frame) '((alpha . 85)))
             (color-theme-ir-black)
             (global-set-key (kbd "s-w") 'delete-frame)))

No entanto, ainda estou tendo o problema em que delete-frame fecha o último quadro quando o emacs foi iniciado como daemon e não me permite criar um novo quadro diferente do emacsclient.

ATUALIZAÇÃO:

Se eu eval (frame-list) , vejo que há dois quadros listados, embora apenas um esteja visível. Notei que isso não ocorre se eu iniciar o Emacs com /Applications/Emacs.app em vez de emacsclient. Eu normalmente inicio o emacs a partir da linha de comando com um apelido e='emacsclient -c -n ' , que é o que cria o segundo quadro. Eu só consigo anexar ao outro quadro iniciando o emacs com o comando aberto. Se eu tentar o emacsclient -n somefile sem -c não recebo nada, e se eu executar emacsclient -n -e '(frame-list)' , vejo que há um quadro que não é visível até usar -c para criar novo quadro ou abrir o emacs a partir da pasta de aplicativos.

    
por Kurt Harriger 04.06.2011 / 15:33

1 resposta

1

A execução de um processo ou aplicativo como um daemon launchd concede a ele um ambiente muito diferente de executá-lo normalmente ou na linha de comando. Gostaria de saber se não seria melhor usar um script de shell como um item de login.

Por exemplo:

#!/bin/bash
while true
do
  open -W /Applications/Emacs.app
done

Esse script precisaria ser salvo em um arquivo com a extensão .command e as permissões 755 ( chmod 0755 myemacsscript.command ) e, em seguida, adicionado ao painel Preferências do sistema: Login: Itens de login.

Ao fazer o login, o Terminal iniciará e executará este script. Você provavelmente desejará configurar um perfil de terminal padrão que exclua o terminal da solicitação de mensagem para este script específico, para que ele não o retenha quando você efetuar logout.

Eu não tenho idéia se isso irá corrigir os problemas específicos com o Emacs.app, mas pode pelo menos fornecer um ambiente mais próximo do que o Emacs.app espera.

    
por 15.08.2012 / 23:00