= WeeChat リレープロトコル
:author: Sébastien Helleu
:email: flashcode@flashtux.org
:toc2:
:toclevels: 3
:toc-title: 目次
:max-width: 100%


翻訳者:

* Ryuunosuke Ayanokouzi <i38w7i3@yahoo.co.jp>, 2014


この文書は WeeChat リレープロトコルについて述べたものです: リレープロトコルとは、WeeChat
データをクライアントに中継するためのもので、多くの場合クライアントはリモートインターフェイスを指します。


[[introduction]]
== はじめに

[[terminology]]
=== 用語

この文書では以下の用語を利用します:

* 'リレー': これは relay プラグインを備えた WeeChat を指し、 "サーバ"
  のように振る舞い、'クライアント' からの接続を受け付けます
* 'クライアント': これは他のソフトウェアのことを指し、ネットワークを介して 'リレー'
  に接続します; 多くの場合、'クライアント' はリモートインターフェイスのことを指します。

[[network_diagram]]
=== ネットワーク図

以下の図に示すように'クライアント' は'リレー' に接続しています:

....
                                               ┌────────────────┐ ワークステーション
 ┌────────┐                                ┌───┤ クライアント 1 │ (Linux、Windows、
 │  irc   │◄──┐  ╔═══════════╤════════╗    │   └────────────────┘ BSD、Mac OS X ...)
 └────────┘   └──╢           │        ║◄───┘   ┌────────────────┐
   ......        ║  WeeChat  │ リレー ║◄───────┤ クライアント 2 │ 携帯デバイス
 ┌────────┐   ┌──╢           │        ║◄───┐   └────────────────┘ (Android、iPhone ...)
 │ jabber │◄──┘  ╚═══════════╧════════╝    │      ......
 └────────┘                                │   ┌────────────────┐
   ......                                  └───┤ クライアント N │ その他のデバイス
                                               └────────────────┘


└────────────┘   └────────────────────┘╘══════╛└──────────────────────────────────────┘
 ネットワーク           ncurses         リレー            リモートインターフェイス
    サーバ          インターフェイス   プロトコル
....

[NOTE]
この文書で述べる全てのクライアントは'リレー' プラグインの 'weechat' プロトコルを使っています。また'リレー'
プラグインは IRC クライアントからの接続を受け入れることができます、この場合'リレー'
プラグインは 'IRC プロキシ' のように振舞います (この文書では説明しません)。

[[protocol_generalities]]
== プロトコルの一般的説明

* 'リレー' プラグインは新しい接続を受け入れるために IP/port をリッスンし、'クライアント'
  は TCP ソケットを使って'リレー' に接続します。
* 'クライアント' の数はオプション 'relay.network.max_clients' で制限されています。
* それぞれの'クライアント' が自分以外のクライアントと協調して動くことはできません。
* 'クライアント' から'リレー' へのメッセージを'コマンド'
  と呼び、これはテキスト形式 (文字列) で送信されます。
* 'リレー' から'クライアント' へのメッセージを'メッセージ'
  と呼び、これはバイナリデータとして送信されます。

[[commands]]
== コマンド (クライアント → リレー)

コマンドのフォーマットは以下です: "(id) command arguments\n".

フィールドは:

* 'id': 'リレー' からの応答に含まれる任意指定のメッセージ識別子;
  識別子は必ず括弧で括り、アンダースコア ("_") を最初につけるのは禁止されています
  (アンダースコアが最初についている識別子は WeeChat 'event' メッセージ用に予約されています)
* 'command': コマンド (以下のテーブルを参照)
* 'arguments': コマンドに対する任意指定の引数
  (複数の引数を渡す場合は空白で区切ってください)。

利用可能なコマンドのリスト (詳しくは次の章を参照):

[width="80%",cols="^3m,14",options="header"]
|===
| コマンド | 説明
| init     | 'リレー' 接続を初期化
| hdata    | 'hdata' を要求
| info     | 'インフォ' を要求
| infolist | 'インフォリスト' を要求
| nicklist | 'ニックネームリスト' を要求
| input    | バッファにデータを送信 (テキストまたはコマンド)
| sync     | バッファを同期 (バッファの最新情報を取得)
| desync   | バッファを非同期 (バッファの更新を止める)
| quit     | 'リレー' から切断
|===

[[command_init]]
=== init

'リレー' 接続を初期化。'リレー'
に送るコマンドは必ずこのコマンドから始めてください。'リレー'
がこのコマンドを受信していない場合、'リレー' は最初のコマンドを受け取った時点で警告無しに接続を閉じます。

構文:

----
init [<option>=<value>,[<option>=<value>,...]]
----

引数:

* 'option': 以下のうちの 1 つ:
** 'password': 'リレー' の認証用パスワード (WeeChat の
   'relay.network.password' オプション)
** 'compression': 圧縮タイプ:
*** 'zlib': 'リレー' から受信するメッセージに対して 'zlib' 圧縮を使う
*** 'off': 圧縮を使わない

[NOTE]
'リレー' が 'zlib' 圧縮をサポートする場合、'zlib' 圧縮はデフォルトで有効化されます。

例:

----
# 初期化、デフォルト設定の zlib を使用 (WeeChat がサポートする場合)
init password=mypass

# 初期化、圧縮を使わない
init password=mypass,compression=off
----

[[command_hdata]]
=== hdata

'hdata' を要求。

構文:

----
(id) hdata <path> [<keys>]
----

引数:

* 'path': hdata へのパス、フォーマットは: "hdata:pointer/var/var/.../var"、最後の
  var に対応する hdata が返されます:
** 'hdata': hdata の名前
** 'pointer': ポインタ ("0x12345") またはリスト名 (例: "gui_buffers")
   (番号も可能、以下を参照)
** 'var': 親 hdata に含まれる変数名 (パスで言う 1 つ前の名前)
   (番号も可能、以下を参照)
* 'keys': hdata で返すキーのコンマ区切りリスト
  (指定しなかった場合、全てのキーが返されます。強大な hdata 構造体の場合全てのキーを返すことはお勧めしません)

ポインタと変数の後に番号を指定することができます。フォーマットは
"(N)"。可能な値は:

* 正数: N 回次の要素への反復を繰り返す
* 負数: N 回前の要素への反復を繰り返す
* '*': 最後の要素まで、次の要素への反復を繰り返す

例:

----
# すべてのバッファを要求、"buffer" 型の hdata が返される
# それぞれのバッファについて "number" と "name" キーが返される
hdata buffer:gui_buffers(*) number,name

# バッファの全ての行を要求、"line_data" 型の hdata が返される
# 全てのキーが返される
hdata buffer:gui_buffers(*)/lines/first_line(*)/data

# 最初のバッファの完全な名前を要求
hdata buffer:gui_buffers full_name
----

[[command_info]]
=== info

'インフォ' を要求。

構文:

----
(id) info <name>
----

引数:

* 'name': 読み出すインフォの名前

例:

----
info version
----

[[command_infolist]]
=== infolist

'インフォリスト' を要求。

[IMPORTANT]
インフォリストの内容は実際のデータの複製です。可能な限り <<command_hdata,hdata>>
コマンドを使ってください、このコマンドはデータを直接読み出すことが可能です
(高速、省メモリ、メッセージで返すオブジェクトのサイズが小さいです)。

構文:

----
(id) infolist <name> [<pointer> [<arguments>]]
----

引数:

* 'name': 取得するインフォリストの名前
* 'pointer': ポインタ (任意)
* 'arguments': 引数 (任意)

例:

----
infolist buffer
----

[[command_nicklist]]
=== nicklist

1 つまたは全てのバッファから'ニックネームリスト' を要求。

Syntax:
構文:

