emacsclient: Erstellen Sie einen Frame, wenn kein Frame vorhanden ist

2798
Idlecool

Ich starte emacs server mit

emacs --daemon 

dann öffnen Sie Dateien mit

emacsclient filename.ext 

Die erste Datei muss jedoch mit geöffnet werden

emacsclient -c filename.ext 

um einen neuen Frame zu erstellen, der später von nachfolgenden Dateien verwendet werden kann, ohne das -cBefehlszeilenflag für Emacsclient zu verwenden.

Ich möchte das automatisieren. msgstr "Wenn es keinen emacs - Frame gibt, sollte emacsclient einen Frame erstellen, ansonsten sollte der aktuelle Frame verwendet werden." Wie geht das?

5
Wenn ich "man emacsclient" mache, sagt es mir nichts über eine "-c" -Option. Wissen Sie, welche Versionen dieses Verhalten zeigen? dmckee vor 13 Jahren 0
@dmckee `emacsclient -c` ist neu in dem stark verbesserten Emacsclient in Emacs 23. Gilles vor 13 Jahren 0

8 Antworten auf die Frage

6
Gilles

Sie können zuerst einen Rahmen erstellen, falls noch kein Rahmen vorhanden ist, und dann die Datei in einem bereits vorhandenen Rahmen öffnen. Hier ist ein Ausschnitt, der in der ursprünglichen Anzeige einen Rahmen erstellt, wenn in der Fensteranzeige noch kein Rahmen geöffnet ist. Möglicherweise möchten Sie dies auf verschiedene Weise anpassen, z. B. indem Sie prüfen, ob bereits ein Rahmen auf dem Display angezeigt wird x-display-list. Sie brauchen (require 'cl)in Ihren `.emacs. Dies erfordert möglicherweise einige Anpassungen, um unter Windows oder Aqua zu funktionieren.

emacsclient -e '(unless (find-if (lambda (f) (let ((p (frame-parameters f))) (assq '\''window-system p))) (frame-list)) (make-frame-on-display (getenv "DISPLAY")))' emacsclient filename.ext 
6
dimitri

Hier ist das emacs-client.sh-Skript, das ich unter Linux verwende, um genau das zu tun, wonach Sie fragen:

#!/bin/sh  xprop -name emacs >/dev/null 2>/dev/null if [ "$?" = "1" ]; then emacsclient -c -n -a "" "$@" else emacsclient -n -a "" "$@" fi 
Diese Antwort erfordert mehr Upvotes! Arash vor 10 Jahren 0
Dies scheint verwirrt zu sein, wenn Sie den Emacs-Frame beenden. Zu diesem Zeitpunkt ist der emacs-Server noch aktiv und die xprop-Zeile gibt 0 zurück, sodass nach dem ersten Mal kein neuer Frame geöffnet wird. Fehlt mir etwas? demented hedgehog vor 9 Jahren 0
Die Lösung von Jim Hunziker scheint nicht das gleiche Problem zu haben. demented hedgehog vor 9 Jahren 0
4
Jim Hunziker

Dies ist wie bei der Lösung von dimitri, behandelt aber den Fall, in dem emacs gestartet wurde emacs --daemon. emacs --daemonmacht ein ausgeblendetes Fenster, das xpropbeim Prüfen auf ein vorhandenes Fenster einen falsch positiven Wert ergibt.

#!/bin/bash  emacsclient -n -e "(if (> (length (frame-list)) 1) 't)" | grep t if [ "$?" = "1" ]; then emacsclient -c -n -a "" "$@" else emacsclient -n -a "" "$@" fi 
2
Ivan Andrus

Ich denke, das Hinzufügen von Gilles 'Funktion server-switch-hookkönnte das tun, was Sie wollen. Unglücklicherweise kann ich mich nicht an die emacs --daemonArbeit machen, um es zu testen.

(add-hook 'server-switch-hook (lambda () (unless (find-if (lambda (f) (let ((p (frame-parameters f))) (assq 'window-system p))) (frame-list)) (make-frame-on-display (getenv "DISPLAY"))))) 
2
Jean-Marc E

Meine Lösung besteht darin, nach dem Starten des Daemons die Erstellung eines Frames zu erzwingen:

function em() { emacs --bg-daemon --display=:0 # Forces emacs to notice I'm using X as well. emacsclient --create-frame --display=:0 --no-wait } 

und dann muss ich nie --create-frame verwenden.

0
ws6079

Unter OSX definiere ich diese Funktion (ähnlich wie bei Jim Hunziker).

emacs () { pgrep -xiq emacs && emacsclient -n $@ || emacsclient -n -c --alternate-editor="" $@; } 
0
brettk

Die Antwort von Jim Hunziker funktioniert für mich nicht ganz (in einigen Situationen gibt die Frame-Liste zwei Elemente zurück, obwohl es keinen X-Frame gibt). Vorausgesetzt, Sie verwenden nur ein DISPLAY, funktionieren die folgenden:

#!/bin/bash  emacsclient -n -e "(null (cl-remove-if (lambda (frame) (null (display-graphic-p frame))) (frame-list)))" | grep >/dev/null nil if [ "$?" = "1" ]; then emacsclient -c -n -a "" "$@" else emacsclient -n -a "" "$@" fi 
0
Zitrax

Eine weitere Version, die auch im tty / console-Modus funktioniert:

#!/bin/bash   emacsclient -n -e "(if (> (length (frame-list)) 1) 't)" | grep t  if [ "$?" = "1" ]; then  if [ "$DISPLAY" = "" ]; then  emacsclient -c -a "" "$@"  else  emacsclient -c -n -a "" "$@"  fi  else  if [ "$DISPLAY" = "" ]; then  emacsclient -a "" "$@" else emacsclient -n -a "" "$@" fi fi 

(Basierend auf Jim Hunzikers Antwort)