Fix the last change.
[riece] / lisp / riece-300.el
1 ;;; riece-300.el --- handlers for 300 replies
2 ;; Copyright (C) 1998-2003 Daiki Ueno
3
4 ;; Author: Daiki Ueno <ueno@unixuser.org>
5 ;; Created: 1998-09-28
6 ;; Keywords: IRC, riece
7
8 ;; This file is part of Riece.
9
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)
13 ;; any later version.
14
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.
19
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.
24
25 ;;; Code:
26
27 (require 'riece-misc)
28
29 (require 'riece-filter)                 ;riece-default-handle-message
30
31 (eval-when-compile
32   (autoload 'riece-default-handle-numeric-reply "riece-filter"))
33 (defun riece-handle-default-300-message (prefix number name string)
34   (riece-default-handle-numeric-reply
35    riece-info-prefix prefix number name string))
36
37 (defun riece-handle-302-message (prefix number name string)
38   "RPL_USERHOST \":*1<reply> *( \" \" <reply> )\""
39   (let ((replies (split-string (substring string 1) " ")))
40     (while replies
41       (if (string-match
42            (concat "^\\(" riece-user-regexp
43                    "\\)\\(\\*\\)?=\\([-+]\\)\\([^ ]+\\)")
44            (car replies))
45           (let ((user (match-string 1 (car replies)))
46                 (operator (not (null (match-beginning 2))))
47                 (away (eq (match-string 3 (car replies)) ?-))
48                 (user-at-host (match-string 4 (car replies)))
49                 status)
50             (if away
51                 (setq status (cons "away" status)))
52             (if operator
53                 (setq status (cons "operator" status)))
54             (riece-user-toggle-away user away)
55             (riece-user-toggle-operator user operator)
56             (riece-insert-info
57              (list riece-dialogue-buffer riece-others-buffer)
58              (concat
59               (riece-concat-server-name
60                (riece-concat-user-status
61                 status
62                 (format "%s is (%s)"
63                         (riece-format-identity
64                          (riece-make-identity user riece-server-name)
65                          t)
66                         (riece-strip-user-at-host user-at-host))))
67               "\n"))))
68       (setq replies (cdr replies)))
69   (riece-update-status-indicators)
70   (force-mode-line-update t)))
71
72 (defun riece-handle-303-message (prefix number name string)
73   (riece-insert-info
74    (list riece-dialogue-buffer riece-others-buffer)
75    (concat
76     (riece-concat-server-name
77      (concat "Online: "
78              (mapconcat
79               (lambda (user)
80                 (riece-format-identity
81                  (riece-make-identity user riece-server-name)
82                  t))
83               (split-string (substring string 1) " ")
84               "")))
85     "\n")))
86
87 (defun riece-handle-301-message (prefix number name string)
88   (if (string-match (concat "^\\(" riece-user-regexp "\\) :") string)
89       (let ((user (match-string 1 string))
90             (message (substring string (match-end 0))))
91         (riece-user-toggle-away user t)
92         (riece-insert-info
93          (list riece-dialogue-buffer riece-others-buffer)
94          (concat
95           (riece-concat-server-name
96            (format "%s is away: %s"
97                    (riece-format-identity
98                     (riece-make-identity user riece-server-name)
99                     t)
100                    message))
101           "\n"))))
102   (riece-update-status-indicators)
103   (force-mode-line-update t))
104
105 (defun riece-handle-305-message (prefix number name string)
106   (riece-user-toggle-away riece-real-nickname nil)
107   (riece-update-status-indicators)
108   (force-mode-line-update t))
109
110 (defun riece-handle-306-message (prefix number name string)
111   (riece-user-toggle-away riece-real-nickname t)
112   (riece-update-status-indicators)
113   (force-mode-line-update t))
114
115 (defun riece-handle-311-message (prefix number name string)
116   (if (string-match
117        (concat "^\\(" riece-user-regexp
118                "\\) \\([^ ]+\\) \\([^ ]+\\) \\* :")
119        string)
120       (let ((user (match-string 1 string))
121             (name (substring string (match-end 0)))
122             (user-at-host (concat (match-string 2 string) "@"
123                                   (match-string 3 string))))
124         (riece-insert-info
125          (list riece-dialogue-buffer riece-others-buffer)
126          (concat
127           (riece-concat-server-name
128            (format "%s is %s (%s)"
129                    (riece-format-identity
130                     (riece-make-identity user riece-server-name)
131                     t)
132                    name
133                    user-at-host))
134           "\n")))))
135
136 (defun riece-handle-312-message (prefix number name string)
137   (if (string-match
138        (concat "^\\(" riece-user-regexp "\\) \\([^ ]+\\) :")
139        string)
140       (riece-insert-info
141        (list riece-dialogue-buffer riece-others-buffer)
142        (concat
143         (riece-concat-server-name
144          (format "on via server %s: %s"
145                  riece-real-server-name
146                  (substring string (match-end 0))))
147         "\n"))))
148
149 (defun riece-handle-313-message (prefix number name string)
150   (if (string-match (concat "^" riece-user-regexp) string)
151       (let ((user (match-string 0 string)))
152         (riece-insert-info
153          (list riece-dialogue-buffer riece-others-buffer)
154          (concat
155           (riece-concat-server-name
156            (concat (riece-format-identity
157                     (riece-make-identity user riece-server-name)
158                     t)
159                    " is an IRC operator"))
160           "\n")))))
161
162 (defun riece-handle-317-message (prefix number name string)
163   (if (string-match
164        (concat "^\\(" riece-user-regexp "\\) \\([0-9]+\\) [^:]*:seconds")
165        string)
166       (let ((user (match-string 1 string))
167             (idle (match-string 2 string)))
168         (riece-insert-info
169          (list riece-dialogue-buffer riece-others-buffer)
170          (concat
171           (riece-concat-server-name
172            (format "%s is %s seconds idle"
173                    (riece-format-identity
174                     (riece-make-identity user riece-server-name)
175                     t)
176                    idle))
177           "\n")))))
178
179 (defun riece-handle-319-message (prefix number name string)
180   (if (string-match (concat "^\\(" riece-user-regexp "\\) :") string)
181       (let ((user (match-string 1 string))
182             (channels
183              (mapconcat
184               (lambda (channel)
185                 (if (string-match
186                      (concat "^\\([@+]?\\)\\(" riece-channel-regexp "\\)")
187                      channel)
188                     (concat
189                      (match-string 1 channel)
190                      (riece-format-identity
191                       (riece-make-identity (match-string 2 channel)
192                                            riece-server-name)
193                       t))))
194               (split-string (substring string (match-end 0)) " ")
195               " ")))
196         (riece-insert-info
197          (list riece-dialogue-buffer riece-others-buffer)
198          (concat
199           (riece-concat-server-name
200            (format "%s: %s"
201                    (riece-format-identity
202                     (riece-make-identity user riece-server-name)
203                     t)
204                    channels))
205           "\n")))))
206
207 (defun riece-handle-351-message (prefix number name string)
208   (if (string-match "\\([^ ]+\\.[^ ]+\\) \\([^ ]+\\) :" string)
209       (riece-insert-info
210        (list riece-dialogue-buffer riece-others-buffer)
211        (concat
212         (riece-concat-server-name
213          (format "%s is running on %s: %s"
214                  (match-string 1 string)
215                  (match-string 2 string)
216                  (substring string (match-end 0))))
217         "\n"))))
218
219 (defun riece-handle-353-message (prefix number name string)
220   "RPL_NAMREPLY \"<channel> :[[@|+]<nick> [[@|+]<nick> [...]]]\"."
221   (if (string-match "^[=\*@] *\\([^ ]+\\) +:" string)
222       (let ((channel (match-string 1 string))
223             (start 0))
224         (setq string (substring string (match-end 0)))
225         (while (string-match
226                 (concat "\\([@+]\\)?\\(" riece-user-regexp "\\) *")
227                 string start)
228           (put-text-property (match-beginning 2) (match-end 2)
229                              'riece-identity
230                              (riece-make-identity (match-string 2 string)
231                                                   riece-server-name)
232                              string)
233           (setq start (match-end 0))
234           (if (match-beginning 1)
235               (if (eq (aref string (match-beginning 1)) ?@)
236                   (progn
237                     (riece-naming-assert-join
238                      (match-string 2 string) channel)
239                     (riece-channel-toggle-operator
240                      channel (match-string 2 string) t))
241                 (if (eq (aref string (match-beginning 1)) ?+)
242                     (progn
243                       (riece-naming-assert-join
244                        (match-string 2 string) channel)
245                       (riece-channel-toggle-speaker
246                        channel (match-string 2 string) t))))
247             (riece-naming-assert-join (match-string 2 string) channel)))
248         (let* ((channel-identity (riece-make-identity channel
249                                                       riece-server-name))
250                (buffer (riece-channel-buffer channel-identity)))
251           (riece-insert-info buffer (concat "Users: " string "\n"))
252           (riece-insert-info
253            (if (and riece-channel-buffer-mode
254                     (not (eq buffer riece-channel-buffer)))
255                (list riece-dialogue-buffer riece-others-buffer)
256              riece-dialogue-buffer)
257            (concat
258             (riece-concat-server-name
259              (format "Users on %s: %s"
260                      (riece-format-identity channel-identity t) string))
261             "\n")))
262         (riece-redisplay-buffers))))
263
264 (defun riece-handle-322-message (prefix number name string)
265   (if (string-match "^\\([^ ]+\\) \\([0-9]+\\) :" string)
266       (let* ((channel (match-string 1 string))
267              (visible (match-string 2 string))
268              (topic (substring string (match-end 0))))
269         (riece-channel-set-topic (riece-get-channel channel) topic)
270         (let* ((channel-identity (riece-make-identity channel
271                                                       riece-server-name))
272                (buffer (riece-channel-buffer channel-identity)))
273           (riece-insert-info buffer (concat visible " users, topic: "
274                                             topic "\n"))
275           (riece-insert-info
276            (if (and riece-channel-buffer-mode
277                     (not (eq buffer riece-channel-buffer)))
278                (list riece-dialogue-buffer riece-others-buffer)
279              riece-dialogue-buffer)
280            (concat
281             (riece-concat-server-name
282              (format "%s: %s users, topic: %s"
283                      (riece-format-identity channel-identity t) visible topic))
284             "\n"))))))
285
286 (defun riece-handle-324-message (prefix number name string)
287   (if (string-match "^\\([^ ]+\\) \\([^ ]+\\) " string)
288       (let* ((channel (match-string 1 string))
289              (mode-string (substring string (match-beginning 2)))
290              (modes (string-to-list (match-string 2 string)))
291              (toggle (car modes)))
292         (setq modes (cdr modes))
293         (while modes
294           (riece-channel-toggle-mode channel (car modes) (eq toggle ?+))
295           (setq modes (cdr modes)))
296         (let* ((channel-identity (riece-make-identity channel
297                                                       riece-server-name))
298                (buffer (riece-channel-buffer channel-identity)))
299           (riece-insert-info buffer (concat "Mode: " mode-string "\n"))
300           (riece-insert-info
301            (if (and riece-channel-buffer-mode
302                     (not (eq buffer riece-channel-buffer)))
303                (list riece-dialogue-buffer riece-others-buffer)
304              riece-dialogue-buffer)
305            (concat
306             (riece-concat-server-name
307              (format "Mode for %s: %s"
308                      (riece-format-identity channel-identity t)
309                      mode-string))
310             "\n")))
311         (riece-update-channel-indicator)
312         (force-mode-line-update t))))
313
314 (defun riece-handle-set-topic (prefix number name string remove)
315   (if (string-match "^\\([^ ]+\\) :" string)
316       (let* ((channel (match-string 1 string))
317              (message (substring string (match-end 0)))
318              (channel-identity (riece-make-identity channel riece-server-name))
319              (buffer (riece-channel-buffer channel-identity)))
320         (if remove
321             (riece-channel-set-topic (riece-get-channel channel) nil)
322           (riece-channel-set-topic (riece-get-channel channel) message)
323         (riece-insert-info buffer (concat "Topic: " message "\n"))
324         (riece-insert-info
325          (if (and riece-channel-buffer-mode
326                   (not (eq buffer riece-channel-buffer)))
327              (list riece-dialogue-buffer riece-others-buffer)
328            riece-dialogue-buffer)
329          (concat
330           (riece-concat-server-name
331            (format "Topic for %s: %s"
332                    (riece-format-identity channel-identity t)
333                    message))
334           "\n"))
335         (riece-update-channel-indicator)))))
336
337 (defun riece-handle-331-message (prefix number name string)
338   (riece-handle-set-topic prefix number name string t))
339
340 (defun riece-handle-332-message (prefix number name string)
341   (riece-handle-set-topic prefix number name string nil))
342
343 (defun riece-handle-341-message (prefix number name string)
344   (if (string-match "^\\([^ ]+\\) " string)
345       (let* ((channel (match-string 1 string))
346              (user (substring string (match-end 0)))
347              (channel-identity (riece-make-identity channel riece-server-name))
348              (buffer (riece-channel-buffer channel-identity)))
349         (riece-insert-info buffer (concat "Inviting " user "\n"))
350         (riece-insert-info
351          (if (and riece-channel-buffer-mode
352                   (not (eq buffer riece-channel-buffer)))
353              (list riece-dialogue-buffer riece-others-buffer)
354            riece-dialogue-buffer)
355          (concat
356           (riece-concat-server-name
357            (format "Inviting %s to %s" user
358                    (riece-format-identity channel-identity t)))
359           "\n")))))
360
361 (defun riece-handle-352-message (prefix number name string)
362   (if (string-match "^\\([^ ]+\\) \\([^ ]+\\) \\([^ ]+\\) \\([^ ]+\\) \\([^ ]+\\) \\([HG]\\)\\(\\*\\)?\\([@+]\\)? :\\([0-9]+\\) " string)
363       (let* ((channel (match-string 1 string))
364              (user (match-string 2 string))
365              (host (match-string 3 string))
366              (server (match-string 4 string))
367              (nick (match-string 5 string))
368              (away (equal (match-string 6 string) "G"))
369              (operator (not (null (match-beginning 7))))
370              (flag (match-string 8 string))
371              (hops (match-string 9 string))
372              (name (substring string (match-end 0)))
373              (buffer (riece-channel-buffer (riece-make-identity
374                                             channel riece-server-name)))
375              (info (format "%10s = %s (%s)"
376                            (concat
377                             (if (memq flag '(?@ ?+))
378                                 (char-to-string flag)
379                               " ")
380                             (riece-format-identity
381                              (riece-make-identity nick riece-server-name)
382                              t))
383                            name
384                            (riece-strip-user-at-host
385                             (concat user "@" host))))
386              status)
387         (if operator
388             (setq status (cons "operator" status)))
389         (if away
390             (setq status (cons "away" status)))
391         (unless (equal hops "0")
392           (setq status (cons (concat "on " server)
393                              (cons (concat hops " hops")
394                                    status))))
395         (if status
396             (setq status (nreverse status)))
397         (riece-naming-assert-join nick channel)
398         (riece-user-toggle-away user away)
399         (riece-user-toggle-operator user operator)
400         (riece-insert-info buffer (concat (riece-concat-user-status
401                                            status info)
402                                           "\n"))
403         (riece-insert-info
404          (if (and riece-channel-buffer-mode
405                   (not (eq buffer riece-channel-buffer)))
406              (list riece-dialogue-buffer riece-others-buffer)
407            riece-dialogue-buffer)
408          (concat
409           (riece-concat-server-name
410            (riece-concat-user-status
411             status
412             (concat
413              (riece-format-identity
414               (riece-make-identity channel riece-server-name)
415               t)
416              " "
417              info)))
418           "\n"))
419         (riece-redisplay-buffers))))
420
421 (defun riece-handle-315-message (prefix number name string))
422 (defun riece-handle-318-message (prefix number name string))
423 (defun riece-handle-323-message (prefix number name string))
424 (defun riece-handle-366-message (prefix number name string))
425
426 (provide 'riece-300)
427
428 ;;; riece-300.el ends here