Emacsdaemon et Emacsclient sur Mac

25

Système d'exploitation: OS X 10.9.5, Mavericks

GNU Emacs 24.3.1 (x86_64-apple-darwin13.1.0, Carbon Version 1.6.0 AppKit 1265.19) du 2014-04-03 sur Rainers-MacBook-Pro-3.local

J'ai installé emacs via homebrew de railwaycat et cela fonctionne bien - rien à redire. Je n'utilise pas emacs dans le termoinal, et je le démarre généralement via l'application.

Comme je l'ai dit - je suis heureux jusqu'à présent.

J'ai juste une chose que je n'ai pas réussi à bien faire (qui fonctionnait bien sous Linux auparavant), qui est:

  1. obtenir le démon emacs à partir de la connexion
  2. utiliser emacsclient pour ouvrir
  3. fermez emacsdaemon et enregistrez tous les fichiers à la déconnexion

Des recettes de travail qui pourraient m'aider à mettre cela en place?

Ajout d'informations

Pour démarrer un démon emacs lors de la connexion

J'ai créé une application Automator exécutant la commande bash

/usr/local/bin/emacs --daemon

et l'a ajouté aux éléments de connexion qui fonctionne bien.

Utilisation du démon du terminal

Je peux utiliser le démon emacs en utilisant

emacsclient .bashrc

qui ouvre .bashrc dans une session de terminal emacs.

Utilisation depuis l'interface graphique

Reste maintenant la question: comment puis-je l'utiliser à partir de l'interface graphique?

Si je comprends bien l'emacsclient, je ne peux pas ouvrir un emacsclient à moins de spécifier un fichier à ouvrir.

Je voudrais ouvrir une interface graphique emacsclient et ouvrir tous les fichiers qui ont été précédemment ouverts ? Est-ce possible?

J'ai découvert que je peux utiliser

emacsclient -c

dans un terminal pour faire ce que je veux - mais puis-je faire de même pour l'interface graphique?

Rainer
la source
Je ne comprends pas ce que "de l'interface graphique" signifie ici. Cela pourrait signifier "double-cliquer sur un fichier dans le Finder" ou autre chose.
tarsius
Utilisation du lanceur d'applications (par exemple via Spotlight)
Rainer
Le lanceur d'applications permet-il de sélectionner des fichiers (qui sont ensuite ouverts à l'aide de l'application par défaut pour le type de fichier). Ou seulement des "applications"? emacsclientn'est pas une application en ce qui concerne OS X, seulement Emacs(et seulement si elle a été installée de cette façon). Pourquoi n'utilisez-vous pas simplement les liaisons de touches système pour sélectionner une application / fenêtre ouverte? (Ne fonctionnera pas si Emacs a été démarré en mode démon et qu'il n'y a pas encore de frame ("fenêtre")).
tarsius
J'ai défini une application appelée Emacsclient qui lance l'emacsclient - donc l'application Emacsclient est là. Je pourrais évidemment passer à une instance emacs en cours d'exécution - mais c'est d'ailleurs le point, en regardant le flux de travail décrit ci-dessus.
Rainer
1
Cette question est presque plus utile que ses réponses :)
Roy Truelove

Réponses:

6

Cela ne me dérange vraiment pas qu'Emacs.app fonctionne toujours, mais le fait que je ne puisse pas fermer la fenêtre sans tuer accidentellement le serveur Emacs était ennuyeux. Et même si vous essayez vraiment de tuer la dernière image, cela ne vous permet toujours pas: "Essayez de supprimer la seule image visible ou iconifiée". ... Alors on triche.

Cette solution masque simplement Emacs (comme Command+ h) lorsque vous essayez de fermer la dernière fenêtre en cliquant sur le bouton Fermer.

Ajoutez quelque chose à votre init Emacs quelque part:

