rougier / svg-lib

Emacs SVG libraries for creatings tags, icons and bars
GNU General Public License v3.0
335 stars 30 forks source link

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

Closed storvik closed 4 months ago

storvik commented 2 years ago

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!

rougier commented 2 years ago

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.

trev-dev commented 1 year ago

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.

rougier commented 1 year ago

Do you know if your emacs has svg support?

storvik commented 1 year ago

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.

rougier commented 1 year ago

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) ?

storvik commented 1 year ago

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

rougier commented 1 year ago

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

AlynxZhou commented 11 months ago

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

rougier commented 11 months ago

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

AlynxZhou commented 11 months ago

@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.

storvik commented 10 months ago

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).
rougier commented 10 months ago

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

storvik commented 10 months ago

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

rougier commented 10 months ago

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

Icy-Thought commented 9 months ago

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!!)

storvik commented 9 months ago

@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!

rougier commented 9 months ago

@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?

storvik commented 5 months ago

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?

rougier commented 5 months ago

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?

storvik commented 5 months ago

@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.

rougier commented 4 months ago

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

bmp commented 1 month ago

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?

Icy-Thought commented 1 month ago

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

alphapapa commented 1 month ago

@bmp Nothing in that message mentions svg-lib.