A comprehensive Neovim plugin for the bkmr snippet manager. Provides seamless integration with the bkmr LSP server and a rich editing interface for managing snippets directly within Neovim.
- LSP Integration: Automatic setup with bkmr LSP server for snippet completion
- Visual Snippet Management: Browse and select snippets using fzf-lua or builtin selector
- Rich Editing Interface: Edit snippets in vsplit with template format matching
bkmr edit
- Neovim 0.8+
- bkmr 4.24.0+ (with LSP support)
- Optional: fzf-lua for enhanced snippet selection
- Optional: nvim-lspconfig for automatic LSP setup
- plenary.nvim for running tests
Using lazy.nvim
{
"sysid/bkmr-nvim",
dependencies = {
"ibhagwan/fzf-lua", -- Optional: for better snippet selection
"neovim/nvim-lspconfig" -- Optional: for automatic LSP setup
},
config = function()
require('bkmr').setup({
debug = false, -- Enable debug logging
ui = {
use_fzf = true, -- Enable fzf-lua integration
}
})
end
}
Default configuration:
require('bkmr').setup({
debug = false, -- Enable debug logging
lsp = {
auto_setup = true, -- Auto-configure with lspconfig
cmd = { "bkmr", "lsp" }, -- LSP server command
filetypes = { -- Supported file types
'rust', 'javascript', 'typescript', 'python', 'go', 'java', 'c', 'cpp',
'html', 'css', 'scss', 'ruby', 'php', 'swift', 'kotlin', 'shell', 'sh',
'bash', 'yaml', 'json', 'markdown', 'xml', 'vim', 'lua', 'toml'
}
},
ui = {
split_direction = "vertical", -- "horizontal" | "vertical"
split_size = "50%", -- Split width/height (number or "N%" for percentage)
use_telescope = false, -- Use telescope for selection
use_fzf = true, -- Use fzf-lua for selection
},
edit = {
auto_save = false, -- Auto-save on buffer leave
confirm_delete = true, -- Confirm before deletion
template_header = true, -- Show template header in edit buffer
}
})
If you prefer manual LSP configuration or don't have nvim-lspconfig:
require('bkmr').setup({
lsp = {
auto_setup = false -- Disable automatic setup
}
})
-- Then manually configure with nvim-lspconfig:
require('lspconfig').bkmr_lsp.setup({
cmd = { "bkmr", "lsp" },
filetypes = { "rust", "python", "javascript" }, -- your preferred filetypes
})
:BkmrEdit [language]
- Browse and edit snippets (defaults to current buffer's filetype if not specified):BkmrNew
- Create new snippet:BkmrDelete <id>
- Delete snippet by ID
When using :BkmrEdit
, you can browse available snippets and select one to edit.
When editing snippets, the interface uses section markers matching bkmr edit
:
# Snippet Template
# Section markers (=== SECTION_NAME ===) are required and must not be removed.
=== ID ===
123
=== CONTENT ===
#!/bin/bash
# This comment is part of the snippet and will be preserved
echo "Hello, World!"
echo "This is my snippet content"
=== TITLE ===
My Example Snippet
=== TAGS ===
_snip_,bash,shell
=== COMMENTS ===
This snippet demonstrates the editing format
=== END ===
Note: All content within sections is preserved literally, including lines starting with #
.
Only template header comments (outside of sections) are ignored.
The plugin automatically configures bkmr LSP completion. Snippets will appear in completion menus based on:
- Current buffer filetype (e.g.,
.rs
files show Rust snippets) - Universal snippets (tagged with appropriate tags)
- Manual completion trigger (varies by completion plugin)
Enable debug mode to see detailed LSP communication:
require('bkmr').setup({
debug = true
})
Debug features:
- All LSP requests and responses are logged
- Large responses (>10 items) are automatically truncated in logs
- Error messages are properly extracted from various response formats
- Use
:messages
to view debug output
The plugin provides a Lua API for integration with other plugins:
local bkmr = require('bkmr')
-- Check if LSP is available
if bkmr.is_lsp_available() then
-- Get current context
local context = bkmr.get_context()
print(context.filetype)
end
-- Programmatically create snippet
bkmr.new_snippet()
-- List snippets with language filter
bkmr.list_snippets("rust")
-- Delete snippet
bkmr.delete_snippet(456)
-- Note: edit_snippet is used internally when selecting from list
The plugin includes a comprehensive test suite using plenary.nvim. Tests cover configuration management, UI template generation/parsing, and LSP response handling.
Install plenary.nvim with your package manager:
-- Using lazy.nvim
{ 'nvim-lua/plenary.nvim' }
-- Using packer.nvim
use 'nvim-lua/plenary.nvim'
# Run all tests (24 tests across 3 modules)
make test
# Run tests interactively in Neovim
make test-interactive
# Run specific test file
make test-file FILE=test_ui.lua
# Manual testing with debug scripts
make test-manual
- Verify bkmr is installed and in PATH:
which bkmr
- Check bkmr version:
bkmr --version
(should be 4.24.0+) - Test LSP manually:
bkmr lsp
- Enable debug mode to see detailed logs
- Ensure snippets exist:
bkmr list
- Check LSP client is attached:
:LspInfo
- Verify filetype mapping in configuration
- Try browsing snippets:
:BkmrEdit
- If fzf-lua isn't working, install it or disable:
use_fzf = false
- For telescope users (not yet implemented), set:
use_telescope = true, use_fzf = false
- Falls back to builtin vim.ui.select if neither is available
"Failed to create/update snippet: Unknown error"
- The LSP server returns the snippet object directly on success
- This is normal behavior and the snippet is actually saved
"E382: Cannot write, 'buftype' option is set"
- This has been fixed - the buffer type is now 'acwrite'
- Save with
:w
should work properly
"Invalid tag: Tag cannot be empty"
- Empty language filters are now properly handled
- Use
:BkmrList
without arguments to list all snippets
- bkmr - Command-line bookmark and snippet manager
- bkmr-intellij-plugin - IntelliJ Platform integration
MIT License - see LICENSE file for details.