----
(id) nicklist [<buffer>]
----

引数:

* 'buffer': ポインタ ('0x12345') またはバッファの完全な名前 (例:
  'core.weechat' または 'irc.freenode.#weechat')

例:

----
# 全てのバッファのニックネームリストを要求
nicklist

# irc.freenode.#weechat のニックネームリストを要求
nicklist irc.freenode.#weechat
----

[[command_input]]
=== input

バッファにデータを送信。

構文:

----
input <buffer> <data>
----

引数:

* 'buffer': ポインタ ('0x12345') またはバッファの完全な名前 (例:
  'core.weechat' または 'irc.freenode.#weechat')
* 'data': バッファに送信するデータ: '/'
   で始まる場合、バッファ内でコマンドとして実行されます、それ以外の場合、テキストはバッファの入力として送信されます。

例:

----
input core.weechat /help filter
input irc.freenode.#weechat hello!
----

[[command_sync]]
=== sync

_バージョン 0.4.1 で更新。_

更新を取得して 1 つまたは複数のバッファを同期。

[IMPORTANT]
バッファのデータ (行、...)
を要求した直後にこのコマンドを送信することをお勧めします。1
つのメッセージの中にこのコマンドを含める (改行文字 "\n" で区切る) ことで同時に送信できます。

構文:

----
sync [<buffer>[,<buffer>...] <option>[,<option>...]]
----

引数:

* 'buffer': ポインタ ('0x12345') またはバッファの完全な名前 (例:
  'core.weechat' または 'irc.freenode.#weechat');
  全てのバッファを指定するには "*" を使ってください
* 'options': 以下に挙げるキーワード、コンマ区切り ("*" に対するデフォルトは
  'buffers,upgrade,buffer,nicklist'、バッファに対するデフォルトは 'buffer,nicklist'):
** 'buffers': バッファに関するシグナルを受け取る (オープン/クローズ、移動、リネーム、
   マージ/アンマージ、隠す/隠さない); これは名前が "*" の場合のみ利用可能
   _(WeeChat バージョン 0.4.1 以上で利用可)_
** 'upgrade': WeeChat アップグレードに関するシグナルを受信 (アップグレード、アップグレードの終了);
   名前が "*" のバッファに対してのみ利用可能
   _(WeeChat バージョン 0.4.1 以上で利用可)_
** 'buffer': バッファに関するシグナルを受信
   (新しい行、型の変更、タイトルの変更、ローカル変数の追加/削除、'buffers'
   と同じバッファに関するシグナル) _(バージョン 0.4.1 で更新)_
** 'nicklist': 変更後にニックネームリストを受信

例:

----
# ニックネームリストを持つ全てのバッファを同期
# (3 つのコマンドは全て等価ですが、
# 将来のバージョンとの互換性を考慮して 1 つ目のコマンドを推奨します)
sync
sync *
sync * buffers,upgrade,buffer,nicklist

# コアバッファを同期
sync core.buffer

# #weechat チャンネルを同期、ニックネームリストは受信しない
sync irc.freenode.#weechat buffer

# 一般的なシグナル + #weechat チャンネルに対する全てのシグナルを取得
sync * buffers,upgrade
sync irc.freenode.#weechat
----

[[command_desync]]
=== desync

_バージョン 0.4.1 で更新。_

更新を中止して 1 つまたは複数のバッファの同期を中止。

[NOTE]
バッファの'オプション'
を削除します。バッファに対する一部のオプションがまだ有効な場合、クライアントはバッファに対するアップデートを受け取ります。

構文:

----
desync [<buffer>[,<buffer>...] <option>[,<option>...]]
----

引数:

* 'buffer': ポインタ ('0x12345') またはバッファの完全な名前 (例:
  'core.weechat' または 'irc.freenode.#weechat');
  全てのバッファを指定するには "*" を使ってください
* 'options': 以下に挙げるキーワード、コンマ区切り ("*" に対するデフォルトは
  'buffers,upgrade,buffer,nicklist'、バッファに対するデフォルトは 'buffer,nicklist'):
  値に関する詳しい情報は <<command_sync,sync コマンド>>をご覧ください

[NOTE]
buffer に "*" を指定した場合、(名前を使って) 同期されている他のバッファは同期状態が保存されます。 +
このため "sync *"、"sync irc.freenode.#weechat"、"desync *" の順に送信した場合、WeeChat
は #weechat チャンネルに対するアップデートを送信し続けます
(アップデートを止めるには、明示してこれを中止しなければいけません)。

例:

----
# ニックネームリストを持つ全てのバッファの同期を中止
# (3 つのコマンドは全て等価ですが、
# 将来のバージョンとの互換性を考慮して 1 つ目のコマンドを推奨します)
desync
desync *
desync * buffers,upgrade,buffer,nicklist

# #weechat チャンネルのニックネームリストの同期を中止 (バッファは同期する)
desync irc.freenode.#weechat nicklist

# #weechat チャンネルの同期を中止
desync irc.freenode.#weechat
----

[[command_test]]
=== test

テストコマンド: WeeChat は様々な種類のオブジェクトを返します。

このコマンドは WeeChat
が返すバイナリオブジェクトのデコーディングをテストする際に便利です。

[IMPORTANT]
このコマンドが返したポインタ値を絶対に使ってはいけません、ポインタ値は無効です。このコマンドを
WeeChat
が返すメッセージのデコーディングをテストする場合以外に使わないでください。

構文:

----
test
----

例:

----
test
----

返されるオブジェクト (以下の順番):

[width="80%",cols="^3,3m,5m",options="header"]
|===
| 型                | 型 (メッセージ中) | 値
| char              | chr               | 65 ("A")
| integer           | int               | 123456
| integer           | int               | -123456
| long              | lon               | 1234567890
| long              | lon               | -1234567890
| string            | str               | "a string"
| string            | str               | ""
| string            | str               | NULL
| buffer            | buf               | "buffer"
| buffer            | buf               | NULL
| pointer           | ptr               | 0x1234abcd
| pointer           | ptr               | NULL
| time              | tim               | 1321993456
| string の配列     | arr str           | [ "abc", "de" ]
| integer の配列    | arr int           | [ 123, 456, 789 ]
|===

[[command_ping]]
=== ping

_WeeChat バージョン 0.4.2 以上で利用可。_

WeeChat にメッセージ "_pong" と同じ引数を持つ返信 ping を送信。

このコマンドは WeeChat
との接続がまだ保持されいることの確認と応答時間を計測する場合に便利です。

構文:

----
ping [<arguments>]
----

例:

----
ping 1370802127000
----

[[command_quit]]
=== quit

'リレー' から切断。

構文:

----
quit
----

例:

----
quit
----

[[messages]]
== メッセージ (リレー → クライアント)

メッセージは以下のフォーマットでバイナリデータとして送信されます (サイズはバイト単位):

....
┌────────╥─────────────╥────╥────────┬──────────╥───────╥────────┬──────────┐
│ length ║ compression ║ id ║ type 1 │ object 1 ║  ...  ║ type N │ object N │
└────────╨─────────────╨────╨────────┴──────────╨───────╨────────┴──────────┘
 └──────┘ └───────────┘ └──┘ └──────┘ └────────┘         └──────┘ └────────┘
     4          1        ??      3        ??                 3        ??
 └────────────────────┘ └──────────────────────────────────────────────────┘
       ヘッダ (5)                        圧縮されたデータ (??)
 └─────────────────────────────────────────────────────────────────────────┘
                               'length' バイト
....

* 'length' (符号なし整数型): メッセージ全体のバイト数
  (このフィールドを含む)
