📑
VimでAIを「対話できるテキストフィルタ」として使う(tgpt)
テキストを選択 → その場で指示を書く → 思考のすぐ下に返答を残す
Vimの中でLLMを使う方法はいろいろありますが、
最近しっくりきているのは AIをUnix的な「テキストフィルタ」として扱う という考え方です。
しかも今回は少し進化して、
- 選択したテキストを渡し
- 毎回、その場で指示(プロンプト)を入力
- 返答を元テキストの直下に追加する
という、軽い対話型 の使い方になりました。
重たいプラグインは不要。
フローティングUIも不要。
stdin → stdout → バッファにテキスト。
それだけなのに、思考の流れがほとんど途切れません。
ワークフロー
- Vimでテキストを書く、または選択する
(質問、下書き、コード、メモなど) - ショートカットキーを押す
- コマンドラインに
tgpt >と表示される - その場で指示を書く
- AIの返答が 選択範囲のすぐ下に追加される
プロンプトも思考の一部。
返答もドキュメントの一部。
すべてが同じテキスト空間に残ります。
なぜこの形がいいのか
多くのAI統合は、
- コンテキストを裏で集め
- 指示を隠し
- 結果だけを差し込む
という設計になりがちです。
この方法はその逆で、すべてが見えます。
- プロンプトは毎回自分で書く
- 選択したテキストがそのまま文脈になる
- 出力はただのテキストとして残る
結果として、
- ノートの余白に質問を書き足す
- 自分の思考に対して、少し賢い返事が返ってくる
そんな感覚に近くなりました。
「AIに書いてもらう」というより、
AIと並んで考える ための使い方です。
Vim設定(対話型プロンプト対応)
tgpt がインストールされ、PATHに通っている前提です。
以下を .vimrc に追加します。
command! -range TgptPrompt call s:tgpt_prompt()
function! s:tgpt_prompt()
" 指示をその場で入力
let l:instruction = input("tgpt > ")
if empty(l:instruction)
echo "tgpt cancelled"
return
endif
" 選択範囲のテキストを取得
let l:selection = join(getline("'<", "'>"), "\n")
" プロンプトを組み立て
let l:prompt = l:instruction . "\n\n" . l:selection
" tgpt 実行
let l:result = system('tgpt', l:prompt)
" 選択範囲の下に結果を追加
call append(line("'>"), split(l:result, "\n"))
endfunction
Visualモード用のマッピング(推奨):
xnoremap <leader>g :<C-u>TgptPrompt<CR>
使い方
- Visualモードでテキストを選択
-
<leader>gを押す - コマンドラインに表示される:
tgpt >
- 例えば、こう入力する:
このコードをやさしく説明して
- 結果が 選択したテキストの直下に追加 される
例:
この関数、なぜ読みにくい気がする?
↓
この関数、なぜ読みにくい気がする?
状態管理とIO処理が混在しており、
一つの関数が複数の責務を持っているためです。
使っている場面
- ラフなメモを少し広げたいとき
- 「自分が見落としている点」を聞きたいとき
- コードを言語化して理解したいとき
- 書いた文章を別の視点で見直したいとき
自動補完ではなく、
思考を深めるための相棒 として使っています。
小さな視点の転換
AIを
「自然言語を扱える
sortやfmt」
のように捉えると、
Vimの既存の思想と自然につながります。
Vimはテキストを操作するのが得意。
AIは、少し気の利いた返事を返すだけ。
おわりに
これはプラグインでも、
大きな仕組みでもありません。
ただの小さな組み合わせです。
でも、
考え方と作業のリズムが少し変わる ことはあります。
補足・発展案
- 非同期実行にする
- Neovim + Luaで書き直す
- 指示の履歴を残す
- 出力を折りたたむ
- Markdown向けに整形する
なども簡単に発展できます。
Discussion