-
Notifications
You must be signed in to change notification settings - Fork 0
/
utils.lisp
59 lines (49 loc) · 2.31 KB
/
utils.lisp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
(defpackage #:deftask-utils
(:use #:cl)
(:export #:assocr #:assocrv #:assocrv-fn
#:relative-time #:roughly-same-time-p))
(in-package #:deftask-utils)
;;; alist utils
(defun assocr (path alist &key (key #'identity) (test #'eql))
(labels ((execute (path alist result)
(cond
((null path)
result)
((atom path)
(assoc path alist :key key :test test))
(t
(let ((next (assoc (first path) alist :key key :test test)))
(execute (cdr path) (cdr next) next))))))
(execute path alist nil)))
(defun assocrv (path alist &key (key #'identity) (test #'eql))
(cdr (assocr path alist :key key :test test)))
(defun assocrv-fn (path &key (key #'identity) (test #'eql))
(lambda (alist)
(assocrv path alist :key key :test test)))
;;; time
(defvar *locale* "en")
(defvar *default-locale* "en")
(defun find-locale (name)
(or (ignore-errors (cl-l10n:locale (substitute #\_ #\- name)))
(cl-l10n:locale *default-locale*)))
(defun relative-time (t1 &key (t2 (local-time:now)) (locale *locale*) (sentencep t))
(let ((diff (local-time:timestamp-difference t2 t1)))
(cond ((minusp diff) ; in the future
(if sentencep "just now" "now"))
((< diff 120) ; < 2 mins
(if sentencep "just now" "now"))
((< diff local-time:+seconds-per-hour+) ; < 1 hour
(format nil "~Am~:[~; ago~]" (floor (/ diff local-time:+seconds-per-minute+)) sentencep))
((< diff local-time:+seconds-per-day+) ; 1 day
(format nil "~Ah~:[~; ago~]" (floor (/ diff local-time:+seconds-per-hour+)) sentencep))
((or (< diff (* 180 local-time:+seconds-per-day+))
(= (local-time:timestamp-year t1) (local-time:timestamp-year t2)))
(cl-l10n:with-locale (find-locale locale)
;; FIXME: pattern should be locale specific
(format nil "~:[~;on ~]~A" sentencep (cl-l10n:format-date nil t1 :pattern "d MMM"))))
(t
(cl-l10n:with-locale (find-locale locale)
;; FIXME: pattern should be locale specific
(format nil "~:[~;in ~]~A" sentencep (cl-l10n:format-date nil t1 :pattern "MMM yyyy")))))))
(defun roughly-same-time-p (t1 t2)
(< (abs (local-time:timestamp-difference t1 t2)) 1))