editprompt
v1.1.1
Published
A CLI tool that lets you write prompts for CLI tools using your favorite text editor
Maintainers
Readme
📝 editprompt
A CLI tool that lets you write prompts for CLI tools using your favorite text editor. Works seamlessly with Claude Code, Codex CLI, Gemini CLI, and any other CLI process.
[!IMPORTANT] 📢 Migrating from v0.8.1 or earlier? Please see the Migration Guide for upgrading to v1.0.0's subcommand-based interface.
🏆 Why editprompt?
- 🎯 Your Editor, Your Way: Write prompts in your favorite editor with full syntax highlighting, plugins, and customizations
- 🚫 No Accidental Sends: Never accidentally hit Enter and send an incomplete prompt again
- 🔄 Iterate Efficiently: Keep your editor open and send multiple prompts without reopening
- 💬 Quote and Reply: Collect multiple text selections and reply to specific parts of AI responses
- 📝 Multi-line Commands: Complex SQL queries, JSON payloads, and structured prompts
✨ Features
- 🖊️ Editor Integration: Use your preferred text editor to write prompts
- 🖥️ Multiplexer Support: Send prompts directly to tmux or WezTerm sessions
- 🖥️ Universal Terminal Support: Works with any terminal via clipboard - no multiplexer required
- 📤 Send Without Closing: Iterate on prompts without closing your editor
- 📋 Quote Buffering: Collect text selections and send them as quoted replies
- 📋 Clipboard Fallback: Automatically copies to clipboard if sending fails
📦 Installation
# Install globally via npm
npm install -g editprompt
# Or use with npx
npx editprompt🚀 Usage
editprompt supports three main workflows to fit different use cases:
Workflow 1: Basic - Write and Send
The simplest way to use editprompt:
- Run
editprompt opento open your editor - Write your prompt
- Save and close the editor
- Content is automatically sent to the target pane or clipboard
Perfect for one-off prompts when you need more space than a terminal input line.
Workflow 2: Interactive - Iterate with Editor Open
For iterating on prompts without constantly reopening the editor:
- Set up a keybinding to open editprompt with
resumesubcommand - Editor pane stays open between sends
- Write, send, refine, send again - all without closing the editor
- Use the same keybinding to toggle between your work pane and editor pane
Ideal for trial-and-error workflows with AI assistants.
Workflow 3: Quote - Collect and Reply
> Some AI agents include leading spaces in their output,which can make the copied text look a bit awkward.
<!-- Write your reply here -->
> Using editprompt’s quote mode or capture mode makes it easy to reply while quoting the AI agent’s output.
<!-- Write your reply here -->For replying to specific parts of AI responses:
- Select text in your terminal (tmux copy mode or WezTerm selection) and trigger collect mode
- Repeat to collect multiple selections
- Run
editprompt dumpto retrieve all collected quotes - Edit and send your reply with context
Perfect for addressing multiple points in long AI responses.
⚙️ Setup & Configuration
Basic Setup
# Use with your default editor (from $EDITOR)
editprompt open
# Specify a different editor
editprompt open --editor nvim
editprompt open -e nvim
# Always copy to clipboard
editprompt open --always-copy
# Show help
editprompt --help
editprompt open --helpTmux Integration
bind -n M-q run-shell '\
editprompt resume --target-pane #{pane_id} || \
tmux split-window -v -l 10 -c "#{pane_current_path}" \
"editprompt open --editor nvim --always-copy --target-pane #{pane_id}"'WezTerm Integration
{
key = "q",
mods = "OPT",
action = wezterm.action_callback(function(window, pane)
local target_pane_id = tostring(pane:pane_id())
-- Try to resume existing editor pane
local success, stdout, stderr = wezterm.run_child_process({
"/bin/zsh",
"-lc",
string.format(
"editprompt resume --mux wezterm --target-pane %s",
target_pane_id
),
})
-- If resume failed, create new editor pane
if not success then
window:perform_action(
act.SplitPane({
direction = "Down",
size = { Cells = 10 },
command = {
args = {
"/bin/zsh",
"-lc",
string.format(
"editprompt open --editor nvim --always-copy --mux wezterm --target-pane %s",
target_pane_id
),
},
},
}),
pane
)
end
end),
},Note: The -lc flag ensures your shell loads the full login environment, making editprompt available in your PATH.
Editor Integration (Send Without Closing)
While editprompt is running, you can send content to the target pane or clipboard without closing the editor. This allows you to iterate quickly on your prompts.
Command Line Usage
# Run this command from within your editor session
editprompt input -- "your content here"
# Sends content to target pane and moves focus there
editprompt input --auto-send -- "your content here"
# Sends content, automatically submits it (presses Enter), and returns focus to editor pane
# Perfect for iterating on prompts without leaving your editor
editprompt input --auto-send --send-key "C-m" -- "your content here"
# Customize the key to send after content (tmux format example)
# WezTerm example: --send-key "\r" (default for WezTerm is \r, tmux default is Enter)This sends the content to the target pane (or clipboard) while keeping your editor open, so you can continue editing and send multiple times.
Options:
--auto-send: Automatically sends the content and returns focus to your editor pane (requires multiplexer)--send-key <key>: Customize the key to send after content (requires--auto-send)- tmux format:
Enter(default),C-a, etc. - WezTerm format:
\r(default),\x01, etc.
- tmux format:
Neovim Integration Example
You can set up a convenient keybinding to send your buffer content:
-- Send buffer content while keeping the editor open
if vim.env.EDITPROMPT then
vim.keymap.set("n", "<Space>x", function()
vim.cmd("update")
-- Get buffer content
local lines = vim.api.nvim_buf_get_lines(0, 0, -1, false)
local content = table.concat(lines, "\n")
-- Execute editprompt command
vim.system(
{ "editprompt", "input", "--", content },
{ text = true },
function(obj)
vim.schedule(function()
if obj.code == 0 then
-- Clear buffer on success
vim.api.nvim_buf_set_lines(0, 0, -1, false, {})
vim.cmd("silent write")
else
-- Show error notification
vim.notify("editprompt failed: " .. (obj.stderr or "unknown error"), vim.log.levels.ERROR)
end
end)
end
)
end, { silent = true, desc = "Send buffer content to editprompt" })
endUsage:
- Open editprompt using the tmux/wezterm keybinding
- Write your prompt in the editor
- Press
<Space>xto send the content to the target pane - The buffer is automatically cleared on success
- Continue editing to send more content
Quote Workflow Setup
Collecting Quotes in tmux Copy Mode
Add this keybinding to your .tmux.conf to collect selected text as quotes:
bind-key -T copy-mode-vi C-e { send-keys -X pipe "editprompt collect --target-pane #{pane_id}" }Usage:
- Enter tmux copy mode (
prefix + [) - Select text using vi-mode keybindings
- Press
Ctrl-eto add the selection as a quote - Repeat to collect multiple quotes
- All quotes are stored in a pane variable associated with the target pane
Collecting Quotes in WezTerm
Add this event handler and keybinding to your wezterm.lua to collect selected text as quotes:
local wezterm = require("wezterm")
wezterm.on("editprompt-collect", function(window, pane)
local text = window:get_selection_text_for_pane(pane)
local target_pane_id = tostring(pane:pane_id())
wezterm.run_child_process({
"/bin/zsh",
"-lc",
string.format(
"editprompt collect --mux wezterm --target-pane %s -- %s",
target_pane_id,
wezterm.shell_quote_arg(text)
),
})
end)
return {
keys = {
{
key = "e",
mods = "CTRL",
action = wezterm.action.EmitEvent("editprompt-collect"),
},
},
}Usage:
- Select text in WezTerm (by dragging with mouse or using copy mode)
- Press
Ctrl-eto add the selection as a quote - Repeat to collect multiple quotes
- All quotes are stored in a configuration file associated with the target pane
Capturing Collected Quotes
Run this command from within your editor pane to retrieve all collected quotes:
editprompt dumpThis copies all collected quotes to the clipboard and clears the buffer, ready for your reply.
Complete workflow:
- AI responds with multiple points
- Select each point in copy mode and press
Ctrl-e - Open your editor pane and run
editprompt dump - Edit the quoted text with your responses
- Send to AI
How quote buffering works:
- tmux: Quotes are stored in pane variables, automatically cleaned up when the pane closes
- WezTerm: Quotes are stored in a configuration file associated with the pane
- Text is intelligently processed: removes common indentation, handles line breaks smartly
- Each quote is prefixed with
>in markdown quote format - Multiple quotes are separated with blank lines
Sending to Multiple Panes
You can send content to multiple target panes simultaneously by specifying --target-pane multiple times:
# Send to multiple panes with open subcommand
editprompt open --target-pane %1 --target-pane %2 --target-pane %3
# Register multiple target panes for use with resume and input modes
editprompt register --target-pane %1 --target-pane %2The content will be sent sequentially to all specified panes. This is useful when you want to send the same prompt to multiple CLI sessions.
Neovim Integration Example
You can set up a convenient keybinding to capture your quote content:
vim.keymap.set("n", "<Space>X", function()
vim.cmd("update")
vim.system({ "editprompt", "dump" }, { text = true }, function(obj)
vim.schedule(function()
if obj.code == 0 then
vim.cmd("silent write")
-- Split stdout by lines
local output_lines = vim.split(obj.stdout, "\n")
local lines = vim.api.nvim_buf_get_lines(0, 0, -1, false)
local is_empty = #lines == 1 and lines[1] == ""
if is_empty then
-- If empty, overwrite from the beginning
vim.api.nvim_buf_set_lines(0, 0, -1, false, output_lines)
vim.cmd("normal 2j")
else
-- If not empty, append to the end
table.insert(output_lines, 1, "")
local line_count = vim.api.nvim_buf_line_count(0)
vim.api.nvim_buf_set_lines(
0,
line_count,
line_count,
false,
output_lines
)
vim.cmd("normal 4j")
end
vim.cmd("silent write")
else
vim.notify(
"editprompt failed: " .. (obj.stderr or "unknown error"),
vim.log.levels.ERROR
)
end
end)
end)
end, { silent = true, desc = "Capture from editprompt quote mode" })Environment Variables
Editor Selection
editprompt respects the following editor priority:
--editor/-ecommand line option$EDITORenvironment variable- Default:
vim
EDITPROMPT Environment Variable
editprompt automatically sets EDITPROMPT=1 when launching your editor. This allows you to detect when your editor is launched by editprompt and enable specific configurations or plugins.
Example: Neovim Configuration
-- In your Neovim config (e.g., init.lua)
if vim.env.EDITPROMPT then
vim.opt.wrap = true
-- Load a specific colorscheme
vim.cmd('colorscheme blue')
endCustom Environment Variables
You can also pass custom environment variables to your editor:
# Single environment variable
editprompt open --env THEME=dark
# Multiple environment variables
editprompt open --env THEME=dark --env FOO=fooooo
# Useful for editor-specific configurations
editprompt open --env NVIM_CONFIG=minimalTarget Pane Environment Variable
When using the send-without-closing feature or dump, editprompt sets EDITPROMPT_TARGET_PANE to the target pane ID. This is automatically used by editprompt input and editprompt dump commands.
