This file describes Riece.

Copyright (C) 2003 Daiki Ueno.

Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.1 or any later version published by the Free Software Foundation; with no Invariant Sections, with no Front-Cover Texts, and with no Back-Cover Texts.  A copy of the license is included in the section entitled "GNU Free Documentation License".

Riece user's manual
*******************

Riece は Emacs で IRC (Internet Relay Chat) に参加するためのプログラムです。

Overview
********

Riece は、長い間メンテナンス不可能な状態にあった Liece のコードを完全に書き直したものです。インターフェースは、Liece からほとんどそのまま踏襲しています。

現在のところ IRC クライアントとしての機能は十分ではありませんが、Liece にはない特長がいくつかあります。以下にそれらの一部を挙げます。

  * 複数のサーバに同時につなげる

  * 一応 API らしい API が用意されている

  * コードサイズが小さい (Liece の半分程度)

  * アドオンによる拡張が可能

  * APEL がいらない

より詳しい情報は、以下のページを御覧ください。

  * http://wiliki.designflaw.org/index.cgi?Riece&l=jp

  * http://www.unixuser.org/~ueno/liece/

Getting started
***************

Required Environments
=====================

次に挙げる環境で動作を確認しています。

  * Emacs 20.7 以上

  * XEmacs 21.4 以上

Installation
============

Riece の最新版は、 http://wiliki.designflaw.org/index.cgi?Riece&l=jp で配布しています。展開したら、以下のコマンドを実行することで手元の環境にインストールできます

     ./configure
     make
     make install

XEmacs のパッケージとしてインストールする場合には以下のようにします。

     ./configure --with-xemacs[=xemacs-21.4.13]
     make package
     make install-package

