~ubuntu-branches/ubuntu/trusty/select-xface/trusty

« back to all changes in this revision

Viewing changes to select-xface.el

  • Committer: Bazaar Package Importer
  • Author(s): Takuo KITAME
  • Date: 2002-02-18 00:21:11 UTC
  • Revision ID: james.westby@ubuntu.com-20020218002111-7hbpu8ny3me8wojz
Tags: upstream-0.15
ImportĀ upstreamĀ versionĀ 0.15

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
;;; select-xface.el --- Select X-Faces graphically
 
2
 
 
3
; Created:    <97/08/22 12:49:31 teranisi>
 
4
; Time-stamp: <2002-02-17 23:46:09 teranisi>
 
5
 
 
6
;; Copyright (C) 1997-2002 Yuuichi Teranishi
 
7
 
 
8
;; Author: Yuuichi Teranishi <teranisi@gohome.org>
 
9
;; Maintainer: Yuuichi Teranishi <teranisi@gohome.org>
 
10
;; Version: 0.15
 
11
;; Target: Emacs, Mule, XEmacs
 
12
 
 
13
;; Select X-Face is free software; you can redistribute it and/or modify
 
14
;; it under the terms of the GNU General Public License as published by
 
15
;; the Free Software Foundation; either version 2, or
 
16
;; any later version.
 
17
 
 
18
;; Select X-Face is distributed in the hope that it will be useful,
 
19
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
 
20
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
21
;; GNU General Public License for more details.
 
22
 
 
23
;; You should have received a copy of the GNU General Public License
 
24
;; along with GNU Emacs; see the file COPYING.  If not, write to the
 
25
;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 
26
;; Boston, MA 02111-1307, USA.
 
27
 
 
28
;; Setup:
 
29
;;
 
