Skip to content

Commit

Permalink
Introduce analogue clock time icon
Browse files Browse the repository at this point in the history
With the SVG library (bundled as part of Emacs), we can generate an
analogue clock for the current time to-the-minute, instead of using the
nearest-hour nerdicon.

This relies on a graphical display, and so a new variable is introduced,
`doom-modeline-time-analogue-clock' and the behaviour is gated
on (display-graphic-p).

There are a number of variables that affect the style of the displayed
clock. For now, I've chosen to be conservative and just expose
`doom-modeline-time-clock-minute-resolution' as a custom variable,
leaving the rest as constants. We may well want to revisit this in the
future.

I've personally been running this variant of the time segment for over a
year now, and as a result am pretty confident there are no behaviour or
performance issues with this implementation.

This implementation is originally sourced from
https://github.com/tecosaur/emacs-config/blob/a3c3b73a00f4e034ffeae11f20b00d1eb948a6e6/config.org#time.
  • Loading branch information
tecosaur authored and seagle0128 committed Mar 7, 2024
1 parent f67f627 commit d066e7b
Show file tree
Hide file tree
Showing 3 changed files with 83 additions and 20 deletions.
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,10 @@ Run `M-x customize-group RET doom-modeline RET` or set the variables.
;; It respects option `doom-modeline-icon' and option `doom-modeline-time-icon'.
(setq doom-modeline-time-live-icon t)
;; Whether to use an analogue clock svg as the live time icon.
;; It respects options `doom-modeline-icon', `doom-modeline-time-icon', and `doom-modeline-time-live-icon'.
(setq doom-modeline-time-analogue-clock t)
;; Whether to use unicode as a fallback (instead of ASCII) when not using icons.
(setq doom-modeline-unicode-fallback nil)
Expand Down
14 changes: 14 additions & 0 deletions doom-modeline-core.el
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,20 @@ It respects option `doom-modeline-icon' and option `doom-modeline-time-icon'."
:type 'boolean
:group 'doom-modeline)

(defcustom doom-modeline-time-analogue-clock t
"Whether to draw an analogue clock SVG as the live time icon.
It respects options `doom-modeline-icon', `doom-modeline-time-icon', and
`doom-modeline-time-live-icon'."
:type 'boolean
:group 'doom-modeline)

(defcustom doom-modeline-time-clock-minute-resolution 1
"The clock will be updated every this many minutes, truncated.
See `doom-modeline-time-analogue-clock'."
:type 'number
:group 'doom-modeline)

(defcustom doom-modeline-unicode-fallback nil
"Whether to use unicode as a fallback (instead of ASCII) when not using icons."
:type 'boolean
Expand Down
85 changes: 65 additions & 20 deletions doom-modeline-segments.el
Original file line number Diff line number Diff line change
Expand Up @@ -3080,28 +3080,73 @@ mouse-3: Restart preview"
;; Display time
;;

(defconst doom-modeline--clock-hour-hand-ratio 0.45
"Length of the hour hand as a proportion of the radius.")

(defconst doom-modeline--clock-minute-hand-ratio 0.7
"Length of the minute hand as a proportion of the radius.")

(defconst doom-modeline--clock-inverse-size 4.8
"The size of the clock, as an inverse proportion to the mode line height.")

(defvar doom-modeline--clock-cache nil
"The last result of `doom-modeline--generate-clock'.")

(defun doom-modeline--generate-clock ()
"Return a string containing the current time as an analogue clock svg.
When the svg library is not availible, return nil."
(cdr
(or (and (equal (truncate (float-time)
(* doom-modeline-time-clock-minute-resolution 60))
doom-modeline--clock-cache))
(and (require 'svg nil t)
(setq doom-modeline--clock-cache
(cons (truncate (float-time)
(* doom-modeline-time-clock-minute-resolution 60))
(with-temp-buffer
(svg-insert-image
(micro-clock-svg
(string-to-number (format-time-string "%-I")) ; hour
(* (truncate (string-to-number (format-time-string "%-M"))
doom-modeline-time-clock-minute-resolution)
doom-modeline-time-clock-minute-resolution) ; minute
(/ doom-modeline-height doom-modeline--clock-inverse-size) ; radius
"currentColor"))
(propertize
" "
'display
(append (get-text-property 0 'display (buffer-string))
'(:ascent center))
'face 'doom-modeline-time
'help-echo (lambda (_window _object _pos)
(format-time-string "%c"))))))))))

(defun doom-modeline-time-icon ()
"Displays the time icon."
(doom-modeline-icon
'mdicon
(if doom-modeline-time-live-icon
(pcase (% (caddr (decode-time)) 12)
(0 "nf-md-clock_time_twelve_outline")
(1 "nf-md-clock_time_one_outline")
(2 "nf-md-clock_time_two_outline")
(3 "nf-md-clock_time_three_outline")
(4 "nf-md-clock_time_four_outline")
(5 "nf-md-clock_time_five_outline")
(6 "nf-md-clock_time_six_outline")
(7 "nf-md-clock_time_seven_outline")
(8 "nf-md-clock_time_eight_outline")
(9 "nf-md-clock_time_nine_outline")
(10 "nf-md-clock_time_ten_outline")
(11 "nf-md-clock_time_eleven_outline"))
"nf-md-clock_outline")
""
""
:face '(:inherit doom-modeline-time :weight normal)))
(or (and doom-modeline-time-live-icon
doom-modeline-time-analogue-clock
(display-graphic-p)
(doom-modeline--generate-clock))
(doom-modeline-icon
'mdicon
(if doom-modeline-time-live-icon
(pcase (% (caddr (decode-time)) 12)
(0 "nf-md-clock_time_twelve_outline")
(1 "nf-md-clock_time_one_outline")
(2 "nf-md-clock_time_two_outline")
(3 "nf-md-clock_time_three_outline")
(4 "nf-md-clock_time_four_outline")
(5 "nf-md-clock_time_five_outline")
(6 "nf-md-clock_time_six_outline")
(7 "nf-md-clock_time_seven_outline")
(8 "nf-md-clock_time_eight_outline")
(9 "nf-md-clock_time_nine_outline")
(10 "nf-md-clock_time_ten_outline")
(11 "nf-md-clock_time_eleven_outline"))
"nf-md-clock_outline")
""
""
:face '(:inherit doom-modeline-time :weight normal))))

(doom-modeline-def-segment time
(when (and doom-modeline-time
Expand Down

0 comments on commit d066e7b

Please sign in to comment.