ChatGPT解决这个技术问题 Extra ChatGPT

How to detect that emacs is in terminal-mode?

In my .emacs file, I have commands that only makes sense in graphical mode (like (set-frame-size (selected-frame) 166 100)). How do I run these only in graphical mode and not in terminal mode (i.e. emacs -nw).

Thanks!


k
knarf

The window-system variable tells Lisp programs what window system Emacs is running under. The possible values are

x Emacs is displaying the frame using X. w32 Emacs is displaying the frame using native MS-Windows GUI. ns Emacs is displaying the frame using the Nextstep interface (used on GNUstep and Mac OS X). pc Emacs is displaying the frame using MS-DOS direct screen writes. nil Emacs is displaying the frame on a character-based terminal.

From the doc.

Edit: it seems that window-system is deprecated in favor of display-graphic-p (source: C-h f window-system RET on 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).

So what you want to do is :

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

And if you don't have an else clause, you can just:

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

(window-system) == "ns" on my mac
s
sanityinc

The answers mentioning window-system and display-graphic-p aren't wrong, but they don't tell the complete picture.

In reality, a single Emacs instance can have multiple frames, some of which might be on a terminal, and others of which might be on a window system. That is to say, you can get different values of window-system even within a single Emacs instance.

For example, you can start a window-system Emacs and then connect to it via emacsclient -t in a terminal; the resulting terminal frame will see a value of nil for window-system. Similarly, you can start emacs in daemon mode, then later tell it to create a graphical frame.

As a result of this, avoid putting code in your .emacs that depends on window-system. Instead, put code like your set-frame-size example in a hook function which runs after a frame is created:

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

Note that the 'after-make-frame-functions hook isn't run for the initial frame, so it's often necessary to also add frame-related hook functions like that above to 'after-init-hook.


Thanks! I'm not clear on the terminology, but if I run (split-window-horizontally), does that create a new frame and thus invoke this? Or does this only run when creating an entirely new window attached to this instance (like by using emacsclient)?
The Emacs terminology uses "frame" to mean what you would normally call a "window", and it uses "window" to denote what you would normally call a "pane". Confusing, but you get used to it eventually. Hope that helps. :-)
And, to answer your question explicitly: split-window-horizontally splits the currently-active pane ("window") in the current window ("frame") into two panes ("windows").
This will not work since: after-make-frame-functions is run after the frame is created. This doesn't apply to the initial emacs frame (on startup) because your .emacs is read after the frame is already created. stackoverflow.com/questions/875667/…
@Rubycut agreed. I should have mentioned that it's often necessary to add frame-related hook functions like that to 'after-init-hook.
B
Bozhidar Batsov

window-system is a variable defined in `C source code'. Its value is x Documentation: Name of window system through which the selected frame is displayed. The value is a symbol--for instance, `x' for X windows. The value is nil if the selected frame is on a text-only-terminal.

Basically do a:

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

deprecated in favor of display-graphic-p
u
uncaught_exceptions

If its in Gui mode, then the following would be true.

(if window-system )


p
paaguti

I have defined an extra function to wrap the window-name functionality because I'm using Emacs everywhere, i.e. from the terminal and in graphics mode and in Linux and 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)))

It can be extended to cover other systems like Windows or older systems where a serial terminal is used. But I Have no time to do so ;-)