XEmacs のパッケージとしてインストールした場合には必要ありませんが、 M-x riece で起動するためには、autoload の設定を御自分の Emacs の設定ファイルに加える必要があります。

     (autoload 'riece "riece" "Start Riece" t)

Startup file
============

はじめてつかう場合には、とくに何も設定する必要はありません。この章は読み飛ばしてください。

Riece は設定ファイルを変数 riece-directory で指示されるディレクトリ (デフォルトは ~/.riece/) から読み込みます。このディレクトリには以下の二種類の設定ファイルが格納されます。

riece-saved-variables-file
     前回のセッションの情報を格納します(デフォルトは ~/.riece/save)

riece-variables-file
     ユーザに固有の設定を記述します(デフォルトは ~/.riece/init)

起動時には、最初に riece-saved-variables-file を、次に riece-variables-file を読み込みます。ファイルが存在しなければ何もしません。

Basic usage
***********

M-x riece とすることで起動します。サーバ名を聞かれるので答えます。接続可能な IRC サーバは各 IRC ネットワーク毎に異なりますが、大抵は Web ページに一覧がまとめてあることが多いでしょう。

  * http://irc.kyoto-u.ac.jp

  * http://freenode.net

もしニックネームが既に使用されている場合、別のニックネームの入力を促されます。ニックネームの初期値は riece-nickname で設定します。デフォルトでは、ユーザのログイン名がそのまま使われます。

無事に接続できたなら、次はチャンネルに参加して会話をしてみましょう。 C-c j とタイプすると、チャンネル名を尋ねられるので、適当なチャンネル名を入力しましょう。たとえば IRCnet には #Liece というチャンネルがあるので、テストにお使いください。

チャンネルに入ることができたら、文章を入力してリターンキーを押すと発言することができます。他の人の会話は画面右上のバッファに表示されます。

Commands
========

文章を入力したバッファ *Commands* は、コマンドバッファと呼ばれ、コマンドバッファからは様々なコマンドを発行することができます。以下に一部を挙げます。

IRC commands
------------

RET
     文章を送ります(riece-command-enter-message)

C-RET
     文章を NOTICE として送ります(riece-command-enter-message-as-notice)

C-c j
     チャンネルに参加します(riece-command-join)

C-c C-p
     チャンネルから離脱します(riece-command-part)

C-c q
     IRC をやめます(riece-command-quit)

C-c n
     自分のニックネームを変更します(riece-command-change-nickname)

C-c f
     ユーザの情報を調べます(riece-command-finger)

C-c C-k
     ユーザをチャンネルから蹴り出します(riece-command-kick)

C-c i
     ユーザをチャンネルに招待します(riece-command-invite)

C-c l
     パターンに対して LIST を発行します(riece-command-list)

C-c C-n
     パターンに対して NAMES を発行します(riece-command-names)

C-c w
     パターンに対して WHO を発行します(riece-command-who)

C-c t
     チャンネルのトピックを設定します(riece-command-topic)

C-c C-m
     チャンネルのモードを設定します(riece-command-change-mode)

C-c o
     ユーザにオペレータ権限を与えます。前置引数 (C-u) を与えると、ユーザから発言権を奪います(riece-command-set-operators)

C-c v
     ユーザに発言権を与えます。前置引数 (C-u) を与えると、ユーザから発言権を奪います(riece-command-set-speakers)

C-c /
     生の IRC コマンドを送ります(riece-command-raw)

Window manipulating commands
----------------------------

C-c r
     ウィンドウを再描画します(riece-command-configure-windows)

C-c C-j
     次のチャンネルに移ります(riece-command-next-channel)

C-c <
     前のチャンネルに移ります(riece-command-previous-channel)

C-c >
     次のチャンネルに移ります(riece-command-next-channel)

C-c 数字
     N番目のチャンネルに移動します(riece-command-switch-to-channel-by-number)

C-c C-c 数字
     N + 10番目のチャンネルに移動します(riece-command-switch-to-channel-by-number)

C-c $
     チャンネルバッファ、またはダイアログバッファのビューを下端まで移動します(riece-command-end-of-buffer)

C-c SPC
     チャンネルバッファ、またはダイアログバッファを上方向にスクロールします(riece-command-scroll-up)

C-c DEL
     チャンネルバッファ、またはダイアログバッファを下方向にスクロールします(riece-command-scroll-down)

Status toggle commands
----------------------

C-c C-t c
     チャンネルバッファの表示・非表示を切り替えます(riece-command-toggle-channel-buffer-mode)

C-c C-t C
     チャンネルリストバッファの表示・非表示を切り替えます(riece-command-toggle-channel-list-buffer-mode)

C-c C-t u
     ユーザリストバッファの表示・非表示を切り替えます(riece-command-toggle-user-list-buffer-mode)

C-c C-t f
     チャンネルバッファ、またはダイアログバッファのスクロールを禁止します(riece-command-toggle-freeze)

C-c C-t o
     チャンネルバッファ、またはダイアログバッファのスクロールを、自分が発言するまで禁止します(riece-command-toggle-own-freeze)

C-c C-t a
     自分の離席状態を切り替えます(riece-command-toggle-away)

Connecting to multiple servers
==============================

Riece の大きな特長に、複数のサーバに同時に接続する機能があります。

新たなサーバに接続し、そのサーバ上のチャンネルに参加する手順は以下のようになります。

 1. C-c O (riece-command-open-server) とします。サーバ名を聞かれるので答えます。

 2. C-c j (riece-command-join) でチャンネルに参加します。ここで、チャンネル名の後に空白で区切ってサーバ名を続けます。空白を入力するには、 C-q を使います。たとえば、サーバ irc6 上の #Liece に参加するには C-c j #Liece C-q SPC irc6 とタイプすることになります。

チャンネルに入らずにコマンドを送るには、C-c M (riece-command-universal-server-name-argument) が便利です。

サーバとの接続に関するコマンドは以下の通りです。

C-c O
     別のサーバに接続します(riece-command-open-server)

C-c C
     サーバとの接続を切断します(riece-command-close-server)

C-c M
     特定のサーバに対して、続くコマンドを発行します(riece-command-universal-server-name-argument)

Advanced usage
**************

この章では、もっと進んだ使い方を解説します。

Server settings
===============

IRC サーバは riece-server 文字列として指定します。ここで riece-server のフォーマットは "<サーバのホスト名>:<ポート番号>[:<パスワード>]" となります。

riece-server-alist を適切に設定すると、キーワードを使って、より詳細な指定が可能になります。以下は筆者の設定から抜き出した例です。

     (setq riece-server-alist
           '(("irc6" :host "irc6.nara.wide.ad.jp")
             ("plum" :host "localhost" :service 26667
              :function relay-open-network-stream))
           riece-server "irc6")

riece-server-alist の各要素の意味は以下の通りです。

  * irc6 という略記名で irc6.nara.wide.ad.jp に接続

  * plum という略記名で relay-open-network-stream を通じて (SSH 経由で) 接続

指定可能なキーワードは以下の通りです。

:host
     サーバのホスト名または IP アドレス

:service
     サーバのサービス名またはポート番号

:nickname
     接続時のニックネーム

:username
     接続時のユーザネーム

:password
     接続時のパスワード

:function
     接続用関数

:coding-system
     コーディングシステム

Add-ons
=======

