Fix interactive spec.
[riece] / lisp / riece-commands.el
index ea07bd9..f48effa 100644 (file)
 
 ;;; Code:
 
 
 ;;; Code:
 
-(eval-when-compile (require 'riece-inlines))
-
 (require 'riece-channel)
 (require 'riece-complete)
 (require 'riece-channel)
 (require 'riece-complete)
+(require 'riece-layout)
 (require 'riece-display)
 (require 'riece-version)
 (require 'riece-server)
 (require 'riece-display)
 (require 'riece-version)
 (require 'riece-server)
 
 ;;; Channel movement:
 (defun riece-command-switch-to-channel (channel)
 
 ;;; Channel movement:
 (defun riece-command-switch-to-channel (channel)
-  (interactive
-   (list (completing-read "Channel/user: "
-                         (mapcar #'list riece-current-channels)
-                         nil t)))
-  (riece-switch-to-channel channel)
-  (riece-command-configure-windows))
+  (interactive (list (riece-completing-read-identity
+                     "Channel/User: " riece-current-channels nil t)))
+  (unless (equal channel riece-current-channels)
+    (riece-switch-to-channel channel)
+    (riece-redisplay-buffers)))
 
 (defun riece-command-switch-to-channel-by-number (number)
   (interactive
 
 (defun riece-command-switch-to-channel-by-number (number)
   (interactive
      (if (string-match "[0-9]+$" command-name)
         (list (string-to-number (match-string 0 command-name)))
        (list (string-to-number (read-string "Number: "))))))
      (if (string-match "[0-9]+$" command-name)
         (list (string-to-number (match-string 0 command-name)))
        (list (string-to-number (read-string "Number: "))))))
-  (let ((channels riece-current-channels)
-       (index 1))
-    (while (and channels
-               (< index number))
-      (if (car channels)
-         (setq index (1+ index)))
-      (setq channels (cdr channels)))
-    (if (car channels)
-       (riece-command-switch-to-channel (car channels))
+  (let ((channel (nth (1- number) riece-current-channels)))
+    (if channel
+       (riece-command-switch-to-channel channel)
       (error "No such number!"))))
       (error "No such number!"))))
-       
+
 (eval-and-compile
   (let ((number 1))
     (while (<= number 20)
 (eval-and-compile
   (let ((number 1))
     (while (<= number 20)
 (defun riece-command-next-channel ()
   "Select the next channel."
   (interactive)
 (defun riece-command-next-channel ()
   "Select the next channel."
   (interactive)
-  (let ((pointer (cdr (string-list-member-ignore-case
-                      riece-current-channel
-                      riece-current-channels))))
-    (while (and pointer
-               (null (car pointer)))
-      (setq pointer (cdr pointer)))
-    (if (car pointer)
-       (riece-command-switch-to-channel (car pointer))
-      (error "No such channel!"))))
+  (when (> (length riece-current-channels) 1)
+    (let ((pointer (cdr (riece-identity-member
+                        riece-current-channel
+                        riece-current-channels))))
+      (while (and pointer
+                 (null (car pointer)))
+       (setq pointer (cdr pointer)))
+      (when (null pointer)
+       (setq pointer riece-current-channels)
+       (while (and pointer
+                   (null (car pointer)))
+         (setq pointer (cdr pointer))))
+      (if (car pointer)
+         (riece-command-switch-to-channel (car pointer))
+       (error "No such channel!")))))
 
 (defun riece-command-previous-channel ()
   "Select the previous channel."
   (interactive)
 
 (defun riece-command-previous-channel ()
   "Select the previous channel."
   (interactive)
-  (let ((pointer (string-list-member-ignore-case
-                 riece-current-channel
-                 riece-current-channels))
-       (start riece-current-channels)
-       channel)
-    (while (and start (not (eq start pointer)))
-      (if (car start)
-         (setq channel (car start)))
-      (setq start (cdr start)))
-    (if channel
-       (riece-command-switch-to-channel channel)
-      (error "No such channel!"))))
+  (when (> (length riece-current-channels) 1)
+    (let ((pointer (riece-identity-member
+                   riece-current-channel
+                   riece-current-channels))
+         (start riece-current-channels)
+         channel)
+      (while (and start (not (eq start pointer)))
+       (if (car start)
+           (setq channel (car start)))
+       (setq start (cdr start)))
+      (when (null channel)
+       (setq start (copy-sequence riece-current-channels))
+       (setq start (delq nil start))
+       (and (> (length start) 1)
+            (setq channel (nth (1- (length start)) start))))
+      (if channel
+         (riece-command-switch-to-channel channel)
+       (error "No such channel!")))))
 
 (defun riece-command-select-command-buffer ()
   "Select the command buffer."
 
 (defun riece-command-select-command-buffer ()
   "Select the command buffer."
   (interactive)
   (riece-redisplay-buffers t))
 
   (interactive)
   (riece-redisplay-buffers t))
 
+(defun riece-command-change-layout (name)
+  "Select a layout-name from all current available layouts and change
+the layout to the selected layout-name."
+  (interactive (list (completing-read "Layout: " riece-layout-alist)))
+  (setq riece-layout name)
+  (riece-command-configure-windows))
+
 (defun riece-command-toggle-channel-buffer-mode ()
   (interactive)
   (setq riece-channel-buffer-mode
 (defun riece-command-toggle-channel-buffer-mode ()
   (interactive)
   (setq riece-channel-buffer-mode
-       (not riece-channel-buffer-mode))
+       (not riece-channel-buffer-mode)
+       riece-save-variables-are-dirty t)
   (riece-command-configure-windows))
 
 (defun riece-command-toggle-user-list-buffer-mode ()
   (interactive)
   (setq riece-user-list-buffer-mode
   (riece-command-configure-windows))
 
 (defun riece-command-toggle-user-list-buffer-mode ()
   (interactive)
   (setq riece-user-list-buffer-mode
-       (not riece-user-list-buffer-mode))
+       (not riece-user-list-buffer-mode)
+       riece-save-variables-are-dirty t)
   (riece-command-configure-windows))
 
 (defun riece-command-toggle-channel-list-buffer-mode ()
   (interactive)
   (setq riece-channel-list-buffer-mode
   (riece-command-configure-windows))
 
 (defun riece-command-toggle-channel-list-buffer-mode ()
   (interactive)
   (setq riece-channel-list-buffer-mode
-       (not riece-channel-list-buffer-mode))
+       (not riece-channel-list-buffer-mode)
+       riece-save-variables-are-dirty t)
   (riece-command-configure-windows))
 
   (riece-command-configure-windows))
 
-(defun riece-get-users-on-server ()
-  (riece-with-server-buffer
-   (let (users)
-     (mapatoms
-      (lambda (atom)
-       (unless (riece-channel-p (symbol-name atom))
-         (push (symbol-name atom) users)))
-      riece-obarray)
-     (if (member riece-real-nickname users)
-        users
-       (cons riece-real-nickname users)))))
-
 (defun riece-command-finger (user &optional recurse)
   (interactive
    (let* ((completion-ignore-case t)
 (defun riece-command-finger (user &optional recurse)
   (interactive
    (let* ((completion-ignore-case t)
 
 (defun riece-command-topic (topic)
   (interactive
 
 (defun riece-command-topic (topic)
   (interactive
-   (list (read-from-minibuffer
-         "Topic: " (cons (or (riece-channel-get-topic
-                              riece-current-channel)
-                             "")
-                         0))))
+   (progn
+     (riece-check-channel-commands-are-usable t)
+     (list (read-from-minibuffer
+           "Topic: " (cons (or (riece-with-server-buffer
+                                   (riece-identity-server
+                                    riece-current-channel)
+                                 (riece-channel-get-topic
+                                  (riece-identity-prefix
+                                   riece-current-channel)))
+                               "")
+                           0)))))
   (riece-send-string (format "TOPIC %s :%s\r\n"
                             (riece-identity-prefix riece-current-channel)
                             topic)))
 
   (riece-send-string (format "TOPIC %s :%s\r\n"
                             (riece-identity-prefix riece-current-channel)
                             topic)))
 
-(defun riece-command-invite (&optional user channel)
+(defun riece-command-invite (user)
   (interactive
   (interactive
-   (let ((completion-ignore-case t)
-        user channel)
-     (if current-prefix-arg
-        (setq channel
-              (completing-read
-               "Channel: "
-               (mapcar #'list riece-current-channels))))
+   (let ((completion-ignore-case t))
+     (riece-check-channel-commands-are-usable t)
      (list (completing-read
            "User: "
      (list (completing-read
            "User: "
-           (mapcar #'list (riece-get-users-on-server)))
-          channel)))
-  (if channel
-      (riece-send-string (format "INVITE %s %s\r\n"
-                                user (riece-identity-prefix channel)))
-    (riece-send-string (format "INVITE %s %s\r\n"
-                              user (riece-identity-prefix
-                                    riece-current-channel)))))
+           (mapcar #'list (riece-get-users-on-server))))))
+  (riece-send-string (format "INVITE %s %s\r\n"
+                            user (riece-identity-prefix
+                                  riece-current-channel))))
+
+(defun riece-command-kick (user &optional message)
+  (interactive
+   (let ((completion-ignore-case t))
+     (riece-check-channel-commands-are-usable t)
+     (list (completing-read
+           "User: "
+           (mapcar #'list
+                   (riece-with-server-buffer
+                       (riece-identity-server riece-current-channel)
+                     (riece-channel-get-users
+                      (riece-identity-prefix riece-current-channel)))))
+          (if current-prefix-arg
+              (read-string "Message: ")))))
+  (riece-send-string
+   (if message
+       (format "KICK %s %s :%s\r\n"
+              (riece-identity-prefix riece-current-channel)
+              user message)
+     (format "KICK %s %s\r\n"
+            (riece-identity-prefix riece-current-channel)
+            user))))
+
+(defun riece-command-names (pattern)
+  (interactive
+   (let ((completion-ignore-case t))
+     (list (read-from-minibuffer
+           "Pattern: "
+           (if (and riece-current-channel
+                    (riece-channel-p (riece-identity-prefix
+                                      riece-current-channel)))
+               (cons (riece-identity-prefix riece-current-channel)
+                     0))))))
+  (if (or (not (equal pattern ""))
+         (yes-or-no-p "Really want to query NAMES without argument? "))
+      (riece-send-string (format "NAMES %s\r\n" pattern))))
+
+(defun riece-command-who (pattern)
+  (interactive
+   (let ((completion-ignore-case t))
+     (list (read-from-minibuffer
+           "Pattern: "
+           (if (and riece-current-channel
+                    (riece-channel-p (riece-identity-prefix
+                                      riece-current-channel)))
+               (cons (riece-identity-prefix riece-current-channel)
+                     0))))))
+  (if (or (not (equal pattern ""))
+         (yes-or-no-p "Really want to query WHO without argument? "))
+      (riece-send-string (format "WHO %s\r\n" pattern))))
+
+(defun riece-command-list (pattern)
+  (interactive
+   (let ((completion-ignore-case t))
+     (list (read-from-minibuffer
+           "Pattern: "
+           (if (and riece-current-channel
+                    (riece-channel-p (riece-identity-prefix
+                                      riece-current-channel)))
+               (cons (riece-identity-prefix riece-current-channel)
+                     0))))))
+  (if (or (not (equal pattern ""))
+         (yes-or-no-p "Really want to query LIST without argument? "))
+      (riece-send-string (format "LIST %s\r\n" pattern))))
 
 (defun riece-command-change-mode (channel change)
   (interactive
    (let* ((completion-ignore-case t)
          (channel
           (if current-prefix-arg
 
 (defun riece-command-change-mode (channel change)
   (interactive
    (let* ((completion-ignore-case t)
          (channel
           (if current-prefix-arg
-              (completing-read
-               "Channel/user: "
-               (mapcar #'list riece-current-channels))
+              (riece-completing-read-identity
+               "Channel/User: " riece-current-channels)
+            (riece-check-channel-commands-are-usable t)
             riece-current-channel))
          (riece-overriding-server-name (riece-identity-server channel))
          (riece-temp-minibuffer-message
           (concat "[Available modes: "
             riece-current-channel))
          (riece-overriding-server-name (riece-identity-server channel))
          (riece-temp-minibuffer-message
           (concat "[Available modes: "
-                  (riece-with-server-buffer
-                   (if (and (riece-channel-p channel)
-                            riece-supported-channel-modes)
-                       (apply #'string riece-supported-channel-modes)
-                     (if (and (not (riece-channel-p channel))
-                              riece-supported-user-modes)
-                         (apply #'string riece-supported-user-modes))))
+                  (riece-with-server-buffer (riece-identity-server channel)
+                    (if (riece-channel-p (riece-identity-prefix channel))
+                        (if riece-supported-channel-modes
+                            (apply #'string riece-supported-channel-modes))
+                      (if riece-supported-user-modes
+                          (apply #'string riece-supported-user-modes))))
                   "]")))
      (list channel
           (read-from-minibuffer
                   "]")))
      (list channel
           (read-from-minibuffer
-           (concat (riece-concat-modes channel "Mode (? for help)") ": ")
+           (concat (riece-concat-channel-modes
+                    channel "Mode (? for help)") ": ")
            nil riece-minibuffer-map))))
            nil riece-minibuffer-map))))
-  (riece-send-string (format "MODE %s :%s\r\n" channel change)))
+  (riece-send-string (format "MODE %s :%s\r\n" (riece-identity-prefix channel)
+                            change)))
 
 (defun riece-command-set-operators (users &optional arg)
   (interactive
 
 (defun riece-command-set-operators (users &optional arg)
   (interactive
-   (let ((operators (riece-channel-get-operators riece-current-channel))
-        (completion-ignore-case t)
-        users)
-     (if current-prefix-arg
+   (progn
+     (riece-check-channel-commands-are-usable t)
+     (let ((operators
+           (riece-with-server-buffer
+               (riece-identity-server riece-current-channel)
+             (riece-channel-get-operators
+              (riece-identity-prefix riece-current-channel))))
+          (completion-ignore-case t)
+          users)
+       (if current-prefix-arg
+          (setq users (riece-completing-read-multiple
+                       "Users"
+                       (mapcar #'list operators)))
         (setq users (riece-completing-read-multiple
                      "Users"
         (setq users (riece-completing-read-multiple
                      "Users"
-                     (mapcar #'list operators)))
-       (setq users (riece-completing-read-multiple
-                   "Users"
-                   (delq nil (mapcar (lambda (user)
-                                       (unless (member user operators)
-                                         (list user)))
-                                     (riece-channel-get-users
-                                      riece-current-channel))))))
-     (list users current-prefix-arg)))
+                     (delq nil (mapcar
+                                (lambda (user)
+                                  (unless (member user operators)
+                                    (list user)))
+                                (riece-with-server-buffer
+                                    (riece-identity-server
+                                     riece-current-channel)
+                                  (riece-channel-get-users
+                                   (riece-identity-prefix
+                                    riece-current-channel))))))))
+       (list users current-prefix-arg))))
   (let (group)
     (while users
   (let (group)
     (while users
-      (push (pop users) group)
+      (setq group (cons (car users) group)
+           users (cdr users))
       (if (or (= (length group) 3)
              (null users))
          (riece-send-string
       (if (or (= (length group) 3)
              (null users))
          (riece-send-string
 
 (defun riece-command-set-speakers (users &optional arg)
   (interactive
 
 (defun riece-command-set-speakers (users &optional arg)
   (interactive
-   (let ((speakers (riece-channel-get-speakers riece-current-channel))
-        (completion-ignore-case t)
-        users)
-     (if current-prefix-arg
+   (progn
+     (riece-check-channel-commands-are-usable t)
+     (let ((speakers
+           (riece-with-server-buffer
+               (riece-identity-server riece-current-channel)
+             (riece-channel-get-speakers
+              (riece-identity-prefix riece-current-channel))))
+          (completion-ignore-case t)
+          users)
+       (if current-prefix-arg
+          (setq users (riece-completing-read-multiple
+                       "Users"
+                       (mapcar #'list speakers)))
         (setq users (riece-completing-read-multiple
                      "Users"
         (setq users (riece-completing-read-multiple
                      "Users"
-                     (mapcar #'list speakers)))
-       (setq users (riece-completing-read-multiple
-                   "Users"
-                   (delq nil (mapcar (lambda (user)
-                                       (unless (member user speakers)
-                                         (list user)))
-                                     (riece-channel-get-users
-                                      riece-current-channel))))))
-     (list users current-prefix-arg)))
+                     (delq nil (mapcar
+                                (lambda (user)
+                                  (unless (member user speakers)
+                                    (list user)))
+                                (riece-with-server-buffer
+                                    (riece-identity-server
+                                     riece-current-channel)
+                                  (riece-channel-get-users
+                                   (riece-identity-prefix
+                                    riece-current-channel))))))))
+       (list users current-prefix-arg))))
   (let (group)
     (while users
   (let (group)
     (while users
-      (push (pop users) group)
+      (setq group (cons (car users) group)
+           users (cdr users))
       (if (or (= (length group) 3)
              (null users))
          (riece-send-string
       (if (or (= (length group) 3)
              (null users))
          (riece-send-string
                   (make-string (length group) ?v)
                   (mapconcat #'identity group " ")))))))
 
                   (make-string (length group) ?v)
                   (mapconcat #'identity group " ")))))))
 
-(defun riece-command-send-message (message)
+(defun riece-command-send-message (message notice)
   "Send MESSAGE to the current channel."
   (if (equal message "")
       (error "No text to send"))
   "Send MESSAGE to the current channel."
   (if (equal message "")
       (error "No text to send"))
-  (unless riece-current-channel
-    (error (substitute-command-keys
-           "Type \\[riece-command-join] to join a channel")))
-  (riece-send-string
-   (format "PRIVMSG %s :%s\r\n"
-          (riece-identity-prefix riece-current-channel)
-          message))
-  (riece-own-channel-message message))
+  (riece-check-channel-commands-are-usable)
+  (if notice
+      (progn
+       (riece-send-string
+        (format "NOTICE %s :%s\r\n"
+                (riece-identity-prefix riece-current-channel)
+                message))
+       (riece-display-message
+        (riece-make-message (riece-current-nickname) riece-current-channel
+                            message 'notice t)))
+    (riece-send-string
+     (format "PRIVMSG %s :%s\r\n"
+            (riece-identity-prefix riece-current-channel)
+            message))
+    (riece-display-message
+     (riece-make-message (riece-current-nickname) riece-current-channel
+                        message nil t))))
 
 (defun riece-command-enter-message ()
   "Send the current line to the current channel."
   (interactive)
   (riece-command-send-message (buffer-substring
                               (riece-line-beginning-position)
 
 (defun riece-command-enter-message ()
   "Send the current line to the current channel."
   (interactive)
   (riece-command-send-message (buffer-substring
                               (riece-line-beginning-position)
-                              (riece-line-end-position)))
+                              (riece-line-end-position))
+                             nil)
+  (let ((next-line-add-newlines t))
+    (next-line 1)))
+
+(defun riece-command-enter-message-as-notice ()
+  "Send the current line to the current channel as NOTICE."
+  (interactive)
+  (riece-command-send-message (buffer-substring
+                              (riece-line-beginning-position)
+                              (riece-line-end-position))
+                             t)
   (let ((next-line-add-newlines t))
     (next-line 1)))
 
 (defun riece-command-join-channel (target key)
   (let ((next-line-add-newlines t))
     (next-line 1)))
 
 (defun riece-command-join-channel (target key)
-  (let ((server-name (riece-identity-server target))
-       process)
-    (if server-name
-       (setq process (cdr (assoc server-name riece-server-process-alist)))
-      (setq process riece-server-process))
+  (let ((process (riece-server-process (riece-identity-server target))))
     (unless process
       (error "%s" (substitute-command-keys
                   "Type \\[riece-command-open-server] to open server.")))
     (unless process
       (error "%s" (substitute-command-keys
                   "Type \\[riece-command-open-server] to open server.")))
 
 (defun riece-command-join (target &optional key)
   (interactive
 
 (defun riece-command-join (target &optional key)
   (interactive
-   (let ((completion-ignore-case t)
-        (target
-         (completing-read "Channel/user: "
-                          (mapcar #'list riece-current-channels)))
-        key)
+   (let* ((completion-ignore-case t)
+         (target
+          (if riece-join-channel-candidate
+              (let ((default (riece-format-identity
+                              riece-join-channel-candidate)))
+                (riece-completing-read-identity
+                 (format "Channel/User (default %s): " default)
+                 riece-current-channels nil nil nil nil default))
+            (riece-completing-read-identity
+             "Channel/User: " riece-current-channels)))
+         key)
      (if (and current-prefix-arg
      (if (and current-prefix-arg
-             (riece-channel-p target))
+             (riece-channel-p (riece-identity-prefix target)))
         (setq key
         (setq key
-              (riece-read-passwd (format "Key for %s: " target))))
+              (riece-read-passwd (format "Key for %s: "
+                                         (riece-format-identity target)))))
      (list target key)))
   (let ((pointer (riece-identity-member target riece-current-channels)))
     (if pointer
        (riece-command-switch-to-channel (car pointer))
      (list target key)))
   (let ((pointer (riece-identity-member target riece-current-channels)))
     (if pointer
        (riece-command-switch-to-channel (car pointer))
-      (if (riece-channel-p target)
+      (if (riece-channel-p (riece-identity-prefix target))
          (riece-command-join-channel target key)
        (riece-command-join-partner target)))))
 
 (defun riece-command-part-channel (target message)
          (riece-command-join-channel target key)
        (riece-command-join-partner target)))))
 
 (defun riece-command-part-channel (target message)
-  (let ((server-name (riece-identity-server target))
-       process)
-    (if server-name
-       (setq process (cdr (assoc server-name riece-server-process-alist)))
-      (setq process riece-server-process))
-    (unless process
-      (error "%s" (substitute-command-keys
-                  "Type \\[riece-command-open-server] to open server.")))
+  (let ((process (riece-server-process (riece-identity-server target))))
     (riece-process-send-string process
                               (if message
                                   (format "PART %s :%s\r\n"
     (riece-process-send-string process
                               (if message
                                   (format "PART %s :%s\r\n"
 
 (defun riece-command-part (target &optional message)
   (interactive
 
 (defun riece-command-part (target &optional message)
   (interactive
-   (let ((completion-ignore-case t)
-        (target
-         (completing-read "Channel/user: "
-                          (mapcar #'list riece-current-channels)
-                          nil t (cons riece-current-channel 0)))
-        message)
-     (if (and current-prefix-arg
-             (riece-channel-p target))
-        (setq message (read-string "Message: ")))
-     (list target message)))
+   (progn
+     (riece-check-channel-commands-are-usable)
+     (let* ((completion-ignore-case t)
+           (target
+            (riece-completing-read-identity
+             (format "Channel/User (default %s): "
+                     (riece-format-identity riece-current-channel))
+             riece-current-channels nil nil nil nil
+             (riece-format-identity riece-current-channel)))
+           message)
+       (if (and current-prefix-arg
+               (riece-channel-p (riece-identity-prefix target)))
+          (setq message (read-string "Message: ")))
+       (list target message))))
   (if (riece-identity-member target riece-current-channels)
   (if (riece-identity-member target riece-current-channels)
-      (if (riece-channel-p target)
+      (if (riece-channel-p (riece-identity-prefix target))
          (riece-command-part-channel target message)
        (riece-part-channel target)
        (riece-redisplay-buffers))
          (riece-command-part-channel target message)
        (riece-part-channel target)
        (riece-redisplay-buffers))
 (defun riece-command-toggle-away (&optional message)
   "Mark yourself as being away."
   (interactive
 (defun riece-command-toggle-away (&optional message)
   "Mark yourself as being away."
   (interactive
-   (if current-prefix-arg
+   (if (and (not (riece-with-server-buffer (riece-identity-server
+                                           (riece-current-nickname))
+                  (riece-user-get-away (riece-identity-prefix
+                                        (riece-current-nickname)))))
+           (or (null riece-away-message)
+               current-prefix-arg))
        (let ((message (read-string "Away message: ")))
         (list message))))
   (if message
        (let ((message (read-string "Away message: ")))
         (list message))))
   (if message
   "Prevent automatic scrolling of the dialogue window.
 If prefix argument ARG is non-nil, toggle frozen status."
   (interactive "P")
   "Prevent automatic scrolling of the dialogue window.
 If prefix argument ARG is non-nil, toggle frozen status."
   (interactive "P")
-  (riece-freeze (if riece-channel-buffer-mode
-                   riece-channel-buffer
-                 riece-dialogue-buffer)
-               (if arg (prefix-numeric-value arg))))
+  (with-current-buffer (if (and riece-channel-buffer-mode
+                               riece-channel-buffer)
+                          riece-channel-buffer
+                        riece-dialogue-buffer)
+    (setq riece-freeze (if arg
+                          (< 0 (prefix-numeric-value arg))
+                        (not riece-freeze))))
+  (riece-update-status-indicators)
+  (force-mode-line-update t))
 
 (defun riece-command-toggle-own-freeze (&optional arg)
   "Prevent automatic scrolling of the dialogue window.
 The difference from `riece-command-freeze' is that your messages are hidden.
 If prefix argument ARG is non-nil, toggle frozen status."
   (interactive "P")
 
 (defun riece-command-toggle-own-freeze (&optional arg)
   "Prevent automatic scrolling of the dialogue window.
 The difference from `riece-command-freeze' is that your messages are hidden.
 If prefix argument ARG is non-nil, toggle frozen status."
   (interactive "P")
-  (riece-own-freeze (if riece-channel-buffer-mode
-                       riece-channel-buffer
-                     riece-dialogue-buffer)
-                   (if arg (prefix-numeric-value arg))))
+  (with-current-buffer (if (and riece-channel-buffer-mode
+                               riece-channel-buffer)
+                          riece-channel-buffer
+                        riece-dialogue-buffer)
+    (if (if arg
+           (< 0 (prefix-numeric-value arg))
+         (not (eq riece-freeze 'own)))
+       (setq riece-freeze 'own)
+      (setq riece-freeze nil)))
+  (riece-update-status-indicators)
+  (force-mode-line-update t))
 
 (defun riece-command-quit (&optional arg)
   "Quit IRC."
 
 (defun riece-command-quit (&optional arg)
   "Quit IRC."
@@ -459,8 +584,11 @@ If prefix argument ARG is non-nil, toggle frozen status."
             (if arg
                 (read-string "Message: ")
               (or riece-quit-message
             (if arg
                 (read-string "Message: ")
               (or riece-quit-message
-                  (riece-extended-version)))))
-       (riece-close-all-server message))))
+                  (riece-extended-version))))
+           (alist riece-server-process-alist))
+       (while alist
+         (riece-quit-server-process (cdr (car alist)) message)
+         (setq alist (cdr alist))))))
 
 (defun riece-command-raw (command)
   "Enter raw IRC command, which is sent to the server."
 
 (defun riece-command-raw (command)
   "Enter raw IRC command, which is sent to the server."
@@ -490,12 +618,11 @@ If prefix argument ARG is non-nil, toggle frozen status."
 (defun riece-command-open-server (server-name)
   (interactive
    (list (completing-read "Server: " riece-server-alist)))
 (defun riece-command-open-server (server-name)
   (interactive
    (list (completing-read "Server: " riece-server-alist)))
-  (let ((process (riece-start-server
-                 (riece-server-name-to-server server-name)
-                 server-name)))
-    (with-current-buffer (process-buffer process)
-      (setq riece-server-name server-name))
-    (push (cons server-name process) riece-server-process-alist)))
+  (if (riece-server-process server-name)
+      (error "%s is already opened" server-name))
+  (riece-open-server
+   (riece-server-name-to-server server-name)
+   server-name))
 
 (defun riece-command-close-server (server-name &optional message)
   (interactive
 
 (defun riece-command-close-server (server-name &optional message)
   (interactive
@@ -504,13 +631,12 @@ If prefix argument ARG is non-nil, toggle frozen status."
             (read-string "Message: ")
           (or riece-quit-message
               (riece-extended-version)))))
             (read-string "Message: ")
           (or riece-quit-message
               (riece-extended-version)))))
-  (riece-close-server server-name message))
+  (riece-quit-server-process (riece-server-process server-name) message))
 
 (defun riece-command-universal-server-name-argument ()
   (interactive)
   (let* ((riece-overriding-server-name
 
 (defun riece-command-universal-server-name-argument ()
   (interactive)
   (let* ((riece-overriding-server-name
-         (completing-read "Server: "
-                          riece-server-process-alist))
+         (completing-read "Server: " riece-server-process-alist))
         (command
          (key-binding (read-key-sequence
                        (format "Command to execute on \"%s\":"
         (command
          (key-binding (read-key-sequence
                        (format "Command to execute on \"%s\":"