svg-lib icon indicating copy to clipboard operation
svg-lib copied to clipboard

Problem using svg-lib / svg-tag-mode with daemon and emacsclient

Open storvik opened this issue 3 years ago • 6 comments

I'm struggling to make svg-tag-mode to work with Emacs daemon and while debugging the issue it seems like the error comes from this library. I'm not that proficient in elisp but bear with me. My configuration while debugging looks like this (basically just straight.el and loading svg-tag-mode):

(setq package-enable-at-startup nil)
(defvar bootstrap-version)
(let ((bootstrap-file
       (expand-file-name "straight/repos/straight.el/bootstrap.el" user-emacs-directory))
      (bootstrap-version 5))
  (unless (file-exists-p bootstrap-file)
    (with-current-buffer
        (url-retrieve-synchronously
         "https://raw.githubusercontent.com/raxod502/straight.el/develop/install.el"
         'silent 'inhibit-cookies)
      (goto-char (point-max))
      (eval-print-last-sexp)))
  (load bootstrap-file nil 'nomessage))

(straight-use-package 'use-package)
(setq straight-use-package-by-default t)

(use-package svg-tag-mode
  :config
  (setq svg-tag-tags
        '((":TODO:" . ((lambda (tag) (svg-tag-make "TODO")))))))

When turning on svg-tag-mode the *Messages* buffer reports the following error

Error during redisplay: (jit-lock-function 1) signaled (wrong-type-argument arrayp nil

After investigating it seemed like the error comes from the font-lock-flush function (https://github.com/rougier/svg-tag-mode/blob/fee61c6a0b0570bd24fd335efef17c7385297aa0/svg-tag-mode.el#L290). And in turn it is the svg-lib-tag that triggers it. I can verify that by running (svg-lib-tag "TEST"), which returns:

let*: Wrong type argument: arrayp, nil

Digging further into the problem I noticed that svg-lib-style-default were getting invalid background and foreground color. Background were set to unspecified-bg and foreground to unspecified-fg. I fixed it by running (setq svg-lib-style-default (svg-lib-style-compute-default)) after starting emacsclient to set sensible default value to svg-lib-style-default.

The value of svg-lib-style-default when starting emacsclient:

(:background "unspecified-bg" :foreground "unspecified-fg" :padding 1 :margin 0 :stroke 2 :radius 3 :alignment 0.5 :width 20 :height 0.9 :scale 0.75 :crop-left nil :crop-right nil :collection "material" :font-family "default" :font-size 0 :font-weight normal)

After updating it to svg-lib-style-compute-default:

(:background "#2E3440" :foreground "#ECEFF4" :padding 1 :margin 0 :stroke 2 :radius 3 :alignment 0.5 :width 20 :height 0.9 :scale 0.75 :crop-left nil :crop-right nil :collection "material" :font-family "Iosevka" :font-size 8 :font-weight regular)

So my best guess is that svg-lib-style-default is set before emacs frame is created and therefore gets an invalid value.

Maybe this is related to issues rougier/svg-tag-mode#21 and rougier/svg-tag-mode#22.

Thank you for your contributions to the Emacs community, much appreciated!

storvik avatar Mar 09 '22 20:03 storvik

Waouuh, thanks for the report and thanks for the amazing debug (and sorry for the delay in my answer). I think you analysis is right and there plenty of bug report for this specific case. One potential solution could be to take advantage of the after-make-frame-functions hook to initialize the default. Or else, to set a real default value based on default face.

rougier avatar Mar 27 '22 18:03 rougier

I'm trying to initialize an icon with after-make-frame-functions but unfortunately the timing doesn't appear to work for me. I am not sure how to get SVGs ready to go after the init process without some function to render them at least once after the frame is made and fully ready for usage. I cannot find a suitable built-in hook.

trev-dev avatar Sep 16 '22 21:09 trev-dev

Do you know if your emacs has svg support?

rougier avatar Oct 01 '22 10:10 rougier

Sorry for the late reply. This is how I got around it

  (defun first-graphical-frame-hook-function ()
    (remove-hook 'focus-in-hook #'first-graphical-frame-hook-function)
    (provide 'my-gui))
  (add-hook 'focus-in-hook #'first-graphical-frame-hook-function)

  (with-eval-after-load 'my-gui
    (setq svg-lib-style-default (svg-lib-style-compute-default)))

Remember trying to use after-make-frame-functions without any luck. I'm actually using with-eval-after-load 'my-gui to get around similar issues in several other packages.

Not sure this can / should be solved within the package itself, but that's up to you @rougier. Feel free to close this issue.

Thanks again @rougier for your work.

storvik avatar Oct 13 '22 20:10 storvik

Thansk for the update. But it is really wierd. How do you start your emacs daemon withut any frame (such I can debug on my side) ?

rougier avatar Oct 17 '22 12:10 rougier

I'm starting Emacs as a systemd service, that's why no frame is created.

storvik avatar Oct 17 '22 18:10 storvik

Maybe your solution is worth a mention in the README. Could you make a PR?

rougier avatar Nov 28 '22 07:11 rougier

I also get this bug with emacsclient, and it also makes me lose some parts of syntax highlighting when enabled svg-tag-mode.

AlynxZhou avatar Jul 25 '23 07:07 AlynxZhou

@AlynxZhou Does the delayed load code above fixes the problem?

rougier avatar Aug 07 '23 14:08 rougier

@AlynxZhou Does the delayed load code above fixes the problem?

The above code looks really wired to me, but it DO fixes the problem for me, maybe it should be added into this package.

AlynxZhou avatar Aug 17 '23 08:08 AlynxZhou

I haven't used this package for a while, but as I recently added it to my config again I poked around a little more. While the workaround above works it's also possible to set the style variable manually. The value can be found by running (svg-lib-style-compute-default).

(setq svg-lib-style-default '(:background "#0d0e1c" :foreground "#ffffff" :padding 1 :margin 0
                                          :stroke 2 :radius 3 :alignment 0.5 :width 20 :height 0.9
                                          :scale 0.75 :ascent center :crop-left nil :crop-right nil
                                          :collection "material" :font-family "Iosevka Nerd Font"
                                          :font-size 12 :font-weight regular))

Tried to play around with face-attribute, setting FRAME to t, without any luck.

(face-attribute FACE ATTRIBUTE &optional FRAME INHERIT)

Inferred type: (function (t t &optional t t) t)

Return the value of FACE’s ATTRIBUTE on FRAME.

See ‘set-face-attribute’ for the list of supported attributes
and their meanings and allowed values.

If the optional argument FRAME is given, report on face FACE in that frame.
If FRAME is t, report on the defaults for face FACE (for new frames).
If FRAME is omitted or nil, use the selected frame.

If INHERIT is nil, only attributes directly defined by FACE are considered,
  so the return value may be ‘unspecified’, or a relative value.
If INHERIT is non-nil, FACE’s definition of ATTRIBUTE is merged with the
  faces specified by its ‘:inherit’ attribute; however the return value
  may still be ‘unspecified’ or relative.
If INHERIT is a face or a list of faces, then the result is further merged
  with that face (or faces), until it becomes specified and absolute.

To ensure that the return value is always specified and absolute, use a
value of ‘default’ for INHERIT; this will resolve any unspecified or
relative values by merging with the ‘default’ face (which is always
completely specified).

storvik avatar Aug 23 '23 10:08 storvik

Thanks. You mean that setting the default style solves the problem?

rougier avatar Aug 24 '23 16:08 rougier

Unfortunately not. Seems like INHERIT could be used in order to avoid getting 'unspecified', but not sure how.

storvik avatar Aug 25 '23 19:08 storvik

So best solution would be probably to start svg-lib only after a frame has been created, what do you think?

rougier avatar Sep 11 '23 09:09 rougier

Can confirm that I am also experiencing the same issue when running Emacs as a daemon. How that is achieved is through this nix module, which simply executes emacs --fg-daemon on user login. (systemd.service)

The issue is not only experienced in svg-tags-mode though, it is also experienced in kind-icon to such an extent that it prevents ement from launching in my Emacs session.

Adding the temporary solution provided @storvik resolved the issue for me. (thanks, storvik!!)

Icy-Thought avatar Sep 20 '23 14:09 Icy-Thought

@rougier seems like people keeps hitting this so if it could be solved within the package itself it probably would be best. But I'm not sure how to do it. One could possible just use the workaround from my comment. Not sure if there are performance impacts etc though.

@Icy-Thought I actually use this workaround for a couple of packages in my config, so svg-lib is not alone. Glad I could help!

storvik avatar Sep 20 '23 19:09 storvik

@storvik Yes, I agree it needs to be fixed. Your anaylisis of the problem makes me think we could simply check for the "state" of svg-lib-style-default when we use it or to postpone initialization (just in time, just before the creation of the first tag). What do you think?

rougier avatar Oct 13 '23 09:10 rougier

Sorry for the late reply, but I haven't been using svg-lib / svg-tag-mode in favor for org-mode. Lately I have tried to include svg-tag-mode into my emacs dashboard. Seems like my fix still is needed to avoid this issue.

I think you could postpone initialization to creation of first tag. It seems more efficient than checking it whenever used. The question is if svg-lib-style-default is supposed to be customized? If so, wouldn't this write over a potential customized value?

Side note, fixing this should also fix https://github.com/rougier/svg-tag-mode/issues/38, I think.

Edit: Maybe it's possible to set defcustom svg-lib-style-default to default nil, and check whether it's nil later and compute defaults if not?

storvik avatar Jan 30 '24 20:01 storvik

Yes, I think the default style should be computed just in time and left to nil until it is necessary. Do you want to make a PR?

rougier avatar Feb 05 '24 14:02 rougier

@rougier I have tried to come up with a decent solution. See my pull request for details. Excited to see if this also fixes issue 38 in svg-tag-mode. As far as I can tell it should fix it.

storvik avatar Feb 05 '24 19:02 storvik

Perfect. You'll need to sign the copyright assignment before I can merge.

rougier avatar Feb 19 '24 10:02 rougier

Sorry about opening the issue again, I am on version 39621cd of svg-lib, whenever I try to set the notification status for a room ement, I get continue to get the error, Error running timer ‘plz--respond’: (wrong-type-argument arrayp nil)

I'm running in a emacs in a daemon mode and then using an emacsclient to connect to it. Are either of you, @storvik or @Icy-Thought continuing to get this issue?

bmp avatar Jun 11 '24 14:06 bmp

Not getting the issue myself and have not encountered that specific issue for quite some time.

Icy-Thought avatar Jun 11 '24 15:06 Icy-Thought

@bmp Nothing in that message mentions svg-lib.

alphapapa avatar Jun 11 '24 19:06 alphapapa