forked from Shirakumo/trial
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathlanguage.lisp
90 lines (73 loc) · 3.09 KB
/
language.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
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
#|
This file is a part of trial
(c) 2019 Shirakumo http://tymoon.eu ([email protected])
Author: Nicolas Hafner <[email protected]>
|#
(in-package #:org.shirakumo.fraf.trial)
(define-global +language-data+ NIL)
(defun languages ()
(mapcar #'pathname-utils:directory-name
(directory (merge-pathnames "lang/*/" (root)))))
(defun language-dir (language)
(merge-pathnames (make-pathname :directory `(:relative "lang" ,(string-downcase language)))
(root)))
(defun language-file (language)
(make-pathname :name "strings" :type "lisp" :defaults (language-dir language)))
(defun language-files (language)
(directory (make-pathname :name :wild :type "lisp" :defaults (language-dir language))))
(defmethod load-language (&optional (language (setting :language)))
(let ((table (make-hash-table :test 'eq)))
(v:info :trial.language "Loading language ~s from ~a" language (language-file language))
(with-trial-io-syntax ()
(with-open-file (stream (language-file language))
(loop for k = (read stream NIL)
for v = (read stream NIL)
while k
do (setf (gethash k table) v))
(setf +language-data+ table)))))
(defmethod save-language (&optional (language (setting :language)))
(when +language-data+
(v:info :trial.language "Saving language ~s to ~s" language (language-file language))
(with-trial-io-syntax ()
(with-open-file (stream (language-file language)
:direction :output
:if-exists :supersede)
(loop for k being the hash-keys of +language-data+
for v being the hash-keys of +language-data+
do (format stream "~s ~s~%" k v))))))
(defun language-string (identifier &optional (errorp T))
(unless +language-data+ (load-language))
(or (gethash identifier +language-data+)
(unless errorp (return-from language-string NIL))
;; Try loading again in case things changed.
(progn (load-language)
(gethash identifier +language-data+))
(restart-case
(error "No language string defined for ~s" identifier)
(retry ()
:report "Retry now."
(language-string identifier))
(use-value (value)
:report "Supply a string to use."
value))))
(defun (setf language-string) (string identifier)
(unless +language-data+ (load-language))
(check-type string string)
(check-type identifier symbol)
(setf (gethash identifier +language-data+) string))
(defun ensure-language-string (thing)
(etypecase thing
(string thing)
(symbol (language-string thing))))
(define-setting-observer load-language :language (value)
(load-language value))
(defun @format (destination identifier &rest args)
(format destination "~?" (language-string identifier) args))
(defun @formats (identifier &rest args)
(format NIL "~?" (language-string identifier) args))
(defmacro @ (identifier)
`(language-string ',identifier))
(set-dispatch-macro-character
#\# #\@ (lambda (s c a)
(declare (ignore c a))
(language-string (read s T NIL T))))