(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"))))

Et ajoutez Emacs à "Utilisateurs et groupes> Éléments de connexion", puis cochez la case "Masquer".

Votre init Emacs doit également appeler (start-server)quelque part.

J'utilise ce emacsclientwrapper pour amener Emacs au premier plan:

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

Problèmes:

  • Activer / afficher Emacs amène toutes les fenêtres au premier plan. C'est un peu gênant.
  • Cliquer sur l'icône Emacs dans le Dock semble parfois créer au hasard une nouvelle fenêtre. Mais pas toujours.
  • TODO: Peut-être que make Command+ wsur la dernière image masque également Emacs?
  • NOUVEAU avec modification: cliquer sur l'icône du dock lorsque toutes les fenêtres sont réduites ne maximise pas automatiquement l'une d'entre elles.

Ceci est basé sur la réponse de @ noaham suggérant de minimiser Emacs, et cette réponse expliquant comment accrocher en essayant de fermer la dernière fenêtre.

MODIFIER:

En cherchant dans la source, j'ai trouvé la "liaison de clé" pourmac-apple-event-map laquelle les appels mac-ae-reopen-application. mac-ae-reopen-applicationsemble vérifier les cadres visibles et iconifiés et doit en quelque sorte manquer notre cadre caché. C'est peut-être un bug.

La solution simple consiste simplement à désactiver la liaison de clé dans votre init:

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

Cela introduit un nouveau bug mineur: cliquer sur l'icône du dock lorsque toutes les fenêtres sont réduites ne maximise pas automatiquement l'une d'entre elles. La bonne solution serait de réécrire mac-ae-reopen-application, mais je connais à peine emacs et elisp.

bburky
la source
Si quelqu'un trouve comment arrêter la nouvelle fenêtre aléatoire (puce deux), dites-le-moi. C'est peut-être la seule chose qui me dérange encore sur cette configuration.
parent5446
@ parent5446, c'est fait! Tout aussi hacky que le premier correctif, mais cela fonctionne.
bburky
Merci! Le piratage ne me dérange pas car la plupart du temps je n'initie pas Emacs depuis le dock de toute façon.
parent5446
4

Le port d'emacs de Yamamoto Mitsuharu ne prend malheureusement pas en charge le multi-tty (voir ce numéro ). Cela signifie que vous ne pouvez pas démarrer le démon emacs à partir du terminal et lancer une fenêtre gui avec emacsclient.

Voici ce que je fais: Dans mon init.el, je l'ai (server-start)et je lance Emacs.app à la connexion. L'ennui ici est que cela ouvre une fenêtre que je dois minimiser manuellement.

J'ai ensuite un script bash appelé emacscavec ce qui suit

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

Je crée ensuite une application avec applescript qui contient les éléments suivants

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

Il est important de passer le -ndrapeau à emacsclient sinon vous ne pourrez utiliser l'application emacsc que pour ouvrir un client à la fois. La définition de la variable de chemin d'accès garantit qu'OS X peut trouver la version correcte d'emacsclient.

Dire à Emacs d '«activer» garantit que votre fenêtre client sera lancée au premier plan.

Comme je l'ai dit, la gêne est que vous devez minimiser manuellement la fenêtre emacs lors de la connexion, puis la faire asseoir sur le dock. Une façon d'éviter cela est de "masquer" automatiquement Emacs après la connexion, mais le faire activer le fera apparaître.

noaham
la source
2

Je ne sais pas en quoi le chemin de fer Emacs est différent de la formule habituelle de brassage maison, mais avec ce dernier, vous le feriez ln -sfv /usr/local/opt/emacs/*.plist ~/Library/LaunchAgents, qui fonctionnerait emacs --daemonlors de la connexion.

Le plist est inclus en tant que document ICI dans la formule . Tout ce dont vous avez besoin pour l'adopter est de modifier le chemin d'accès à votre application emacs dans la ligne <string>#{opt_bin}/emacs</string>.

BTW, vous pouvez également obtenir Emacs en tant qu'application OS X avec Homebrew Emacs si vous l'installez avec l' --cocoaoption. (Vous devrez également exécuter brew linkappsensuite, pour le lier /Applicationsou créer le lien vous-même.

Davor Cubranic
la source
1

Sur les mac, les démons sont, 90% du temps, gérés à l'aide de launchd . Il peut les exécuter sur de nombreux déclencheurs, y compris la connexion / déconnexion de l'utilisateur. Il existe une jolie application Mac appelée Lingon pour afficher et modifier les différentes choses que launchd gère. Le wiki emacs en a quelques mentions , y compris et un exemple de fichier de configuration . Mais cela semble ne pas répondre à votre préoccupation, à savoir comment arrêter le démon à la déconnexion.

Ben Hyde
la source
0

Créez une application AppleScript comme celle-ci:

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

Vous devrez peut-être ajuster le chemin, ou vous pourrez peut-être supprimer complètement le chemin. Vous pouvez également utiliser quelque chose de plus sophistiqué avec le démarrage du démon s'il n'est pas encore en cours d'exécution.

tarse
la source
@Rainer Avez-vous du succès avec ça? Vous pouvez également rechercher une implémentation plus sophistiquée qui démarre même le démon si nécessaire avant de s'y connecter à l'aide d'emacsclient. "emacsclient applescript" donne de bons résultats avec la recherche google.
tarsius
Attendez-vous toujours une meilleure réponse ou serait-il possible d'accepter celle-ci?
tarsius