Riece では、ユーザが新たな機能を追加し、自由に取り外しできるよう、アドオンと呼ばれる機構を用意しています。アドオンは通常の elisp モジュールを拡張したもので、ロードの順番だけではなく、初期化処理の依存関係も記述することができます。

現在、以下のモジュールがアドオンとして実装されています：

riece-highlight
     バッファの色付け

riece-ctcp
     CTCP (Client To Client Protocol)

riece-url
     会話に現れた URL の収集

riece-unread
     発言のあったチャンネルに!マークをつける

riece-rdcc
     DCC (Direct Client Connection) によるファイル転送

これらのうち、riece-highlight と riece-ctcp はデフォルトで組み込まれています。

アドオンを組み込むには riece-addons を設定します。たとえば riece-url を組み込む場合には、~/.riece/init.el に以下のように記述します。

     (add-to-list 'riece-addons 'riece-url t)

Writing add-ons
===============

アドオンの条件を満たすモジュールは以下の関数を提供します。

<モジュール名>-requires
     依存する他のアドオン(シンボルのリスト)を返します(オプション)

<モジュール名>-insinuate
     初期化処理を行います

Riece 側では以下の処理を行います。

 1. 変数 riece-addons に列挙されたモジュールを読み込む

 2. それぞれのモジュールに対し、<モジュール名>-requires が用意されていれば呼び出して依存グラフを作る

 3. 依存グラフに対してトポロジカルソート (cf. tsort(1)) を行う

 4. 得た依存順序に従って <モジュール名>-insinuate 呼び出す

作成したアドオンは、load-path の通ったディレクトリ、または riece-addon-directory (デフォルトでは ~/.riece/addons/) に置くことで組み込み可能な状態になります。

Handler hooks
=============

Riece には、ハンドラフックと呼ばれる特殊なフックがあります。これらは IRC のメッセージを受け取った前後で実行されるフックです。

説明のために message を IRC のメッセージ名(PRIVMSG など)を全て小文字にしたものとします。

riece-<message>-hook
     message が届いたときに最初に呼ばれるフック

riece-after-<message>-hook
     message の処理が終わった後に呼ばれるフック

ここで riece-<message>-hook の返り値には意味があり、非 nil を返すものがあれば、その後の処理をおこないません。また、その場合には riece-after-<message>-hook も呼び出されません。

フックの引数は RFC2812 の prefix と Parameters に相当する 2 つの引数が渡ります。

Development
***********

開発者募集中。

CVS
===

Riece の開発は CVS を利用して行っています。CVS サーバから最新のスナップショットを取得するには以下のようにします。

 1. CVS サーバへのログイン

          cvs -d :pserver:anonymous@cvs.m17n.org:/cvs/root login
          CVS password: [CR] # NULL string

 2. モジュールのチェックアウト

          cvs -d :pserver:anonymous@cvs.m17n.org:/cvs/root checkout riece

 3. configure の生成

          autoreconf -f -i -v

Debugging
=========

riece-debug を t に設定すると、デバッグ出力が有効になります。また、サーバからの生の出力が " *IRC*[<サーバ名>]" バッファに消されずに残ります。

Modules
=======

基本的に依存関係の上位にあるものから：

Core modules
------------

riece-globals
     大域変数の定義

riece-options
     ユーザオプションの定義

riece-version
     バージョンの定義

riece-inlines
     雑多なインライン関数の定義

riece-coding
     コーディングシステム関連の関数の定義

riece-complete
     ミニバッファでの補完を助ける関数の定義

riece-identity
     channel/user object の大域表記を操作する関数の定義

riece-channel
     channel object 関連の定義

riece-user
     user object 関連の定義

riece-misc
     雑多な関数の定義(インライン関数を除く)

riece-display
     表示用バッファの管理

riece-server
     IRCサーバとの接続管理

riece-naming
     名前管理のための mediator のようなもの

riece-message
     message object 関連の定義

riece-filter
     プロセスフィルタのエントリポイント

riece-handle
     通常のメッセージのハンドラ。riece-filter のみから呼ばれる

riece-000
     000番台の numeric reply のハンドラ。riece-filter のみから呼ばれる

riece-200
     200番台の numeric reply のハンドラ。riece-filter のみから呼ばれる

riece-300
     300番台の numeric reply のハンドラ。riece-filter のみから呼ばれる

riece-400
     400番台の numeric reply のハンドラ。riece-filter のみから呼ばれる

riece-500
     500番台の numeric reply のハンドラ。riece-filter のみから呼ばれる

riece-commands
     コマンドの定義

riece
     エントリポイント。各バッファのモード定義など

Add-ons
-------

riece-highlight
     バッファの色付け

riece-ctcp
     CTCP (Client To Client Protocol)

