Как определить, что emacs находится в терминальном режиме?

81

В моем .emacsфайле есть команды, которые имеют смысл только в графическом режиме (например, (set-frame-size (selected-frame) 166 100)). Как мне запустить их только в графическом режиме, а не в режиме терминала (т.е. emacs -nw).

Благодаря!

Sligocki
источник

Ответы:

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 оконная система 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))
Knarf
источник
(window-system) == "ns" на моем Mac
Николас
43

Ответы, в которых упоминается, window-systemи display-graphic-pне ошибочны, но они не дают полной картины.

В действительности, один экземпляр Emacs может иметь несколько фреймов, некоторые из которых могут быть на терминале, а другие - в оконной системе. Другими словами, вы можете получить разные значения window-systemдаже в пределах одного экземпляра Emacs.

Например, вы можете запустить оконную систему Emacs, а затем подключиться к ней через emacsclient -tтерминал; результирующий терминальный фрейм будет иметь значение nilдля 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

оконная система - это переменная, определенная в `исходном коде C '. Его значение x

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

В основном делайте:

(if window-system
    (progn
      (something)
      (something-else)))
Божидар Бацов
источник
устарело в пользу display-graphic-p
ivo Welch
6

Если он в режиме Gui, то будет верно следующее.

(если оконная система)

uncaught_exceptions
источник
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 или более старых систем, в которых используется последовательный терминал. Но у меня нет времени на это ;-)

паагути
источник