こんにちは。ナミレリです。今回はNeovimで使うChatGPTのプラグインである、jackMort/ChatGPT.nvimを紹介します。ChatGPT.nvimを使うとNeovimから:ChatGPTで呼び出すことができ、リアルタイムにChatGPTと会話することができます。
2024年3月:最新版に沿って、大幅に内容を書き直しました。
jackMort/ChatGPT.nvimの主な機能は以下のようなものです。
・直感的なインターフェイス
・Awesome ChatGPT PromptsからChatGPTの役割を選択・設定できる
・プラグラミングのサポート
・GitHub Copilotのようなコード補完
・アクションをカスタマイズすることができる
FizzBuzzのPythonプログラムを教えて
ChatGPTの役割を選択・設定
この記事はこんな人にオススメ
- NeovimでChatGPTを使いたい方
- CLI派でなるべくnvimから離れたくない方
- 美しいインタフェースでモチベを上げたい方
- Neovimが大好きで仕方ない
- Neovim独自の機能やプラグインシステムをフルに活用したい方
- VSCodeよりNeovim派の方
- M3 MacBook Air 15インチ(メモリ24GB)
- macOS Sonoma 14.4
- Neovim v0.9.5
目次
はじめに
今回紹介するjackMort/ChatGPT.nvimついて簡単に紹介します。
jackMort/ChatGPT.nvim
jackMort/ChatGPT.nvimの主な機能は、先程も書きましたが以下の通りです。
・直感的なインターフェイス
・Awesome ChatGPT PromptsからChatGPTの役割を選択・設定できる
・プラグラミングのサポート
・GitHub Copilotのようなコード補完
・アクションをカスタマイズすることができる
ブラウザや別のアプリに切り替えることなく、Neovimの開発環境内で直接ChatGPTを利用できるのが良いです。また、コード等を編集中に直接ChatGPTに聞いたりアドバイスを求めたりもできます。凄い時代です。
あと、Neovimのプラグインなのでカスタマイズ性も高く、ほぼすべての設定を自分好みにすることもでき、とても便利なプラグインです。
Neovimのインストールと設定
Neovimをインストールしていない方は、以下の様にbrewでneovimをインストールします。
brew install neovim
インストールしているneovimのバージョンを確認しておきます。
nvim --version
NVIM v0.9.5
Build type: Release
LuaJIT 2.1.1710088188
システム vimrc: "$VIM/sysinit.vim"
省略時の $VIM: "/opt/homebrew/Cellar/neovim/0.9.5/share/nvim"
Run :checkhealth for more info
Neovimの初期設定など最初にやっておくべき設定については下の記事をぜひご覧ください。
Neovimをかっこ良くクールに使う設定
事前準備
curlの確認
プラグインのインストールにはcurlが必要ですのでインストールされているか確認します。Macであれば標準でcurlはインストールされています。
which curl
/usr/bin/curl
$OPENAI_API_KEYの確認
openaiのサイトからAPIキーを取得します。ここから取得します。
取得したAPIキーは、他の人と共有したりPythonコード(ブラウザ、アプリ等)で公開してしまうのはNGです。漏洩のリスクを軽減するために環境変数に設定しておきます。OPENAI_API_KEYという環境変数に設定します。
YOUR_API_KEYの部分に実際に取得したAPIキーを置き換えてください。
export OPENAI_API_KEY="YOUR_API_KEY"
APIキーはここから取得します。https://platform.openai.com/account/api-keys
よりセキュアに、jackMort/ChatGPT.nvimがAPIキーを受け取る方法について、公式で2つの方法が紹介されています。
ChatGPT.nvimのインストール
では、早速、jackMort/ChatGPT.nvimを公式の通りにインストールしてみます。
パッケージマネージャはPackerを使っていますので、~/.config/nvim/lua/plugins.luaに下の内容を追加します。
~/.config/nvim/lua/plugins.luaの編集
ChatGPT.nvimの公式githubを参考に、下のように~/.config/nvim/lua/plugins.luaを編集します。
最下部のend)より前に追加します。
nvim ~/.config/nvim/lua/plugins.lua
use({
"jackMort/ChatGPT.nvim",
config = function()
require("chatgpt").setup()
end,
requires = {
"MunifTanjim/nui.nvim",
"nvim-lua/plenary.nvim",
"folke/trouble.nvim",
"nvim-telescope/telescope.nvim"
}
})
:PackerInstallする
保存後にnvimを立ち上げ直すか、:source %で再読み込みし、:PackerInstallするとplugins.luaに書かれていてインストールされていないプラグインがインストールされます。
:PackerInstall
デフォルト設定では、modelはgpt-3.5-turbo、temperatureは0、max_tokensは300になっていますが、とりあえずデフォルトで機能を試してみたいと思います。
なお、デフォルト設定については、こちらに詳しく記載があります。
ChatGPT.nvimの使い方
それでは、ChatGPT.nvimを使ってみます。
ChatGPT.nvimの起動
nvimを起動して:ChatGPTで起動します。デフォルトのモデルであるgpt-3.5-turboでChatGTPと会話するインタラクティブなウィンドウが開きます。<leader>ccでも起動することができます。
ChatGPT.nvimを起動する
:ChatGPTRunの後に補完候補を表示したのが下の状態です。ChatGPTRun [action]で特定のアクションを実行することができます。例えば、ChatGPTRun translate japaneseで選択された範囲を日本語翻訳することができます。
ChatGPTRunでアクションを補完したところ
:ChatGPT、:ChatGPTActAs、:ChatGPTCompleteCodeなど、たくさんの便利なコマンドがありますので、以下に簡単にまとめます。
キーマップについてwhich-keyの設定をすると便利に使えます。
コマンド | キーマップ | 説明 |
---|---|---|
:ChatGPT | <leader>cc | gpt-3.5-turboモデルでChatGTPと会話するインタラクティブなウィンドウを開く。 |
:ChatGPTActAs | gpt-3.5-turboモデルでAwesomeのChatGPTプロンプトからChatGPTの役割を選択する。 | |
:ChatGPTCompleteCode | gpt-3.5-turboモデルでコードを完成してもらう。 | |
:ChatGPTEdiWithInstructions | <leader>ce | code-davinci-edit-001 モデル(コーディング用に微調整されたGPT 3.5)を使用して、選択したテキストかウィンドウ全体を編集するためのインタラクティブなウィンドウを開く。 |
:ChatGPTRun | gpt-3.5-turboモデルでChatGPTRun [action]特定のアクションを実行するコマンド。以下にアクションを記載します。 | |
:ChatGPTRun complete_code | 既存のコードを完成してもらう。 | |
:ChatGPTRun grammar_correction | <leader>cg | 標準的なコードに修正してもらう。 |
:ChatGPTRun translate | <leader>ct | 翻訳してもらう。 :ChatGPTRun translate japanesesで日本語に翻訳。 |
:ChatGPTRun keywords | <leader>ck | 文章から主なキーワードを抽出してもらう。 |
:ChatGPTRun docstring | <leader>cd | 指定された言語のベストプラクティスに従って、docstringを書く。 |
:ChatGPTRun add_tests | <leader>ca | コードのテストを実装してもらう。 |
:ChatGPTRun optimize_code | <leader>co | コードを最適化してもらう。 |
:ChatGPTRun summarize | <leader>cs | 文章を要約してもらう。 |
:ChatGPTRun fix_bugs | <leader>cf | コードのバグを修正してもらう。 |
:ChatGPTRun explain_code | <leader>cx | コードの内容を説明してもらう。 |
:ChatGPTRun roxygen_edit | <leader>cr | R言語の関数を文章化するスケルトンを書いてもらう。 |
:ChatGPTRun code_readability_analysis | <leader>cl | コードの可読性の問題を挙げてもらう。 |
:ChatGPTコマンド
ChatGTPと会話するインタラクティブなウィンドウが立ち上がる:ChatGPTコマンドの詳細です。
ヘルプを表示する:C-h
操作するためのキーマップがわからなくなったら、C-hで下の画像のようにヘルプを表示することができます。非表示にするにはもう一度C-hを押します。
ヘルプを表示する:<C-h>
メッセージを送信する方法:C-Enter
まず覚えておきたいキーマップは、メッセージを送信するC-Enterです。
プロンプトの入力はiでインサートモードにして普通に入力し、ノーマルモードにして送信はC-Enterです。
ウィンドウを閉じる方法:C-c
次に覚えておきたいキーマップは、閉じる方法だと思います。ウィンドウを閉じるにはC-cです。
設定状態の表示:C-o
設定状態を確認する場合は、C-oで下のように設定状態が表示されます。非表示にするにはもう一度C-oを押します。
C-oで開いた設定ウィンドウの各項目でEnter
キーを押すことで設定を変更することができます。この設定はセクション間で保存されます。
設定状態の表示:<C-o>
modelをgpt-4に設定変更して、max_tokensが300、top_pの値は1、tempratureなどが0であることがわかります。
セッションの表示:C-p
セッションを確認する場合は、C-pで下のようにセッションが表示されます。非表示にするにはもう一度C-pを押します。
セッションの表示:<C-p>
:ChatGPT(インタラクティブウィンドウ)でのキーマップ一覧
:ChatGPTと:ChatGPTEditWithInstructionsで以下のキーマップが利用できます。
キーマップ | 説明 |
---|---|
C-Enter(ノーマルモードにて) | 送信する |
C-c | ウィンドウを閉じる |
C-f | サイクルモード |
Tab | サイクルウィンドウ |
d | メッセージの削除 / セッションの削除 |
C-r | ドラフトメッセージ |
e | メッセージの編集 |
C-n | 新しいセッションを開始 |
C-j | 次のメッセージ |
C-k | 前のメッセージ |
r | セッション名の変更 |
C-d | 下にスクロール |
C-u | 上にスクロール |
C-c | 閉じる |
Space | セッションの選択 |
C-x | メッセージ生成を停止 |
C-h | ヘルプ表示のトグル |
C-r | message role 表示のトグル |
C-p | セッション表示のトグル |
C-o | 設定ウィンドウ表示のトグル |
C-s | system role 表示のトグル |
C-y | 回答をヤンク |
C-k | 回答のコードをヤンク |
APIキーの安全な管理方法
jackMort/ChatGPT.nvimの公式githubにAPIキーの管理方法について、3つの方法の記載があります。こちらです。
1つ目は、環境変数を介したやり方、2つ目は1Passwords CLIを用いる方法、3つ目はGPGを使って暗号化、復号化する方法です。ぞれぞれ見ていきましょう。
環境変数を介する方法
zshを使っている場合には、~/.zshrcの環境変数としてAPIキーを設定おく方法です。具体的には以下のようにOPENAI_API_KEYにAPIキーを設定します。
~/.zshrc
export OPENAI_API_KEY="**YOUR_API_KEY**"
環境変数に設定することでzshから直接アクセスできるためシンプルで簡単です。また、スクリプトやプログラム、アプリケーションから自動的に環境変数を読み込むことができるので、便利です。
シェルの設定ファイルに平文で保存されるため、万が一第三者に読まれた場合にはAPIキーが漏れてしまいます。また、シェルの設定ファイルをgitで管理している場合、万が一誤って公開してしまった場合も同様に、APIキーが漏れます。
1Passwords CLIを用いる方法
1passwordについては、以下の記事で詳しく紹介していますのでぜひご覧ください。
1passwordは最も信頼できるパスワードマネージャです。opコマンドでコマンドラインから高度に使うこともできます。
1password CLIを用いてAPIキーを取得するには下のように設定します。
~/.config/nvim/init.lua
require("chatgpt").setup({
api_key_cmd = "op read op://private/OpenAI/credential --no-newline"
})
「op://private/OpenAI/credential」の部分は、1passwordで秘密参照をコピーすると簡単です。
その後、シェルの設定ファイルから、環境変数OPENAI_API_KEYは削除しておきます。
1Passwordは強固なセキュリティ基準を持つパスワードマネージャで、APIキーなどの機密情報を安全に管理できます。また、1Passwordはマルチプラットフォームで利用できるので、CLIツールを通じてMacやLinuxで使うことができ、スクリプトやプログラムと統合しやすいです。
1Passwordは主にサブスクリプションサービスであるため有料。
CLIツールの使用はある程度の知識が必要で、最初は複雑に感じられるかもしれません。また、スクリプトやプログラムを起動するたびに1Passwordにアクセスするために認証をする必要があり、これが相当な手間に感じることもしばしばあります。
GPGを用いる方法
GPG(GNU Privacy Guard)は、データの暗号化とデジタル署名を行うためのツールです。公開鍵暗号化技術を使用し、メールやファイルなどの情報を安全に送受信することができます。公開鍵(暗号化に使用し、誰にでも共有できる鍵)と秘密鍵(復号化や署名の確認に使用し、所有者だけが持つ鍵)のペアを生成し、このペアの鍵で情報を保護します。またGPGはオープンソースでプライバシーとセキュリティを高めるために広く利用されています。
GPG(GNU Privacy Guard)は、公開鍵暗号方式を用いてファイルなどを高度に暗号化することができます。GPGはオープンソースであり、MacやLinuxなど多くのOSで利用できます。
GPGの設定と鍵管理は、最初はハードルが高いです。また、公開鍵と秘密鍵のペアを適切に安全に管理する必要がでてきます。
結論:1Password CLIがベスト
セキュリティと利便性のバランスを考えると、1Password CLIに軍配が上がります。
理由は、環境変数に設定することは平文でありリスクが最も高いのでNG。GPGは設定と鍵の管理が複雑でNG。消去法でも1Password CLIという結論になりますが、1passwordは有料ですが、最も信頼でき安心して使える点が魅力です。APIキーの管理のみならず、パスワード管理の全体が便利になる点も良いと思っています。
which-keyプラグインのマッピング
which-key用の設定も用意されています。
c = {
name = "ChatGPT",
c = { "<cmd>ChatGPT<CR>", "ChatGPT" },
e = { "<cmd>ChatGPTEditWithInstruction<CR>", "Edit with instruction", mode = { "n", "v" } },
g = { "<cmd>ChatGPTRun grammar_correction<CR>", "Grammar Correction", mode = { "n", "v" } },
t = { "<cmd>ChatGPTRun translate<CR>", "Translate", mode = { "n", "v" } },
k = { "<cmd>ChatGPTRun keywords<CR>", "Keywords", mode = { "n", "v" } },
d = { "<cmd>ChatGPTRun docstring<CR>", "Docstring", mode = { "n", "v" } },
a = { "<cmd>ChatGPTRun add_tests<CR>", "Add Tests", mode = { "n", "v" } },
o = { "<cmd>ChatGPTRun optimize_code<CR>", "Optimize Code", mode = { "n", "v" } },
s = { "<cmd>ChatGPTRun summarize<CR>", "Summarize", mode = { "n", "v" } },
f = { "<cmd>ChatGPTRun fix_bugs<CR>", "Fix Bugs", mode = { "n", "v" } },
x = { "<cmd>ChatGPTRun explain_code<CR>", "Explain Code", mode = { "n", "v" } },
r = { "<cmd>ChatGPTRun roxygen_edit<CR>", "Roxygen Edit", mode = { "n", "v" } },
l = { "<cmd>ChatGPTRun code_readability_analysis<CR>", "Code Readability Analysis", mode = { "n", "v" } },
},
デフォルトの設定
デフォルトの設定も公式に詳しく記載されていいます。
local M = {}
function M.defaults()
local defaults = {
api_key_cmd = nil,
yank_register = "+",
edit_with_instructions = {
diff = false,
keymaps = {
close = "<C-c>",
accept = "<C-y>",
toggle_diff = "<C-d>",
toggle_settings = "<C-o>",
toggle_help = "<C-h>",
cycle_windows = "<Tab>",
use_output_as_input = "<C-i>",
},
},
chat = {
welcome_message = WELCOME_MESSAGE,
loading_text = "Loading, please wait ...",
question_sign = "", -- 🙂
answer_sign = "ﮧ", -- 🤖
border_left_sign = "",
border_right_sign = "",
max_line_length = 120,
sessions_window = {
active_sign = " ",
inactive_sign = " ",
current_line_sign = "",
border = {
style = "rounded",
text = {
top = " Sessions ",
},
},
win_options = {
winhighlight = "Normal:Normal,FloatBorder:FloatBorder",
},
},
keymaps = {
close = "<C-c>",
yank_last = "<C-y>",
yank_last_code = "<C-k>",
scroll_up = "<C-u>",
scroll_down = "<C-d>",
new_session = "<C-n>",
cycle_windows = "<Tab>",
cycle_modes = "<C-f>",
next_message = "<C-j>",
prev_message = "<C-k>",
select_session = "<Space>",
rename_session = "r",
delete_session = "d",
draft_message = "<C-r>",
edit_message = "e",
delete_message = "d",
toggle_settings = "<C-o>",
toggle_sessions = "<C-p>",
toggle_help = "<C-h>",
toggle_message_role = "<C-r>",
toggle_system_role_open = "<C-s>",
stop_generating = "<C-x>",
},
},
popup_layout = {
default = "center",
center = {
width = "80%",
height = "80%",
},
right = {
width = "30%",
width_settings_open = "50%",
},
},
popup_window = {
border = {
highlight = "FloatBorder",
style = "rounded",
text = {
top = " ChatGPT ",
},
},
win_options = {
wrap = true,
linebreak = true,
foldcolumn = "1",
winhighlight = "Normal:Normal,FloatBorder:FloatBorder",
},
buf_options = {
filetype = "markdown",
},
},
system_window = {
border = {
highlight = "FloatBorder",
style = "rounded",
text = {
top = " SYSTEM ",
},
},
win_options = {
wrap = true,
linebreak = true,
foldcolumn = "2",
winhighlight = "Normal:Normal,FloatBorder:FloatBorder",
},
},
popup_input = {
prompt = " ",
border = {
highlight = "FloatBorder",
style = "rounded",
text = {
top_align = "center",
top = " Prompt ",
},
},
win_options = {
winhighlight = "Normal:Normal,FloatBorder:FloatBorder",
},
submit = "<C-Enter>",
submit_n = "<Enter>",
max_visible_lines = 20,
},
settings_window = {
setting_sign = " ",
border = {
style = "rounded",
text = {
top = " Settings ",
},
},
win_options = {
winhighlight = "Normal:Normal,FloatBorder:FloatBorder",
},
},
help_window = {
setting_sign = " ",
border = {
style = "rounded",
text = {
top = " Help ",
},
},
win_options = {
winhighlight = "Normal:Normal,FloatBorder:FloatBorder",
},
},
openai_params = {
model = "gpt-3.5-turbo",
frequency_penalty = 0,
presence_penalty = 0,
max_tokens = 300,
temperature = 0,
top_p = 1,
n = 1,
},
openai_edit_params = {
model = "gpt-3.5-turbo",
frequency_penalty = 0,
presence_penalty = 0,
temperature = 0,
top_p = 1,
n = 1,
},
use_openai_functions_for_edits = false,
actions_paths = {},
show_quickfixes_cmd = "Trouble quickfix",
predefined_chat_gpt_prompts = "https://raw.githubusercontent.com/f/awesome-chatgpt-prompts/main/prompts.csv",
highlights = {
help_key = "@symbol",
help_description = "@comment",
},
}
return defaults
end
M.options = {}
M.namespace_id = vim.api.nvim_create_namespace("ChatGPTNS")
function M.setup(options)
options = options or {}
M.options = vim.tbl_deep_extend("force", {}, M.defaults(), options)
end
return M
最後に
最後まで読んでいただきありがとうございます。今回の【Mac】neovimでChatGPTと会話するはいかがでしたでしょうか。
普段からneovimを使っている方にとって、ChatGPT.nvimは遊んでみたくなるプラグインです。これでまたしばらくnvimから離れられない生活が続きます。
ChatGPT関連の別の記事
公式ChatGPTのMac用デスクトップアプリを使う
OpenAIライブラリ1系の変更点
neovimでChatGPT
PythonでChatGPTのAPI
MacでChatGPT
MacでChatGPT
VSCodeでChatGPT
LinuxのターミナルからChatGPT
PythonでGPT-3