riece-url
     会話に現れた URL の収集

riece-unread
     発言のあったチャンネルに!マークをつける

riece-rdcc
     DCC (Direct Client Connection) によるファイル転送 (Ruby による実装)

riece-ndcc
     DCC (Direct Client Connection) によるファイル転送 (Emacs 21.3 の make-network-connection による実装)

Namespace management
====================

Riece は複数のサーバに同時に接続するため、サーバ毎に別々の名前空間を管理しています。この名前空間には、サーバのプロセスに結び付けられたバッファのローカル変数を介してアクセスします。

Obtaining server buffer
-----------------------

サーバのバッファを取得するには、まずはじめにサーバの名前を得る必要があります。これには riece-find-server-name を使います。この関数は、状況に応じて選択すべきサーバの名前を返します。具体的には以下の順序で検索を行います。

 1. 大域変数 riece-overrinding-server-name の値

 2. riece-server-name がカレントバッファのローカル変数であるならば、既にプロセスのバッファにいるとみなせるので、riece-server-name の値そのもの

 3. ユーザが現在いるチャンネル (riece-current-channel) の大域名(後述) から切り出したサーバ名

こうして得たサーバ名で riece-server-process-alist を索き、サーバのプロセスを取得します。マクロ riece-with-server-buffer を使うと、ここまでを一括でやったうえで、プロセスのバッファで式を評価することができます。

Global name
-----------

複数のサーバに繋いだ場合、チャンネル名やニックを(サーバのバッファ上だけではなく)大域的に区別する必要が生じます。そこで、これらの名前を工夫して、名前の後に空白を挟んでサーバ名を指定する手法を採っています。これを大域名と呼びます。たとえば、irc6 というサーバの #Liece というチャンネルの大域名は #Liece irc6 となります。

ここで区切りを空白にしているのは、RFC2812 でチャンネルに使用できない文字だからです。

大域名を扱うには、riece-identity という抽象を介します。このモジュールでは、以下のような関数が定義されています。

 -- Function: riece-make-identity prefix &optional server
     大域表記を作り出します。server が省略された場合には、riece-find-server-name を使って取得したサーバ名を使います

 -- Function: riece-identity-prefix identity
     大域表記からサーバ名を除く部分を返します

 -- Function: riece-identity-server identity
     大域表記からサーバを除く部分を返します

 -- Function: riece-identity-equal a b
     二つの大域表記が同等か調べます。引数として与えられた文字列にサーバ名が付加されていなければ、付加してから検査を行います

 -- Function: riece-identity-equal-no-server a b
     riece-identity-equal と一緒ですが、サーバ名の付加は行いません

Channel and user management
---------------------------

IRC のチャンネルとユーザは基本的に単なるベクターとして表現されています。 JOIN や PART といった特別な操作は、これらのオブジェクトには結びつけません。結びつけたほうがオブジェクト指向で良いのではないか、という意見もありますが、そのようにすると、相互の結び付きが緊密になりすぎ、スパゲッティのもとになることは既に経験済みです。

Channels
........

riece-channel は、IRC のチャンネルを表すオブジェクトです。以下の要素を持ちます。

users
     参加しているユーザの名前(局所名)のリスト

operators
     オペレータ権限をもつユーザの名前のリスト

speakers
     発言権をもつユーザの名前のリスト

modes
     チャンネルのモード(文字のリスト)

banned
     MODE +b で指定されたパターンの一覧

invited
     MODE +I で指定されたパターンの一覧

uninvited
     MODE +e で指定されたパターンの一覧

Users
.....

riece-user は、IRC に参加しているユーザを表すオブジェクトです。以下の要素を持ちます。

channels
     参加しているチャンネルの名前(局所名)のリスト

user-at-host
     "<user>@<host>" の形で与えられるユーザの情報

modes
     ユーザのモード(文字のリスト)

away
     AWAY 中かどうか

Mediator
........

さて、チャンネルとユーザの参加を管理するために、 riece-naming という上位のモジュールを用意しています。これは、デザインパターンでいうところの Mediator パターンに相当するものです。

riece-naming を介することで、前述のチャンネル・ユーザオブジェクトに直接手を触れることなく、名前空間に安全にアクセスすることができます。

提供する主な関数は以下の 3 つです。

 -- Function: riece-naming-assert-join user-name channel-name
     ユーザがチャンネルに参加したことを表明します

 -- Function: riece-naming-assert-part user-name channel-name
     ユーザがチャンネルから離脱したことを表明します

 -- Function: riece-naming-assert-rename old-name new-name
     ユーザの名前が変更されたことを表明します