Jak wykryć, że emacs jest w trybie terminala?


81

W moim .emacspliku mam polecenia, które mają sens tylko w trybie graficznym (np (set-frame-size (selected-frame) 166 100).). Jak uruchomić je tylko w trybie graficznym, a nie w trybie terminala (tj emacs -nw.).

Dzięki!

Odpowiedzi:


101

window-systemZmienna mówi programów Lisp jaki system okno Emacs jest uruchomiona w ramach. Możliwe wartości to

x
Emacs wyświetla ramkę używając X.
w32
Emacs wyświetla ramkę używając natywnego GUI MS-Windows.
ns
Emacs wyświetla ramkę używając interfejsu Nextstep (używanego w GNUstep i Mac OS X).
szt
Emacs wyświetla ramkę używając bezpośrednich zapisów ekranowych MS-DOS.
zero
Emacs wyświetla ramkę na terminalu znakowym.

Z doc .

Edycja : wygląda na to, że window-system jest przestarzały na rzecz display-graphic-p(źródło: Ch f window-system RET na emacs 23.3.1).

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

Więc to, co chcesz zrobić, to:

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

A jeśli nie masz klauzuli else, możesz po prostu:

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

(window-system) == "ns" na moim Macu
nicolas

43

Odpowiedzi wspominają window-systemi display-graphic-pnie są błędne, ale nie dają pełnego obrazu.

W rzeczywistości pojedyncza instancja Emacsa może mieć wiele ramek, z których niektóre mogą znajdować się na terminalu, a inne w systemie okienkowym. Oznacza to, że możesz uzyskać różne wartości window-systemnawet w ramach jednej instancji Emacsa.

Na przykład, możesz uruchomić system okienkowy Emacs, a następnie połączyć się z nim przez emacsclient -tterminal; wynikowa ramka terminala będzie miała wartość nilfor window-system. Podobnie, możesz uruchomić emacsa w trybie demona, a następnie powiedzieć mu, aby utworzył ramkę graficzną.

W związku z tym unikaj umieszczania w swoim .emacs kodu, od którego zależy window-system. Zamiast tego umieść kod, taki jak set-frame-sizeprzykład, w funkcji przechwytującej, która działa po utworzeniu ramki:

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

Zwróć uwagę, że 'after-make-frame-functionshak nie jest uruchamiany dla początkowej klatki, więc często konieczne jest również dodanie funkcji zaczepienia związanych z ramkami, takich jak te powyżej 'after-init-hook.


Dzięki! Nie mam jasności co do terminologii, ale jeśli uruchomię (podzielone okno w poziomie), czy to tworzy nową ramkę, a zatem wywołuje to? Czy może to działa tylko podczas tworzenia całkowicie nowego okna dołączonego do tej instancji (na przykład przy użyciu emacsclient)?
sligocki

6
Terminologia Emacsa używa „ramki” do określenia tego, co normalnie nazywasz „oknem”, a „okno” do określenia tego, co normalnie nazywasz „okienkiem”. Mylące, ale w końcu przyzwyczajasz się do tego. Mam nadzieję, że to pomoże. :-)
sanityinc

4
Odpowiadając wprost na twoje pytanie: split-window-horizontallydzieli aktualnie aktywny panel („okno”) w bieżącym oknie („ramka”) na dwa panele („okna”).
sanityinc

2
To nie zadziała, ponieważ: funkcje po wykonaniu ramki są uruchamiane po utworzeniu ramki. Nie dotyczy to początkowej ramki emacsa (podczas uruchamiania), ponieważ plik .emacs jest odczytywany po utworzeniu ramki. stackoverflow.com/questions/875667/…
Rubycut,

1
@Rubycut zgodził się. Powinienem był wspomnieć, że często konieczne jest dodawanie takich funkcji zaczepienia związanych z ramkami 'after-init-hook.
zdrowie

8

system-okna jest zmienną zdefiniowaną w `kodzie źródłowym C. ' Jego wartość to x

Dokumentacja: nazwa systemu okiennego, w którym wyświetlana jest wybrana rama. Wartość jest symbolem - na przykład `x 'dla X okien. Wartość jest zerowa, jeśli wybrana ramka znajduje się na terminalu zawierającym tylko tekst.

Zasadniczo wykonaj:

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

przestarzałe na rzecz display-graphic-p
ivo Welch


2

Zdefiniowałem dodatkową funkcję do zawijania funkcjonalności nazwy okna, ponieważ używam Emacsa wszędzie, tj. Z terminala i w trybie graficznym oraz w Linuksie i 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)))

Można go rozszerzyć, aby objąć inne systemy, takie jak Windows lub starsze systemy, w których używany jest terminal szeregowy. Ale nie mam na to czasu ;-)

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.