An open API service indexing awesome lists of open source software.

https://github.com/julwrites/llm-nvim

Neovim plugin for llm CLI
https://github.com/julwrites/llm-nvim

Last synced: about 2 months ago
JSON representation

Neovim plugin for llm CLI

Awesome Lists containing this project

README

          

# llm-nvim

A Neovim plugin for integrating with [Simon Willison's llm CLI tool](https://github.com/simonw/llm).

## Feature Demos

### Model, Plugin and Key Management
https://github.com/user-attachments/assets/d8c9b2f8-4617-4534-9a64-05a2447d9380

### Schema Management
https://github.com/user-attachments/assets/b326370e-5752-46af-ba5c-6ae08d157f01

### Fragment Management
https://github.com/user-attachments/assets/2fc30538-6fd5-4cfa-9b7b-7fd7757f20c1

## Feature List

- Unified LLM command interface (`:LLM`)
- Interactive prompting with fragments support
- Process selected text or entire files with LLMs
- Explain code in current buffer
- Support for custom models and system prompts
- API key management for multiple providers
- Fragment management (files, URLs, GitHub repos)
- Unified manager window (`:LLMConfig`) with views for:
- Models
- Plugins
- API Keys
- Fragments
- Markdown-formatted responses with syntax highlighting
- Asynchronous command execution

## Requirements

- Neovim 0.7.0 or later
- Lua 5.2+ (Neovim bundles LuaJIT 2.1+ which is compatible)
- [llm CLI tool](https://github.com/simonw/llm) installed (`pip install llm` or `brew install llm`)

### Lua Compatibility Note

This plugin uses Lua 5.2+ APIs (`table.unpack`) for forward compatibility. Neovim bundles LuaJIT 2.1+ which provides these APIs, so no additional Lua installation is required.

## Installation

### Using [vim-plug](https://github.com/junegunn/vim-plug)

```vim
Plug 'julwrites/llm-nvim'
```

### Using [packer.nvim](https://github.com/wbthomason/packer.nvim)

```lua
use 'julwrites/llm-nvim'
```

### Using [lazy.nvim](https://github.com/folke/lazy.nvim)

```lua
-- Example lazy.nvim configuration
return {
{
'julwrites/llm-nvim',
-- Optional: Specify dependencies if needed, e.g., for UI components
-- dependencies = { 'nvim-lua/plenary.nvim' },
config = function()
-- Configure the plugin
require('llm').setup({
-- Specify the default LLM model to use
model = 'gpt-4o', -- Or 'claude-3-haiku-20240307', 'llama3', etc.

-- Define a default system prompt (optional)
system_prompt = 'You are a helpful Neovim assistant.',

-- Disable default key mappings if you prefer to set your own
-- no_mappings = true,

-- Enable debug logging (optional)
-- debug = true,

-- Enable or disable automatic updates for the underlying `llm` CLI tool.
-- Defaults to `false`.
-- auto_update_cli = false,

-- Set the interval in days for checking for `llm` CLI updates.
-- Defaults to `7`.
-- auto_update_interval_days = 7,
})

-- Example custom key mappings (if no_mappings = true or for overrides)
-- vim.keymap.set('n', 'lp', '(llm-prompt)', { desc = "LLM Prompt" })
-- vim.keymap.set('v', 'ls', '(llm-selection)', { desc = "LLM Selection" })
-- vim.keymap.set('n', 'lt', '(llm-toggle)', { desc = "LLM Toggle Manager" })
end
}
}
```

## Configuration

```lua
-- Setup with configuration options
require('llm').setup({
model = 'gpt-4o', -- Default model to use
system_prompt = 'You are a helpful assistant.', -- Default system prompt
no_mappings = false, -- Set to true to disable default mappings
debug = false, -- Set to true to enable debug output
auto_update_cli = false, -- Enable/disable CLI auto-updates (default: false)
auto_update_interval_days = 7, -- Interval in days for CLI update checks (default: 7)
})

-- Custom mappings
vim.keymap.set('n', 'lp', '(llm-prompt)')
vim.keymap.set('v', 'ls', '(llm-selection)')
vim.keymap.set('n', 'le', '(llm-explain)')
vim.keymap.set('n', 'lm', '(llm-models)') -- Note: (llm-select-model) is deprecated
```

### Automatic CLI Updates

The plugin includes a feature to automatically check for updates to the `llm` command-line tool upon startup.

- When enabled via the `auto_update_cli = true` setting, the plugin will check if the configured `auto_update_interval_days` has passed since the last check.
- If an update check is due, it will attempt to update the `llm` CLI tool. The update mechanism tries common upgrade methods including `uv tool upgrade llm`, `pipx upgrade llm`, `pip install --upgrade llm` (and `python -m pip install --upgrade llm`), and `brew upgrade llm` to keep the tool current.
- This check runs asynchronously in the background to avoid impacting Neovim's startup time.
- You will receive a notification about the outcome of the update attempt (success or failure).

This helps ensure your `llm` tool stays up-to-date with the latest features and fixes.

## Usage Examples

### Commands

#### Unified LLM Command
- `:LLM {prompt}` - Send prompt to LLM
- `:LLM file [{prompt}]` - Send current file's content with optional prompt
- `:LLM selection [{prompt}]` - Send visual selection with optional prompt
- `:LLM explain` - Explain current buffer's code
- `:LLM fragments` - Interactive prompt with fragment selection
- `:LLM update` - Manually trigger an update check for the underlying `llm` CLI tool.

#### Unified Manager
- `:LLMConfig [view]` - Open unified manager window
- Optional views: `models`, `plugins`, `keys`, `fragments`
- `:LLMConfig models` - Open Models view
- `:LLMConfig plugins` - Open Plugins view
- `:LLMConfig keys` - Open API Keys view
- `:LLMConfig fragments` - Open Fragments view

### Basic Prompting

1. Type `:LLM Write a short poem about Neovim` and press Enter.
2. A new buffer will open with the LLM's response.

### Working with Code

1. Visually select a block of code.
2. Type `:LLMWithSelection Refactor this code for clarity` and press Enter.
3. The selected code and your prompt will be sent to the LLM.

### Explaining Code

1. Open a code file.
2. Type `:LLMExplain` and press Enter.
3. The LLM will explain the code in the current buffer.

### Using the Unified Manager

1. Type `:LLMConfig` or press `ll` (default mapping).
2. The manager window opens, likely showing the Models view first.
3. Press `P` to switch to the Plugins view.
4. Press `K` to switch to the API Keys view.
5. Navigate the list using `j` and `k`.
6. Follow the instructions in the header for actions (e.g., press `s` in the Models view to set a default model).
7. Press `q` or `` to close the manager.

## Suggested Mappings

The plugin provides default key mappings that can be disabled with `no_mappings = true`. Here are the default mappings and some suggested alternatives:

```lua
-- Toggle unified manager
vim.keymap.set('n', 'll', 'LLMConfig', { desc = "Toggle LLM Manager" })

-- Basic prompt
vim.keymap.set('n', 'lp', 'LLM', { desc = "LLM Prompt" })

-- Explain current buffer
vim.keymap.set('n', 'le', 'LLM explain', { desc = "Explain Code" })

-- Prompt with visual selection
vim.keymap.set('v', 'ls', 'LLM selection', { desc = "LLM Selection" })

-- Interactive fragments
vim.keymap.set('n', 'lf', 'LLM fragments', { desc = "LLM with Fragments" })
```

## Development

### Testing

The plugin includes a test suite using [busted](https://github.com/Olivine-Labs/busted). To run the tests, you first need to install the test dependencies:

```bash
sudo luarocks install busted
sudo luarocks install luassert
```

Then, you can run the tests:

```bash
# Run all tests
make test

# Run a specific test file
make test file=init_spec.lua
```

Tests cover:
- Core functionality (prompts, code explanation)
- Model management
- Plugin management
- API key management
- Fragment management

### Code Coverage

This project enforces a minimum code coverage of 70%. The CI/CD pipeline will fail if the coverage drops below this threshold. To run the coverage check locally, you first need to install the coverage dependencies:

```bash
sudo luarocks install luacov
sudo luarocks install luacov-console
```

Then, you can run the coverage check:

```bash
make coverage
```

This will run the tests with Luacov and print a coverage report to the console.

## Troubleshooting

### Lua Compatibility Errors

If you encounter errors like "attempt to call a nil value (global 'unpack')":
- Ensure you're using Neovim 0.7.0 or later
- Check your Lua version: `:lua print(_VERSION)` in Neovim
- Update Neovim if you're using an older version
- Report the issue with your Neovim and Lua versions if problems persist

The plugin requires Lua 5.2+ APIs which are provided by Neovim's bundled LuaJIT 2.1+.

## Documentation

For more detailed documentation, including architecture and contribution guides, see the [Documentation Directory](docs/README.md).

## License

Apache 2.0