Як виявити, що emacs перебуває в термінальному режимі?


81

У моєму .emacsфайлі у мене є команди, які мають сенс лише в графічному режимі (наприклад (set-frame-size (selected-frame) 166 100)). Як запустити їх лише в графічному режимі, а не в термінальному (тобто emacs -nw).

Дякую!

Відповіді:


101

window-systemЗмінні повідомляють програми Лиспа , що вікно системи Emacs працює під управлінням . Можливі значення такі

х
Emacs відображає кадр за допомогою X.
w32
Emacs відображає кадр за допомогою власного графічного інтерфейсу MS-Windows.
росіяни
Emacs відображає кадр за допомогою інтерфейсу Nextstep (використовується на GNUstep та Mac OS X).
ПК
Emacs відображає кадр за допомогою прямого запису на екран MS-DOS.
нуль
Emacs відображає кадр на символьному терміналі.

З док .

Редагувати : здається, що віконна система застаріла на користь display-graphic-p(джерело: Ch f window-system RET на 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).

Отже, що ви хочете зробити, це:

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

І якщо у вас немає пропозиції else, ви можете просто:

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

(window-system) == "ns" на моєму mac
nicolas

43

Відповіді згадують window-systemі display-graphic-pпомиляються, але вони не дають повного уявлення.

Насправді один екземпляр Emacs може мати декілька кадрів, деякі з яких можуть бути на терміналі, а інші - у віконній системі. Тобто ви можете отримувати різні значення window-systemнавіть у межах одного екземпляра Emacs.

Наприклад, ви можете запустити віконну систему Emacs, а потім підключитися до неї через emacsclient -tтермінал; отриманий термінальний кадр побачить значення nilfor window-system. Подібним чином ви можете запустити emacs у режимі демона, а потім пізніше сказати йому створити графічний кадр.

В результаті цього уникайте розміщення коду у .emacs, який залежить від window-system. Натомість помістіть код, як ваш set-frame-sizeприклад, у функцію підключення, яка запускається після створення кадру:

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

Зауважте, що 'after-make-frame-functionsхук не запускається для початкового кадру, тому часто доводиться також додавати такі функції кадру, пов’язані з кадрами, як вище 'after-init-hook.


Дякую! Мені незрозуміла термінологія, але якщо я запускаю (розділити вікно по горизонталі), чи створює це новий фрейм і таким чином викликає це? Або це працює лише під час створення повністю нового вікна, приєднаного до цього екземпляра (наприклад, за допомогою emacsclient)?
sligocki

6
Термінологія Emacs використовує "фрейм", щоб означати те, що ви зазвичай називали б "вікном", а "вікно" позначає те, що ви зазвичай називали б "вікном". Заплутано, але з часом звикаєш. Сподіваюся, що це допомагає. :-)
sanityinc

4
І, щоб відповісти на ваше запитання явно: split-window-horizontallyрозбиває активну область ("вікно") у поточному вікні ("кадр") на дві панелі ("вікна").
sanityinc

2
Це не буде працювати, оскільки: after-make-frame-functions запускається після створення кадру. Це не стосується початкового кадру emacs (під час запуску), оскільки ваш .emacs читається після того, як фрейм уже створений. stackoverflow.com/questions/875667 / ...
Rubycut

1
@Rubycut погодився. Я повинен був згадати, що часто доводиться додавати такі функції, пов'язані з кадрами 'after-init-hook.
sanityinc

8

window-system - це змінна, визначена у `C вихідному коді '. Його значення x

Документація: Назва віконної системи, через яку відображається вибраний кадр. Значення є символом - наприклад, `x 'для X windows. Значення дорівнює нулю, якщо вибраний кадр знаходиться на текстовому терміналі.

В основному зробити:

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

застаріло на користь display-graphic-p
ivo Welch


2

Я визначив додаткову функцію для обгортання функцій імені вікна, оскільки я використовую Emacs скрізь, тобто з терміналу та в графічному режимі, а також в Linux та 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)))

Його можна поширити на інші системи, такі як Windows, або старіші системи, де використовується послідовний термінал. Але в мене немає часу на це ;-)

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.