1 ;;; riece-display.el --- buffer arrangement
2 ;; Copyright (C) 1998-2003 Daiki Ueno
4 ;; Author: Daiki Ueno <ueno@unixuser.org>
6 ;; Keywords: IRC, riece
8 ;; This file is part of Riece.
10 ;; This program is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 2, or (at your option)
15 ;; This program is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 ;; GNU General Public License for more details.
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GNU Emacs; see the file COPYING. If not, write to the
22 ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
23 ;; Boston, MA 02111-1307, USA.
27 (require 'riece-options)
28 (require 'riece-channel)
30 (require 'riece-layout)
31 (require 'riece-signal)
33 (defvar riece-channel-buffer-format "*Channel:%s*"
34 "Format of channel message buffer.")
35 (defvar riece-channel-buffer-alist nil
36 "An alist mapping identities to channel buffers.")
38 (defvar riece-update-buffer-functions nil
39 "Functions to redisplay the buffer.
40 Local to the buffer in `riece-buffer-list'.")
42 (defvar riece-update-indicator-functions
43 '(riece-update-status-indicators
44 riece-update-channel-indicator
45 riece-update-long-channel-indicator
46 riece-update-channel-list-indicator)
47 "Functions to update modeline indicators.")
49 (defun riece-display-connect-signals ()
52 (lambda (signal handback)
54 (set-buffer (car (riece-signal-args signal)))
55 (run-hooks 'riece-update-buffer-functions))))
57 'riece-switch-to-channel
58 (lambda (signal handback)
59 (riece-update-status-indicators)
60 (riece-update-channel-indicator)
61 (riece-update-long-channel-indicator)
62 (riece-update-channel-list-indicator)
63 (force-mode-line-update t)
64 (riece-emit-signal 'riece-update-buffer riece-user-list-buffer)
65 (riece-emit-signal 'riece-update-buffer riece-channel-list-buffer)
67 (riece-redraw-layout))))
69 'riece-naming-assert-channel-users
70 (lambda (signal handback)
71 (riece-emit-signal 'riece-update-buffer riece-user-list-buffer)))
73 'riece-naming-assert-join
74 (lambda (signal handback)
75 (riece-emit-signal 'riece-update-buffer riece-user-list-buffer))
77 (and riece-current-channel
78 (riece-identity-equal (nth 1 (riece-signal-args signal))
79 riece-current-channel)
80 (not (riece-identity-equal (car (riece-signal-args signal))
81 (riece-current-nickname))))))
83 'riece-naming-assert-join
84 (lambda (signal handback)
85 (riece-join-channel (nth 1 (riece-signal-args signal)))
86 (riece-switch-to-channel (nth 1 (riece-signal-args signal)))
87 (setq riece-join-channel-candidate nil))
89 (riece-identity-equal (car (riece-signal-args signal))
90 (riece-current-nickname))))
92 'riece-naming-assert-part
93 (lambda (signal handback)
94 (riece-emit-signal 'riece-update-buffer riece-user-list-buffer))
96 (and riece-current-channel
97 (riece-identity-equal (nth 1 (riece-signal-args signal))
98 riece-current-channel)
99 (not (riece-identity-equal (car (riece-signal-args signal))
100 (riece-current-nickname))))))
101 (riece-connect-signal
102 'riece-naming-assert-part
103 (lambda (signal handback)
104 (riece-part-channel (nth 1 (riece-signal-args signal))))
106 (riece-identity-equal (car (riece-signal-args signal))
107 (riece-current-nickname))))
108 (riece-connect-signal
109 'riece-naming-assert-rename
110 (lambda (signal handback)
111 (riece-emit-signal 'riece-update-buffer riece-user-list-buffer))
113 (and riece-current-channel
114 (equal (riece-identity-server (nth 1 (riece-signal-args signal)))
115 (riece-identity-server riece-current-channel))
116 (riece-with-server-buffer (riece-identity-server
117 riece-current-channel)
118 (riece-identity-assoc
119 (riece-identity-prefix (nth 1 (riece-signal-args signal)))
120 (riece-channel-get-users (riece-identity-prefix
121 riece-current-channel))
123 (riece-connect-signal
124 'riece-naming-assert-rename
125 (lambda (signal handback)
126 (riece-update-status-indicators)
127 (riece-update-channel-indicator)
128 (force-mode-line-update t))
130 (riece-identity-equal (nth 1 (riece-signal-args signal))
131 (riece-current-nickname))))
132 (riece-connect-signal
133 'riece-naming-assert-rename
134 (lambda (signal handback)
135 (riece-switch-to-channel (nth 1 (riece-signal-args signal))))
137 (and riece-current-channel
138 (riece-identity-equal (car (riece-signal-args signal))
139 riece-current-channel))))
140 (riece-connect-signal
141 'riece-naming-assert-rename
142 (lambda (signal handback)
143 (let* ((old-identity (car (riece-signal-args signal)))
144 (new-identity (nth 1 (riece-signal-args signal)))
145 (pointer (riece-identity-member old-identity
146 riece-current-channels)))
147 ;; Rename the channel buffer.
149 (setcar pointer new-identity)
150 (with-current-buffer (riece-channel-buffer old-identity)
151 (rename-buffer (riece-channel-buffer-name new-identity) t)
152 (setq riece-channel-buffer-alist
153 (cons (cons new-identity (current-buffer))
154 (delq (riece-identity-assoc old-identity
155 riece-channel-buffer-alist)
156 riece-channel-buffer-alist))))))))
157 (riece-connect-signal
158 'riece-user-toggle-away
159 (lambda (signal handback)
160 (riece-update-status-indicators)
161 (force-mode-line-update t))
163 (riece-identity-equal (car (riece-signal-args signal))
164 (riece-current-nickname))))
165 (riece-connect-signal
166 'riece-user-toggle-operator
167 (lambda (signal handback)
168 (riece-update-status-indicators)
169 (force-mode-line-update t))
171 (riece-identity-equal (car (riece-signal-args signal))
172 (riece-current-nickname))))
173 (riece-connect-signal
174 'riece-channel-set-topic
175 (lambda (signal handback)
176 (riece-update-long-channel-indicator)
177 (force-mode-line-update t))
179 (and riece-current-channel
180 (riece-identity-equal (car (riece-signal-args signal))
181 riece-current-channel))))
182 (riece-connect-signal
183 'riece-channel-set-modes
184 (lambda (signal handback)
185 (riece-update-status-indicators)
186 (force-mode-line-update t))
188 (and riece-current-channel
189 (riece-identity-equal (car (riece-signal-args signal))
190 riece-current-channel))))
191 (riece-connect-signal
192 'riece-channel-toggle-operator
193 (lambda (signal handback)
194 (riece-emit-signal 'riece-update-buffer riece-user-list-buffer))
196 (and riece-current-channel
197 (riece-identity-equal (car (riece-signal-args signal))
198 riece-current-channel))))
199 (riece-connect-signal
200 'riece-channel-toggle-speaker
201 (lambda (signal handback)
202 (riece-emit-signal 'riece-update-buffer riece-user-list-buffer))
204 (and riece-current-channel
205 (riece-identity-equal (car (riece-signal-args signal))
206 riece-current-channel))))
207 (riece-connect-signal
208 'riece-buffer-toggle-freeze
209 (lambda (signal handback)
210 (riece-update-status-indicators)
211 (force-mode-line-update t))))
213 (defun riece-update-user-list-buffer ()
215 (if (and riece-current-channel
216 (riece-channel-p (riece-identity-prefix riece-current-channel)))
218 (riece-with-server-buffer (riece-identity-server
219 riece-current-channel)
220 (riece-channel-get-users (riece-identity-prefix
221 riece-current-channel))))
222 (inhibit-read-only t)
225 (riece-kill-all-overlays)
227 (insert (if (memq ?o (cdr (car users)))
229 (if (memq ?v (cdr (car users)))
232 (riece-format-identity
233 (riece-make-identity (car (car users))
234 (riece-identity-server
235 riece-current-channel))
238 (setq users (cdr users)))))))
240 (defun riece-format-identity-for-channel-list-buffer (index identity)
241 (or (run-hook-with-args-until-success
242 'riece-format-identity-for-channel-list-buffer-functions index identity)
243 (concat (format "%2d:%c" index
244 (if (riece-identity-equal identity riece-current-channel)
247 (riece-format-identity identity))))
249 (defun riece-update-channel-list-buffer ()
251 (let ((inhibit-read-only t)
254 (channels riece-current-channels))
256 (riece-kill-all-overlays)
259 (insert (riece-format-identity-for-channel-list-buffer
260 index (car channels))
262 (setq index (1+ index)
263 channels (cdr channels))))))
265 (defun riece-update-channel-indicator ()
266 (setq riece-channel-indicator
267 (if riece-current-channel
268 (riece-format-identity riece-current-channel)
271 (defun riece-update-long-channel-indicator ()
272 (setq riece-long-channel-indicator
273 (if riece-current-channel
274 (if (riece-channel-p (riece-identity-prefix riece-current-channel))
275 (riece-concat-channel-modes
276 riece-current-channel
277 (riece-concat-channel-topic
278 riece-current-channel
279 (riece-format-identity riece-current-channel)))
280 (riece-format-identity riece-current-channel))
283 (defun riece-format-identity-for-channel-list-indicator (index identity)
284 (or (run-hook-with-args-until-success
285 'riece-format-identity-for-channel-list-indicator-functions
287 (let ((string (riece-format-identity identity))
290 (while (string-match "%" string start)
291 (setq start (1+ (match-end 0))
292 string (replace-match "%%" nil nil string)))
293 (format "%d:%s" index string))))
295 (defun riece-update-channel-list-indicator ()
296 (if (and riece-current-channels
297 ;; There is at least one channel.
298 (delq nil (copy-sequence riece-current-channels)))
301 (setq riece-channel-list-indicator
308 (riece-format-identity-for-channel-list-indicator
310 (setq index (1+ index))))
311 riece-current-channels))
312 pointer riece-channel-list-indicator)
315 (setcdr pointer (cons "," (cdr pointer))))
316 (setq pointer (cdr (cdr pointer)))))
317 (setq riece-channel-list-indicator "No channel")))
319 (defun riece-update-status-indicators ()
320 (if riece-current-channel
321 (with-current-buffer riece-command-buffer
322 (riece-with-server-buffer (riece-identity-server riece-current-channel)
323 (setq riece-away-indicator
324 (if (and riece-real-nickname
325 (riece-user-get-away riece-real-nickname))
328 riece-operator-indicator
329 (if (and riece-real-nickname
330 (riece-user-get-operator riece-real-nickname))
333 riece-user-indicator riece-real-nickname))))
334 (setq riece-freeze-indicator
335 (with-current-buffer (if (and riece-channel-buffer-mode
336 riece-channel-buffer)
338 riece-dialogue-buffer)
339 (if (eq riece-freeze 'own)
345 (defun riece-update-buffers (&optional buffers)
347 (setq buffers riece-buffer-list))
350 (set-buffer (car buffers))
351 (run-hooks 'riece-update-buffer-functions))
352 (setq buffers (cdr buffers)))
353 (run-hooks 'riece-update-indicator-functions)
354 (force-mode-line-update t)
355 (run-hooks 'riece-update-buffer-hook))
357 (defun riece-channel-buffer-name (identity)
358 (let ((channels (riece-identity-member identity riece-current-channels)))
360 (setq identity (car channels))
362 (message "%S is not a member of riece-current-channels" identity)))
363 (format riece-channel-buffer-format (riece-format-identity identity))))
366 (autoload 'riece-channel-mode "riece"))
367 (defun riece-channel-buffer-create (identity)
369 (riece-get-buffer-create (riece-channel-buffer-name identity)
371 (setq riece-channel-buffer-alist
372 (cons (cons identity (current-buffer))
373 riece-channel-buffer-alist))
374 (unless (eq major-mode 'riece-channel-mode)
376 (let (buffer-read-only)
377 (riece-insert-info (current-buffer)
378 (concat "Created on "
379 (funcall riece-format-time-function
382 (run-hook-with-args 'riece-channel-buffer-create-functions identity)))
385 (defun riece-channel-buffer (identity)
386 (cdr (riece-identity-assoc identity riece-channel-buffer-alist)))
388 (defun riece-switch-to-channel (identity)
389 (let ((last riece-current-channel))
390 (setq riece-current-channel identity
391 riece-channel-buffer (riece-channel-buffer riece-current-channel))
392 (run-hook-with-args 'riece-after-switch-to-channel-functions last)
393 (riece-emit-signal 'riece-switch-to-channel)))
395 (defun riece-join-channel (identity)
396 (unless (riece-identity-member identity riece-current-channels)
397 (setq riece-current-channels
398 (riece-identity-assign-binding
399 identity riece-current-channels
403 (riece-parse-identity channel)))
404 riece-default-channel-binding)))
405 (riece-channel-buffer-create identity)))
407 (defun riece-switch-to-nearest-channel (pointer)
408 (let ((start riece-current-channels)
410 (while (and start (not (eq start pointer)))
412 (setq identity (car start)))
413 (setq start (cdr start)))
416 (null (car pointer)))
417 (setq pointer (cdr pointer)))
418 (setq identity (car pointer)))
420 (riece-switch-to-channel identity)
421 (let ((last riece-current-channel))
422 (run-hook-with-args 'riece-after-switch-to-channel-functions last)
423 (setq riece-current-channel nil)
424 (riece-emit-signal 'riece-switch-to-channel)))))
426 (defun riece-part-channel (identity)
427 (let ((pointer (riece-identity-member identity riece-current-channels)))
429 (setcar pointer nil))
430 (if (riece-identity-equal identity riece-current-channel)
431 (riece-switch-to-nearest-channel pointer))))
433 (defun riece-redisplay-buffers (&optional force)
434 (riece-update-buffers)
435 (riece-redraw-layout force)
436 (run-hooks 'riece-redisplay-buffers-hook))
438 (provide 'riece-display)
440 ;;; riece-display.el ends here