* 'compression' (バイト型): フラグ:
** '0x00': これ以降のデータは圧縮されていません
** '0x01': これ以降のデータは 'zlib' で圧縮されています
* 'id' (文字列型): クライアントが送信した識別子 (コマンド名の前につけられる);
  コマンドに識別子が含まれない場合は空文字列でも可
  (内容を含まない長さゼロの文字列)
* 'type' (3 文字): 型の種類: 3 文字 (以下の表を参照)
* 'object': オブジェクト (以下の表を参照)

[[message_compression]]
=== 圧縮

'compression' フラグが 0x01 の場合、これ以降の*全ての* データは 'zlib'
で圧縮されているため、処理前に必ず展開してください。

[[message_identifier]]
=== 識別子

識別子 ('id') には 2 種類あります:

* 'クライアント' が送信する 'id': 'リレー' は 'id' を含む受信メッセージに対して同じ 'id' を付けて応答します。
* イベントの 'id': 一部のイベントで、'リレー' は 'クライアント' に向けて特別な、アンダースコアで始まる、'id'
  を含むメッセージを送信します (以下の表を参照)

WeeChat の予約識別子:

[width="100%",cols="5,5,3,4,7",options="header"]
|===
| 識別子 | 'sync' で受信 | 送信されるデータ |
  説明 | 推奨するクライアントの挙動

| _buffer_opened | buffers / buffer | hdata: buffer |
  バッファのオープン | バッファを開く

| _buffer_type_changed | buffers / buffer | hdata: buffer |
  バッファの種類変更 | バッファの種類を変更

| _buffer_moved | buffers / buffer | hdata: buffer |
  バッファの移動 | バッファを移動

| _buffer_merged | buffers / buffer | hdata: buffer |
  バッファのマージ | バッファをマージ

| _buffer_unmerged | buffers / buffer | hdata: buffer |
  バッファのアンマージ | バッファをアンマージ

| _buffer_hidden | buffers / buffer | hdata: buffer |
  バッファを隠す | バッファを隠す

| _buffer_unhidden | buffers / buffer | hdata: buffer |
  バッファを隠すことを止める | バッファを隠すことを止める

| _buffer_renamed | buffers / buffer | hdata: buffer |
  バッファのリネーム | バッファをリネーム

| _buffer_title_changed | buffers / buffer | hdata: buffer |
  バッファのタイトル変更 | バッファのタイトルを変更

| _buffer_localvar_added | buffers / buffer | hdata: buffer |
  ローカル変数の追加 | バッファに対するローカル変数を追加

| _buffer_localvar_changed | buffers / buffer | hdata: buffer |
  ローカル変数の変更 | バッファに対するローカル変数を変更

| _buffer_localvar_removed | buffers / buffer | hdata: buffer |
  ローカル変数を削除 | バッファからローカル変数を削除

| _buffer_closing | buffers / buffer | hdata: buffer |
  バッファのクローズ | バッファを閉じる

| _buffer_cleared | buffer | hdata: buffer |
  バッファのクリア | バッファをクリア

| _buffer_line_added | buffer | hdata: line |
  バッファへの行追加 | バッファに行を表示

| _nicklist | nicklist | hdata: nicklist_item |
  バッファのニックネームリスト | ニックネームリストを置換

| _nicklist_diff | nicklist | hdata: nicklist_item |
  バッファに対するニックネームの差分  | ニックネームリストを更新

| _pong | (常に) | string: ping arguments |
  "ping" に対する応答 | 応答時間の測定

| _upgrade | upgrade | (空) |
  WeeChat のアップグレード中 | WeeChat との同期を中止 (または切断)

| _upgrade_ended | upgrade | (空) |
  WeeChat のアップグレード終了 | WeeChat との同期および再同期
|===

[[message_buffer_opened]]
==== _buffer_opened

このメッセージは WeeChat が "buffer_opened"
シグナルを送信する際にクライアントに送られます。

hdata として送られるデータ:

[width="100%",cols="3m,2,10",options="header"]
|===
| 名前            | 型        | 説明
| number          | integer   | バッファ番号 (≥ 1)
| full_name       | string    | 完全な名前 (例: 'irc.freenode.#weechat')
| short_name      | string    | 短い名前 (例: '#weechat')
| nicklist        | integer   | バッファがニックネームリストを持つ場合 1、それ以外は 0
| title           | string    | バッファのタイトル
| local_variables | hashtable | ローカル変数
| prev_buffer     | pointer   | 前のバッファへのポインタ
| next_buffer     | pointer   | 次のバッファへのポインタ
|===

例: freenode の '#weechat' チャンネルに参加、新しいバッファは
'irc.freenode.#weechat':

[source,python]
----
id: '_buffer_opened'
hda:
  keys: {'number': 'int', 'full_name': 'str', 'short_name': 'str', 'nicklist': 'int',
         'title': 'str', 'local_variables': 'htb', 'prev_buffer': 'ptr', 'next_buffer': 'ptr'}
  path: ['buffer']
  item 1:
    __path: ['0x35a8a60']
    number: 3
    full_name: 'irc.freenode.#weechat'
    short_name: None
    nicklist: 0
    title: None
    local_variables: {'plugin': 'irc', 'name': 'freenode.#weechat'}
    prev_buffer: '0x34e7400'
    next_buffer: '0x0'
----

[[message_buffer_moved]]
==== _buffer_moved

このメッセージは WeeChat が "buffer_moved"
シグナルを送信する際にクライアントに送られます。

hdata として送られるデータ:

[width="100%",cols="3m,2,10",options="header"]
|===
| 名前        | 型      | 説明
| number      | integer | バッファ番号 (≥ 1)
| full_name   | string  | 完全な名前 (例: 'irc.freenode.#weechat')
| prev_buffer | pointer | 前のバッファへのポインタ
| next_buffer | pointer | 次のバッファへのポインタ
|===

例: バッファ 'irc.freenode.#weechat' を番号 2 に移動:

[source,python]
----
id: '_buffer_moved'
hda:
  keys: {'number': 'int', 'full_name': 'str', 'prev_buffer': 'ptr', 'next_buffer': 'ptr'}
  path: ['buffer']
  item 1:
    __path: ['0x34588c0']
    number: 2
    full_name: 'irc.freenode.#weechat'
    prev_buffer: '0x347b9f0'
    next_buffer: '0x3471bc0'
----

[[message_buffer_merged]]
==== _buffer_merged

このメッセージは WeeChat が "buffer_merged"
シグナルを送信する際にクライアントに送られます。

hdata として送られるデータ:

[width="100%",cols="3m,2,10",options="header"]
|===
| 名前        | 型      | 説明
| number      | integer | バッファ番号 (≥ 1)
| full_name   | string  | 完全な名前 (例: 'irc.freenode.#weechat')
| prev_buffer | pointer | 前のバッファへのポインタ
| next_buffer | pointer | 次のバッファへのポインタ
|===

例: バッファ 'irc.freenode.#weechat' をバッファ #2 とマージ:

[source,python]
----
id: '_buffer_merged'
hda:
  keys: {'number': 'int', 'full_name': 'str', 'prev_buffer': 'ptr', 'next_buffer': 'ptr'}
  path: ['buffer']
  item 1:
    __path: ['0x4db4c00']
    number: 2
    full_name: 'irc.freenode.#weechat'
    prev_buffer: '0x4cef9b0'
    next_buffer: '0x0'
----

[[message_buffer_unmerged]]
==== _buffer_unmerged

このメッセージは WeeChat が "buffer_unmerged"
シグナルを送信する際にクライアントに送られます。

hdata として送られるデータ:

[width="100%",cols="3m,2,10",options="header"]
|===
| 名前        | 型      | 説明
| number      | integer | バッファ番号 (≥ 1)
| full_name   | string  | 完全な名前 (例: 'irc.freenode.#weechat')
| prev_buffer | pointer | 前のバッファへのポインタ
| next_buffer | pointer | 次のバッファへのポインタ
|===

