This advice is potentially defined before the autoloads for telega have run, which means that the macro-expansion fails and `telega-ins-fmt` is looked up as a function. With this setup the initialisation works as expected.
		
			
				
	
	
		
			81 lines
		
	
	
	
		
			2.8 KiB
		
	
	
	
		
			EmacsLisp
		
	
	
	
	
	
			
		
		
	
	
			81 lines
		
	
	
	
		
			2.8 KiB
		
	
	
	
		
			EmacsLisp
		
	
	
	
	
	
| ;;; dottime.el --- use dottime in the modeline
 | |
| ;;
 | |
| ;; Copyright (C) 2019 Google Inc.
 | |
| ;;
 | |
| ;; Author: Vincent Ambo <tazjin@google.com>
 | |
| ;; Version: 1.0
 | |
| ;; Package-Requires: (cl-lib)
 | |
| ;;
 | |
| ;;; Commentary:
 | |
| ;;
 | |
| ;; This package changes the display of time in the modeline to use
 | |
| ;; dottime (see https://dotti.me/) instead of the standard time
 | |
| ;; display.
 | |
| ;;
 | |
| ;; Modeline dottime display is enabled by calling
 | |
| ;; `dottime-display-mode' and dottime can be used in Lisp code via
 | |
| ;; `dottime-format'.
 | |
| 
 | |
| (require 'cl-lib)
 | |
| (require 'time)
 | |
| 
 | |
| (defun dottime--format-string (&optional offset prefix)
 | |
|   "Creates the dottime format string for `format-time-string'
 | |
|   based on the local timezone."
 | |
| 
 | |
|   (let* ((offset-sec (or offset (car (current-time-zone))))
 | |
|          (offset-hours (/ offset-sec 60 60))
 | |
|          (base (concat prefix "%m-%dT%H·%M")))
 | |
|     (if (/= offset-hours 0)
 | |
|         (concat base (format "%0+3d" offset-hours))
 | |
|       base)))
 | |
| 
 | |
| (defun dottime--display-time-update-advice (orig)
 | |
|   "Function used as advice to `display-time-update' with a
 | |
|   rebound definition of `format-time-string' that renders all
 | |
|   timestamps as dottime."
 | |
| 
 | |
|   (cl-letf* ((format-orig (symbol-function 'format-time-string))
 | |
|              ((symbol-function 'format-time-string)
 | |
|               (lambda (&rest _)
 | |
|                 (funcall format-orig (dottime--format-string) nil t))))
 | |
|     (funcall orig)))
 | |
| 
 | |
| (defun dottime-format (&optional time offset prefix)
 | |
|   "Format the given TIME in dottime at OFFSET. If TIME is nil,
 | |
|   the current time will be used. PREFIX is prefixed to the format
 | |
|   string verbatim.
 | |
| 
 | |
|   OFFSET can be an integer representing an offset in seconds, or
 | |
|   the argument can be elided in which case the system time zone
 | |
|   is used."
 | |
| 
 | |
|   (format-time-string (dottime--format-string offset prefix) time t))
 | |
| 
 | |
| (defun dottime-display-mode (arg)
 | |
|   "Enable time display as dottime. Disables dottime if called
 | |
|   with prefix 0 or nil."
 | |
| 
 | |
|   (interactive "p")
 | |
|   (if (or (eq arg 0) (eq arg nil))
 | |
|       (advice-remove 'display-time-update #'dottime--display-time-update-advice)
 | |
|     (advice-add 'display-time-update :around #'dottime--display-time-update-advice))
 | |
|   (display-time-update)
 | |
| 
 | |
|   ;; Amend the time display in telega.el to use dottime.
 | |
|   ;;
 | |
|   ;; This will never display offsets in the chat window, as those are
 | |
|   ;; always visible in the modeline anyways.
 | |
|   (when (featurep 'telega)
 | |
|     (defun telega-ins--dottime-advice (orig timestamp)
 | |
|       (let* ((dtime (decode-time timestamp t))
 | |
|              (current-ts (time-to-seconds (current-time)))
 | |
|              (ctime (decode-time current-ts))
 | |
|              (today00 (telega--time-at00 current-ts ctime)))
 | |
|         (if (> timestamp today00)
 | |
|             (telega-ins (format "%02d·%02d" (nth 2 dtime) (nth 1 dtime)))
 | |
|           (funcall orig timestamp))))
 | |
| 
 | |
|     (advice-add 'telega-ins--date :around #'telega-ins--dottime-advice)))
 | |
| 
 | |
| (provide 'dottime)
 |