Skip to content

sysid/bkmr-nvim

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

14 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

bkmr-nvim

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.

Features

  • 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

The bkmr LSP completion system works by:

  1. Filetype detection: Automatically uses your current buffer's filetype to filter snippets
  2. Tag-based filtering: Snippets must be tagged with both snip AND the language name (e.g., make)
  3. LSP activation: The LSP only attaches to buffers with filetypes in the configured list

Example

Make a bkmr snippet target availabe in nvim buffer for Makefile:

  1. Enable LSP for Makefiles

Add 'make' to the filetypes configuration so the LSP attaches to Makefile buffers.

  1. Tag target correctly

Your target snippet needs proper tags to appear in Makefile completion:

  • Option A: Tag it as make,snip (Makefile-only)
  • Option B: Tag it as universal,snip (appears in all languages with auto-comment translation)
  • Option C: Tag it as make,bash,shell,snip (appears in Makefiles and shell scripts)

Requirements

  • Neovim 0.8+
  • bkmr 4.24.0+ (with LSP support)
  • Optional: fzf-lua for enhanced snippet selection
  • Optional: nvim-lspconfig for automatic LSP setup

Development Requirements

Installation

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
}

Configuration

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
  }
})

Manual LSP Setup

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
})

Usage

Commands

  • :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.

Snippet Editing

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.

LSP Completion

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)

Debug Mode

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

API

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

Testing

The plugin includes a comprehensive test suite using plenary.nvim. Tests cover configuration management, UI template generation/parsing, and LSP response handling.

Prerequisites

Install plenary.nvim with your package manager:

-- Using lazy.nvim
{ 'nvim-lua/plenary.nvim' }

-- Using packer.nvim
use 'nvim-lua/plenary.nvim'

Running Tests

# 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

Troubleshooting

LSP Not Starting

  1. Verify bkmr is installed and in PATH: which bkmr
  2. Check bkmr version: bkmr --version (should be 4.24.0+)
  3. Test LSP manually: bkmr lsp
  4. Enable debug mode to see detailed logs

No Completions

  1. Ensure snippets exist: bkmr list
  2. Check LSP client is attached: :LspInfo
  3. Verify filetype mapping in configuration
  4. Try browsing snippets: :BkmrEdit

Snippet Selection Issues

  1. If fzf-lua isn't working, install it or disable: use_fzf = false
  2. For telescope users (not yet implemented), set: use_telescope = true, use_fzf = false
  3. Falls back to builtin vim.ui.select if neither is available

Common Errors

"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

Related Projects

License

MIT License - see LICENSE file for details.