例: バッファ 'irc.freenode.#weechat' をアンマージ:

[source,python]
----
id: '_buffer_unmerged'
hda:
  keys: {'number': 'int', 'full_name': 'str', 'prev_buffer': 'ptr', 'next_buffer': 'ptr'}
  path: ['buffer']
  item 1:
    __path: ['0x4db4c00']
    number: 3
    full_name: 'irc.freenode.#weechat'
    prev_buffer: '0x4cef9b0'
    next_buffer: '0x0'
----

[[message_buffer_hidden]]
==== _buffer_hidden

_WeeChat バージョン 1.0 以上で利用可。_

このメッセージは WeeChat が "buffer_hidden"
シグナルを送信する際にクライアントに送られます。

hdata として送られるデータ:

[width="100%",cols="3m,2,10",options="header"]
|===
| 名前        | 型      | 説明
| number      | integer | バッファ番号 (≥ 1)
| full_name   | string  | 完全な名前 (例: 'irc.freenode.#weechat')
| prev_buffer | pointer | 前のバッファへのポインタ
| next_buffer | pointer | 次のバッファへのポインタ
|===

例: バッファ 'irc.freenode.#weechat' を隠す:

[source,python]
----
id: '_buffer_hidden'
hda:
  keys: {'number': 'int', 'full_name': 'str', 'prev_buffer': 'ptr', 'next_buffer': 'ptr'}
  path: ['buffer']
  item 1:
    __path: ['0x4db4c00']
    number: 2
    full_name: 'irc.freenode.#weechat'
    prev_buffer: '0x4cef9b0'
    next_buffer: '0x0'
----

[[message_buffer_unhidden]]
==== _buffer_unhidden

_WeeChat バージョン 1.0 以上で利用可。_

このメッセージは WeeChat が "buffer_unhidden"
シグナルを送信する際にクライアントに送られます。

hdata として送られるデータ:

[width="100%",cols="3m,2,10",options="header"]
|===
| 名前        | 型      | 説明
| number      | integer | バッファ番号 (≥ 1)
| full_name   | string  | 完全な名前 (例: 'irc.freenode.#weechat')
| prev_buffer | pointer | 前のバッファへのポインタ
| next_buffer | pointer | 次のバッファへのポインタ
|===

例: バッファ 'irc.freenode.#weechat' を隠すことを止める:

[source,python]
----
id: '_buffer_unhidden'
hda:
  keys: {'number': 'int', 'full_name': 'str', 'prev_buffer': 'ptr', 'next_buffer': 'ptr'}
  path: ['buffer']
  item 1:
    __path: ['0x4db4c00']
    number: 3
    full_name: 'irc.freenode.#weechat'
    prev_buffer: '0x4cef9b0'
    next_buffer: '0x0'
----

[[message_buffer_renamed]]
==== _buffer_renamed

このメッセージは WeeChat が "buffer_renamed"
シグナルを送信する際にクライアントに送られます。

hdata として送られるデータ:

[width="100%",cols="3m,2,10",options="header"]
|===
| 名前            | 型        | 説明
| number          | integer   | バッファ番号 (≥ 1)
| full_name       | string    | 完全な名前 (例: 'irc.freenode.#weechat')
| short_name      | string    | 短い名前 (例: '#weechat')
| local_variables | hashtable | ローカル変数
|===

例: プライベートバッファを 'FlashCode' から 'Flash2' にリネーム:

[source,python]
----
id: '_buffer_renamed'
hda:
  keys: {'number': 'int', 'full_name': 'str', 'short_name': 'str', 'local_variables': 'htb'}
  path: ['buffer']
  item 1:
    __path: ['0x4df7b80']
    number: 5
    full_name: 'irc.freenode.Flash2'
    short_name: 'Flash2'
    local_variables: {'server': 'freenode', 'plugin': 'irc', 'type': 'private',
                      'channel': 'FlashCode', 'nick': 'test', 'name': 'local.Flash2'}
----

[[message_buffer_title_changed]]
==== _buffer_title_changed

このメッセージは WeeChat が "buffer_title_changed"
シグナルを送信する際にクライアントに送られます。

hdata として送られるデータ:

[width="100%",cols="3m,2,10",options="header"]
|===
| 名前      | 型      | 説明
| number    | integer | バッファ番号 (≥ 1)
| full_name | string  | 完全な名前 (例: 'irc.freenode.#weechat')
| title     | string  | バッファのタイトル
|===

例: チャンネル '#weechat' のトピックを変更:

[source,python]
----
id: '_buffer_title_changed'
hda:
  keys: {'number': 'int', 'full_name': 'str', 'title': 'str'}
  path: ['buffer']
  item 1:
    __path: ['0x4a715d0']
    number: 3
    full_name: 'irc.freenode.#weechat'
    title: 'Welcome on #weechat!  https://weechat.org/'
----

[[message_buffer_cleared]]
==== _buffer_cleared

_WeeChat バージョン 1.0 以上で利用可。_

このメッセージは WeeChat が "buffer_cleared"
シグナルを送信する際にクライアントに送られます。

hdata として送られるデータ:

[width="100%",cols="3m,2,10",options="header"]
|===
| 名前      | 型      | 説明
| number    | integer | バッファ番号 (≥ 1)
| full_name | string  | 完全な名前 (例: 'irc.freenode.#weechat')
|===

例: バッファ 'irc.freenode.#weechat' をクリア:

[source,python]
----
id: '_buffer_cleared'
hda:
  keys: {'number': 'int', 'full_name': 'str'}
  path: ['buffer']
  item 1:
    __path: ['0x4a715d0']
    number: 3
    full_name: 'irc.freenode.#weechat'
----

[[message_buffer_type_changed]]
==== _buffer_type_changed

このメッセージは WeeChat が "buffer_type_changed"
シグナルを送信する際にクライアントに送られます。

hdata として送られるデータ:

[width="100%",cols="3m,2,10",options="header"]
|===
| 名前      | 型      | 説明
| number    | integer | バッファ番号 (≥ 1)
| full_name | string  | 完全な名前 (例: 'irc.freenode.#weechat')
| type      | integer | バッファの種類: 0 = フォーマット済み (デフォルト)、1 = 自由内容
|===

例: バッファ 'script.scripts' の種類をフォーマット済み (0) から自由内容
(1) に変更:

[source,python]
----
id: '_buffer_type_changed'
hda:
  keys: {'number': 'int', 'full_name': 'str', 'type': 'int'}
  path: ['buffer']
  item 1:
    __path: ['0x27c9a70']
    number: 4
    full_name: 'script.scripts'
    type: 1
----

[[message_buffer_localvar_added]]
==== _buffer_localvar_added

このメッセージは WeeChat が "buffer_localvar_added"
シグナルを送信する際にクライアントに送られます。

hdata として送られるデータ:

[width="100%",cols="3m,2,10",options="header"]
|===
| 名前            | 型        | 説明
| number          | integer   | バッファ番号 (≥ 1)
| full_name       | string    | 完全な名前 (例: 'irc.freenode.#weechat')
| local_variables | hashtable | ローカル変数
|===

例: 'irc.freenode.#weechat' にローカル変数 'test' を追加:

[source,python]
----
id='_buffer_localvar_added', objects:
hda:
  keys: {'number': 'int', 'full_name': 'str', 'local_variables': 'htb'}
  path: ['buffer']
  item 1:
    __path: ['0x4a73de0']
    number: 3
    full_name: 'irc.freenode.#weechat'
    local_variables: {'server': 'freenode', 'test': 'value', 'plugin': 'irc',
                      'type': 'channel', 'channel': '#weechat', 'nick': 'test',
                      'name': 'freenode.#weechat'}
