GitHub上のソースコードを、ブラウザではなくターミナルからじっくり読むためのTUIアプリケーション RepoTrek をRustで作りました。
GitHubはこちらです。
RepoTrekは、単なるgit logビューアやGit操作ツールではなく、
GitHubのリポジトリを「読む」ことに特化したターミナルブラウザ
を目指しています。
現在のバージョンは v0.3.9 です。
RepoTrekとは
普段GitHubでOSSのコードを読んでいると、次のような操作をかなり頻繁に行います。
- ディレクトリを辿る
- ソースコードを読む
- ファイルの履歴を見る
- Blameを見る
- その行を書いたコミットへ飛ぶ
- Commit diffを見る
- 別のファイルへ移動する
- Pull RequestやIssueを確認する
- ブランチを切り替える
- リポジトリ内を検索する
GitHubのWeb UIは非常に便利ですが、コードを長時間読む用途では、
- マウス操作が多い
- ページ遷移が多い
- 大量のコミットを連続して読むのが少し面倒
- ターミナルとブラウザを行き来する
と感じることがありました。
そこで、
GitHub Web UI
↓
terminal-native
↓
keyboard-first
↓
source code reading
という方向でRepoTrekを作っています。
起動
ビルド済みバイナリなら、
Linux
./repotrek
macOS
./repotrek
Windows
.\repotrek.exe
Rust環境がある場合は、
cargo run --release
でも起動できます。
ホーム画面
RepoTrekを引数なしで起動すると、まずホーム画面が開きます。
ホームには、
Repository or search
History
Featured
Recommended
があります。
リポジトリを直接開く場合は、
rust-lang/rust
のように、
owner/repository
形式で入力します。
それ以外の文字列はGitHubのリポジトリ検索として扱います。
例えば、
terminal git
のように入力すると検索結果が表示されます。
検索結果はGitHub側の結果をそのまま並べるだけではなく、RepoTrek側でも名前や完全一致などを考慮して並べ替えています。
cloneせずに読む
RepoTrekの特徴のひとつが、
リポジトリをローカルへcloneしなくても読める
ことです。
例えばLinux kernelを見る場合も、
repotrek
を起動して、
torvalds/linux
と入力するだけです。
ローカルに巨大なGit object databaseを持つ必要はありません。
概念的には、
RepoTrek
│
├─ GitHub REST API
│
├─ GitHub GraphQL API
│
└─ local cache / history
という構成になっています。
そのため、
Repository
↓
GitHub API
↓
RepoTrek model
↓
TUI
という流れで表示しています。
将来的にGitHub以外のGit forgeにも対応しやすいよう、GitHub APIレスポンスをUIが直接扱うのではなく、Provider層を挟む構成にしています。
Code
Repositoryを開くと、GitHubのCodeタブに近い感覚でファイルツリーを辿れます。
📁 src
📁 docs
📄 Cargo.toml
📄 README.md
基本操作は、
↑ / ↓ 移動
Enter 開く
Esc 上へ戻る
u 上のディレクトリ
Backspace 戻る
です。
ディレクトリ一覧には、
..
も表示されるため、それを選択して上の階層へ移動することもできます。
ソースコード表示
ファイルを開くと、行番号付きでソースコードを表示します。
RepoTrekではファイル拡張子などから言語を判定して、言語ごとに構文色を変えています。
現在は例えば、
- Rust
- C / C++
- C#
- Python
- Go
- Java
- Kotlin
- Swift
- JavaScript
- TypeScript
- JSON
- YAML
- TOML
- Shell
- SQL
- HTML
- CSS
- Markdown
などを対象にしています。
未知の言語では通常のプレーンテキスト表示へフォールバックします。
Dark / Lightテーマ
標準はDarkテーマです。
T
で、
Dark
↕
Light
を切り替えられます。
Lightテーマは単なる色反転ではなく、
- 白背景
- 黒系文字
- Light用syntax color
- Light用選択色
- Light用diff色
を別に定義しています。
設定は保存されるので、次回起動時にも維持されます。
現在行
コードリーダーでは、現在読んでいる行を見失わないことがかなり重要なので、
cursor line
selected lines
には別の背景色を使っています。
DarkとLightでそれぞれ専用色を定義しています。
行選択とコピー
ターミナルごとのショートカット競合をかなり試した結果、現在は次の操作にしています。
Shift+J 下へ範囲選択
Shift+K 上へ範囲選択
Shift+A 全選択
Shift+C コピー
Esc 選択解除
Vim風の、
v 選択開始 / 解除
y コピー
も残しています。
macOSではCtrl+↑などがOS側ショートカットと衝突しやすかったため、最終的にShift+J/Kを正式な選択操作にしました。
Blame
ファイル画面では、
Code
Blame
History
を切り替えられます。
Blameでは、
この行
↓
commit
↓
author
↓
history
を辿れます。
Blame情報についてはGitHub GraphQL APIも利用しています。
Blame上で行を選び、
Enter
すると、その行に対応するcommitへ移動できます。
File History
Historyでは、そのファイルに関係するコミットだけを表示できます。
例えば、
src/provider/github.rs
を読んでいるときにHistoryへ移動すると、
● fix: improve public API fallback
● feat: add repository search
● refactor: provider abstraction
● initial implementation
のように、そのファイルの変遷を追えます。
コードを理解するときに、
現在のコードだけではなく「なぜこうなったのか」
を見るのに便利です。
Commit
Commit一覧では、コミットを連続して読めます。
横幅のあるターミナルでは、
Commit list Diff
────────────────────────────────────
fix something │ @@ -10,7 +10,8
add feature │
refactor module │ - old
│ + new
のような表示も行います。
Web UIで、
Back
クリック
Diff
Back
次のCommit
と移動する代わりに、キーボードで連続して履歴を読むことを意識しています。
Diffにも行番号
diffには、
old line
new line
+/-
source
を表示します。
例えば、
81 81 fn example() {
82 - old_code();
82 + new_code();
83 83 }
のような形です。
追加行と削除行は背景色も変えています。
折り返し
コードやdiffは、
w
で折り返しを切り替えられます。
コードの場合、
wrap_code
CommitやPRなどのdiffでは、
wrap_diff
として別々に設定を保持しています。
Branch
B
でBranch pickerを開けます。
main
develop
feature/foo
release/...
などから選択して、
Enter
で切り替えます。
切り替えるとCode viewもそのbranchへ更新されます。
ファイル検索
f
でリポジトリ内のファイルを検索できます。
単純な前方一致だけではなく、簡易fuzzy matchingを行っています。
例えば、
githubprovider
のような入力から、
src/provider/github.rs
を候補として出すこともできます。
コード全文検索
s
または、
/
でリポジトリ内コード検索を開きます。
検索結果からEnterすると、そのファイルを開いて該当文字列付近へ移動します。
Symbol
ファイル内では、
@
でシンボル一覧を表示できます。
例えばRustなら、
struct
enum
trait
impl
fn
などを抽出して移動できます。
Definition探索
d
では、現在行のidentifierを元に定義候補を検索します。
現在はLSPを起動しているわけではなく、GitHub上のコード検索と簡易解析を組み合わせたheuristicな実装です。
将来的にはこの辺をもっと強化したいところです。
Pull Requests / Issues / Actions / Releases
Repository画面上部には、
Code
Commits
Pull Requests
Issues
Actions
Releases
があります。
初期実装では外部GitHubページへのリンク中心でしたが、現在は基本的な情報をRepoTrek内でも表示するようにしています。
例えばPull Requestでは、
- title
- author
- state
- base / head
- changed files
- additions / deletions
- comments
- diff
などをTUIで読めます。
Issueも本文とコメントをTUI上で確認できます。
GitHub Actionsではworkflow runやjob、stepを確認できます。
必要な場合だけ、
o
でGitHub Webを開きます。
GitHub Authentication
公開リポジトリは認証なしでもある程度利用できます。
より多くAPIを使う場合やprivate repositoryへアクセスする場合はGitHub authenticationを利用します。
RepoTrekでは、
F2
から認証メニューを開けます。
現在は、
GitHub CLI
Personal Access Token
Persistent Token
などに対応しています。
Tokenを毎回入力しなくて済むよう、利用可能な環境では永続化します。
macOSではKeychainも利用します。
History
RepoTrekは最近開いたrepositoryをローカルに記録します。
そのため、
RepoTrek
↓
History
↓
前回開いていたrepository
という使い方ができます。
履歴の個別削除は、
d
全削除は確認付きで行えます。
Featured / Recommended
ホーム画面には、
Featured
Recommended
もあります。
FeaturedはGitHub上のrepository候補を表示します。
Recommendedについては、将来的には閲覧履歴などを使って、
よく読むlanguage
よく読むorganization
repository topics
閲覧頻度
などからローカル推薦できるようにしたいと考えています。
履歴を外部サーバーへ送信せず、ローカルで嗜好モデルを作るような構成も面白そうです。
印刷用HTML
これは少し変わった機能かもしれません。
RepoTrekでは、
p
で、現在読んでいるソースコードやCommit diffを印刷用HTMLとしてExportできます。
生成物は、
exports/
へ保存します。
ファイル名には、
YYYYMMDD-HHMMSS
形式の日時を入れています。
例えば、
exports/
└── 20260809-103015-repotrek-rust-lang-rust-src-lib.rs.html
のようになります。
同じ秒に同名ファイルを生成した場合も、
-2
-3
のようにsuffixを付けて上書きしません。
印刷HTMLでは、
- 行番号
- syntax highlight
- diffのold/new行番号
- add/delete背景
- A4 landscape
- white background
など、紙で読むことを前提にした別レイアウトを使っています。
Rust + Ratatui
RepoTrekはRustで実装しています。
TUI部分にはRatatuiを利用しています。
大まかな構造は、
main
│
├── app
│ └── state / command / key handling
│
├── ui
│ └── Ratatui rendering
│
├── provider
│ └── GitHub API abstraction
│
├── model
│ └── common repository models
│
├── highlight
│ └── syntax highlighting
│
├── storage
│ └── history
│
├── settings
│
├── auth
│
└── export
のようになっています。
GitHub固有DTOをTUIへ直接流さず、
GitHub API DTO
↓
RepositoryProvider
↓
RepoTrek model
↓
App state
↓
UI
にしているのは、今後GitLabやForgejoなどを追加できる余地を残したかったためです。
GitHub Actions
Release時にはGitHub Actionsで、
Linux
x86_64
ARM64
macOS
Apple Silicon
Intel
Windows
x86_64
ARM64
の6種類をビルドする構成にしています。
タグをpushすると、
vX.Y.Z
↓
GitHub Actions
↓
build
↓
archive
↓
SHA256SUMS
↓
GitHub Release
まで自動化しています。
さらにcrates.ioへのpublishもGitHub Actionsから行う構成にしています。
なぜGitクライアントではなく「コードブラウザ」なのか
既に、
- git
- tig
- lazygit
- gitui
- GitHub CLI
など、非常に優秀なツールがあります。
RepoTrekはそれらを置き換えたいわけではありません。
目的が少し違います。
Git client
↓
repositoryを操作する
RepoTrek
↓
repositoryを読む
という違いです。
特に、
Code
↓
Blame
↓
Commit
↓
Diff
↓
History
↓
別ファイル
を高速に往復することを重視しています。
今後やりたいこと
現在もまだv0.xなので、改善したいところはかなりあります。
- GitLab / Gitea / Forgejo対応
- より高度なsymbol解析
- LSP連携
- repository間検索
- commit graph改善
- PR review表示改善
- Actions log閲覧
- より高度なローカルrecommendation
- キャッシュ戦略改善
- 大規模repository向けperformance tuning
- mouse操作
- terminal capability detection改善
などです。
ただ、まずは、
OSSのソースコードをターミナルで楽しく読める
という部分をきちんと作り込んでいきたいと思っています。
Repository
RepoTrekはこちらです。
RustやTUIが好きな方、OSSのソースコードを読むのが好きな方に使ってもらえたら嬉しいです。
バグ報告や改善案、Pull Requestも歓迎です。
最後に
RepoTrekを作り始めた理由はかなり単純で、
GitHubのコードをターミナルから気持ちよく読みたかった
からです。
GitHub Webの優れた情報構造はなるべく残しつつ、
mouse
↓
keyboard
browser
↓
terminal
page navigation
↓
continuous exploration
へ変換していくようなイメージで作っています。
まだ発展途中ですが、ソースコードを「書く」ためではなく、「読む」ための開発ツールとして育てていきたいと思います。
