Run certain Emacs init commands only in GUI mode - emacs

Is there a way to run certain commands (from init.el) only when I am in GUI mode and not in terminal mode. I want to set a certain color scheme when I run the GUI version, but that scheme screws up the terminal window's colors pretty badly. I'm looking for some variable/function which would look something like this:
(if gui-mode (color-scheme-blah))
or:
(unless terminal-mode (color-scheme-blah))

You want something like
(if window-system (color-scheme-blah))
window-system can be 'x or 'mswindows or possibly even other values, but it's always nil when you are on a terminal.

To generally test for a graphic display you want to use the following:
(display-graphic-p &optional DISPLAY)
It returns non-nil if DISPLAY is a graphic display. Using for example the window-system variable also works, but requires you to refer to a specific environment (such as X or Microsoft Windows).

When using emacsclient and frames GUI or terminal mode is not necessarily a global concept. See the very useful answer to my question at https://superuser.com/questions/165335/how-can-i-show-the-emacs-menu-in-gui-emacs-frames-but-not-in-tty-frames-when-usin .

Related

emacs - startup window size changed from default to maximum

I use below code to setup emacs using fullscreen:
(setq initial-frame-alist '( (fullscreen . maximized)))
(setq default-frame-alist '( (fullscreen . fullheight)))
I wish it startup with maximized window, the behavior is almost as expected but the window size firstly with default size, then I can see it changed to maximum size obviously.
How can emacs startup to fullscreen in one step?
Look at the documentation for initial-frame-alist (C-h v initial-frame-alist). In particular, Emacs creates the first frame before reading init.el, so you need to specify these things somewhere other than init.el. Two common ways are to give the --maximized command line option, or to set the X11 resource Emacs.Fullscreen: maximized; either of these are applied before init.el is read and evaluated.
It looks like you're on OS X, which I don't have, and it may be different there.
Update for Emacs 27:
You can set these things in early-init.el, which loads before the GUI starts.

One emacs.d/init.el to suit non-x session and x-session

When I start emacs without an x-server running, some of the things in my init.el fail, eg:
(require 'sr-speedbar)
is inappropriate without a graphical server, where I should rather start
(require 'speedbar)
What do emacs experts recommend as an appropriate init.el configuration in instances where emacs can be called as often from no-x modes as x-based modes? Is there an established way to provide a general, parallel experience under either regime or graceful fallback?
A lot depends on what environments you typically run in and what level of
control you need. For example, if you are just wanting to distinguish between
running under a full graphics capable environment, you can use display-graphic-p
e.g.
(when (display-graphic-p)
;; do stuff which needs a graphic display)
However, if you need to distinguish between different platforms, such as when
running under OSX, you would need something like
(when (eq system-type 'darwin)
;; do stuff which should only run when on OSX'))
Finally, for situations where you need to only configure something when running
under a specific window system, you can use something like
(when (eq window-system 'x)
;; only under X window frame))
However, there are some subtleties to be aware of. Some of these variables, such
as window-system are a test of the current frame. So, you need to think about
when the code is executed. For example, if you run emacs as a daemon, what would
be the value of window-system at the time your init is loaded? Likewise, if you
use emacs as a daemon or use emacsclient to open a new 'frame' it may be opened
a either a graphic or a text frame. Sometimes, you may need to create a new
command which wraps around what you want to do and does the test at the point
you execute the command so that it can respond to the specific frame you are in
when you execute the command.

emacs doremi: to change color-themes

I'm trying to get doremi working in emacs. Specifically, at this stage, to allow me to quickly scroll through a condensed list of color-themes and see each theme as I go through it. For this I would use the 'M-x doremi-color-themes+' command.
What I've done:
Installed color-themes (successfull)
Installed doremi.el, doremi-cmd.el, ring+.el and added
(add-to-list 'loadpath "~/elisp/themes")
(add-to-list 'loadpath "~/elisp/doremi/")
(require 'color-theme)
(color-theme-initialize)
(color-theme-classic)
;; create a list of color themes to scroll through using 'doremi-cmd
(setq my-color-themes (list 'color-theme-classic
'color-theme-retro-green
'color-theme-gray30
'color-theme-subtle-hacker
'color-theme-jonadabian-slate))
(require 'doremi)
(require 'doremi-cmd)
(require 'ring+)
to the .emacs file.
What emacs does:
When I type the comand 'M-x doremi-color-themes+' into the mini-buffer it seems to accept that I've given it a valid command and tells me to use the and arrow keys to move through the list. But when I do that all that happens is the cursor moves up and down in the active window. No changing of color-themes.
Being somewhat new to emacs (and especially customising it) I'm sure I have missed a step or put something in the wrong place. Perhaps there's some sort of (setq 'bla-bla-bla (...)) I need to do?
Sorry for your trouble. Please state your Emacs version (M-x emacs-version), and your version of color-theme.el.
You do not need to require library ring+.el if you use Emacs 23 or later (its code was included in GnuEmacs 23.)
You do not need to use (color-theme-initialize) or (color-theme-classic). The former is done automatically by doremi-color-themes+.
Try starting from emacs -Q (i.e., no init file, ~/.emacs), to be sure there is no interference from stuff in your init file.
Your variable my-color-themes is not referenced anywhere. Instead of defining that variable, just customize user option doremi-color-themes. (Or leave its value nil, which means that all color themes will be cycled through.)
Feel free to contact me by email if you continue to have a problem. Or continue here, if you prefer.
[Just to be sure: you are using color-theme.el, right? There is a lot of confusion out there between Emacs "custom themes" and color themes. Do Re Mi supports both, but they are different critters.]
After a bit for back and forth with #Drew we found a solution to the problem.
It turned out the major problem was that I was using emacs in 'terminal mode' rather than as a GUI application. Bare in mind I'm using a mac.
In the context of Terminal, my arrow keys send escape sequences and so doremi cannot read the event as intended. So it just escapes and applies the message to the active buffer.
There is an answer.
By adding the following lines to my .emacs file (or whatever your init file for emacs is) I was able to redirect doremi to use two other keys. ie. not the up and down arrows.
(setq doremi-down-keys '(?n))
(setq doremi-up-keys '(?p))
Doing this tells doremi to use 'n' as the down key and 'p' as the up key. And all works just fine.
Because I am only new to the world of programming and computing I may often use incorrect terminology. If this is the case please let me know and I will edit accordingly for clarity and consistency.

Settings only for GUI/Terminal emacs

I'm trying to set a theme - one only for terminal, and one only for gui.
I've read this thread: Run certain Emacs init commands only in GUI mode
Which led me here: https://superuser.com/questions/165335/how-can-i-show-the-emacs-menu-in-gui-emacs-frames-but-not-in-tty-frames-when-usi
And tried to create a function to suit my need.
(defun set-frame-theme (frame)
(let ((want-theme (memq (framep frame) '(x w32 ns))))
(set-frame-parameter frame '(load-theme '(if want-theme monokai solarized-dark) t))))
(add-hook 'after-make-frame-functions 'set-frame-theme)
It doesn't work.
I'm trying him to load monokai only if gui, otherwise load solarized-dark.
It does work for the GUI interface, but causes the terminal to seemingly crash.
Suggestions?
The emacs lisp function,
(display-graphic-p)
Will return true if emacs is running in a GUI.
In your .emacs, add the following to switch between your GUI and terminal themes
(if (display-graphic-p)
(load-GUI-theme)
(load-Terminal-theme))
For easier configuration, I have a simple function called is-in-terminal
(defun is-in-terminal()
(not (display-graphic-p)))
you could use this to write an easier to read function
(if (is-in-terminal)
(load-Terminal-theme)
(load-GUI-theme))
For a more complete approach to Terminal Only configuration I have a macro that works just like progn but only evaluates the body when Emacs is running without a GUI
(defmacro when-term (&rest body)
"Works just like `progn' but will only evaluate expressions in VAR when Emacs is running in a terminal else just nil."
`(when (is-in-terminal) ,#body))
Example Usage:
(when-term
(load-my-term-theme)
(set-some-keybindings)
(foo-bar))
This entire block will be totally ignored if running in a GUI, but will run if in Terminal.
All this code was taken from a file in my config, if interested you can check it out here:
https://github.com/jordonbiondo/Emacs/blob/master/Jorbi/jorbi-util.el
i could solve the issue with:
(if (display-graphic-p) (load-theme 'solarized-dark t))
the final t is to override the confirmation prompt in theme selection.
More here.
I too had the problem of emacs crashing when running in terminal mode while selecting a color-theme.
I would say this is not an issue with the color-theme but with emacs itself.
Updating to the newest version from HEAD did work for me as of time of this writing.
As mentioned at https://www.emacswiki.org/emacs/CustomizingFaces
"If you want different color schemes for different displays, you can customize this as well. In the customize buffer, click the [State] button and choose “Show all display specs”. Now you can use different specs for different displays."
Seems like an issue with the theme itself - nothing more and nothing less. uh well.

custom-theme-set-faces compatible with tty

I have created an emacs-23 custom theme using customize-create-theme. It works fine under X (Linux gnome desktop). However, when running under a tty (within gnome-terminal) some of the colors are wrong.
It is not the accuracy of the colors which are a problem (although it would be nice to match them under both situations) but the fact that some are so off as to be unworkable. For example, function names which appear green under X are invisible under the tty, although keywords which appear gold under X also appear gold (or at least some kind of yellow) under the tty.
Perhaps under the tty colors can't be matched exactly and so something similar is being substituted? If so, this doesn't seem to work all the time.
How can I fix this? Is it possible to specify, either in the 'customize' GUI or in the ~/.emacs.d/my-theme.el file, that certain faces only apply to frames displayed on X and others are only for the tty, or something similar?
(I'm interested in getting this, the built-in emacs theming system working rather than using some external color theme system.)
If a color is unavailable on a frame, emacs should try and pick something "close", but that's often very wrong on limited color displays. You should ask emacs how many colors it thinks it has in gnome-terminal either using M-x list-colors-display (to actually view the colors) or run (display-color-cells) in the scratch buffer. If it says you only have 8, you might want to consider changing your TERM environment variable to something like xterm-256color before you start emacs (though I'm not sure how well this actually works in gnome-terminal; I use xterm).
So that might help emacs be able to find a color that's closer, but if it's still wrong, you'll want to do something more drastic, like set the colors based on the window system.
If you're not using daemon mode, you can use something like
(if window-system (set-face-foreground 'font-lock-function-name-face "LightSkyBlue"))
If you use M-x describe-face, it will ask which face you want to describe, defaulting to the one currently at point. You can get the name (and usually the color) from there.
If you are using daemon mode, then you'll want different colors for each frame, in which case you'll need to set the color for the frame in the new frame hook, something more like:
(defun set-new-frame-colors (frame)
"Set colors based on frame type."
(if (window-system frame)
(set-face-forgeground 'font-lock-function-name-face "LightSkyBlue" frame)
(set-face-forgeground 'font-lock-function-name-face "blue" frame)))
(add-hook 'after-make-frame-functions 'set-new-frame-colors)
Alternatively, instead of checking (window-system frame), you could check (length (defined-colors frame)) and base it on how many colors are supported by the system, so that you can have different colors for 8-color vs. 256-color terminals.
You can tell whether or not the current frame is associated with a graphical window by examining the variable window-system. The link has the documentation, but it looks like:
window-system is a variable defined in `C source code'.
Its value is nil
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.
So, you can wrap the current theme inside an
(if window-system
;; current theme configuration
)
and then when in an xterm, create a new one that you like, and put that in the else (or another if statement, or unless and when)