----

[[message_buffer_localvar_changed]]
==== _buffer_localvar_changed

このメッセージは WeeChat が "buffer_localvar_changed"
シグナルを送信する際にクライアントに送られます。

hdata として送られるデータ:

[width="100%",cols="3m,2,10",options="header"]
|===
| 名前            | 型        | 説明
| number          | integer   | バッファ番号 (≥ 1)
| full_name       | string    | 完全な名前 (例: 'irc.freenode.#weechat')
| local_variables | hashtable | ローカル変数
|===

例: 'irc.freenode.#weechat' に含まれるローカル変数 'test' を更新:

[source,python]
----
id='_buffer_localvar_changed', objects:
hda:
  keys: {'number': 'int', 'full_name': 'str', 'local_variables': 'htb'}
  path: ['buffer']
  item 1:
    __path: ['0x4a73de0']
    number: 3
    full_name: 'irc.freenode.#weechat'
    local_variables: {'server': 'local', 'test': 'value2', 'plugin': 'irc',
                      'type': 'channel', 'channel': '#weechat', 'nick': 'test',
                      'name': 'freenode.#weechat'}
----

[[message_buffer_localvar_removed]]
==== _buffer_localvar_removed

このメッセージは WeeChat が "buffer_localvar_removed"
シグナルを送信する際にクライアントに送られます。

hdata として送られるデータ:

[width="100%",cols="3m,2,10",options="header"]
|===
| 名前            | 型        | 説明
| number          | integer   | バッファ番号 (≥ 1)
| full_name       | string    | 完全な名前 (例: 'irc.freenode.#weechat')
| local_variables | hashtable | ローカル変数
|===

例: 'irc.freenode.#weechat' からローカル変数 'test' を削除:

[source,python]
----
id: '_buffer_localvar_removed'
hda:
  keys: {'number': 'int', 'full_name': 'str', 'local_variables': 'htb'}
  path: ['buffer']
  item 1:
    __path: ['0x4a73de0']
    number: 3
    full_name: 'irc.freenode.#prout'
    local_variables: {'server': 'local', 'plugin': 'irc', 'type': 'channel',
                      'channel': '#weechat', 'nick': 'test', 'name': 'freenode.#weechat'}
----

[[message_buffer_line_added]]
==== _buffer_line_added

このメッセージは WeeChat が "buffer_line_added"
シグナルを送信する際にクライアントに送られます。

hdata として送られるデータ:

[width="100%",cols="3m,2,10",options="header"]
|===
| 名前         | 型               | 説明
| buffer       | pointer          | バッファへのポインタ
| date         | time             | メッセージの日付
| date_printed | time             | WeeChat メッセージを表示した日付
| displayed    | char             | メッセージが表示される場合は 1、メッセージがフィルタされる (隠される) 場合は 0
| highlight    | char             | 行がハイライト部分を含む場合は 1、それ以外は 0
| tags_array   | string の配列    | 行に対するタグのリスト
| prefix       | string           | プレフィックス
| message      | string           | メッセージ
|===

例: バッファ 'irc.freenode.#weechat' でニックネーム 'FlashCode' からの新しいメッセージ 'hello!':

[source,python]
----
id: '_buffer_line_added'
hda:
  keys: {'buffer': 'ptr', 'date': 'tim', 'date_printed': 'tim', 'displayed': 'chr',
         'highlight': 'chr', 'tags_array': 'arr', 'prefix': 'str', 'message': 'str'}
  path: ['line_data']
  item 1:
    __path: ['0x4a49600']
    buffer: '0x4a715d0'
    date: 1362728993
    date_printed: 1362728993
    displayed: 1
    highlight: 0
    tags_array: ['irc_privmsg', 'notify_message', 'prefix_nick_142', 'nick_FlashCode', 'log1']
    prefix: 'F06@F@00142FlashCode'
    message: 'hello!'
----

[[message_buffer_closing]]
==== _buffer_closing

このメッセージは WeeChat が "buffer_closing"
シグナルを送信する際にクライアントに送られます。

hdata として送られるデータ:

[width="100%",cols="3m,2,10",options="header"]
|===
| 名前      | 型      | 説明
| number    | integer | バッファ番号 (≥ 1)
| full_name | string  | 完全な名前 (例: 'irc.freenode.#weechat')
|===

例: WeeChat がバッファ 'irc.freenode.#weechat' を閉じる:

[source,python]
----
id: '_buffer_closing'
hda:
  keys: {'number': 'int', 'full_name': 'str'}
  path: ['buffer']
  item 1:
    __path: ['0x4a715d0']
    number: 3
    full_name: 'irc.freenode.#weechat'
----

[[message_nicklist]]
==== _nicklist

このメッセージはニックネームリストに対して巨大な更新 (グループおよびニックネームの追加/更新/変更)
が行われた場合にクライアントに送られます。このメッセージには完全なニックネームリストが含まれます。

ニックネームリストに対して小さな更新が行われた場合 (例えばニックネームを 1
つだけ追加)、識別子 '_nicklist_diff' を含むメッセージが送信されます (以下を参照)。

hdata として送られるデータ:

[width="100%",cols="3m,2,10",options="header"]
|===
| 名前         | 型      | 説明
| group        | char    | グループの場合 1、ニックネームの場合 0
| visible      | char    | グループおよびニックネームが表示される場合 1、それ以外は 0
| level        | integer | グループのレベル (ニックネームの場合 0)
| name         | string  | グループおよびニックネームの名前
| color        | string  | 名前の色
| prefix       | string  | プレフィックス (ニックネーム専用)
| prefix_color | string  | プレフィックスの色 (ニックネーム専用)
|===

例: バッファ 'irc.freenode.#weechat' のニックネームリスト:

[source,python]
----
id: '_nicklist'
hda:
  keys: {'group': 'chr', 'visible': 'chr', 'level': 'int', 'name': 'str', 'color': 'str',
         'prefix': 'str', 'prefix_color': 'str'}
  path: ['buffer', 'nicklist_item']
  item 1:
    __path: ['0x4a75cd0', '0x31e95d0']
    group: 1
    visible: 0
    level: 0
    name: 'root'
    color: None
    prefix: None
    prefix_color: None
  item 2:
    __path: ['0x4a75cd0', '0x41247b0']
    group: 1
    visible: 1
    level: 1
    name: '000|o'
    color: 'weechat.color.nicklist_group'
    prefix: None
    prefix_color: None
  item 3:
    __path: ['0x4a75cd0', '0x4a60d20']
    group: 0
    visible: 1
    level: 0
    name: 'FlashCode'
    color: '142'
    prefix: '@'
    prefix_color: 'lightgreen'
  item 4:
    __path: ['0x4a75cd0', '0x4aafaf0']
    group: 1
    visible: 1
    level: 1
    name: '001|v'
    color: 'weechat.color.nicklist_group'
    prefix: None
    prefix_color: None
  item 5:
    __path: ['0x4a75cd0', '0x4a48d80']
    group: 1
    visible: 1
    level: 1
    name: '999|...'
    color: 'weechat.color.nicklist_group'
    prefix: None
    prefix_color: None
  item 6:
    __path: ['0x4a75cd0', '0x4a5f560']
    group: 0
    visible: 1
    level: 0
    name: 'test'
    color: 'weechat.color.chat_nick_self'
    prefix: ' '
    prefix_color: ''
----

[[message_nicklist_diff]]
==== _nicklist_diff

_WeeChat バージョン 0.4.1 以上で利用可。_

