Wie erkennt man, dass sich Emacs im Terminal-Modus befindet?


81

In meiner .emacsDatei befinden sich Befehle, die nur im grafischen Modus (wie (set-frame-size (selected-frame) 166 100)) sinnvoll sind . Wie führe ich diese nur im Grafikmodus und nicht im Terminalmodus (dh emacs -nw) aus?

Vielen Dank!

Antworten:


101

Die window-systemVariable teilt Lisp-Programmen mit, unter welchem ​​Fenstersystem Emacs ausgeführt wird. Die möglichen Werte sind

x
Emacs zeigt den Rahmen mit X an.
w32
Emacs zeigt den Frame über die native MS-Windows-Benutzeroberfläche an.
ns
Emacs zeigt den Frame über die Nextstep-Oberfläche an (wird unter GNUstep und Mac OS X verwendet).
pc
Emacs zeigt den Frame mit direkten MS-DOS-Bildschirmschreibvorgängen an.
Null
Emacs zeigt den Frame auf einem zeichenbasierten Terminal an.

Aus dem Dokument .

Bearbeiten : Es scheint, dass das Fenstersystem zugunsten von display-graphic-p(Quelle: Ch f Fenstersystem RET auf Emacs 23.3.1) veraltet ist.

(display-graphic-p &optional DISPLAY)

Return non-nil if DISPLAY is a graphic display.
Graphical displays are those which are capable of displaying several
frames and several different fonts at once.  This is true for displays
that use a window system such as X, and false for text-only terminals.
DISPLAY can be a display name, a frame, or nil (meaning the selected
frame's display).

Was Sie also tun möchten, ist:

(if (display-graphic-p)
    (progn
    ;; if graphic
      (your)
      (code))
    ;; else (optional)
    (your)
    (code))

Und wenn Sie keine else-Klausel haben, können Sie einfach:

;; more readable :)
(when (display-graphic-p)
    (your)
    (code))

(Fenstersystem) == "ns" auf meinem Mac
Nicolas

42

Die Antworten erwähnen window-systemund display-graphic-psind nicht falsch, aber sie sagen nicht das vollständige Bild.

In der Realität kann eine einzelne Emacs-Instanz mehrere Frames haben, von denen sich einige auf einem Terminal und andere auf einem Fenstersystem befinden können. Das heißt, Sie können window-systemsogar innerhalb einer einzelnen Emacs-Instanz unterschiedliche Werte erhalten .

Sie können beispielsweise ein Emacs-Fenstersystem starten und dann über emacsclient -tein Terminal eine Verbindung dazu herstellen . Der resultierende Terminalrahmen sieht einen Wert von nilfür window-system. Ebenso können Sie Emacs im Daemon-Modus starten und später anweisen, einen grafischen Rahmen zu erstellen.

Vermeiden Sie daher, Code in Ihre .emacs einzufügen, der davon abhängt window-system. Fügen Sie stattdessen Code wie in Ihrem set-frame-sizeBeispiel in eine Hook-Funktion ein, die ausgeführt wird, nachdem ein Frame erstellt wurde:

(add-hook 'after-make-frame-functions
  (lambda ()
    (if window-system
      (set-frame-size (selected-frame) 166 100)))))

Beachten Sie, dass der 'after-make-frame-functionsHook nicht für den ersten Frame ausgeführt wird. Daher ist es häufig erforderlich, auch rahmenbezogene Hook-Funktionen wie die oben genannten hinzuzufügen 'after-init-hook.


Vielen Dank! Die Terminologie ist mir nicht klar, aber wenn ich laufe (Fenster horizontal teilen), wird dadurch ein neuer Frame erstellt und dieser aufgerufen? Oder wird dies nur ausgeführt, wenn ein völlig neues Fenster erstellt wird, das an diese Instanz angehängt ist (z. B. mithilfe von emacsclient)?
Sligocki

6
Die Emacs-Terminologie verwendet "Rahmen", um zu bezeichnen, was Sie normalerweise als "Fenster" bezeichnen würden, und "Fenster", um zu bezeichnen, was Sie normalerweise als "Fenster" bezeichnen würden. Verwirrend, aber man gewöhnt sich irgendwann daran. Hoffentlich hilft das. :-)
Sanityinc

4
Und um Ihre Frage explizit zu beantworten: split-window-horizontallyTeilt den aktuell aktiven Bereich ("Fenster") im aktuellen Fenster ("Rahmen") in zwei Bereiche ("Fenster") auf.
Sanityinc

2
Dies funktioniert nicht, da: after-make-frame-Funktionen ausgeführt werden, nachdem der Frame erstellt wurde. Dies gilt nicht für den anfänglichen Emacs-Frame (beim Start), da Ihre .emacs gelesen werden, nachdem der Frame bereits erstellt wurde. stackoverflow.com/questions/875667/…
Rubycut

1
@ Rubycut stimmte zu. Ich hätte erwähnen sollen, dass es oft notwendig ist, solche rahmenbezogenen Hook-Funktionen hinzuzufügen 'after-init-hook.
Sanityinc

8

Fenstersystem ist eine Variable, die im C-Quellcode definiert ist. Sein Wert ist x

Dokumentation: Name des Fenstersystems, durch das der ausgewählte Rahmen angezeigt wird. Der Wert ist ein Symbol - zum Beispiel "x" für X-Fenster. Der Wert ist Null, wenn sich der ausgewählte Frame auf einem Nur-Text-Terminal befindet.

Grundsätzlich machen Sie eine:

(if window-system
    (progn
      (something)
      (something-else)))

veraltet zugunsten von Display-Grafik-p
ivo Welch


2

Ich habe eine zusätzliche Funktion zum Umschließen der Fensternamenfunktion definiert, da ich Emacs überall verwende, dh vom Terminal und im Grafikmodus sowie unter Linux und MacOS:

(defun window-system-name()
  (cond ((eq system-type 'gnu/linux) (if (display-graphic-p) "x"   "nox"))
    ((eq system-type 'darwin)    (if (display-graphic-p) "mac" "nox"))
    (t (error "Unsupported window-system") nil)))

Es kann auf andere Systeme wie Windows oder ältere Systeme ausgedehnt werden, auf denen ein serielles Terminal verwendet wird. Dafür habe ich aber keine Zeit ;-)

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.