30
;; (autoload 'select-xface "select-xface" "Select X-Face" t)
 
31
;;
 
32
;; For Mew:
 
33
;; (add-hook 'mew-draft-mode-hook
 
34
;;        (lambda ()
 
35
;;          (define-key (current-local-map) "\C-c\C-x"
 
36
;;            'select-xface)))
 
37
;;
 
38
;; For Gnus:
 
39
;; (add-hook 'gnus-message-setup-hook
 
40
;;        (lambda ()
 
41
;;          (define-key (current-local-map) "\C-x4x"
 
42
;;            'select-xface)))
 
43
;; For mh-e:
 
44
;; (add-hook 'mh-letter-mode-hook
 
45
;;        (lambda ()
 
46
;;          (define-key (current-local-map) "\C-x4x"
 
47
;;            'select-xface)))
 
48
;; For MAIL, RMAIL, VM, cmail, Wanderlust:
 
49
;; (add-hook 'mail-mode-hook
 
50
;;        (lambda ()
 
51
;;          (define-key (current-local-map) "\C-x4x"
 
52
;;            'select-xface)))
 
53
 
 
54
;;; Commentary:
 
55
;; 
 
56
 
 
57
;;; Code:
 
58
 
 
59
(defconst select-xface-appname "Select X-Face")
 
60
(defconst select-xface-version-number "v0.15")
 
61
(defconst select-xface-codename "Live And Let Die")
 
62
 
 
63
(defconst select-xface-version
 
64
  (concat select-xface-appname " "
 
65
          select-xface-version-number " - \""
 
66
          select-xface-codename "\""))
 
67
 
 
68
;;
 
69
;; Users may set these variables
 
70
;;
 
71
(defvar select-xface-directory "~/.xfaces"
 
72
  "*files or subdirectories in this directory become the candidates.")
 
73
 
 
74
(defvar select-xface-height 5
 
75
  "*height of the popup buffer.")
 
76
 
 
77
(defvar select-xface-field-insert-before "^X-Mailer:\\|^User-Agent:\\|^--"
 
78
  "*insert xface field before this regexp.")
 
79
 
 
80
(defvar select-xface-mode-hook nil
 
81
  "*hooks to be called after select-xface-mode starts.")
 
82
 
 
83
(defvar select-xface-insert-hook nil
 
84
  "*hooks to be called after xface is inserted.")
 
85
 
 
86
(defvar select-xface-candidate-regexp "^[^.].*"
 
87
  "*only file/directory names containing that regexp are adopted.")
 
88
 
 
89
(defvar select-xface-gzip-program "gzip"
 
90
  "*gzip executable.")
 
91
 
 
92
(defvar select-xface-add-x-face-version-header nil
 
93
  "*insert X-Face-Version header.")
 
94
 
 
95
(defvar select-xface-header-separator-regexp "\\(^--.*$\\)\\|\\(\n\n\\)"
 
96
  "*header separator. (regexp)")
 
97
 
 
98
(defvar select-xface-display-func
 
99
  (function
 
100
   (lambda (beg end)
 
101
     (cond
 
102
      ((featurep 'xemacs)
 
103
       (require 'highlight-headers)
 
104
       (let ((highlight-headers-hack-x-face-p t)
 
105
             (x-face-xmas-like-highlight-headers nil))
 
106
         (highlight-headers beg end nil)))
 
107
      ((fboundp 'x-face-decode-message-header)
 
108
       (x-face-decode-message-header beg end))
 
109
      (t nil))))
 
110
  "xface display function.")
 
111
 
 
112
;;
 
113
;; No setting is needed for these variables.
 
114
;;
 
115
(defvar select-xface-candidate-list nil)
 
116
(defvar select-xface-face-list nil)
 
117
(defvar select-xface-current-list-pos 0)
 
118
(defvar select-xface-mode-map nil)
 
119
(defvar select-xface-parent-buffer nil)
 
120
(defvar select-xface-orig-window-config nil)
 
121
(defvar select-xface-popup-menu nil)
 
122
(defconst select-xface-buffer select-xface-appname)
 
123
 
 
124
(defmacro select-xface-header-end ()
 
125
  (` (save-excursion
 
126
       (goto-char (point-min))
 
127
       (if (re-search-forward select-xface-header-separator-regexp nil t)
 
128
           (point)))))
 
129
 
 
130
(if select-xface-mode-map
 
131
    nil
 
132
  (setq select-xface-mode-map (make-sparse-keymap))
 
133
  (define-key select-xface-mode-map "p"        'select-xface-prev-face)
 
134
  (define-key select-xface-mode-map "\C-p"     'select-xface-prev-face)
 
135
  (define-key select-xface-mode-map [up]       'select-xface-prev-face)
 
136
  (define-key select-xface-mode-map "n"        'select-xface-next-face)
 
137
  (define-key select-xface-mode-map "\C-n"     'select-xface-next-face)
 
138
  (define-key select-xface-mode-map [down]     'select-xface-next-face)
 
139
  (define-key select-xface-mode-map "\C-m"     'select-xface-out)
 
140
  (define-key select-xface-mode-map "o"        'select-xface-out)
 
141
  (define-key select-xface-mode-map "q"        'select-xface-exit)
 
142
  (define-key select-xface-mode-map "\C-g"     'select-xface-exit)
 
143
; (define-key select-xface-mode-map [?a up]    'select-xface-append-out-top)
 
144
  (define-key select-xface-mode-map [?a right] 'select-xface-append-out-last)
 
145
; (define-key select-xface-mode-map [?a down]  'select-xface-append-out-bottom)
 
146
  (define-key select-xface-mode-map [?a left]  'select-xface-append-out-first)
 
147
  (define-key select-xface-mode-map " "        'select-xface-append-out-last)
 
148
  (define-key select-xface-mode-map "r"        'select-xface-rebuild-face-list)
 
149
  )
 
150
 
 
151
(defun select-xface-make-popup-menu ()
 
152
  "define popup menu."
 
153
  (if (not select-xface-popup-menu)
 
154
      (easy-menu-define
 
155
       select-xface-popup-menu
 
156
       select-xface-mode-map "Menu for Select X-Face"
 
157
       '("Select X-Face"
 
158
         ["Prev"   select-xface-prev-face       t]
 
159
         ["Next"   select-xface-next-face       t]
 
160
         ["Output" select-xface-out             t]
 
161
         ["Append" select-xface-append-out-last t]
 
162
         "----"
 
163
         ["Quit"   select-xface-exit            t]
 
164
         )
 
165
       )
 
166
    )
 
167
  (easy-menu-add select-xface-popup-menu))
 
168
  
 
169
 
 
170
(defun select-xface-mode ()
 
171
;;a up    select-xface-append-out-top    append the current as the top face
 
172
;;a down  select-xface-append-out-bottom append the current as the bottom face
 
173
"Major mode for select and insert X-Face: field in the current draft buffer.
 
174
 
 
175
RET     select-xface-out               output the current face
 
176
o       select-xface-out               output the current face
 
177
C-n     select-xface-next-face         display the next candidate
 
178
n       select-xface-next-face         display the next candidate
 
179
C-p     select-xface-prev-face         display the previous candidate
 
180
p       select-xface-prev-face         display the previous candidate
 
181
a right select-xface-append-out-last   append the current as the last face
 
182
a left  select-xface-append-out-first  append the current as the first face
 
183
r       select-xface-rebuild-face-list rebuild face list
 
184
SPC     select-xface-append-out-last   append the current as the last face
 
185
C-g     select-xface-exit              quit selecting face
 
186
q       select-xface-exit              quit selecting face
 
187
"
 
188
  (interactive)
 
189
  (setq major-mode 'select-xface-mode)
 
190
  (setq mode-name select-xface-appname)
 
191
  (use-local-map select-xface-mode-map)
 
192
  (make-local-variable 'tab-width)
 
193
  (setq tab-width 8)
 
194
  (select-xface-make-popup-menu)
 
195
  (if (featurep 'xemacs)
 
196
      (set-specifier text-cursor-visible-p (cons (current-buffer) nil)))
 
197
  (run-hooks 'select-xface-mode-hook))
 
198
 
 
199
(defun select-xface-delete-all-xface-related-fields ()
 
200
  "delete all xface related fields in the current buffer."
 
201
  (save-excursion
 
202
    (goto-char (point-min))
 
203
    (while (re-search-forward
 
204
            "^\\(X-Face.*:\\) *\\(.*\\(\n[ \t].*\\)*\\)\n"
 
205
            (select-xface-header-end) t)
 
206
      (delete-region (match-beginning 0) (match-end 0))
 
207
      (goto-char (point-min)))))
 
208
 
 
209
 
 
210
(defun select-xface-collect-xface-related-fields ()
 
211
  "collect the xface related fields in the current buffer."
 
212
  (let ((end (select-xface-header-end))
 
213
        ret)
 
214
    (save-excursion
 
215
      (goto-char (point-min))
 
216
      (while (re-search-forward
 
217
              "\\(^\\(X-Face-Type:\\)[ \t]*\\(.*\\(\n[ \t].*\\)*\\)\n\\)\\|\\(^\\(X-Face[-0-9]*:\\)[ \t]*\\(.*\\(\n[ \t].*\\)*\\)\n\\)" end t)
 
218
        (setq ret (concat ret
 
219
                          (buffer-substring (match-beginning 0)
 
220
                                            (match-end 0)))))
 
221
      (if ret
 
222
          (let ((ret-len (length ret)))
 
223
            (if (string= (substring ret (- ret-len 1) ret-len) "\n")
 
224
                (setq ret (substring ret 0 (- ret-len 1)))))))
 
225
    ret))
 
226
 
 
227
(defun select-xface-append-out-last ()
 
228
  "append the current face as the last face."
 
229
  (interactive)
 
230
  (setq this-command 'select-xface-out)
 
231
  (select-xface-insert (select-xface-make-out-xface)
 
232
                       'last)
 
233
  )
 
234
 
 
235
(defun select-xface-append-out-first ()
 
236
  "append the current face as the frst face."
 
237
  (interactive)
 
238
  (setq this-command 'select-xface-out)
 
239
  (select-xface-insert (select-xface-make-out-xface)
 
240
                       'first))
 
241
 
 
242
(defun select-xface-append-out-top ()
 
243
  "append the current face as the top face."
 
244
  (interactive)
 
245
  (select-xface-insert (select-xface-make-out-xface)
 
246
                       'top))
 
247
 
 
248
(defun select-xface-append-out-bottom ()
 
249
  "append the current face as the bottom face."
 
250
  (interactive)
 
251
  (select-xface-insert (select-xface-make-out-xface)
 
252
                       'bottom))
 
253
 
 
254
(defun select-xface-make-append-xface (current-xface
 
255
                                       out-xface
 
256
                                       direction)
 
257
  "append the current face in the specified direction."
 
258
  (interactive)
 
259
  (let (insert-str)
 
260
    (cond
 
261
     ((eq direction 'top)
 
262
      (setq insert-str
 
263
            (concat "X-Face-Type: geometry=1x2\n"
 
264
                    out-xface
 
265
                    current-xface "\n")))
 
266
     ((eq direction 'first)
 
267
      (setq insert-str
 
268
            (concat ;; "X-Face-Type: geometry=2x1\n"
 
269
                    out-xface "\n"
 
270
                    current-xface)))
 
271
     ((eq direction 'bottom)
 
272
      (setq insert-str
 
273
            (concat "X-Face-Type: geometry=1x2\n"
 
274
                    (if current-xface (concat current-xface "\n"))
 
275
                    out-xface)))
 
276
     (t ;; last or other
 
277
      (setq insert-str
 
278
            (concat ;; "X-Face-Type: geometry=2x1\n"
 
279
                    (if current-xface (concat current-xface "\n"))
 
280
                    out-xface))))
 
281
    insert-str
 
282
   ))
 
283
 
 
284
(defun select-xface-make-out-xface ()
 
285
  "make output xface string from select-xface buffer."
 
286
  (nth select-xface-current-list-pos select-xface-face-list))
 
287
 
 
288
(defun select-xface-out ()
 
289
  "output the current face."
 
290
  (interactive)
 
291
  (select-xface-insert (select-xface-make-out-xface)))
 
292
 
 
293
(defun select-xface-insert (out-xface &optional append-direction)
 
294
  "insert the xface into the draft buffer."
 
295
  (save-window-excursion
 
296
    (delete-window)
 
297
    (let ((inhibit-read-only t)
 
298
          current-xface beg end
 
299
          )
 
300
      (save-excursion
 
301
        (set-buffer select-xface-parent-buffer)
 
302
        (if append-direction
 
303
            (setq current-xface
 
304
                  (select-xface-collect-xface-related-fields)))
 
305
        (select-xface-delete-all-xface-related-fields)
 
306
        (goto-char (point-min))
 
307
        (re-search-forward select-xface-field-insert-before end t)
 
308
        (beginning-of-line)
 
309
        (setq beg (point))
 
310
        (if append-direction
 
311
            (insert (select-xface-make-append-xface current-xface
 
312
                                                    out-xface
 
313
                                                    append-direction))
 
314
          (insert out-xface))
 
315
        (insert "\n")
 
316
        (put-text-property beg (point) 'invisible nil)
 
317
        (if (and (fboundp 'x-face-insert-version-header)
 
318
                 x-face-add-x-face-version-header)
 
319
            (progn
 
320
              (setq beg (point))
 
321
              (x-face-insert-version-header)
 
322
              (if (not (eq beg (point)))
 
323
                  (progn
 
324
                    (put-text-property beg (point) 'invisible nil)
 
325
                    (insert (concat "                with "
 
326
                                    select-xface-version "\n")))))
 
327
          (if select-xface-add-x-face-version-header
 
328
              (insert (concat "X-Face-Version: " select-xface-version "\n"))))
 
329
        (run-hooks 'select-xface-insert-hook)
 
330
        )
 
331
      )
 
332
    )
 
333
  (select-xface-exit))
 
334
 
 
335
(defun select-xface-prev-face ()
 
336
  "display previous candidate."
 
337
  (interactive)
 
338
  (if (= 0 select-xface-current-list-pos)
 
339
      (select-xface-set-list-pos (1- (length select-xface-face-list)))
 
340
    (select-xface-set-list-pos (1- select-xface-current-list-pos))))
 
341
 
 
342
(defun select-xface-next-face ()
 
343
  "display next candidate."
 
344
  (interactive)
 
345
  (if (= select-xface-current-list-pos (1- (length select-xface-face-list)))
 
346
      (select-xface-set-list-pos 0)
 
347
    (select-xface-set-list-pos (1+ select-xface-current-list-pos))))
 
348
 
 
349
(defun select-xface-set-invisible (string)
 
350
  "set string invisible."
 
351
  (save-excursion
 
352
    (goto-char (point-min))
 
353
    (while (re-search-forward (concat "\\(" string "\\)") nil t)
 
354
      (put-text-property
 
355
       (match-beginning 1) (match-end 1) 'invisible t))))
 
356
 
 
357
(defun select-xface-set-list-pos (pos)
 
358
  "display nth candidate in the popup buffer."
 
359
  (setq select-xface-current-list-pos pos)
 
360
;  (message (format "%d th entry." pos))
 
361
  (let ((buffer-read-only nil)
 
362
        (entry (nth pos select-xface-face-list))
 
363
        (xface-name (nth pos select-xface-candidate-list))
 
364
        )
 
365
    (setq xface-name (if xface-name xface-name "No name"))
 
366
    (erase-buffer)
 
367
    (if (not entry)
 
368
        ()
 
369
      (if (string-match "^X-Face-Type: .*\n" entry)
 
370
          (progn
 
371
            (insert "From: \n")
 
372
            (insert entry)
 
373
            (insert "\n")
 
374
            (funcall select-xface-display-func (point-min) (point-max))
 
375
            (goto-char (point-min))
 
376
            (while (re-search-forward "^X-Face-Type: .*\n" nil t)
 
377
              (delete-region (match-beginning 0) (match-end 0)))
 
378
            (re-search-backward "From:" nil t)
 
379
            (select-xface-set-invisible "X-Face:")
 
380
            (select-xface-set-invisible "From:")
 
381
            (select-xface-set-invisible "     ")
 
382
            )
 
383
        (insert "From: \n")
 
384
        (insert entry)
 
385
        (insert "\n")
 
386
        (funcall select-xface-display-func (point-min) (point-max))
 
387
        (goto-char (point-min))
 
388
        (select-xface-set-invisible "From:")
 
389
        (select-xface-set-invisible "     "))
 
390
      (goto-char (point-max))
 
391
      (if (featurep 'xemacs)
 
392
          (goto-char (point-min))
 
393
        (while (char-equal (char-before (point)) ?\n)
 
394
          (backward-char 1)))
 
395
      (set-buffer-modified-p nil)
 
396
      (rename-buffer (concat select-xface-appname "(" xface-name ")"))
 
397
      (setq select-xface-buffer (concat
 
398
                                 select-xface-appname "(" xface-name ")"))
 
399
      )))
 
400
 
 
401
(defun select-xface-check-rgb (list)
 
402
  "check if files in the path are rgb."
 
403
  (let ((tmplist list))
 
404
    (setq tmplist (delete "red" tmplist))
 
405
    (setq tmplist (delete "green" tmplist))
 
406
    (setq tmplist (delete "blue" tmplist))
 
407
    (not tmplist)))
 
408
 
 
409
(defun select-xface-make-candidate-list (path)
 
410
  "make file list in the path."
 
411
  (let (ret files attr)
 
412
    (setq ret
 
413
          (directory-files path nil select-xface-candidate-regexp nil))
 
414
    (setq ret (delete "." ret))
 
415
    (setq ret (delete ".." ret))
 
416
    (setq files ret)
 
417
    (while files
 
418
      (setq attr (car files))
 
419
      (if (car (file-attributes (expand-file-name attr path)))
 
420
          (setq ret (delete attr ret)))
 
421
      (setq files (cdr files)))
 
422
    ret)
 
423
  )
 
424
 
 
425
(defun select-xface-reduce-needless-character-in-buffer ()
 
426
  "reduce needless character for xface in the buffer."
 
427
  (if (= 0 (buffer-size))
 
428
      ()
 
429
    ;; reduce a space character in the beginning of the buffer.
 
430
    (while (char-equal (char-after (point-min)) ? )
 
431
      (progn
 
432
        (goto-char (point-min))
 
433
        (delete-char 1)))
 
434
    ;; reduce a newline character in the end of the buffer.
 
435
    (while (char-equal (char-before (point-max)) ?\n)
 
436
      (progn
 
437
        (goto-char (1- (point-max)))
 
438
        (delete-char 1)))))
 
439
  
 
440
(defun select-xface-reduce-needless-character-in-string (string)
 
441
  "reduce needless character for xface in the string."
 
442
  (let ((strlen (length string))
 
443
        (ret-string string))
 
444
    (if (= 0 strlen)
 
445
        ()
 
446
      ;; reduce a newline character in the end of the string.
 
447
      (while (and (not (= strlen 0))
 
448
                  (string= (substring ret-string (- strlen 1) strlen) "\n"))
 
449
        (setq ret-string (substring ret-string 0 (- strlen 1)))
 
450
        (setq strlen (- strlen 1)))
 
451
      ;; reduce a space character in the beginning of the string.
 
452
      (while (and (not (= strlen 0))
 
453
                  (string= (substring ret-string 0 1) " "))
 
454
        (setq ret-string (substring ret-string 1 strlen))
 
455
        (setq strlen (- strlen 1))))
 
456
    ret-string
 
457
    ))
 
458
 
 
459
(defun select-xface-make-xface-string (candidate-name directory)
 
460
  "make xface string from face file."
 
461
  (save-excursion
 
462
    (let ((tmp-buffer (get-buffer-create (concat
 
463
                                          "*Select-X-Face-"
 
464
                                          (expand-file-name candidate-name
 
465
                                                            directory)
 
466
                                          "-tmp*"
 
467
                                          )))
 
468
          (coding-system-for-read 'binary)
 
469
          (coding-system-for-write 'binary)
 
470
          format-alist jka-compr-compression-info-list
 
471
          child-clist ret-string)
 
472
      (set-buffer tmp-buffer)
 
473
      (if (not (file-directory-p
 
474
                (expand-file-name candidate-name
 
475
                                  directory)))
 
476
          (progn
 
477
            (if (string-match "\\.xbm\\(\\.gz\\)?$" candidate-name)
 
478
                ;;
 
479
                ;; use X-Face utility for xbm or gzipped xbm file.
 
480
                ;;
 
481
                (if (fboundp 'x-face-insert)
 
482
                    (let (x-face-add-x-face-version-header)
 
483
                      (condition-case ()
 
484
                          (x-face-insert
 
485
                           (expand-file-name candidate-name
 
486
                                             select-xface-directory))
 
487
                        (error
 
488
                         (setq select-xface-candidate-list
 
489
                               (delete candidate-name
 
490
                                       select-xface-candidate-list))
 
491
                         (message (format
 
492
                                   "%s has illegal contents(ignored)."
 
493
                                   candidate-name))))
 
494
                      (select-xface-reduce-needless-character-in-buffer)
 
495
                      )
 
496
                  (message "xbm file is not supported."))
 
497
              ;;
 
498
              ;; xface file.
 
499
              ;;
 
500
              (insert-file-contents
 
501
               (expand-file-name candidate-name directory))
 
502
              (if (looking-at "\x1f\x8b") ; gzipped?
 
503
                  (call-process-region
 
504
                   (point-min) (point-max)
 
505
                   select-xface-gzip-program t t nil "-cd"))
 
506
              (select-xface-reduce-needless-character-in-buffer)
 
507
              (goto-char (point-min))
 
508
              (if (not (re-search-forward "X-Face:" nil t))
 
509
                  (insert "X-Face: ")))
 
510
            (setq ret-string
 
511
                  (select-xface-reduce-needless-character-in-string
 
512
                   (concat
 
513
                    (buffer-substring (point-min)
 
514
                                      (point-max))))))
 
515
        ;;
 
516
        ;; recursive subdirectory processing.
 
517
        ;;
 
518
        (setq child-clist (select-xface-make-candidate-list
 
519
                           (expand-file-name candidate-name
 
520
                                             directory)))
 
521
        (if (select-xface-check-rgb child-clist)
 
522
            (progn
 
523
              (insert )
 
524
              (setq ret-string
 
525
                    (concat "X-Face-Type: RGB; geometry=1x1\n"
 
526
                            (select-xface-make-xface-string
 
527
                             "red"
 
528
                             (expand-file-name candidate-name directory))))
 
529
              (setq ret-string
 
530
                    (concat ret-string "\n"
 
531
                            (select-xface-make-xface-string
 
532
                             "green"
 
533
                             (expand-file-name candidate-name directory))))
 
534
              (setq ret-string
 
535
                    (concat ret-string "\n"
 
536
                            (select-xface-make-xface-string
 
537
                             "blue"
 
538
                             (expand-file-name candidate-name directory)))))
 
539
;;      (insert (format "X-Face-Type: geometry=%dx1\n"
 
540
;;                    (length child-flist)))
 
541
          ;; insert subdirectory candidates recursively.
 
542
          (let (cur-cname)
 
543
            (while child-clist
 
544
              (setq cur-cname (car child-clist))
 
545
              (setq ret-string
 
546
                    (concat ret-string
 
547
                            (select-xface-make-xface-string
 
548
                             cur-cname
 
549
                             (expand-file-name candidate-name directory))
 
550
                            "\n"
 
551
                            ))
 
552
              (setq child-clist (cdr child-clist)))
 
553
            )
 
554
          ))
 
555
      (setq ret-string (select-xface-reduce-needless-character-in-string
 
556
                        ret-string))
 
557
      (if (string= ret-string "") (setq ret-string nil))
 
558
      (kill-buffer tmp-buffer)
 
559
      ret-string
 
560
      )))
 
561
 
 
562
(defun select-xface-add-face-to-face-list (face &optional name)
 
563
  "add face to select-xface-face-list. returns pos."
 
564
  (let ((flist select-xface-face-list)
 
565
        (found nil)
 
566
        (pos 0)
 
567
        )
 
568
    (catch 'loop
 
569
      (while flist
 
570
        (if (string= face (car flist))
 
571
            (progn
 
572
              (setq found t)
 
573
              (throw 'loop nil))
 
574
          (setq flist (cdr flist))
 
575
          (setq pos (1+ pos))
 
576
          )))
 
577
    (if (and face (not found))
 
578
        (setq select-xface-face-list (append select-xface-face-list
 
579
                                             (list face)))
 
580
      (if name
 
581
          (progn
 
582
            (setq select-xface-candidate-list
 
583
                  (delete name
 
584
                          select-xface-candidate-list))
 
585
            (message "Same candidate already exists!"))))
 
586
    (if (not face) (setq pos 0))
 
587
    pos))
 
588
 
 
589
(defun select-xface-rebuild-face-list ()
 
590
  "rebuild face list from directory."
 
591
  (interactive)
 
592
  (setq select-xface-candidate-list nil)
 
593
  (setq select-xface-face-list nil)
 
594
  (select-xface-make-face-list)
 
595
  (if select-xface-face-list
 
596
      (select-xface-set-list-pos 0)
 
597
    (message "No X-Face candidates.")
 
598
    (select-xface-exit)
 
599
    )
 
600
  )
 
601
 
 
602
(defun select-xface-make-face-list ()
 
603
  "make face list from directory."
 
604
  ;; if select-xface-candidate-list is nil, all files or directories
 
605
  ;; that contain select-xface-candidate-regexp
 
606
  ;; in the select-xface-directory became the candidates.
 
607
  (if (not select-xface-candidate-list)
 
608
      (setq select-xface-candidate-list
 
609
            (select-xface-make-candidate-list select-xface-directory)))
 
610
  ;; make face list from candidate list.
 
611
  (if (not select-xface-face-list)
 
612
      (select-xface-make-face-list-from-candidate-list
 
613
       select-xface-candidate-list)))
 
614
  
 
615
(defun select-xface-make-face-list-from-candidate-list (candidate-list)
 
616
  "make list of faces."
 
617
  (save-excursion
 
618
    (let ((ret-list nil)
 
619
          (clist candidate-list))
 
620
      (while clist
 
621
        (select-xface-add-face-to-face-list
 
622
         (select-xface-make-xface-string
 
623
          (car clist) select-xface-directory)
 
624
         (car clist))
 
625
        (setq clist (cdr clist)))
 
626
      ret-list ;; return value
 
627
      )))
 
628
  
 
629
(defun select-xface-pop-to-buffer (buf)
 
630
  "split current window."
 
631
  (split-window-vertically)
 
632
  (other-window 1)
 
633
  (switch-to-buffer buf))
 
634
 
 
635
(defun select-xface ()
 
636
  "select xfaces graphically."
 
637
  (interactive)
 
638
  (if (not select-xface-display-func)
 
639
      (message "cannot display X-Face in your environment.")
 
640
    (setq select-xface-parent-buffer (buffer-name))
 
641
    (select-xface-make-face-list)
 
642
  ;; add current face to candidate list.
 
643
    (let (pos)
 
644
      (setq pos (select-xface-add-face-to-face-list
 
645
                 (select-xface-collect-xface-related-fields)))
 
646
      (if select-xface-face-list
 
647
          (progn
 
648
            (setq select-xface-orig-window-config
 
649
                  (current-window-configuration))
 
650
            (if (get-buffer select-xface-buffer)
 
651
                (select-xface-pop-to-buffer select-xface-buffer)
 
652
              (let* ()
 
653
                (select-xface-pop-to-buffer select-xface-buffer)
 
654
                (enlarge-window (- select-xface-height (window-height)))
 
655
                (select-xface-set-list-pos pos)
 
656
                (toggle-read-only)))
 
657
            (select-xface-mode))
 
658
        (message "No X-Face candidates."))
 
659
      ))
 
660
  )
 
661
 
 
662
(defun select-xface-exit ()
 
663
  "quit selecting xface."
 
664
  (interactive)
 
665
  (pop-to-buffer select-xface-parent-buffer)
 
666
  (set-window-configuration select-xface-orig-window-config)
 
667
  (kill-buffer select-xface-buffer)
 
668
)
 
669
 
 
670
(provide 'select-xface)
 
671
;;; select-xface.el ends here