このメッセージはニックネームリストに対して小さな更新 (グループおよびニックネームの追加/更新/変更)
が行われた場合にクライアントに送られます。このメッセージにはニックネームリストの差分が含まれます
(古いニックネームリストと新しいニックネームリストの差分)。

hdata として送られるデータ:

[width="100%",cols="3m,2,10",options="header"]
|===
| 名前         | 型      | 説明
| _diff        | char    | 差分の種類 (下を参照)
| group        | char    | グループの場合 1、ニックネームの場合 0
| visible      | char    | グループおよびニックネームが表示される場合 1、それ以外は 0
| level        | integer | グループのレベル (ニックネームの場合 0)
| name         | string  | グループおよびニックネームの名前
| color        | string  | 名前の色
| prefix       | string  | プレフィックス (ニックネーム専用)
| prefix_color | string  | プレフィックスの色 (ニックネーム専用)
|===

'_diff' のとりうる値:

* `^`: 親グループ:
  これの後に続くグループまたはニックネームに関する操作はこのグループに対して行う
* `+`: このグループおよびニックネームを親グループに追加
* `-`: このグループおよびニックネームを親グループから削除
* `*`: このグループおよびニックネームを親グループで更新

例: ニックネーム 'master' を '000|o' (IRC チャンネルのチャンネルオペレータ)
グループに追加、ニックネーム 'nick1' と 'nick2' を '999|...' に追加
(IRC チャンネルの一般ユーザ):

[source,python]
----
id: '_nicklist_diff'
hda:
  keys: {'_diff': 'chr', 'group': 'chr', 'visible': 'chr', 'level': 'int', 'name': 'str',
         'color': 'str', 'prefix': 'str', 'prefix_color': 'str'}
  path: ['buffer', 'nicklist_item']
  item 1:
    __path: ['0x46f2ee0', '0x343c9b0']
    _diff: 94 ('^')
    group: 1
    visible: 1
    level: 1
    name: '000|o'
    color: 'weechat.color.nicklist_group'
    prefix: None
    prefix_color: None
  item 2:
    __path: ['0x46f2ee0', '0x47e7f60']
    _diff: 43 ('+')
    group: 0
    visible: 1
    level: 0
    name: 'master'
    color: 'magenta'
    prefix: '@'
    prefix_color: 'lightgreen'
  item 3:
    __path: ['0x46f2ee0', '0x46b8e70']
    _diff: 94 ('^')
    group: 1
    visible: 1
    level: 1
    name: '999|...'
    color: 'weechat.color.nicklist_group'
    prefix: None
    prefix_color: None
  item 4:
    __path: ['0x46f2ee0', '0x3dba240']
    _diff: 43 ('+')
    group: 0
    visible: 1
    level: 0
    name: 'nick1'
    color: 'green'
    prefix: ' '
    prefix_color: ''
  item 5:
    __path: ['0x46f2ee0', '0x3c379d0']
    _diff: 43 ('+')
    group: 0
    visible: 1
    level: 0
    name: 'nick2'
    color: 'lightblue'
    prefix: ' '
    prefix_color: ''
----

[[message_pong]]
==== _pong

_WeeChat バージョン 0.4.2 以上で利用可。_

このメッセージは 'リレー' が "ping" メッセージを受信する際にクライアントに送られます。

文字列として送られるデータ: "ping" メッセージで受信した引数。

クライアントは応答時間を測定し、応答時間が長い場合は切断することを推奨します。

[[message_upgrade]]
==== _upgrade

_WeeChat バージョン 0.3.8 以上で利用可。_

このメッセージは WeeChat がアップグレード処理を始める際にクライアントに送られます。

メッセージにデータは含まれません。

クライアントは WeeChat との同期を中止するか
('desync' コマンドを送信)、WeeChat から切断することを推奨します
(これはアップグレードの後はすべてのポインタが変わるからです)。

[NOTE]
WeeChat のアップグレード中、ソケットは開いたままです
(ただし SSL を使っている場合は閉じられます)。

[[message_upgrade_ended]]
==== _upgrade_ended

_WeeChat バージョン 0.3.8 以上で利用可。_

このメッセージは WeeChat
がアップグレード処理を終えた際にクライアントに送られます。

メッセージにデータは含まれません。

クライアントは WeeChat との同期を再開することを推奨します:
クライアントを開始して 'init' 以降に送信したすべてのコマンドを再送信。

[[objects]]
=== オブジェクト

オブジェクトは 'type' と呼ばれる 3 文字で特定されます。以下の種類が使われます:

[width="100%",cols="^2m,5,10",options="header"]
|===
| 型   | 値                    | 長さ
| chr  | 符号付文字            | 1 バイト
| int  | 符号付整数            | 4 バイト
| lon  | 符号付長整数          | 1 バイト + 文字列で表現した整数の長さ
| str  | 文字列                | 4 バイト + 文字列の長さ (最後の '\0' を含まない)
| buf  | バッファのバイト数    | 4 バイト + データの長さ
| ptr  | ポインタ              | 1 バイト + 文字列で表現したポインタの長さ
| tim  | 時間                  | 1 バイト + 文字列で表現した時間の長さ
| htb  | ハッシュテーブル      | 可変
| hda  | hdata の内容          | 可変
| inf  | インフォ: 名前 + 内容 | 可変
| inl  | インフォリストの内容  | 可変
| arr  | オブジェクトの配列    | 3 バイト (型) + オブジェクトの数 + データ
|===

[[object_char]]
==== 符号付文字

1 つの符号付文字は 1 バイトとして保存されます。

例:

....
┌────┐
│ 41 │ ────► 65 (0x41: "A")
└────┘
....

[[object_integer]]
==== 符号付整数

1 つの符号付整数は 4 バイトとして保存され、ビッグエンディアンフォーマットでエンコードされています
(データは上位バイトを先頭にして並べられています)。

範囲: -2147483648 から 2147483647。

例:

....
┌────┬────┬────┬────┐
│ 00 │ 01 │ E2 │ 40 │ ────► 123456
└────┴────┴────┴────┘

┌────┬────┬────┬────┐
│ FF │ FE │ 1D │ C0 │ ────► -123456
└────┴────┴────┴────┘
....

[[object_long_integer]]
==== 符号付長整数

1 つの符号付長整数は文字列としてエンコードされています、文字列の長さは 1 バイトで表現されています。

範囲: -9223372036854775808 から 9223372036854775807。

例:

....
┌────╥────┬────┬────┬────┬────┬────┬────┬────┬────┬────┐
│ 0A ║ 31 │ 32 │ 33 │ 34 │ 35 │ 36 │ 37 │ 38 │ 39 │ 30 │ ────► 1234567890
└────╨────┴────┴────┴────┴────┴────┴────┴────┴────┴────┘
 └──┘ └───────────────────────────────────────────────┘
length '1'  '2'  '3'  '4'  '5'  '6'  '7'  '8'  '9'  '0'

┌────╥────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┐
│ 0B ║ 2D │ 31 │ 32 │ 33 │ 34 │ 35 │ 36 │ 37 │ 38 │ 39 │ 30 │ ────► -1234567890
└────╨────┴────┴────┴────┴────┴────┴────┴────┴────┴────┴────┘
 └──┘ └────────────────────────────────────────────────────┘
length '-'  '1'  '2'  '3'  '4'  '5'  '6'  '7'  '8'  '9'  '0'
....

[[object_string]]
==== 文字列

1 つの文字列はその長さ (4 バイト表現した整数) + 文字列の内容 (最後の '\0' を除く) で表現されています。

例:

