diff --git a/README.md b/README.md index cd10e984..13ceadbf 100644 --- a/README.md +++ b/README.md @@ -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) diff --git a/doom-modeline-core.el b/doom-modeline-core.el index 4ce0406c..a7b51bc4 100644 --- a/doom-modeline-core.el +++ b/doom-modeline-core.el @@ -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 diff --git a/doom-modeline-segments.el b/doom-modeline-segments.el index 1fcf9978..c9faa468 100644 --- a/doom-modeline-segments.el +++ b/doom-modeline-segments.el @@ -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