Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Theme does not load with emacs --daemon #59

Open
robert-uhl opened this issue Jan 18, 2018 · 32 comments · May be fixed by #115
Open

Theme does not load with emacs --daemon #59

robert-uhl opened this issue Jan 18, 2018 · 32 comments · May be fixed by #115

Comments

@robert-uhl
Copy link

If emacs is started with emacs --daemon, the nord theme will not properly load, but will instead display as grey-on-white; there are many messages like the following:

Unable to load color "brightblack"
Unable to load color "brightcyan"
Unable to load color "brightblack" [5 times]
Unable to load color "brightblack"
Unable to load color "brightcyan"
Unable to load color "brightblack" [2 times]
Unable to load color "brightcyan"
Unable to load color "brightblack" [5 times]
Unable to load color "brightcyan"
Unable to load color "brightblack" [2 times]
Unable to load color "brightcyan" [3 times]
Unable to load color "brightblack"
Unable to load color "brightcyan"
Unable to load color "brightblack"
Unable to load color "brightcyan"
Unable to load color "brightblack" [5 times]

I believe that this is because in daemon mode there is no terminal, and thus nothing to send the colour names to. I think that the fix is to use the color class system as documented in Defining Faces.

@ghost
Copy link

ghost commented Jan 21, 2018

(if (daemonp) 
	    (add-hook 'after-make-frame-functions 
		      (lambda (frame) 
			(with-selected-frame frame (load-theme 'nord t)))) 
	  (load-theme 'nord t))

This fixed it for me.

@robert-uhl
Copy link
Author

@gutigen, the problem with that is that it reloads Nord with every single new frame.

I got some code together using the class system, but it's horribly ugly code. I think I need to try a new approach.

@jaccarmac
Copy link

jaccarmac commented Aug 22, 2018

To avoid the load-on-every-frame problem I whipped up a variant using cl-labels.

(if (daemonp)
    (cl-labels ((load-nord (frame)
                           (with-selected-frame frame
                             (load-theme 'nord t))
                           (remove-hook 'after-make-frame-functions #'load-nord)))
      (add-hook 'after-make-frame-functions #'load-nord))
  (load-theme 'nord t))

Note that this requires lexical-binding: t. Without lexical binding you could wrap the form in cl-block or use cl-letf instead of cl-labels.

Update: daemonp is technically not the best way to check for server status, as I found out. However, it is the correct condition in this case as I also found out. See this tech note attached to my config.

@arcticicestudio
Copy link
Contributor

Sorry again for the delay. There's another issue about the ANSI color definitions so maybe I'll check how to better implement these to avoid the named "bright" colors listed above in the error log.

@arcticicestudio
Copy link
Contributor

arcticicestudio commented Dec 16, 2018

Sorry for the long absence, I've been busy again with my job and work on the official Nord Docs with the goal to finally have a single-source-of-truth for all of Nord's port projects. Anyway, I'd like to get some of the long-time queued issues of some port projects done, including this one.

@somesoup emailed me and submitted #68, a fix for this daemon mode problem. @zvbuhl posted some ideas how to solve it using the definition of faces and @jaccarmac also proposed another way how to solve it. @slippycheeze offered help for some problems in #66 (comment) and maybe has some ideas and opinions to get this done too.
It would be really nice if we can discuss together what's the best solution to fix this. I'm happy about any help! It bothers me a lot that I could not solve some of the open issues in this repository due to the missing experience with Emacs and the fact that even after searching through many documentations and tutorials not able to find a up-to-date or correct solution. There are also not always ways to reproduce some of the problems.
In short: OSS lives from contributors and I welcome any help for this very much 😄

I tried to reproduce the log posted in the initial post, but when I run emacs --daemon it starts without any errors but only a warning:

Warning: due to a long standing Gtk+ bug
http://bugzilla.gnome.org/show_bug.cgi?id=85715
Emacs might crash when run in daemon mode and the X11 connection is unexpectedly lost.
Using an Emacs configured with --with-x-toolkit=lucid does not have this problem.
Loading hl-line...
Loading hl-line...done
Loading linum...
Loading linum...done
Loading paren...
Loading paren...done
Starting Emacs daemon.

It also works fine running Emacs without the GUI (emacs -nw).
I use GNU Emacs 26.1 on Arch Linux with Kernel 4.18.7-arch1-1-ARCH. The package build script can be found in the official repositories, maybe there are some differences in the compile options.
Can anyone who's still affected by the problem please provide a step-by-step reproduction guide?

Like I said I'm not a Emacs user and I have no experience with Lisp so I rely on community help.

@jaccarmac
Copy link

jaccarmac commented Dec 17, 2018

Thanks for circling back! My snippet is working well enough in practice for now, but I've noticed some irregularities and will work on a reproduction guide later this week. That warning is just noise: It has to do with the way Emacs was compiled, not the environment it is running in nor the config.

@CrosleyZack
Copy link

I can recreate this issue. I am loading Emacs 26.1 using emacsclient -nc with the daemon being run by systemd on startup using systemctl start --user emacs. My system is running Kernel version 4.19.13-1-MANJARO. I receive the same errors as @zvbuhl regarding colors being unable to load.

@slippycheeze
Copy link
Contributor

The way to solve this "correctly" is to define the faces with all the options, and let Emacs select the appropriate color given the properties of the current frame. That'll work correctly with daemon mode, as well as a mixture of graphical and tty instances.

TL;DR is instead of defining variables like this:

(nord0 (if (or (daemonp) (display-graphic-p)) "#2E3440" nil))

You want to define faces like this:

(defface nord0-face 
  '((((type graphic) (min-colors 256)) :background "#2E3440")
   (((min-colors 16)) :background "#whatever")
   ((t :background "#if nothing else matches, I guess?")))

Additionally, check in the document linked below the default spec, which lets you set the baseline, then only define what is different in the rest of the matches.

I'd also consider a match for 24-bit color without the terminal type being set, so people with 24-bit TTY stuff setup will be able to get the full color experience.

Sorry not to have time to address this myself, and only give pointers. Life isn't kind, sometimes.

References:

@arcticicestudio
Copy link
Contributor

@slippycheeze Thanks, this helps a lot and looks like the way to go. Absolute no problem for the delayed response time. Unfortunately, I have the same problem that the day only has 24h and necessary real life tasks absorbing almost all of it 😒

Since this is a open source project, everyone is free to go for it and submit a PR if it should be merged into this project. As soon as I'm done with porting all documentation and assets of all Nord's port project to the new official website of Nord there is hopefully more time to work on all the issues and PRs waiting in the queue.

@jaccarmac
Copy link

Might look at PR'ing this. Are there guidelines for what the Nord colors are in smaller color spaces or should I just eyeball it for 24-bit and 16-color displays?

@rien333
Copy link
Contributor

rien333 commented Jun 18, 2019

The newest release made this a lot worse. Basically no colors seem to be available and @accarmac init.el addition fails to connect to the daemon completely, with no output. (emacs just briefly flashes and then quits). The daemon is running, but there is no way to connect to it.

Edit: nvm, downgrading does not seem to work. I think I might have manually changed something to nord-theme.el to fix the problem at some point. At the moment however, emacs is completely unusable when using nord.

@robert-uhl
Copy link
Author

@rien333 I just upgraded to 0.4.0 (20190616.1757) and it seems to work okay. Still loads as light-blue on white, but I’m able to load the theme manually once I’ve got an X frame open, and then proceed as normal.

@rien333
Copy link
Contributor

rien333 commented Jun 19, 2019

Fixed by using the code from PR #64 (that adds a proper 24-bit check) and the daemon solution provided by the "ghost account". When using the solution provided by @jaccarmac my emacsclient just doesn't connect, and I havent been able to get useful debug info from it. (I've seen emacs complain about cl-labels before, maybe it's something about that). Manually loading the theme also works fine now.

btw, I'm using emacs-26.2.

@arcticicestudio
Copy link
Contributor

@rien333 Thanks for your feedback, this helps to decide which of the already four proposed solutions might work the best for latest and older versions 👍

@jaccarmac
Copy link

@rien333 Are you using lexical-binding: t? That's probably the easiest way cl-labels would fail. Perhaps I should whip up a non-lexical solution so it works for more people.

@rien333
Copy link
Contributor

rien333 commented Jun 19, 2019

That variable is nil, according to emacs. I also don't alter it in my init.el, nor does setting it to t have any effect. It's somewhat weird actually if I'm the only one that has problems with your snippet, I probably need to bisect my init.el.

As an aside, I'm using the kitty terminal emulator, with 24-bit support in emacs made available by a .terminfo file tailored to the true color spec kitty uses. (not sure if that's relevant but yeah)

@jaccarmac
Copy link

It needs to be set with a file-local variable as in my config (see top), otherwise cl-labels will not work properly in that snippet. Otherwise you'll need to use cl-block or cl-letf; I just set my init file as lexical so can't tell you exactly how to do so.

Further information about lexical-binding: Emacs manual, Chris Wellons's blog

@robert-uhl
Copy link
Author

Here’s an attempt not to rely on the setting at daemon-start time. It’s a mechanical translation, and it’s embarrassingly unabstracted, but … maybe it’s a start?

https://github.com/zvbuhl/nord-emacs/tree/theme-tty

@rien333
Copy link
Contributor

rien333 commented Jun 19, 2019

@jaccarmac, the addition on top of the file did the trick, thank you for your assistance and the resources on lexical-binding; I wan't completely familiar with the subject yet.

@aiguofer
Copy link

aiguofer commented Jul 6, 2019

So... I'm having a bit of a different issue than most folks here. I'm running emacs off systemctl --user using emacs --fg-daemon.

The theme works great in either terminal (emacsclient -t) or as a frame in X (emacsclient -c). The problem is that it doesn't work in both... it's one or the other (whichever starts first). This is an issue for me because I don't use emacsclient directly but instead have an "editor" script that will use console if I launch in console or a frame otherwise:

#!/bin/bash

if [ -z "$(pgrep emacs)" ]; then
    systemctl --user restart emacs
    sleep 10
fi

SOCKET=$(lsof -c emacs | grep $USER | grep server | grep STREAM | awk '{print $9}' | sort | uniq)
PARAMS="--socket-name=$SOCKET"

if [[ $TMUX || $SSH_CLIENT ]]
then
    PARAMS+=" -t"
else
    PARAMS+=" -c"
fi

exec  /usr/bin/emacsclient $PARAMS $@

Note: I can "switch" the working one by manually calling load-theme in an emacsclient in either terminal or in X, but it'll break the other.

@rien333
Copy link
Contributor

rien333 commented Jul 6, 2019

It might be that I'm missing something important, but it seems to me as if you start emacs the same way I do. I can use the nord-theme fine in either an X frame or in my terminal, and my systemd unit file shows that I also start emacs with emacs --fg-daemon. Is there something different about your setup? Not sure if it's relevant to you and whether you already tried it, but I remember all my problems going away when I patched with PR #64 and added @jaccarmac solution to my init.el.

@aiguofer
Copy link

aiguofer commented Jul 6, 2019

@rien333 thanks for your input! unfortunately that still didn't solve it for me... if it makes a difference, I'm running tmux inside terminator for the console. I've got the nord-theme set up for terminator and using set -g default-terminal screen-256color in tmux.

@rien333
Copy link
Contributor

rien333 commented Jul 6, 2019

I'm seeing the same behavior as you if I run tmux with set -g default-terminal screen-256color.

However, if I use TERM=kitty-24bit emacsclient -t in tmux---a terminfo file I need to use in order for emacs 24-bit support and my terminal to work together---it works fine. Not sure if I'm telling you stuff you already know, but yeah the TERM variable/terminfo or tmux could be the problem.

@aiguofer
Copy link

aiguofer commented Jul 6, 2019

@rien333 thanks! yeah just figured that out... after a bit of googling I finally got it working following this post, with the difference that I went ahead and put TERM=screen-24bit in my .zshrc.

I should add I didn't need the #64 patch, but I did need @jaccarmac's fix for the daemon.

arcticicestudio added a commit that referenced this issue Jan 5, 2020
In order to fix "unable to load color x" errors when running Emacs in
daemon-mode, the defined theme colors are now tested against the
`display-color-cells` "display feature testing" function [1] to support
24-bit color terminals with a fallback to the `display-graphic-p`
function.

This is a first step to fix the problems described in GH-59.

Related to GH-59
@arcticicestudio
Copy link
Contributor

arcticicestudio commented Jan 5, 2020

I've submitted and merged #88 (superseded #64 due to stale state and merge conflicts) as a first step to fix the problem(s) documented in this issue.
A by far better soluttion should be a refactoring of the theme colors to make use of defined faces (also mentioned by @zvbuhl and @slippycheeze) in combination with capability tests for display feature/color support.

Anyway, the next release version will include the changes from #88 and I'd really appreciate feeback if it's a step forwards better compatibility 😄

@rien333
Copy link
Contributor

rien333 commented Jan 7, 2020

@arcticicestudio this is the first time I upgraded nord-theme without it breaking my colors and me having to manually intervene, so it's definitely a step forward in compatibility for my setup (I do have some other fixes from this thread applied to my init.el, though.). Thanks for your time and your continued support!

@jaccarmac
Copy link

jaccarmac commented Jan 7, 2020

Can't speak to the issues folks were having in a TTY, but I still need my delayed-load hack for the theme to load under a daemon properly.

arcticicestudio added a commit that referenced this issue Jan 8, 2020
In order to fix "unable to load color x" errors when running Emacs in
daemon-mode, the defined theme colors are now tested against the
`display-color-cells` "display feature testing" function [1] to support
24-bit color terminals with a fallback to the `display-graphic-p`
function.

This is a first step to fix the problems described in GH-59.

Related to GH-59
@iamriel
Copy link

iamriel commented Apr 9, 2020

EMACS version: 28.0.5
nord-theme version: 20200108.833

I encounter this issue and I have this as a fix:

(defvar my:theme 'nord)
(defvar my:theme-window-loaded nil)
(defvar my:theme-terminal-loaded nil)

(if (daemonp)
    (add-hook 'after-make-frame-functions(lambda (frame)
                                          (select-frame frame)
                                          (if (window-system frame)
                                              (unless my:theme-window-loaded
                                                (if my:theme-terminal-loaded
                                                    (enable-theme my:theme)
                                                  (load-theme my:theme t))
                                                (setq my:theme-window-loaded t)
                                                )
                                            (unless my:theme-terminal-loaded
                                              (if my:theme-window-loaded
                                                  (enable-theme my:theme)
                                                (load-theme my:theme t))
                                              (setq my:theme-terminal-loaded t)
                                              )
                                            )))

  (progn
    (load-theme my:theme t)
    (if (display-graphic-p)
        (setq my:theme-window-loaded t)
      (setq my:theme-terminal-loaded t)))
  )

I forgot where I found that snippet but credits to the owner.

It works pretty well when I open it in the GUI with emacsclient -nc, but when I run emacsclient -t in the terminal, the theme is different, and I see the Unable to load color errors.

Weird thing is that when I run emacsclient -t BEFORE opening emacs in a GUI, it loads correctly, but when I run it AFTER running emacsclient -nc (GUI), the terminal colors get messed up. You can check the screenshot attached:

Left side is terminal while right side is the GUI:

2020-04-09_23-53

@jaccarmac
Copy link

Interesting. I don't really use terminal Emacs, but decided to see how my fix fared in the same situation. And it turns out that if I start a daemon and then open a terminal client before a graphical client, the graphical client doesn't load the correct colors. If a graphical client is opened before everything plays together nicely.

@arcticicestudio
Copy link
Contributor

@iamriel Thanks for your help 👍

I've also noticed the exact same behavior while trying to reproduce the problem and thought it was my fault and lack of experience/usage with Emacs, but it's "good" to see that this is not scoped to my system. I'll keep this on my list for things that requires manual testing when the faces for theme colors are implemented.

@xukai92
Copy link

xukai92 commented May 10, 2021

Just to mention that the unoffical Nord theme in the Doom themes (https://github.com/hlissner/emacs-doom-themes/blob/master/themes/doom-nord-theme.el) doesn't suffer from this issue but that theme is not as polished as this offical one. I wonder if we could merge these two version; Doom themes seem to well-maintained.

@EdwardIII
Copy link

EdwardIII commented Oct 12, 2022

Hey, still seeing this on:

  • nord-theme-20200620.1122 (0.5.0)
  • emacs 28.1
  • Wayland on linux
  • Running emacs in daemon mode

Is #59 (comment) still the way to go?

EdwardIII pushed a commit to EdwardIII/nord-emacs that referenced this issue Oct 18, 2022
rjekker pushed a commit to rjekker/fnord-theme that referenced this issue Oct 11, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

10 participants