....
┌────┬────┬────┬────╥────┬────┬────┬────┬────┐
│ 00 │ 00 │ 00 │ 05 ║ 68 │ 65 │ 6C │ 6C │ 6F │ ────► "hello"
└────┴────┴────┴────╨────┴────┴────┴────┴────┘
 └─────────────────┘ └──────────────────────┘
       length         'h'  'e'  'l'  'l'  'o'
....

空文字列を表現するには長さをゼロにしてください:

....
┌────┬────┬────┬────┐
│ 00 │ 00 │ 00 │ 00 │ ────► ""
└────┴────┴────┴────┘
 └─────────────────┘
       length
....

'NULL' 文字列 (C 言語の NULL ポインタ) を表現するにはの長さを -1 にしてください:

....
┌────┬────┬────┬────┐
│ FF │ FF │ FF │ FF │ ────► NULL
└────┴────┴────┴────┘
 └─────────────────┘
       length
....

[[object_buffer]]
==== バッファ

<<object_string,string>> と同じフォーマット; 内容は単純なバイトの配列。

[[object_pointer]]
==== ポインタ

1 つのポインタは文字列 (16 進数) としてエンコードされています、文字列の長さは 1 バイトで表現されています。

例:

....
┌────╥────┬────┬────┬────┬────┬────┬────┬────┬────┐
│ 09 ║ 31 │ 61 │ 32 │ 62 │ 33 │ 63 │ 34 │ 64 │ 35 │ ────► 0x1a2b3c4d5
└────╨────┴────┴────┴────┴────┴────┴────┴────┴────┘
 └──┘ └──────────────────────────────────────────┘
length '1'  'a'  '2'  'b'  '3'  'c'  '4'  'd'  '5'
....

'NULL' ポインタを表現するには長さを 1 で値を 0 にしてください:

....
┌────╥────┐
│ 01 ║ 00 │ ────► NULL (0x0)
└────╨────┘
 └──┘ └──┘
length  0
....

[[object_time]]
==== 時間

1 つの時間 (秒数) は文字列としてエンコードされています、文字列の長さは 1 バイトで表現されています。

例:

....
┌────╥────┬────┬────┬────┬────┬────┬────┬────┬────┬────┐
│ 0A ║ 31 │ 33 │ 32 │ 31 │ 39 │ 39 │ 33 │ 34 │ 35 │ 36 │ ────► 1321993456
└────╨────┴────┴────┴────┴────┴────┴────┴────┴────┴────┘
 └──┘ └───────────────────────────────────────────────┘
length '1'  '3'  '2'  '1'  '9'  '9'  '3'  '4'  '5'  '6'
....

[[object_hashtable]]
==== ハッシュテーブル

1 つのハッシュテーブルにはキーの種類、値の種類、ハッシュテーブルに含まれるアイテムの数
(1 バイト表現の整数)、アイテムのキーと値が含まれています

....
┌───────────┬─────────────┬───────╥───────┬─────────╥─────╥───────┬─────────┐
│ type_keys │ type_values │ count ║ key 1 │ value 1 ║ ... ║ key N │ value N │
└───────────┴─────────────┴───────╨───────┴─────────╨─────╨───────┴─────────┘
....

例:

....
┌─────┬─────┬───╥──────┬─────╥──────┬─────┐
│ str │ str │ 2 ║ key1 │ abc ║ key2 │ def │ ────► { 'key1' => 'abc',
└─────┴─────┴───╨──────┴─────╨──────┴─────┘         'key2' => 'def' }
 └───┘ └───┘ └─┘ └──────────┘ └──────────┘
 type  type count   item 1       item 2
 keys values
....

[[object_hdata]]
==== Hdata

1 つの 'hdata' には hdata 名を含むパス、キーのリスト、オブジェクトセットの数、オブジェクトセット
(ポインタのパス、オブジェクト) が含まれています。

....
┌────────┬──────┬───────╥────────┬─────────────────────╥──
│ h-path │ keys │ count ║ p-path │ value 1 ... value N ║ ...
└────────┴──────┴───────╨────────┴─────────────────────╨──

   ──╥────────┬─────────────────────╥─────┐
 ... ║ p-path │ value 1 ... value N ║ ... │
   ──╨────────┴─────────────────────╨─────┘
....

* 'h-path' (文字列): hdata にアクセスする際に使うパス (例:
  'buffer/lines/line/line_data'); 返される hdata はパスの最後の要素です
* 'keys' (文字列): 'key:type' のリスト (コンマ区切り) を含む文字列,
  例: 'number:int,name:str'
* 'count' (文字列): オブジェクトセットの数
* 'p-path': オブジェクトへのポインタを含むパス
  (ポインタの数はパスに含まれる要素の数)
* 'values': 値のリスト (値の数は hdata
  で返されるキーの数)

2 つのバッファ (weechat コアと freenode サーバ) と
2 つのキー ('number' と 'full_name') を持つ hdata の例:

....
# コマンド
hdata buffer:gui_buffers(*) number,full_name

# 応答
┌────────┬──────────────────────────┬───╥──
│ buffer │ number:int,full_name:str │ 2 ║ ...
└────────┴──────────────────────────┴───╨──
 └──────┘ └────────────────────────┘ └─┘
  h-path          keys              count

   ──╥─────────┬───┬──────────────╥─────────┬───┬────────────────────┐
 ... ║ 0x12345 │ 1 │ core.weechat ║ 0x6789a │ 2 │irc.server.freenode │
   ──╨─────────┴───┴──────────────╨─────────┴───┴────────────────────┘
      └──────────────────────────┘ └────────────────────────────────┘
               buffer 1                        buffer 2
....

コアバッファの行を含む hdata の例:

....
# コマンド
hdata buffer:gui_buffers(*)/lines/first_line(*)/data

# 応答
┌─────────────────────────────┬─────┬────╥──
│ buffer/lines/line/line_data │ ... │ 50 ║ ...
└─────────────────────────────┴─────┴────╨──
 └───────────────────────────┘ └───┘ └──┘
      h-path (hdata names)     keys  count

   ──╥───────────┬───────────┬───────────┬───────╥──
 ... ║ 0x23cf970 │ 0x23cfb60 │ 0x23d5f40 │ ..... ║ ...
   ──╨───────────┴───────────┴───────────┴───────╨──
      └─────────────────────────────────┘ └─────┘
               p-path (pointers)          objects
      └─────────────────────────────────────────┘
                         line 1

   ──╥───────────┬───────────┬───────────┬───────╥──────────────┐
 ... ║ 0x23cf970 │ 0x23cfb60 │ 0x23d6110 │ ..... ║ ............ │
   ──╨───────────┴───────────┴───────────┴───────╨──────────────┘
      └─────────────────────────────────┘ └─────┘
               p-path (pointers)          objects
      └─────────────────────────────────────────┘ └────────────┘
                         line 2                     lines 3-50
....

ニックネームリストを含む hdata の例:

....
# コマンド
nicklist

