# 画面設計書 16-RSS Reader

## 概要

本ドキュメントは、Doom EmacsにおけるRSS Reader画面の設計仕様を定義するものである。elfeedパッケージを利用したRSSフィード購読機能について、その2ペイン構成、記事表示、およびワークスペース連携を記載する。

### 本画面の処理概要

RSS Reader画面は、RSSフィードを購読し、記事一覧と記事本文を2ペイン形式で表示する機能である。

**業務上の目的・背景**：技術ブログ、ニュースサイト、プロジェクト更新情報などを効率的に購読したいユーザー向けに、Emacs内でRSSリーダー機能を提供する。専用のRSSリーダーアプリを別途起動することなく、エディタ内で情報収集が可能。org-modeファイルでのフィード管理（elfeed-org）により、フィードの整理やタグ付けが容易。

**画面へのアクセス方法**：`=rss`コマンドでRSSリーダーを起動。workspacesモジュール有効時は専用ワークスペース（`*rss*`）で開かれる。直接`elfeed`コマンドでも起動可能。

**主要な操作・処理内容**：
1. フィード記事一覧の表示と検索
2. 記事本文の表示（HTMLレンダリング）
3. 記事の既読/未読管理
4. フィードの更新
5. YouTube動画との連携（+youtubeフラグ）

**画面遷移**：`=rss`で記事一覧（elfeed-search-mode）を開き、記事を選択すると下部ペインに記事詳細（elfeed-show-mode）が表示される。ナビゲーションキーで記事間を移動可能。

**権限による表示制御**：本機能に権限による表示制御はない。全ユーザーが同一の機能を利用可能である。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 83 | RSSリーダー | 主機能 | elfeedによるRSSフィード読み取り |

## 画面種別

一覧・詳細（2ペイン構成）

## URL/ルーティング

Emacsモード: `elfeed-search-mode`, `elfeed-show-mode`
バッファ名: `*elfeed-search*`, `*elfeed-entry*`
コマンド: `=rss`, `elfeed`

## 入出力項目

| 項目名 | 入力/出力 | データ型 | 説明 |
|--------|----------|---------|------|
| フィードURL | 入力 | URL | 購読するRSSフィードのURL |
| フィルター文字列 | 入力 | 文字列 | 記事絞り込み条件 |
| 記事一覧 | 出力 | リスト | フィード記事のリスト |
| 記事本文 | 出力 | HTML | レンダリングされた記事内容 |
| 既読/未読状態 | 出力 | タグ | 記事の読了状態 |

## 表示項目

### 記事一覧画面（elfeed-search-mode）

| 項目名 | 表示位置 | 説明 |
|--------|---------|------|
| 日付 | 左側 | 記事の公開日 |
| タイトル | 中央 | 記事タイトル |
| フィード名 | 右側 | フィードの名前 |
| タグ | 右側 | 記事に付与されたタグ |

### 記事詳細画面（elfeed-show-mode）

| 項目名 | 表示位置 | 説明 |
|--------|---------|------|
| タイトル | 上部 | 記事タイトル |
| メタ情報 | 上部 | 公開日、フィード名、リンク |
| 本文 | 中央 | HTMLレンダリングされた記事本文 |
| 画像 | 本文内 | スライス表示された画像（スクロール最適化） |

## イベント仕様

### 1-RSSリーダー起動

`=rss`コマンドを実行すると、以下の処理が行われる：
1. workspacesモジュール有効時: 専用ワークスペース（`*rss*`）を作成/切り替え
2. 無効時: 現在のウィンドウ構成を保存し、全ウィンドウを削除
3. `elfeed`コマンドを実行して記事一覧を表示

### 2-記事選択

記事一覧でRETキーを押すと、`+rss/open`が実行され：
1. 選択した記事のunreadタグを削除（既読化）
2. 記事一覧の表示を更新
3. 下部ペイン（75%サイズ）に記事詳細を表示

### 3-次/前の記事へ移動

- `next-buffer`（リマップ）: `+rss/next`で次の記事を表示
- `previous-buffer`（リマップ）: `+rss/previous`で前の記事を表示

### 4-記事リンクのコピー

`gc`キーで`+rss/copy-link`を実行し、現在の記事のURLをクリップボードにコピー。

### 5-フィード更新

`r`キーで`elfeed-search-update--force`を実行し、全フィードを再取得。

### 6-記事をブラウザで開く

`M-RET`で`elfeed-search-browse-url`を実行し、記事を外部ブラウザで開く。

### 7-RSSリーダー終了

`q`キーで`elfeed-kill-buffer`を実行。検索バッファが閉じられると`+rss-cleanup-h`が実行され、関連バッファとワークスペースがクリーンアップされる。

## データベース更新仕様

elfeedは独自のデータベースを使用する：

| 操作 | 対象 | 説明 |
|-----|------|------|
| 記事取得 | elfeed-db-directory | フィードデータの永続化 |
| 既読/未読 | タグシステム | unreadタグの追加/削除 |
| 添付ファイル | elfeed-enclosure-default-dir | ダウンロードファイルの保存 |

データベースパス: `~/.doom.d/data/elfeed/db/`
添付ファイルパス: `~/.doom.d/data/elfeed/enclosures/`

## メッセージ仕様

| メッセージ種別 | メッセージ内容 | 表示条件 |
|--------------|--------------|---------|
| コピー通知 | `Copied {url} to clipboard` | +rss/copy-link実行時 |
| 警告 | `elfeed-org: ignoring {file} because it can't be read` | org設定ファイルが見つからない場合 |

## 例外処理

