Theming Nyxt, midnight theme

By John Mercouris

Theming Nyxt is straightforward and powerful. Every class has an associated style slot (attribute) composed of CSS. You can change/append to this slot to modify the default theme, or create your own from scratch.

For the purposes of this article, we'll be modifying the default theme to make a dark version.

The first thing we'll change is the appearance of the prompt-buffer:

(define-configuration prompt-buffer
  ((style (str:concat
           %slot-default%
           (cl-css:css
            '((body
               :background-color "black"
               :color "#808080")
              ("#prompt-area"
               :background-color "black")
              ;; The area you input text in.
              ("#input"
               :background-color "white")
              (".source-name"
               :color "black"
               :background-color "gray")
              (".source-content"
               :background-color "black")
              (".source-content th"
               :border "1px solid lightgray"
               :background-color "black")
              ;; The currently highlighted option.
              ("#selection"
               :background-color "#37a8e4"
               :color "black")
              (.marked :background-color "darkgray"
                       :font-weight "bold"
                       :color "white")
              (.selected :background-color "black"
                         :color "white")))))))

What we've done here is concatenated the %slot-default of the minibuffer style with our own CSS that changes the background color and text color.

Next, let's handle the appearance of internal buffers. Internal buffers are used when you create any kind of buffer that is populated by Nyxt (help buffers, list messages, list buffers, etc).

;;; Panel buffers are the same in regards to style.
(define-configuration (internal-buffer panel-buffer)
  ((style
    (str:concat
     %slot-default%
     (cl-css:css
      '((body
         :background-color "black"
         :color "lightgray")
        (hr
         :color "darkgray")
        (a
         :color "lightgray")
        (.button
         :color "lightgray"
         :background-color "gray")))))))

Here we've added styling for <hr> elements and for .buttons.

Finally, we come to our first, and only special case, windows. For windows we must set the message-buffer-style to control the appearance of the message area at the bottom of the window.

(define-configuration window
  ((message-buffer-style
    (str:concat
     %slot-default%
     (cl-css:css
      '((body
         :background-color "black"
         :color "white")))))))

Et voila!

We hope you enjoy making Nyxt your own. Please feel free to share your themes that you create on our communication channels, we'd love to see what you can come up with! Thanks for reading :-)

Future Work

We believe that this system could be further enhanced by the creation of a define-theme macro/framework (built on top of the define-configuration macro). This framework could provide facilities to design and manage themes.

(define-theme my-theme
  ((buffer "custom-css-here)
   (internal-buffer "other-css-there")))

Installation/uninstallation of themes could be fully functional. You could test and develop as many themes as you like without leaving your system in a corrupt state. We're excited to see what we can come up with together!