~ubuntu-branches/ubuntu/maverick/uim/maverick

« back to all changes in this revision

Viewing changes to scm/custom-rt.scm

  • Committer: Bazaar Package Importer
  • Author(s): Masahito Omote
  • Date: 2006-11-23 15:10:53 UTC
  • mfrom: (3.1.8 edgy)
  • Revision ID: james.westby@ubuntu.com-20061123151053-q42sk1lvks41xpfx
Tags: 1:1.2.1-9
uim-gtk2.0.postinst: Don't call update-gtk-immodules on purge.
(closes: Bug#398530)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
;;; custom-rt.scm: Partial customization support for runtime input
 
2
;;;                processes
 
3
;;;
 
4
;;; Copyright (c) 2003-2006 uim Project http://uim.freedesktop.org/
 
5
;;;
 
6
;;; All rights reserved.
 
7
;;;
 
8
;;; Redistribution and use in source and binary forms, with or without
 
9
;;; modification, are permitted provided that the following conditions
 
10
;;; are met:
 
11
;;; 1. Redistributions of source code must retain the above copyright
 
12
;;;    notice, this list of conditions and the following disclaimer.
 
13
;;; 2. Redistributions in binary form must reproduce the above copyright
 
14
;;;    notice, this list of conditions and the following disclaimer in the
 
15
;;;    documentation and/or other materials provided with the distribution.
 
16
;;; 3. Neither the name of authors nor the names of its contributors
 
17
;;;    may be used to endorse or promote products derived from this software
 
18
;;;    without specific prior written permission.
 
19
;;;
 
20
;;; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND
 
21
;;; ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 
22
;;; IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 
23
;;; ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE
 
24
;;; FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 
25
;;; DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 
26
;;; OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 
27
;;; HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 
28
;;; LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 
29
;;; OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 
30
;;; SUCH DAMAGE.
 
31
;;;;
 
32
 
 
33
;; This file provides partial custom definition support for runtime
 
34
;; input processes. The processes that wants full-featured custom API
 
35
;; such as uim-pref must overrides these definitions by loading
 
36
;; custom.scm.
 
37
;;
 
38
;; The name 'custom-rt' is not the best to represent this partial
 
39
;; functionality. Give me better name.  -- YamaKen 2005-01-14
 
40
 
 
41
;; TODO: write test-custom-rt.scm
 
42
 
 
43
(require "util.scm")
 
44
(require "key.scm")
 
45
 
 
46
(define custom-full-featured? #f)
 
47
;; experimental
 
48
(define custom-enable-mtime-aware-user-conf-reloading? #f)
 
49
 
 
50
(define-record 'custom-choice-rec
 
51
  '((sym   #f)
 
52
    (label "")
 
53
    (desc  "")))
 
54
 
 
55
(define custom-required-custom-files ())
 
56
(define custom-rt-primary-groups ())
 
57
(define custom-set-hooks ())
 
58
;; experimental
 
59
(define custom-group-conf-freshnesses ())  ;; (gsym . mtime)
 
60
 
 
61
(define custom-file-path
 
62
  (lambda (gsym)
 
63
    (let* ((group-name (symbol->string gsym))
 
64
           (path (string-append (getenv "HOME")
 
65
                                "/.uim.d/customs/custom-"
 
66
                                group-name
 
67
                                ".scm")))
 
68
      path)))
 
69
 
 
70
;; experimental
 
71
(define custom-update-group-conf-freshness
 
72
  (lambda (gsym)
 
73
    (let ((mtime (file-mtime (custom-file-path gsym))))
 
74
      (set! custom-group-conf-freshnesses
 
75
            (alist-replace (cons gsym mtime)
 
76
                           custom-group-conf-freshnesses))
 
77
      #t)))
 
78
 
 
79
;; experimental
 
80
(define custom-group-conf-updated?
 
81
  (lambda (gsym)
 
82
    (let ((prev-mtime (assq-cdr gsym custom-group-conf-freshnesses)))
 
83
      (or (not prev-mtime)
 
84
          (not (= (file-mtime (custom-file-path gsym))
 
85
                  prev-mtime))))))
 
86
 
 
87
;; experimental
 
88
(define custom-load-updated-group-conf
 
89
  (lambda (gsym)
 
90
    (or (not (custom-group-conf-updated? gsym))
 
91
        (and (try-load (custom-file-path gsym))
 
92
             (custom-update-group-conf-freshness gsym)))))
 
93
 
 
94
;; full implementation
 
95
;; This proc is existing for DUMB loading. No more processing such as
 
96
;; mtime comparation or history recording must not be added. Please
 
97
;; keep in mind responsibility separation, and don't alter an API
 
98
;; specification previously stabilized, without discussion.
 
99
;;   -- YamaKen 2005-08-09
 
100
(define custom-load-group-conf
 
101
  (lambda (gsym)
 
102
    (try-load (custom-file-path gsym))))
 
103
 
 
104
;; TODO: disable all newly defined customs when an error occurred in loading
 
105
;; full implementation
 
106
(define require-custom
 
107
  (lambda (filename)
 
108
    (let ((pre-groups (custom-list-primary-groups)))
 
109
      (require filename)
 
110
      (if (not (member filename custom-required-custom-files))
 
111
          (set! custom-required-custom-files
 
112
                (cons filename custom-required-custom-files)))
 
113
      (let* ((post-groups (custom-list-primary-groups))
 
114
             (new-groups (list-tail post-groups (length pre-groups))))
 
115
        (if (and (not (getenv "LIBUIM_VANILLA"))
 
116
                 (not (setugid?)))
 
117
            (for-each (lambda (gsym)
 
118
                        (custom-load-group-conf gsym)
 
119
                        (custom-update-group-conf-freshness gsym))
 
120
                      (reverse new-groups)))))))
 
121
 
 
122
;; full implementation
 
123
(define custom-reload-customs
 
124
  (lambda ()
 
125
    (for-each load (reverse custom-required-custom-files))
 
126
    (custom-call-all-hook-procs custom-set-hooks)))
 
127
 
 
128
;; full implementation
 
129
(define custom-modify-key-predicate-names
 
130
  (lambda (keys)
 
131
    (map (lambda (key)
 
132
           (if (symbol? key)
 
133
               (symbolconc key '?)
 
134
               key))
 
135
         keys)))
 
136
 
 
137
;; lightweight implementation
 
138
(define custom-choice-range-reflect-olist-val
 
139
  (lambda (dst-sym src-sym indication-alist)
 
140
    #f))
 
141
 
 
142
;; full implementation
 
143
(define custom-rt-add-primary-groups
 
144
  (lambda (gsym)
 
145
    (if (not (member gsym custom-rt-primary-groups))
 
146
        (set! custom-rt-primary-groups
 
147
              (cons gsym custom-rt-primary-groups)))))
 
148
 
 
149
;; lightweight implementation
 
150
(define custom-list-primary-groups
 
151
  (lambda ()
 
152
    (reverse custom-rt-primary-groups)))
 
153
 
 
154
;; TODO: write test
 
155
;; lightweight implementation
 
156
(define custom-add-hook
 
157
  (lambda (custom-sym hook-sym proc)
 
158
    (if (eq? hook-sym
 
159
             'custom-set-hooks)
 
160
        (set! custom-set-hooks
 
161
              (alist-replace (cons custom-sym proc)
 
162
                             custom-set-hooks)))))
 
163
 
 
164
;; TODO: write test
 
165
;; lightweight implementation
 
166
(define custom-call-hook-procs
 
167
  (lambda (sym hook)
 
168
    (let ((proc (assq sym hook)))
 
169
      (if proc
 
170
          ((cdr proc))))))
 
171
 
 
172
;; TODO: write test
 
173
;; full implementation
 
174
(define custom-call-all-hook-procs
 
175
  (lambda (hook)
 
176
    (for-each (lambda (pair)
 
177
                ((cdr pair)))
 
178
              hook)))
 
179
 
 
180
;; lightweight implementation
 
181
(define define-custom-group
 
182
  (lambda (gsym label desc)
 
183
    #f))
 
184
 
 
185
;; lightweight implementation
 
186
(define custom-exist?
 
187
  (lambda (sym type)
 
188
    (symbol-bound? sym)))
 
189
 
 
190
;; lightweight implementation
 
191
(define custom-key-exist?
 
192
  (lambda (sym)
 
193
    (let ((key-sym (symbolconc sym '?)))
 
194
      (and (symbol-bound? sym)
 
195
           (list? (symbol-value sym))
 
196
           (symbol-bound? key-sym)
 
197
           (procedure? (symbol-value key-sym))))))
 
198
 
 
199
;; lightweight implementation
 
200
(define custom-value
 
201
  (lambda (sym)
 
202
    (symbol-value sym)))
 
203
 
 
204
;; TODO: rewrite test
 
205
;; lightweight implementation
 
206
(define custom-set-value!
 
207
  (lambda (sym val)
 
208
    (and (cond
 
209
          ((custom-key-exist? sym)
 
210
           (set-symbol-value! sym val)
 
211
           (let ((key-val (custom-modify-key-predicate-names val)))
 
212
             (eval (list 'define (symbolconc sym '?)
 
213
                         (list 'make-key-predicate (list 'quote key-val)))
 
214
                   (interaction-environment)))
 
215
           #t)
 
216
          ((custom-exist? sym #f)
 
217
           (set-symbol-value! sym val)
 
218
           #t)
 
219
          (else
 
220
           #f))
 
221
         (begin
 
222
           (custom-call-hook-procs sym custom-set-hooks)
 
223
           #t))))
 
224
 
 
225
;; TODO: rewrite test
 
226
;; lightweight implementation
 
227
(define define-custom
 
228
  (lambda (sym default groups type label desc)
 
229
    (custom-rt-add-primary-groups (car groups))
 
230
    (if (not (custom-exist? sym type))
 
231
        (begin
 
232
          (let ((quoted-default (if (or (symbol? default)
 
233
                                        (list? default))
 
234
                                    (list 'quote default)
 
235
                                    default)))
 
236
            (eval (list 'define sym quoted-default)
 
237
                  (interaction-environment))
 
238
            (if (custom-key-exist? sym)
 
239
                ;; already define-key'ed in ~/.uim
 
240
                (custom-call-hook-procs sym custom-set-hooks)
 
241
                (begin
 
242
                  (if (eq? (car type)
 
243
                           'key)
 
244
                      (eval (list 'define (symbolconc sym '?) list)
 
245
                            (interaction-environment)))
 
246
                  (custom-set-value! sym default))))))))  ;; to apply hooks
 
247
 
 
248
;; lightweight implementation
 
249
;; warning: no validation performed
 
250
(define custom-prop-update-custom-handler
 
251
  (lambda (context custom-sym val)
 
252
    (custom-set-value! custom-sym val)))
 
253
 
 
254
;; custom-reload-user-configs can switch its behavior by
 
255
;; custom-enable-mtime-aware-user-conf-reloading? since the
 
256
;; experimental code breaks the semantics of custom variable
 
257
;; broadcasting.
 
258
;;
 
259
;; For example, an arbitrary uim-enabled process can update a custom
 
260
;; variable by its own code without any helper message passing. In
 
261
;; such case, the previously defined broadcasting behavior overwrites
 
262
;; the variable locally modified even if the corresponding custom file
 
263
;; is not updated.
 
264
;;
 
265
;; To make the latter code default, a discussion is required.
 
266
;;   -- YamaKen 2005-08-09
 
267
(define custom-reload-user-configs
 
268
  (lambda ()
 
269
    (and (not (getenv "LIBUIM_VANILLA"))
 
270
         (not (setugid?))
 
271
         (let ((load-conf (if custom-enable-mtime-aware-user-conf-reloading?
 
272
                              custom-load-updated-group-conf
 
273
                              custom-load-group-conf)))  ;; original behavior
 
274
           (for-each load-conf (custom-list-primary-groups))
 
275
           (custom-call-all-hook-procs custom-set-hooks)))))