1 ;;; riece.el --- IRC client for Emacsen
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-filter)
28 (require 'riece-display)
29 (require 'riece-server)
30 (require 'riece-compat)
31 (require 'riece-commands)
33 (defvar riece-channel-list-mode-map (make-sparse-keymap))
34 (defvar riece-user-list-mode-map (make-sparse-keymap))
36 (defvar riece-dialogue-mode-map
37 (let ((keymap (make-keymap)))
38 (suppress-keymap keymap 'nodigit)
41 (defvar riece-command-mode-map (make-keymap))
42 (defvar riece-command-map (make-sparse-keymap))
44 (defvar riece-command-mode-syntax-table nil)
46 (put 'riece-command-mode 'mode-class 'special)
47 (put 'riece-dialogue-mode 'mode-class 'special)
48 (put 'riece-others-mode 'derived-mode-parent 'riece-dialogue-mode)
49 (put 'riece-channel-list-mode 'mode-class 'special)
50 (put 'riece-user-list-mode 'mode-class 'special)
51 (put 'riece-channel-mode 'derived-mode-parent 'riece-dialogue-mode)
53 (defvar riece-buffer-alist
54 '((riece-command-buffer "*Commands*" riece-command-mode)
55 (riece-dialogue-buffer "*Dialogue*" riece-dialogue-mode)
56 (riece-others-buffer "*Others*" riece-others-mode)
57 (riece-channel-list-buffer "*Channels*" riece-channel-list-mode)
58 (riece-user-list-buffer " *Users*" riece-user-list-mode)))
60 (defvar riece-select-keys
61 `("1" riece-command-switch-to-channel-by-number-1
62 "2" riece-command-switch-to-channel-by-number-2
63 "3" riece-command-switch-to-channel-by-number-3
64 "4" riece-command-switch-to-channel-by-number-4
65 "5" riece-command-switch-to-channel-by-number-5
66 "6" riece-command-switch-to-channel-by-number-6
67 "7" riece-command-switch-to-channel-by-number-7
68 "8" riece-command-switch-to-channel-by-number-8
69 "9" riece-command-switch-to-channel-by-number-9
70 "0" riece-command-switch-to-channel-by-number-10
71 ,(concat riece-command-prefix "1")
72 riece-command-switch-to-channel-by-number-11
73 ,(concat riece-command-prefix "2")
74 riece-command-switch-to-channel-by-number-12
75 ,(concat riece-command-prefix "3")
76 riece-command-switch-to-channel-by-number-13
77 ,(concat riece-command-prefix "4")
78 riece-command-switch-to-channel-by-number-14
79 ,(concat riece-command-prefix "5")
80 riece-command-switch-to-channel-by-number-15
81 ,(concat riece-command-prefix "6")
82 riece-command-switch-to-channel-by-number-16
83 ,(concat riece-command-prefix "7")
84 riece-command-switch-to-channel-by-number-17
85 ,(concat riece-command-prefix "8")
86 riece-command-switch-to-channel-by-number-18
87 ,(concat riece-command-prefix "9")
88 riece-command-switch-to-channel-by-number-19
89 ,(concat riece-command-prefix "0")
90 riece-command-switch-to-channel-by-number-20))
92 ;;; Keymap macros. -- borrowed from `gnus-util.el'.
93 (defmacro riece-local-set-keys (&rest plist)
94 "Set the keys in PLIST in the current keymap."
95 `(riece-define-keys-1 (current-local-map) ',plist))
97 (defmacro riece-define-keys (keymap &rest plist)
98 "Assign KEYMAP keys from PLIST."
99 `(riece-define-keys-1 ',keymap ',plist))
101 (defmacro riece-define-keys-safe (keymap &rest plist)
102 "Assign KEYMAP keys from PLIST without overwriting previous definitions."
103 `(riece-define-keys-1 ',keymap ',plist t))
105 (put 'riece-define-keys 'lisp-indent-function 1)
106 (put 'riece-define-keys-safe 'lisp-indent-function 1)
107 (put 'riece-local-set-keys 'lisp-indent-function 1)
109 (defun riece-define-keys-1 (keymap plist &optional safe)
110 "Assign KEYMAP keys from PLIST.
111 If optional argument SAFE is nil, overwrite previous definitions."
113 (error "Can't set keys in a null keymap"))
116 (setq keymap (symbol-value keymap)))
119 (set (car keymap) nil)
120 (define-prefix-command (car keymap))
121 (define-key (symbol-value (nth 2 keymap))
122 (if (symbolp (nth 1 keymap))
123 (symbol-value (nth 1 keymap))
126 (setq keymap (symbol-value (car keymap)))))
129 (if (symbolp (setq key (car plist)))
130 (setq key (symbol-value key)))
131 (setq plist (cdr plist))
133 (eq (lookup-key keymap key) 'undefined))
134 (define-key keymap key (car plist))
136 (setq plist (cdr plist)))))
139 (riece-define-keys riece-dialogue-mode-map
142 [backspace] scroll-down
146 "/" riece-command-raw
148 "<" beginning-of-buffer
149 "\C-ta" riece-command-toggle-away
150 "c" riece-command-select-command-buffer
151 "f" riece-command-finger
152 "\C-tf" riece-command-toggle-freeze
153 "\C-to" riece-command-toggle-own-freeze
154 "\C-tu" riece-command-toggle-user-list-buffer-mode
155 "\C-tc" riece-command-toggle-channel-buffer-mode
156 "\C-tC" riece-command-toggle-channel-list-buffer-mode
157 "\C-tl" riece-command-change-layout
158 "i" riece-command-invite
159 "j" riece-command-join
160 "\C-k" riece-command-kick
161 "l" riece-command-list
162 "M" riece-command-change-mode
163 "n" riece-command-change-nickname
164 "N" riece-command-names
166 "O" riece-command-open-server
167 "C" riece-command-close-server
168 "M" riece-command-universal-server-name-argument
169 "q" riece-command-quit
170 "r" riece-command-configure-windows
171 "x" riece-command-copy-region
172 "t" riece-command-topic
173 "w" riece-command-who)
175 (riece-define-keys riece-command-mode-map
176 "\r" riece-command-enter-message
177 [(control return)] riece-command-enter-message-as-notice)
179 (riece-define-keys (riece-command-map riece-command-prefix
180 riece-command-mode-map)
181 "\177" riece-command-scroll-down
182 [delete] riece-command-scroll-down
183 [backspace] riece-command-scroll-down
184 " " riece-command-scroll-up
185 "$" riece-command-end-of-buffer
186 ">" riece-command-next-channel
187 "<" riece-command-previous-channel
188 "\C-j" riece-command-next-channel
189 "\C-n" riece-command-names
190 "l" riece-command-list
191 "\C-m" riece-command-change-mode
192 "o" riece-command-set-operators
193 "\C-p" riece-command-part
194 "r" riece-command-configure-windows
195 "v" riece-command-set-speakers
197 (set-keymap-parent riece-command-map riece-dialogue-mode-map)
199 (riece-define-keys riece-user-list-mode-map
200 "o" riece-command-set-operators
201 "v" riece-command-set-voices
202 "f" riece-command-finger
203 " " riece-command-nick-scroll-up
204 "\177" riece-command-nick-scroll-down
205 [delete] riece-command-nick-scroll-down
206 [backspace] riece-command-nick-scroll-down
207 "c" riece-command-select-command-buffer)
209 (riece-define-keys riece-channel-list-mode-map
210 ">" riece-command-next-channel
211 "<" riece-command-previous-channel
213 "c" riece-command-select-command-buffer)
215 (riece-define-keys-1 riece-dialogue-mode-map riece-select-keys)
216 (riece-define-keys-1 riece-channel-list-mode-map riece-select-keys))
218 (defun riece-read-variables-files (&optional file)
219 "Read variables FILEs."
220 (or (file-directory-p riece-directory)
221 (make-directory riece-directory))
222 (let ((files (if file
223 (setq riece-variables-file file
224 riece-variables-files (list file))
225 riece-variables-files)))
228 (load (expand-file-name (car files)))
230 (setq files (cdr files)))))
232 (defvar print-quoted)
233 (defvar print-escape-multibyte)
234 (defun riece-save-variables-files ()
235 "Save current settings to `riece-variables-file'."
236 (with-temp-file riece-saved-variables-file
237 (let ((print-quoted t)
239 print-escape-multibyte
242 (variables riece-saved-forms))
244 (prin1 `(setq ,(car variables)
245 ',(symbol-value (car variables)))
248 (setq variables (cdr variables)))))
249 (setq riece-save-variables-are-dirty nil))
252 (defun riece (&optional confirm)
253 "Connect to the IRC server and start chatting.
254 If optional argument CONFIRM is non-nil, ask which IRC server to connect."
256 (riece-read-variables-files (if noninteractive
257 (car command-line-args-left)))
258 (riece-insinuate-addons riece-addons)
259 (run-hooks 'riece-after-load-startup-hook)
260 (if (riece-server-opened)
261 (error "Already running"))
262 (if (or confirm (null riece-server))
263 (setq riece-server (completing-read "Server: " riece-server-alist)))
264 (if (stringp riece-server)
265 (setq riece-server (riece-server-name-to-server riece-server)))
266 (riece-create-buffers)
267 (switch-to-buffer riece-command-buffer)
268 (riece-redisplay-buffers)
269 (riece-open-server riece-server "")
270 (run-hooks 'riece-startup-hook)
271 (message "%s" (substitute-command-keys "Type \\[describe-mode] for help")))
274 (if riece-save-variables-are-dirty
275 (riece-save-variables-files))
276 (while riece-buffer-list
277 (if (and (get-buffer (car riece-buffer-list))
278 (buffer-live-p (car riece-buffer-list)))
279 (funcall riece-buffer-dispose-function (car riece-buffer-list)))
280 (setq riece-buffer-list (cdr riece-buffer-list)))
281 (setq riece-server nil
282 riece-current-channels nil