Configuração básica do servidor Emacs no OSX

Configuração básica do servidor Emacs no OSX

Comprei recentemente meu primeiro Mac em uma década e estou configurando-o. Sou um usuário do Emacs e decidi que queroapenas Emacs normaisnão o Aquamacs para que eu possa usar minha configuração existente de outros sistemas operacionais. Tentei seguir vários tutoriais que encontrei on-line (comoEste,Esteeeste do site de onde baixei o Emacs) e tentei combinar as peças de várias maneiras, mas nunca coloquei as coisas em um estado que se aproximasse do que estou acostumado/esperando:

  1. Um daemon Emacs começa a rodarna inicializaçãoouassim que eu precisar; qualquer um está bom. Quaisquer novos quadros Emacs são apoiados pelo mesmo servidor.
  2. Quando abro um arquivo de texto no Finder, o arquivo é aberto no Emacs, em um quadro gráfico existente, se possível.
  3. Se eu executar o Emacs.app, o sistema reutilizará o daemon emacs que está sendo executado em segundo plano, em vez de iniciar uma nova instância e abrir uma nova janela nela. (gorjeta de chapéu)
  4. Quando executo o Emacs a partir de um terminal, o terminal cuida de seus negócios sem esperar que eu termine com o Emacs (a menos que eu use '-nw')
  5. AFAIK em nenhum momento durante as operações descritas acima o Emacs deve terminar em um estado ("modo de edição de servidor?") Onde está esperando que eu digite C-x #, embora eu não tenha um conhecimento profundo disso.
  6. (Eu consideraria isso um bônus) Existe alguma maneira de invocar o Emacs a partir de um terminal para que o Emacs reutilize um quadro existente, se possível.

Como eu poderia configurar o Emacs para se comportar assim?

Estou particularmente perplexo ao fazer com que o Finder abra coisas no Emacs da maneira que desejo (# 2), já que os guias que encontrei geralmente criam vários aliases, Applescripts, scripts bash, etc. que quero dizer ao Finder para usar para abrir arquivos de texto.

Obrigado!

A.@lawlist pergunta: "Um novo quadro está sendo aberto por padrão quando você abre um novo arquivo no terminal, mesmo que haja um quadro existente?" A resposta é que se eu iniciar um servidor na inicialização conforme descritoaqui, abrir um quadro e, em seguida, abrir um arquivo digitando /Applications/Emacs.app/Contents/MacOS/bin/emacsclient -n <whatever>, posso fazer com que o arquivo seja aberto em um quadro existente. Se não houver nenhum quadro aberto no momento, tenho que usar "-nc" ou quando tento abrir um arquivo nada acontece.

B.@lawlist pergunta: "Você deseja que o daemon seja executado no login ou seria suficiente carregar o Emacs manualmente após o login?" Executar manualmente seria bom.

Responder1

Para fazer o Emacs.app abrir arquivos em um quadro existente em vez de um novo quadro, adicione (setq ns-pop-up-frames nil)a um arquivo de configuração como ~/.emacs.

Você pode abrir um arquivo de um terminal com open -a emacs fileou emacsclient -n file. Se o Emacs.app não estiver aberto, mas houver um Emacs --daemonprocesso, por algum motivo emacsclient -n filenão funciona, mas emacsclient -nc filefunciona.

Certifique-se de usar o emacsclientbinário incluído na versão do Emacs que você usa, como /Applications/Emacs.app/Contents/MacOS/bin/emacsclient, ou /usr/local/bin/emacsclientse você instalou o Emacs com Homebrew.

Para iniciar um servidor Emacs no login, por exemplo, salve este plist como ~/Library/LaunchAgents/my.emacsdaemon.plist:

<?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>my.emacsdaemon</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/> <!-- run the program again if it terminates -->
</dict>
</plist>

O plist é carregado automaticamente na próxima vez que você fizer login, mas você pode carregá-lo imediatamente executando launchctl load ~/Library/LaunchAgents/my.emacsdaemon.plist.

Editar: ainda não sei por que as pessoas estão associando tipos de arquivo a um aplicativo AppleScript em vez de apenas ao Emacs.app. O script na resposta de kuzzooroo também pode ser escrito como um script de shell:

macos=/Applications/Emacs.app/Contents/MacOS
if pgrep -qf 'Emacs.*--daemon'; then
  [[ $($macos/bin/emacsclient -e '(<= 2 (length (visible-frame-list)))') = t ]] && args=-nc || args=-n
else
  $macos/Emacs --daemon
  args=-nc
fi
$macos/bin/emacsclient $args "$@"
open -a /Applications/Emacs.app

Você pode usarOrnitorrincopara salvar o script como um aplicativo:

Acabei de começar a usar o Emacs, mas tenho uma configuração completamente diferente. Criei meu próprio aplicativo Emacs fazendo uma cópia do iTerm.app, alterando o CFBundleIdentifier no Info.plist para que o aplicativo use um arquivo de preferências diferente e definindo o comando padrão como /usr/local/bin/emacs. (server-start)Eu adicionei ~/.emacse abro o aplicativo Emacs personalizado no login. Usei o Platypus para criar um aplicativo que roda emacsclient -n "$@";open -b my.emacse tornei-o o aplicativo padrão para arquivos de texto.

Responder2

A solução de Lauri combinada com as sugestões dos comentários resolveram amplamente meus problemas. Colei abaixo alguns Applescript que juntei de coisas que encontrei online. O script ajuda a suavizar algumas rugas restantes, por exemplo, seu comportamento é um pouco melhor se não houver nenhum quadro Emacs atual.

EDIT: o objetivo do script é ser associado a arquivos .txt no Finder.

-- http://superuser.com/questions/457484/how-to-open-emacs-from-macs-finder
-- https://gist.github.com/ambethia/304964#comment-799519
on run {input}
    set filepath to quoted form of POSIX path of input
    tell application "Terminal"
        try
            -- we look for <= 2 because Emacs --daemon seems to always have an entry in visibile-frame-list even if there isn't
            set frameVisible to do shell script "/Applications/Emacs.app/Contents/MacOS/bin/emacsclient -e '(<= 2 (length (visible-frame-list)))'"
            if frameVisible is "t" then
                do shell script "/Applications/Emacs.app/Contents/MacOS/bin/emacsclient -n " & filepath
            else
                -- there is a not a visible frame, launch one
                do shell script "/Applications/Emacs.app/Contents/MacOS/bin/emacsclient -c -n " & filepath
            end if
        on error
            -- daemon is not running, start the daemon and open a frame     
            do shell script "/Applications/Emacs.app/Contents/MacOS/Emacs --daemon"
            do shell script "/Applications/Emacs.app/Contents/MacOS/bin/emacsclient -c -n"
        end try
    end tell

    -- bring the visible frame to the front
    tell application "Emacs" to activate

    return input
end run

informação relacionada