Skip to content

miniatureape/sendkeys.nvim

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 

Repository files navigation

sendkeys.nvim

Wire up commands that get sent to tmux panes on Neovim events (buffer opened, written, updated, or closed), with an in-editor UI for managing them.

Requirements

  • Neovim >= 0.10, built with LuaJIT (the default for all official builds)
  • tmux on $PATH
  • nui.nvim
  • libpcre2-8 loadable at runtime, for path-match (see below). Ships with macOS by default at /usr/lib/libpcre2-8.dylib; on Linux it's commonly already present as a dependency of git/php/nginx/ripgrep, otherwise install via your package manager (e.g. apt install libpcre2-8-0, brew install pcre2).

Installation

lazy.nvim:

{
  "yourname/sendkeys.nvim",
  dependencies = { "MunifTanjim/nui.nvim" },
  opts = {},
}

opts = {} calls require('sendkeys').setup({}). If you don't call setup() yourself, the plugin calls it with defaults on VimEnter so autocmds are still wired up.

Setup options

require("sendkeys").setup({
  -- Directory the sendkeys.json config file lives in.
  -- Default: vim.fn.stdpath("config")
  config_dir = vim.fn.stdpath("config"),

  -- Enable debug logging to ~/sendkeys.nvim.log
  debug = false,
})

Usage

Command Description
:SendKeys Open the list view (all configured commands)
:SendKeysNew Open the create view directly
:SendKeysReload Reload config from disk and re-wire autocmds

List View (:SendKeys)

  • j / k, arrows — move selection (preview pane updates live)
  • <CR> — open the highlighted command in the Edit View
  • a — create a new command
  • e — toggle enabled/disabled on the highlighted command
  • d — delete the highlighted command (confirms first)
  • q / <Esc> — close

Edit / Create View

  • e — toggle enabled
  • n — edit name (prompt)
  • c — edit command (opens a split; :w to save, q to cancel)
  • p — edit path-match regex (opens a split; :w to save, q to cancel)
  • h — pick the nvim-hook (open / write / update / close buffer)
  • t — pick a tmux pane (lists live panes, or enter one manually)
  • s — save (persists to disk and re-wires autocmds immediately)
  • x — delete (existing commands only, confirms first)
  • q / <Esc> — cancel without saving

Command configuration

Each entry has:

  • command — the shell command text, sent to tmux literally (see Escaping, below). Supports placeholders for the buffer that triggered the autocmd (see Placeholders, below).
  • tmux-pane — a tmux pane id, or a session:window.pane target as understood by tmux send-keys -t.
  • nvim-hook — one of open buffer, write buffer, update buffer, close buffer, mapped internally to BufReadPost/BufNewFile, BufWritePost, TextChanged, and BufDelete respectively.
  • path-match — a real PCRE pattern matched against the buffer's full path, via a direct LuaJIT FFI binding to the system libpcre2-8 (not a hand-rolled matcher, and not Vim regex). Leave empty to match every buffer. Example: \.lua$ matches only Lua files; (?i)\.ya?ml$ matches .yml/.yaml case-insensitively.
  • enabled — when off, the command is never sent and no autocmd is wired for it.

Configuration persists as JSON at <config_dir>/sendkeys.json (default ~/.config/nvim/sendkeys.json).

Placeholders

command text may reference the buffer that triggered the autocmd with {{...}} placeholders (expanded just before sending, using the actual triggering buffer — not whatever happens to be the current buffer):

Placeholder Expands to
{{file}} full path, e.g. /home/me/project/foo.lua
{{file:tail}} filename only, e.g. foo.lua
{{file:head}} containing directory
{{file:root}} full path without extension
{{file:ext}} extension only, e.g. lua

Example: command = "cat {{file}}" sends cat /home/me/project/foo.lua.

A bare % (Vim's usual current-file placeholder) was considered, but since command is arbitrary shell text where % shows up constantly on its own (printf "%s\n", date +%Y-%m-%d, ...), substituting it unconditionally would silently corrupt unrelated commands. {{...}} doesn't collide with real-world shell syntax, so it's used instead. Any {{...}} that isn't a recognized placeholder is left as-is.

Escaping

Commands are sent via tmux send-keys -t <pane> -l -- <command> (-l = literal, so words that look like tmux key names — Enter, C-c, etc. — are typed as plain text, not interpreted), followed by a separate send-keys Enter to run the line. Every tmux invocation goes through vim.fn.system() with an argument list, so there is no shell in between and no shell-escaping to worry about.

Debugging

Set debug = true in setup() to log to ~/sendkeys.nvim.log. Failed sends always produce an error notification (vim.notify + an echoed error message), regardless of debug mode.

About

A UI to help run commands in tmux panes when vim autocmds run

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages