Symon
Symon (pronounced “simon”) is a tiny system monitor which displays system information in the echo area when Emacs is has been idle for a few seconds.
This is a fork of zk_phi’s Symon, which has been largely rewritten. It fixes a number of bugs and shortcomings and emphasizes customizability and code reuse, but also drops support for non-Linux platforms. It works nicely with EXWM.
Screenshot
Installation
Recommended:
(use-package symon
:straight (:host github :repo "ieure/symon")
:config (symon-mode 1))
If you don’t use straight
, you can clone the repo, open it with
dired, and M-x install-package-from-buffer RET
.
What about putting it in MELPA?
I don’t have much interest in doing this. While I think MELPA’s goals of having only high-quality curated packages is laudable, and the bar to contributing is reasonable, it’s still higher than I care to clear.
Configuration
Global options
symon-monitors
- List of list of monitors.
Each outer list is a page. Symon rotates through pages as it refreshes
(every symon-refresh-rate
seconds).
Each inner list is a list of monitors. Members of that list may be the symbol of a monitor; a direct monitor value; or an expression which evaluates to one of those things.
symon-delay
- Delay in seconds until Symon appears.
symon-refresh-rate
- How often to obtain new values from the monitors.
Standard monitors
- =symon-battery=
- Displays battery and charging status.
- =symon-cpu=
- Monitors CPU load.
- =symon-cpufreq=
- Monitors CPU frequency.
- =symon-fan=
- Monitors fan speed.
- =symon-memory=
- Displays memory usage.
- =symon-swap=
- Displays swap usage.
- =symon-temp=
- Monitors temperatures.
- =symon-time=
- Display a clock in Symon.
Creating new monitors
Symon uses EIEIO classes to implement monitors, and provides two base classes to build on:
symon-monitor
- This is the base class, suitable for monitors that display a single value.
symon-monitor-history
- This class keeps a history of values, and can create mini graphs of them.
Defining the class
The simplest monitor is:
(defclass symon-hello (symon-monitor))
If your monitor needs to hold state or user configuration options, those are stored in slots of the object. This separates the code which does the monitoring from the thing being monitored — for example, if you write a disk space monitor, you can specify the mountpoint in the constructor, which lets you monitor multiple disks with the same code.
(defclass symon-hello (symon-monitor)
((greeting :initform "Hello" ; Default value
:initarg :greeting))) ; Keyword for customizing.
Fetching values
The symon-monitor-fetch
generic function evaluates to the
current value of the monitor. Fetching and displaying are
orthogonal, asynchronous operations. The fetch function should
only obtain and return the value — it shouldn’t concern itself
with display or periodic refresh at all.
(cl-defmethod symon-monitor-fetch ((this symon-hello))
user-login-name)
Displaying the value
The symon-monitor-display
generic function formats the value
returned from the fetch function into something pleasing for a
human to look at. This might include embedding it in a format
string, or setting text properties like the display face.
If this method evaluates to a falsey value (nil
or =”“= (the
empty string)), the monitor won’t be displayed. This is useful
for conditional display of monitors, such as a media player
monitor that hides when nothing is playing, a swap monitor that
hides when no swap is used, etc.
(cl-defmethod symon-monitor-display ((this symon-custom-monitor))
(with-slots (greeting) this
(propertize
(format "%s, %s" greeting (symon-monitor-value this))
'face 'compilation-info)))
The default implementation of symon-monitor-display
is generic
and suitable for many monitors — you may not need your own method
at all.
Display options & defaults
Default options should be stored as a plist in the monitor’s
default-display-opts
slot. Users may set the display-opts
plist per instance; the base class will merge the two. This
allows users to specify only the changes they want, instead of
repeating the defaults.
The following options are supported by the default
symon-monitor-display
method:
:index
. A string, which is prepended to the current monitor value.:unit
. A string representing the unit the monitor is measuring, which is appended to the current monitor value.
Sparklines
For monitors based on symon-monitor-history
, a small graph
(sparkline) can be displayed. It offers additional options,
specified with the :sparkline
keyword in :display-opts
.
(symon-monitor-class-symbol
:display-opts '(:sparkline (:type gridded :lower-bound 0 :upper-bound 1000)))
The sparkline options are passed directly to the
symon-sparkline
constructor; see its documentation for a more
information.
Constructing the monitor
Defining the monitor controls how it works; an instance determines what it monitors.
(setq my/hello-monitor (symon-hello :greeting "Hi"))
Contributors
- zk_phi is the original author of Symon.
- Pierre Lecocq added Darwin support.
- Ian Eure substantially rewrote and extended Symon.