TL;DR
こんにちは。今回は、Go言語で作成したシンプルなCLIツールをご紹介します。
このツールを使えば、ファイルを選択してその内容を丸ごとクリップボードにコピーすることができます。
生成AIに質問する際など、複数のファイル内容を一度にコピーしたいときに便利になるかと思います。
1. CLIでできること
該当リポジトリはこちらです:makinzm/partial-tree-copy
このCLIツールの主な機能は複数ファイルのコピーです。
複数のファイルを選択して、一度にその内容をコピーすることが可能です。
1.1. デモ
(手順1)コンソール上で、コピーをしたい内容があるディレクトリに移動をします。
(手順2)次に今回作成したコマンドを実行します。
❯ partial-tree-copy
すると次のような画面になります。
❯ partial-tree-copy
> 📁 /<CurrentDirectory>
How to use
Press 'w'/Ctrl+'c' to quit, 'Enter' to select a file or expand/collapse a dir, up('k')/down('j') to move
画面の下のHow to use
に従ってEnter
を押して、いくつかファイルを選択します。
❯ partial-tree-copy
> 📁 /<CurrentDirectory>
📁 .git
[ ].gitignore
[ ]LICENSE
[ ]README.md
[ ]go.mod
[ ]go.sum
[ ]partial-tree-copy
📂 src
[レ] commands.go
[レ] main.go
[ ]models.go
> [レ] update.go
How to use
Press 'w'/Ctrl+'c' to quit, 'Enter' to select a file or expand/collapse a dir, up('k')/down('j') to move
最後にw
を押して終了をします。
その内容はクリップボードにコピーされているため、すぐ貼り付けを行うことができます。
実際にコピーできる内容は以下の通りで 「★★」で区切られている形をしています。
2. コードのポイントの抜粋
このツールのコードには、Go言語の基本的な文法で構成されています。
いくつかポイントを抜粋して解説します。
2.1 構造体の定義と再帰的なデータ構造
type fileNode struct {
name string // ファイル名またはディレクトリ名
path string // フルパス
isDir bool // ディレクトリかどうか
expanded bool // 展開されているかどうか
children []*fileNode // 子ノードのスライス
selected bool // 選択されているかどうか
parent *fileNode // 親ノードへのポインタ
}
- ポイント:構造体内で自身の型のポインタをフィールドとして持つことで、再帰的なデータ構造(ツリー構造)を表現しています。
2.2 マップの活用
selection map[string]*fileNode
- ポイント:選択されたファイルを管理するためにマップを使用し、選択状態を保持しています。
2.3. キーボード入力の処理
case tea.KeyMsg:
switch msg.String() {
case "ctrl+c", "w":
m.copySelection()
return m, tea.Quit
// 他のキー入力の処理
}
- ポイント:ユーザーからのキー入力を検知して、それぞれの操作に応じた関数を呼び出しています。
3. まだ改善できていないところ
このツールには、まだいくつか改善の余地があります。
3.1 検索機能の未実装
- 課題:現在はファイルツリーを手動で展開して目的のファイルを探す必要があります。
- 改善案:ファイル名やディレクトリ名で検索できる機能を追加すると、目的のファイルに素早くアクセスできます。
3.2 カーソルの表示範囲の問題
- 課題:ファイルツリーが膨大な場合、カーソルが表示範囲外に移動してしまう場合があります。
- 改善案:カーソルの位置を適切に制御し、表示範囲内に収めるロジックを追加する必要があります。
3.3. お願い
上記の内容以外にも、興味のある方はぜひぜひPRを送っていただけると嬉しいです🙇
4. 最後に
今回、Goで初めてCLIツールを作成しました。
ChatGPTの力を借りつつではありますが、比較的簡素に行いたいことを実現できたので、Go言語のパワフルな標準ライブラリとサードパーティライブラリに感心しました。
最後までお読みいただき、ありがとうございました!