iTranslated by AI
Writing Claude Code prompts in Neovim (tmux version)
Introduction
Writing Claude Code prompts comfortably in Neovim
The article above introduced a method using zellij, but since I'm a tmux user, I tried setting it up to do something similar with tmux. I had just recently moved to Neovim, so it was very helpful to see how this could be achieved.
Previously, it was difficult to write directly into the prompt on Claude Code, and I often made accidental submissions, so I used to write in a notepad first and then submit it.
However, with this setup, I can now write and submit prompts in a pop-up Neovim without leaving Claude Code, which has made it considerably more comfortable.
Operation Image

Prerequisites
- tmux
- neovim
- fzf
Settings
neovim
If you are using lazy.nvim, configure it as follows.
The fzf itself needs to be installed using mise or similar, and its PATH needs to be specified, so you will need to modify the relevant parts.
~/.config/nvim/lua/plugins/fzf.lua
return {
"ibhagwan/fzf-lua",
dependencies = { "nvim-tree/nvim-web-devicons" },
config = function()
local fzf = require("fzf-lua")
-- ★ PATH issue workaround: fix fzf_bin
fzf.setup({
fzf_bin = os.getenv("HOME") .. "/.local/share/mise/shims/fzf",
})
-- ★ In markdown, @ → insert file
vim.api.nvim_create_autocmd("FileType", {
pattern = "markdown",
callback = function(ev)
vim.keymap.set("i", "@", function()
local selected_path = nil
fzf.files({
file_icons = false,
git_icons = false,
actions = {
["default"] = function(selected, opts)
if selected and selected[1] then
local file = require("fzf-lua.path").entry_to_file(selected[1], opts)
selected_path = file and file.path or nil
end
end
},
winopts = {
on_close = function()
vim.schedule(function()
if selected_path then
vim.api.nvim_put({ "@" .. selected_path }, "", false, true)
else
vim.api.nvim_put({ "@" }, "", false, true)
end
vim.defer_fn(function()
vim.cmd("startinsert!")
end, 10)
end)
end
}
})
end, { buffer = ev.buf, noremap = true })
end,
})
end
}
tmux
Add the following to ~/.tmux.conf. I have set it to bind e, but you can change this to your preference.
# Alt-e to launch popup editor (pass the ID of the caller pane)
bind e run-shell "bash ~/.config/tmux/claude-prompt-edit.sh '#{pane_id}'"
Create a script named ~/.config/tmux/claude-prompt-edit.sh and add the following content.
#!/usr/bin/env bash
# Caller pane ID (passed from tmux.conf)
TARGET_PANE="$1"
# Create a temporary file
TMPFILE="$(mktemp /tmp/claude-prompt-XXXXXX.md)"
# Check if running inside a tmux session (precaution)
if [ -z "${TMUX:-}" ]; then
echo "Error: This script must be run inside a tmux session." >&2
exit 1
fi
# Launch "usual shell environment + nvim" inside the popup
# -E: Close popup when command (nvim) finishes
tmux display-popup -E -w 80% -h 70% -T "Claude Prompt" \
"$SHELL -i -c 'nvim \"$TMPFILE\"'"
# ==== The following will be executed after nvim is closed ====
# Debug: Display TMPFILE path and size in tmux status
if [ -f "$TMPFILE" ]; then
SIZE="$(wc -c < "$TMPFILE" 2>/dev/null || echo 0)"
tmux display-message "claude-popup: file=$TMPFILE size=${SIZE}B"
else
tmux display-message "claude-popup: TMPFILE not found: $TMPFILE"
fi
# Paste if temporary file has content
if [ -s "$TMPFILE" ]; then
CONTENT="$(cat "$TMPFILE")"
# Put into buffer
tmux set-buffer -b claude_prompt -- "$CONTENT"
# ★ Explicitly paste into the caller pane ★
tmux paste-buffer -b claude_prompt -t "$TARGET_PANE"
else
tmux display-message "claude-popup: TMPFILE is empty, skip paste"
fi
# Cleanup
rm -f "$TMPFILE"
exit 0
Conclusion
It's a bit strange that the prompt isn't automatically pasted onto Claude Code when returning from the Neovim popup. However, it still works fine since pressing Enter sends it correctly. If anyone knows a solution, please let me know.
Discussion
私も似たようなことをやっています。
バッファを介さず
で直接送りつけています!
この保険的フォールバックは参考になりました!ありがとうございます☺️
みんなやっぱりclaude codeのプロンプトで苦戦してますね笑
vimモードあっても使いにくいですよね
まぁでもメモ帳で残しておくのも、実行した内容をログとして残しておけるのでこれはこれで良かったかも?とちょっと思ってたり。(ログを残す仕組み作ってる方もいるし、claude-memもありますが