# 応答
┌───────────────────┬──
│ buffer/nick_group │ ...
└───────────────────┴──
 └─────────────────┘
        h-path

   ──╥───────────────────────────────────────────────────────────┬────╥──
 ... ║ group:chr,visible:chr,name:str,color:str,prefix:str,(...) │ 12 ║ ...
   ──╨───────────────────────────────────────────────────────────┴────╨──
      └─────────────────────────────────────────────────────────┘ └──┘
                                 keys                             count

   ──╥─────────┬─────────┬───┬───┬──────┬─┬─┬─┬───╥──
 ... ║ 0x12345 │ 0x6789a │ 1 │ 0 │ root │ │ │ │ 0 ║ ...
   ──╨─────────┴─────────┴───┴───┴──────┴─┴─┴─┴───╨──
      └─────────────────┘ └──────────────────────┘
             p-path               objects
      └──────────────────────────────────────────┘
                  group (nicklist root)

   ──╥─────────┬─────────┬───┬───┬───────┬─┬─┬─┬───╥──
 ... ║ 0x123cf │ 0x678d4 │ 1 │ 0 │ 000|o │ │ │ │ 1 ║ ...
   ──╨─────────┴─────────┴───┴───┴───────┴─┴─┴─┴───╨──
      └─────────────────┘ └───────────────────────┘
             p-path                objects
      └───────────────────────────────────────────┘
                    group (channel ops)

   ──╥─────────┬─────────┬───┬───┬──────────┬──────┬───┬────────────┬───╥──
 ... ║ 0x128a7 │ 0x67ab2 │ 0 │ 1 │ ChanServ │ blue │ @ │ lightgreen │ 0 ║ ...
   ──╨─────────┴─────────┴───┴───┴──────────┴──────┴───┴────────────┴───╨──
      └─────────────────┘ └────────────────────────────────────────────┘
             p-path                          objects
      └────────────────────────────────────────────────────────────────┘
                               nick (@ChanServ)
....

[[object_info]]
==== インフォ

1 つの'インフォ' は名前と値を含んでいます (両方とも文字列)。

....
┌──────┬───────┐
│ name │ value │
└──────┴───────┘
....

* 'name' (文字列): インフォの名前
* 'value' (文字列): 値

'version' インフォの例:

....
┌─────────┬───────────────────┐
│ version │ WeeChat 0.3.7-dev │
└─────────┴───────────────────┘
....

[[object_infolist]]
==== インフォリスト

1 つの'インフォリスト' は名前、アイテムの数、アイテム
(変数のセット) を含んでいます。

....
┌──────┬───────╥────────╥─────╥────────┐
│ name │ count ║ item 1 ║ ... ║ item N │
└──────┴───────╨────────╨─────╨────────┘
....

アイテムとは:

....
┌───────╥────────┬────────┬─────────╥─────╥────────┬────────┬─────────┐
│ count ║ name 1 │ type 1 │ value 1 ║ ... ║ name N │ type N │ value N │
└───────╨────────┴────────┴─────────╨─────╨────────┴────────┴─────────┘
....

* 'name' (文字列): インフォリストの名前 ('buffer'、'window'、'bar'、...)
* 'count' (整数): アイテムの数
* 'item':
** 'count': アイテムに含まれる変数の数
** 'name': 変数の名前
** 'type': 変数の型 ('int'、'str'、...)
** 'value': 変数の値

2 つのバッファ (weechat コアと freenode サーバ) を持つインフォリストの例:

....
# コマンド
infolist buffer

# 応答
┌────────┬───╥────┬─────────┬─────┬─────────┬─────╥──
│ buffer │ 2 ║ 42 │ pointer │ ptr │ 0x12345 │ ... ║ ...
└────────┴───╨────┴─────────┴─────┴─────────┴─────╨──
 └──────┘ └─┘ └──────────────────────────────────┘
   name  count              item 1

   ──╥────┬─────────┬─────┬─────────┬─────┐
 ... ║ 42 │ pointer │ ptr │ 0x6789a │ ... │
   ──╨────┴─────────┴─────┴─────────┴─────┘
      └──────────────────────────────────┘
                    item 2
....

[[object_array]]
==== 配列

1 つの配列は型 (3 バイト) + オブジェクトの数 (4 バイト表現の整数) + データからなります。

2 つの文字列を持つ配列の例:

....
┌─────╥────┬────┬────┬────╥────┬────┬────┬────╥──
│ str ║ 00 │ 00 │ 00 │ 02 ║ 00 │ 00 │ 00 │ 03 ║ ...
└─────╨────┴────┴────┴────╨────┴────┴────┴────╨──
 └───┘ └─────────────────┘ └─────────────────┘
 type   number of strings        length

   ──╥────┬────┬────╥────┬────┬────┬────╥────┬────┐
 ... ║ 61 │ 62 │ 63 ║ 00 │ 00 │ 00 │ 02 ║ 64 │ 65 │ ────► [ "abc", "de" ]
   ──╨────┴────┴────╨────┴────┴────┴────╨────┴────┘
      └────────────┘ └─────────────────┘ └───────┘
       'a'  'b'  'c'       length         'd'  'e'
....

3 つの整数を持つ配列の例:

....
┌─────╥────┬────┬────┬────╥────┬────┬────┬────╥──
│ int ║ 00 │ 00 │ 00 │ 03 ║ 00 │ 00 │ 00 │ 7B ║ ...
└─────╨────┴────┴────┴────╨────┴────┴────┴────╨──
 └───┘ └─────────────────┘ └─────────────────┘
 type   number of integers      123 (0x7B)

   ──╥────┬────┬────┬────╥────┬────┬────┬────┐
 ... ║ 00 │ 00 │ 01 │ C8 ║ 00 │ 00 │ 03 │ 15 │ ────► [ 123, 456, 789 ]
   ──╨────┴────┴────┴────╨────┴────┴────┴────┘
      └─────────────────┘ └─────────────────┘
          456 (0x1C8)         789 (0x315)
....

'NULL' 配列:

....
┌─────╥────┬────┬────┬────┐
│ str ║ 00 │ 00 │ 00 │ 00 │ ────► NULL
└─────╨────┴────┴────┴────┘
 └───┘ └─────────────────┘
 type   number of strings
....

[[typical_session]]
== 典型的なセッション

....
    ┌──────────────┐                  ┌────────┐                  ┌─────────┐
    │ クライアント ├ ─(ネットワーク)─ ┤ リレー ├──────────────────┤ WeeChat │
    └──────────────┘                  └────────┘                  └─────────┘
         ║                                 ║                           ║
         ╟───────────────────────────────► ║                           ║
         ║ ソケットをオープン              ║ クライアントを追加        ║
         ║                                 ║                           ║
         ╟───────────────────────────────► ║                           ║
         ║ cmd: init password=xxx,...      ║ クライアントを初期化/許可 ║
         ║                                 ║                           ║
         ╟───────────────────────────────► ║                           ║
         ║ cmd: hdata buffer ...           ╟─────────────────────────► ║
         ║      sync ...                   ║ hdata の要求              ║ hdata
         ║                                 ║                           ║ の値を読み出し
         ║                                 ║ ◄─────────────────────────╢
         ║ ◄───────────────────────────────╢                     hdata ║
バッファ ║                 msg: hda buffer ║                           ║
  を作成 ║                                 ║                           ║
         ║            ........             ║           ........        ║
         ║                                 ║                           ║
         ╟───────────────────────────────► ║                           ║
         ║ cmd: input ...                  ╟─────────────────────────► ║
         ║                                 ║ バッファにデータを送信    ║ バッファに
         ║                                 ║                           ║ データを送信
         ║            ........             ║           ........        ║
         ║                                 ║                           ║ シグナル
         ║                                 ║ ◄─────────────────────────╢ の受信
         ║ ◄───────────────────────────────╢              シグナル XXX ║ (リレー
バッファ ║          msg: id: "_buffer_..." ║                           ║ がフック)
  を更新 ║                                 ║                           ║
         ║            ........             ║           ........        ║
         ║                                 ║                           ║
         ╟───────────────────────────────► ║                           ║
         ║ cmd: ping ...                   ║                           ║
         ║                                 ║                           ║
         ║ ◄───────────────────────────────╢                           ║
    応答 ║            msg: id: "_pong" ... ║                           ║
    時間 ║                                 ║                           ║
  を計測 ║            ........             ║           ........        ║
         ║                                 ║                           ║
         ╟───────────────────────────────► ║                           ║
         ║ cmd: quit                       ║ クライアントを切断        ║
         ║                                 ║                           ║
....
