emacs-libvterm icon indicating copy to clipboard operation
emacs-libvterm copied to clipboard

Colors in `vterm` do not update after loading a new theme

Open adonig opened this issue 1 year ago • 1 comments

Description

When I switch themes in Emacs using auto-dark, the colors in vterm do not update to reflect the new theme's color scheme. The vterm-color-* faces appear to retain the old theme's colors until I trigger some external action, like resizing the window, which forces a refresh and updates the colors correctly.

I've tried adding hooks to after-load-theme-hook to refresh or redraw vterm buffers programmatically, but none of the solutions I've attempted have worked reliably. Some of these approaches include:

  • Adjusting vterm-color-* faces directly.
  • Triggering a redisplay using force-window-update or redisplay.
  • Attempting to resize the vterm buffer programmatically.

However, these methods either fail to refresh the colors or result in unexpected issues, such as loss of terminal content.

Question

Is there an existing way to programmatically make vterm refresh its display and adjust its colors after switching themes? If not, could you suggest a workaround or a direction for resolving this issue?

Steps to Reproduce

  1. Open a vterm buffer.
  2. Load a new theme with M-: (load-theme 'theme-name).
  3. Observe that the colors in the vterm buffer do not update until a manual action (e.g., resizing the window) is performed.

Expected Behavior

The vterm colors should automatically adjust to match the new theme when the theme is switched.

Actual Behavior

The vterm colors do not update, and the old theme's colors persist until the buffer is redrawn by resizing or other indirect means.

Environment

  • Emacs Version: 29.4
  • OS: Fedora 41 Workstation
  • vterm Version: fd50624
  • Theme(s): modus-themes, leuven

Additional Notes

If a solution or workaround exists, I would be happy to implement it. Alternatively, if this is a missing feature, I’d be glad to contribute by testing or providing additional details if needed.

adonig avatar Dec 01 '24 11:12 adonig

@adonig I got some workaround working via triggering the buffer size. The thing is that is_invalidate flag tracked on the C module side and it will ignore any redisplay requests if it thinks buffer isn't changed. There are few ways to trigger it and seems like term_resize is the safest one.

(add-hook 'enable-theme-functions
          (lambda (_theme)
            (dolist (buf (buffer-list))
              (with-current-buffer buf
                (when (derived-mode-p 'vterm-mode)
                  (let* ((inhibit-read-only t)
                         (height (window-body-height))
                         (width (window-body-width)))
                    (vterm--set-size vterm--term (1- height) width)
                    (vterm--set-size vterm--term height width)))))))

ssbb avatar Dec 06 '25 21:12 ssbb