| 例外状態 | 処理内容 |
|---------|---------|
| org設定ファイルなし | 該当ファイルをスキップし警告を表示 |
| フィード取得エラー | エラーをログに記録、他のフィードは継続 |
| 死んだフィード検出 | `+rss-dead-feeds`関数で1年以上更新のないフィードを検出可能 |

## 備考

- elfeedパッケージはRSSフィード取得とデータベース管理を担当
- elfeed-orgはorg-modeファイルでのフィード定義を担当（+orgフラグ）
- elfeed-goodiesはUI拡張を担当
- elfeed-tubeはYouTubeフィード連携を担当（+youtubeフラグ）
- 画像は自動的にスライス表示され、スクロールが最適化される（`+rss-enable-sliced-images`）
- 記事詳細ペインは選択後にフォーカス、自動クローズなし
- shr-max-image-proportionは0.8に設定（画像が画面幅の80%を超えない）

---

## コードリーディングガイド

本画面を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: データ構造を理解する

RSSリーダーの設定変数とデータディレクトリを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | config.el | `modules/app/rss/config.el` | 7-15行目: カスタム変数定義 |

**読解のコツ**: `+rss-`プレフィックスの変数がDoom独自設定、`elfeed-`プレフィックスがelfeedパッケージ設定。

#### Step 2: エントリーポイントを理解する

elfeedパッケージの基本設定を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | config.el | `modules/app/rss/config.el` | 21-67行目: elfeed設定 |

**主要処理フロー**:
1. **24-25行目**: データベースと添付ファイルのパス設定
2. **27-30行目**: デフォルトフィルター、エントリー表示関数の設定
3. **32-34行目**: ポップアップルール設定（75%サイズ）

#### Step 3: 記事表示のカスタマイズを理解する

記事詳細表示の最適化を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | config.el | `modules/app/rss/config.el` | 43-53行目: 表示最適化 |
| 3-2 | autoload.el | `modules/app/rss/autoload.el` | 73-82行目: +rss-elfeed-wrap-h |

**主要処理フロー**:
- **44行目**: `+rss-elfeed-wrap-h`でテキスト折り返しを設定
- **50-53行目**: 画像スライス表示の設定

#### Step 4: キーバインドを理解する

ナビゲーションとアクションのキーバインドを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | config.el | `modules/app/rss/config.el` | 56-67行目: キーバインド設定 |

**主要処理フロー**:
- **57-59行目**: next/previous-bufferのリマップ
- **61-67行目**: Evil連携キーバインド

#### Step 5: autoload関数を理解する

RSSリーダーの起動と記事操作を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 5-1 | autoload.el | `modules/app/rss/autoload.el` | 5-23行目: =rss関数 |
| 5-2 | autoload.el | `modules/app/rss/autoload.el` | 35-60行目: +rss/open, next, previous |

**主要処理フロー**:
- **9-19行目**: workspacesモード連携
- **36-42行目**: `+rss/open`で記事を既読化して表示
- **44-60行目**: 次/前の記事へ移動

#### Step 6: クリーンアップ処理を理解する

終了時のリソース解放を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 6-1 | autoload.el | `modules/app/rss/autoload.el` | 91-116行目: +rss-cleanup-h |

**主要処理フロー**:
- **95行目**: 終了時にelfeed-db-compactを実行
- **99-109行目**: 関連バッファをすべて削除
- **110-116行目**: ワークスペースまたはウィンドウ構成を復元

### プログラム呼び出し階層図

```
=rss
    │
    ├─ [workspacesモード有効時]
    │      ├─ +workspace-switch "*rss*" t
    │      ├─ doom/switch-to-scratch-buffer
    │      ├─ elfeed
    │      └─ +workspace/display
    │
    └─ [workspacesモード無効時]
           ├─ current-window-configuration (保存)
           ├─ delete-other-windows
           └─ elfeed

elfeed-search-mode
    │
    └─ RET → +rss/open
              ├─ elfeed-untag entry 'unread
              ├─ elfeed-search-update-entry
              └─ elfeed-show-entry
                     └─ elfeed-show-mode

elfeed-show-mode
    │
    ├─ next-buffer → +rss/next
    │                   └─ elfeed-show-entry-delete + forward-line + +rss/open
    │
    ├─ previous-buffer → +rss/previous
    │                      └─ elfeed-show-entry-delete + forward-line -1 + +rss/open
    │
    └─ gc → +rss/copy-link
             └─ kill-new (URL)

q → elfeed-kill-buffer
    └─ +rss-cleanup-h
          ├─ elfeed-db-compact
          ├─ kill related buffers
          └─ restore window/workspace
```

### データフロー図

```
[入力]                   [処理]                      [出力]

フィードURL         ───▶ elfeed-update            ───▶ elfeed-db
(org-mode/設定)                                           │
                                                          ▼
                                              elfeed-search-mode
                                                    (記事一覧)
                                                          │
                                                          ▼
記事選択            ───▶ +rss/open               ───▶ elfeed-show-mode
(RET)                       │                        (記事詳細)
                            │
                            └─ elfeed-untag unread ───▶ 既読状態

gc                  ───▶ +rss/copy-link          ───▶ クリップボード

q                   ───▶ +rss-cleanup-h          ───▶ DB圧縮
                            │                         バッファ削除
                            └─ elfeed-db-compact       WS復元
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| config.el | `modules/app/rss/config.el` | ソース | メイン設定ファイル、elfeed設定 |
| autoload.el | `modules/app/rss/autoload.el` | ソース | 起動/終了コマンド、記事操作 |
| doctor.el | `modules/app/rss/doctor.el` | 診断 | 設定診断 |
| packages.el | `modules/app/rss/packages.el` | 設定 | パッケージ依存関係定義 |
