Skip to content
SVG-based themes for mode-line
Emacs Lisp
Find file
Latest commit 80a0e01 Apr 25, 2015 @sabof Version bump to 0.1.3
Failed to load latest commit information.
.gitignore
.projectile
README.md
screenshot.png
svg-mode-line-themes-bio-diesel.el
svg-mode-line-themes-black-crystal.el
svg-mode-line-themes-core.el
svg-mode-line-themes-diesel.el
svg-mode-line-themes-nasa.el
svg-mode-line-themes-tests.el
svg-mode-line-themes-widgets.el
svg-mode-line-themes.el

README.md

svg-mode-line-themes

screenshot

Installation

You need to obtain xmlgen. When installing through package.el, this should be done automatically.

Add to your .emacs:

(require 'svg-mode-line-themes)
(smt/enable)
(smt/set-theme 'black-crystal)
(set-face-attribute 'mode-line nil :box nil)
(set-face-attribute 'mode-line-inactive nil :box nil)

Font size calculation is imperfect, so it might require adjustments for your particular font/size combination. Should the font/size be different from the emacs default, clicking and row auto-hiding will not work precisely. The following example shows how to explicitly set font parameters.

(let (( theme-archetype (cdr (assoc 'archetype smt/themes)))
      ( row-archetype (cdr (assoc 'archetype smt/rows))))
  (setf (getf theme-archetype :style)
        (list :font-family "DejaVu Sans Mono"
              :font-size "10pt"))
  (setf (getf row-archetype :baseline) 12))

Usage

You can cycle through available themes, using M-x smt/next-theme

Creating and modifying themes

You might want to see how the included themes are implemented, but here is a short introduction.

Three types of objects are used: widgets, rows and themes. Widgets correspond to bits of text which might have an individual style and on-click behaviour. Rows correspond to a number of widgets placed one after the other. Rows can be aligned to the left, right, or centered (the corresponding values of :align are "left", "right" and "center"). Themes can contain one or more rows, a background and an overlay (A layer placed on top of everything else. You'd probably want to make it semi-transparent.)

Objects are implemented as plists and prototype inheritance is used. Each object has a :prototype property pointing to it's parent. Each object type also has a "namespace" - an alist (ex. smt/widgets). The prototype can contain a direct reference to an object, or a name of an object from the namespace. Ultimately each object of a certain type inherits from an "archetype" object contained within the corresponding namespace.

By using macros smt/deftheme, smt/defrow and smt/defwidget, one creates an object and adds it to the type's namespace. Should an object with the same name already exist, it will be replaced - which is an easy way to change the behaviour of existing themes.

Most properties can have direct values, or contain a function that accepts one value - the object itself, but there are exceptions. A propety's getter (such as smt/w-text, which retrieves the text from a widget) will return the value, or the result of evaluating the function.

Each theme has a :rows property, which is a list of rows. The order matters - should rows happen to overlap, rows appearing later on the list will be hidden.

Here is an example of creating a theme derived from black-crystal, but without the line-number information:

(smt/deftheme black-crystal-no-pager
  :prototype 'black-crystal
  :rows (list
         'default-left
         (smt/make-row
          :prototype 'default-right
          :margin 2)))

Themes, rows and widgets have a :style property. :style is different from the inline CSS style propety, it can contain any parameter (including :style, which will correspond to inline CSS). When a widget is being exported, it will contain attributes from the :style property of the relevant theme and row, as well as it's own.

Themes have a property called :local-widgets. When a row is being exported, and it encounters a symbol naming a widget, it will first look in the theme's :local-widgets, and then in smt/widgets alist. Widgets defined in :local-widgets, can't use names of previous widgets as their :prototype (:local-widgets works like let, and not like let*).

This is an example of diesel, with blue titles.

(defun smt/diesel-blue-title-style (widget)
  (smt/combine-styles
   (smt/w-style (smt/w-prototype widget))
   (list :fill (if (smt/window-active-p)
                   "#21D0EE"
                   "#4C5055")
         :font-weight "bold")))

(smt/deftheme diesel-blue
  :prototype 'diesel
  :local-widgets
  (lambda (theme)
    (let (( parent-local-widgets
            (smt/t-local-widgets
             (smt/t-prototype theme))))
      (append (list (cons 'buffer-name
                          (smt/make-widget
                           :prototype 'buffer-name
                           :style 'smt/diesel-blue-title-style))
                    (cons 'minor-modes
                          (smt/make-widget
                           :prototype 'minor-modes
                           :style 'smt/diesel-blue-title-style)))
              parent-local-widgets))))
Something went wrong with that request. Please try again.