A Neovim plugin that integrates the llm command-line tool for AI-powered text generation directly into your editor.
- Asynchronous execution - Run LLM commands without blocking your editor
- Synchronous mode - Insert LLM output directly at cursor position with
!bang - Visual selection support - Send selected text as input to the LLM
- Dedicated output window - View LLM responses in a persistent split window
- Progress indicator - Animated feedback while waiting for responses
- Vim modifiers support - Use
%,%:p, and other filename modifiers in commands - Smart output formatting - Automatically formats output with comment strings when inserting into code files
You must have the llm CLI tool installed and configured:
uv tool install llm
# or pipx install llmRefer to their docs for more information
Using lazy.nvim:
{
{
"https://github.com/BlakeJC94/llm.nvim",
opts = {
autoscroll = true,
llm_path = "llm", -- Can be a string or a function
template = nil, -- Default template name, passed as -t <template>
split = {
direction = "horizontal",
size = 14,
position = "bottom",
},
},
cmd = {
"LLM",
"LLMToggle",
"LLMOpen",
"LLMClose",
"LLMStop",
},
-- Optional: set keymaps
keys = {
{
"<Leader>s",
":LLM ",
mode = {"n", "v"},
},
{
"<Leader>S",
":LLMToggle<CR>",
mode = "n",
},
},
}Execute an LLM command asynchronously and display output in the LLM window.
Arguments that don't start with a known llm subcommand (like logs,
templates, chat, etc.) are automatically prefixed with prompt, so
:LLM "Explain this" runs llm prompt "Explain this". If a template is
configured, -t <template> is also prepended.
:LLM "Explain this code" < %
:LLM "Write a function to reverse a string"
:'<,'>LLM "Refactor this code"
:LLM logs -n 1Execute an LLM command synchronously and insert output at the cursor position. Output is automatically wrapped in comments based on the current filetype.
:LLM! "Add error handling"
:'<,'>LLM! "Add JSDoc comments"Toggle the LLM output window open/closed.
Open the LLM output window.
Close the LLM output window.
Stop the currently running LLM command.
The plugin can be configured during setup:
opts = {
template = "default", -- default template passed as -t <template>
split = {
direction = "horizontal", -- or "vertical"
size = 16, -- window size in lines/columns
position = "bottom", -- "bottom", "top", "left", or "right"
},
wo = {
-- Window options for the LLM window
wrap = true,
number = false,
relativenumber = false,
cursorline = false,
cursorcolumn = false,
signcolumn = "no",
spell = false,
},
bo = {
-- Buffer options for the LLM buffer
buflisted = false,
filetype = "markdown",
},
})The template option sets a default template passed to llm via the -t
flag on every :LLM invocation. When nil or empty, the plugin will fall
back to the LLM_DEFAULT_TEMPLATE environment variable if set. If neither is
provided, no -t flag is added.
Templates are YAML files stored in the directory returned by
llm templates path. For example:
# $(llm templates path)/default.yaml
name: default
model: openrouter/deepseek/deepseek-v4-flash
system: |
Be as short, direct and concise as possible. Do not make any further
suggestions --- I'll ask exactly what I need and nothing more. If I need some
coding help, just return the required code with minimal explanation. Again --- I
will ask you if I need you to explain it further. Lists are preferred, and
please no bold textWith template = "default" in your config, every :LLM call will
automatically use -t default, selecting the model and system prompt defined
above.
:LLM "Explain what this file does" < %:LLM -c "Explain this part in more detail"Select code in visual mode, then:
:'<,'>LLM "Refactor this to be more efficient":LLM! "Write a function that validates email addresses":LLM logs -n 1 --json | jq -r '.[].response'Select a function, then:
:'<,'>LLM! "Add comprehensive docstrings and comments"The output will be automatically formatted as comments based on your filetype.
MIT