Emacsdaemon e Emacsclient no Mac

25

SO: OS X 10.9.5, Mavericks

GNU Emacs 24.3.1 (x86_64-apple-darwin13.1.0, versão de carbono 1.6.0 AppKit 1265.19) de 03/04/2014 em Rainers-MacBook-Pro-3.local

Eu instalei o emacs via homebrew da railwaycat e funciona muito bem - sem queixas. Eu não uso o emacs no termoinal e normalmente inicio-o através do aplicativo.

Como eu disse - estou feliz até agora.

Só tenho uma coisa que não consegui acertar (que funcionava muito bem no Linux antes), que é:

  1. obtenha o daemon do emacs a partir do login
  2. usando o emacsclient para abrir
  3. feche o emacsdaemon e salve todos os arquivos no logoff

Alguma receita de trabalho que possa me ajudar a configurar isso?

Informação adicionada

Para iniciar um daemon emacs após o login

Criei um aplicativo Automator executando o comando bash

/usr/local/bin/emacs --daemon

e adicionou aos itens de login, o que funciona muito bem.

Utilizando o Daemon do Terminal

Posso utilizar o daemon emacs usando

emacsclient .bashrc

que abre o .bashrc em uma sessão do terminal emacs.

Utilizando a partir da GUI

Agora permanece a pergunta: como posso utilizá-lo na GUI?

Como eu entendo o emacsclient, não posso abrir um emacsclient a menos que especifique um arquivo para abrir.

Gostaria de abrir uma GUI do emacsclient e abrir todos os arquivos que foram abertos anteriormente ? Isso é possível?

Eu descobri que posso usar

emacsclient -c

em um terminal para fazer o que eu quero - mas posso fazer o mesmo pela GUI?

Rainer
fonte
Não entendo o que "da GUI" significa aqui. Isso pode significar "clicar duas vezes em um arquivo no Finder" ou em algo completamente diferente.
tarsius 25/09/14
Usando o NAL (por exemplo, por meio de destaque)
Rainer
O Disparador de Aplicativos permite selecionar arquivos (que são abertos usando o aplicativo padrão para o tipo de arquivo). Ou apenas "Aplicativos"? emacsclientnão é um aplicativo no que diz respeito ao OS X, apenas o Emacsé (e somente se tiver sido instalado dessa maneira). Por que você não usa as ligações de teclas do sistema para selecionar um aplicativo / janela aberto? (Não funcionará se o Emacs tiver sido iniciado no modo daemon e ainda não houver quadro ("janela")).
tarsius 26/09/14
Eu defini um aplicativo chamado Emacsclient que inicia o emacsclient - então o aplicativo Emacsclient está lá. Obviamente, eu poderia mudar para uma instância do emacs em execução - mas isso é além do ponto, observando o fluxo de trabalho descrito acima.
Rainer
11
Esta questão é quase mais útil do que suas respostas :)
Roy Truelove

Respostas:

6

Realmente não me importo que o Emacs.app esteja sempre em execução, mas o fato de não poder fechar a janela sem matar acidentalmente o servidor Emacs era irritante. E mesmo se você tentar realmente matar o último quadro, ele ainda não permitirá: "Tente excluir o único quadro visível ou iconificado". ... Então nós trapaceamos.

Esta solução apenas oculta o Emacs (como Command+ h) quando você tenta fechar a última janela clicando no botão Fechar.

Adicione o seguinte ao seu Emacs init em algum lugar:

(defadvice handle-delete-frame (around my-handle-delete-frame-advice activate)
  "Hide Emacs instead of closing the last frame"
  (let ((frame   (posn-window (event-start event)))
        (numfrs  (length (frame-list))))
    (if (> numfrs 1)
      ad-do-it
      (do-applescript "tell application \"System Events\" to tell process \"Emacs\" to set visible to false"))))

E adicione o Emacs a "Usuários e grupos> Itens de login" e clique na caixa de seleção "Ocultar".

Seu init do Emacs também precisa ligar para (start-server)algum lugar.

Estou usando este emacsclientwrapper para trazer o Emacs para a frente primeiro:

#!/bin/sh
osascript -e 'tell application "Emacs" to activate'
exec emacsclient "$@"

Problemas:

  • A ativação / exibição do Emacs traz todas as janelas para a frente. Isso é um pouco chato.
  • Clicar no ícone do Emacs no Dock parece criar uma nova janela aleatoriamente. Mas não sempre.
  • TODO: Talvez fazer Command+ wno último quadro também oculte o Emacs?
  • NOVO com edição: clicar no ícone do dock quando todas as janelas são minimizadas não maximiza automaticamente uma delas.

Isso se baseia na resposta do @ noaham, sugerindo minimizar o Emacs, e esta resposta explicando como conectar tentando fechar a última janela.

EDITAR:

Pesquisando pela fonte, encontrei a "ligação de teclas" para amac-apple-event-map qual as chamadas mac-ae-reopen-application. mac-ae-reopen-applicationparece verificar quadros visíveis e iconificados e, de alguma forma, deve perder o nosso oculto. Isso é possivelmente um bug.

A solução mais fácil é desabilitar a ligação de teclas no seu init:

(define-key mac-apple-event-map [core-event reopen-application] nil)

Isso introduz um novo bug menor: clicar no ícone do dock quando todas as janelas são minimizadas não maximiza automaticamente uma delas. A correção correta seria reescrever mac-ae-reopen-application, mas eu mal conheço emacs e elisp.

bburky
fonte
Se alguém descobrir como parar a nova janela aleatória (ponto dois), por favor me diga. Talvez seja a única coisa que ainda me incomoda nessa configuração.
parent5446
@ parent5446, pronto! Tão hacky quanto a primeira correção, mas funciona.
bburky
Obrigado! A parte do hack não me incomoda, pois na maioria das vezes eu não inicio o Emacs a partir do dock de qualquer maneira.
parent5446
4

Infelizmente, a porta Yamamoto Mitsuharu do emacs não suporta multi-tty (consulte esta edição ). Isso significa que você não pode iniciar o daemon emacs a partir do terminal e iniciar uma janela da interface gráfica com o emacsclient.

Aqui está o que eu faço: No meu init.el eu tenho (server-start)e inicio o Emacs.app no ​​login. O aborrecimento aqui é que isso abre uma janela que eu tenho que minimizar manualmente.

Em seguida, tenho um script bash chamado emacsccom o seguinte

#!/bin/bash                                                                          
export PATH=/usr/local/bin:/usr/bin:/bin:/usr/local/sbin:/usr/sbin:/sbin
emacsclient -n -c

Em seguida, crio um aplicativo com o AppleScript que contém os seguintes

tell application "Emacs"
    activate
end tell
do shell script "~/bin/emacsc"

É importante passar a -nbandeira para o emacsclient, caso contrário, você poderá usar o aplicativo emacsc apenas para abrir um cliente por vez. A configuração da variável de caminho garante que o OS X encontre a versão correta do emacsclient.

Dizer ao Emacs para "ativar" garante que a janela do seu cliente será iniciada em primeiro plano.

Como eu disse, o aborrecimento é que você precisa minimizar manualmente a janela do emacs no logon e deixá-la no banco dos réus. Uma maneira de evitar isso é "ocultar" o Emacs automaticamente após o login, mas ativá-lo fará com que ele seja reexibido.

noaham
fonte
2

Não tenho certeza de como o Emacs railwaycat é diferente da fórmula comum de fabricação caseira, mas com o último você faria ln -sfv /usr/local/opt/emacs/*.plist ~/Library/LaunchAgents, o que seria executado emacs --daemonno login.

O plist é incluído como um documento HERE no fórmula . Tudo o que você precisa adotar é mudar o caminho para o seu aplicativo emacs na linha <string>#{opt_bin}/emacs</string>.

BTW, você também pode obter o Emacs como um aplicativo OS X com o Homebrew Emacs se você instalá-lo com a --cocoaopção (Você também precisará executar brew linkappsposteriormente, vinculá-lo /Applicationsou criar o link você mesmo.

Davor Cubranic
fonte
1

No mac, os daemons são, 90% do tempo, gerenciados usando o launchd . É possível executá-los em vários gatilhos, incluindo login / logout do usuário. Existe um aplicativo Mac bonito chamado Lingon para visualizar e editar as várias coisas que o launchd está gerenciando. O wiki do emacs tem algumas menções a isso, incluindo e um arquivo de configuração de exemplo . Mas parece que isso não resolve a sua preocupação, ou seja, como desligar o daemon no logout.

Ben Hyde
fonte
0

Crie um aplicativo AppleScript como este:

tell application "Terminal"
do shell script "/usr/local/bin/emacsclient -c"
endtell

Pode ser necessário ajustar o caminho ou deixar de fora completamente o caminho. Você também pode usar algo mais sofisticado para iniciar o daemon, se ele ainda não estiver em execução.

tarso
fonte
@Rainer Tendo algum sucesso com isso? Você também pode procurar uma implementação mais sofisticada que até inicie o daemon, se necessário, antes de conectar-se a ele usando o emacsclient. "AppleScript emacsclient" fornece bons resultados com a pesquisa no Google.
tarsius
Você ainda está esperando uma resposta melhor ou seria possível aceitá-la?
tarsius