๐Ÿš€ code-companion-picker.nvim

March 24, 2026 ยท View on GitHub

Finally, a way to actually browse your CodeCompanion prompts!

Stop memorizing prompt names or hunting through files. This plugin gives you a beautiful, fast picker with rich markdown previews that shows you exactly what each prompt does before you use it. Think Telescope for files, but for your AI prompts.

Perfect for:

  • ๐Ÿค– AI power users with large prompt libraries
  • ๐Ÿ“ Prompt collectors who want to actually use what they save
  • โšก Efficiency lovers who prefer visual browsing over memorization
  • ๐ŸŽฏ Context switchers who need different prompts for different tasks

โœจ What You Get

  • ๐Ÿ” Lightning-fast fuzzy search through your entire prompt library
  • ๐Ÿ“– Rich markdown previews with syntax highlighting
  • ๐ŸŽจ Fully customizable preview rendering - show exactly what you want to see
  • โšก Modern picker backends - Snacks (recommended) or Telescope
  • ๐Ÿง  Smart prompt handling - system prompts update context, user prompts add to chat
  • ๐Ÿ”ง Dynamic content support - prompts that use your current selection and context
  • ๐Ÿ“‹ Multiple access methods - commands, slash commands, or direct API calls

Screenshots

Coming soon - screenshots of the beautiful prompt previews and selection UI

Installation

Requirements

{
  '3ZsForInsomnia/code-companion-picker.nvim',
  dependencies = { 'folke/snacks.nvim' },
  opts = {
    picker = "snacks",
  },
  keys = {
    { "<leader>cp", "<cmd>CodeCompanionPrompts<cr>", desc = "Browse CodeCompanion Prompts" },
  },
}

With Telescope (โš ๏ธ Deprecated)

Note: Telescope support is deprecated and will be removed in a future release. Please use Snacks instead.

{
  '3ZsForInsomnia/code-companion-picker.nvim',
  dependencies = { 'nvim-telescope/telescope.nvim' },
  opts = {
    picker = "telescope",
  },
  keys = {
    { "<leader>cp", "<cmd>CodeCompanionPrompts<cr>", desc = "Browse CodeCompanion Prompts" },
  },
}

In-Chat Access

Add this to your CodeCompanion config for in-chat slash command access:

{
  strategies = {
    chat = {
      slash_commands = {
        prompts = require("code-companion-picker").select_slash_command,
      },
    },
  },
}

Then use /prompts in any CodeCompanion chat buffer to browse and insert prompts on the fly!

How Prompts Work

When you select a prompt:

  • System prompts โ†’ Updates your chat's system context
  • User prompts โ†’ Adds content to chat as your message without submitting, so you can edit before sending
  • Mixed prompts โ†’ Applies system context first, then adds user content
  • Model specified โ†’ Automatically switches to the prompt's preferred model

๐ŸŽจ Customizing Previews

Want to customize how prompt previews look? The plugin uses a composable rendering system where you can override individual sections or disable them entirely.

Quick example:

{
  renderers = {
    description = function(text, _)
      return text and ("๐Ÿ“‹ " .. text) or nil
    end,
    current_system = false, -- disable showing current system prompt
    model = function(model, _)
      return model and ("๐Ÿค– " .. model) or nil
    end,
  }
}

๐Ÿ“– See the full customization guide โ†’

The guide covers all 9 sections, advanced examples, and real-world configurations.

โš™๏ธ Configuration

{
  '3ZsForInsomnia/code-companion-picker.nvim',
  opts = {
    picker = "snacks", -- "snacks" or "telescope"
    highlights = {
      -- Customize syntax highlighting colors
      yaml_key = { fg = "#79dac8", bold = true },
      yaml_description = { fg = "#ff9e64" },
      yaml_model = { fg = "#9d7cd8" },
      system_header = { fg = "#f7768e", bold = true },
      user_header = { fg = "#9ece6a", bold = true },
      -- ... see source for all options
    },
    renderers = {
      -- Customize how each section is rendered in the preview
      description = function(text, _)
        return text and ("๐Ÿ“‹ **Description:** " .. text) or nil
      end,
      model = function(model, _)
        return model and ("๐Ÿค– **Model:** " .. model) or nil
      end,
      tools = function(tools_array, _)
        return (#tools_array > 0) and ("๐Ÿ”ง **Tools:** " .. table.concat(tools_array, ", ")) or nil
      end,
      current_system = false, -- Disable showing current system prompt
      -- Override other sections: opts, mode, context, system_prompt, user_prompt
    },
  }
}

Got VS Code prompts? Check out vs-code-companion - easily import your VS Code style prompts into CodeCompanion format. Perfect for migrating existing prompt libraries or sharing prompts between VS Code and Neovim!

๐Ÿ› ๏ธ Extending the Plugin

Public API

The plugin exposes several functions for custom integrations:

local picker = require("code-companion-picker")

-- Get all prompts from CodeCompanion's prompt library
local prompts = picker.get_codecompanion_prompts()

-- Create display text for a prompt
local display = picker.create_prompt_display_text(prompt_info)

-- Convert prompt to markdown with custom renderers
local markdown = picker.codecompanion_to_markdown(prompt_data, prompt_name, custom_renderers)

-- Apply syntax highlighting to buffer
picker.apply_markdown_highlighting(bufnr, lines, highlights)

Custom Picker Integration

To add support for a new picker backend:

local picker = require("code-companion-picker")
local handlers = require("code-companion-picker.ui.handlers")

-- Get prompts
local prompts = picker.get_codecompanion_prompts()

-- Create your picker UI with the prompts
-- When user selects a prompt, call:
handlers.handle_prompt_selection(selected_prompt_info)

The handle_prompt_selection function handles all the complexity of applying prompts correctly based on their type and content.


Happy prompting! ๐Ÿš€

TODO

  • Extract get_or_open_chat pattern from skill_handlers.lua into chat_utils and reuse in handlers.lua and tool_handlers.lua
  • Remove redundant snacks availability checks โ€” ui/pickers.lua guards duplicate what snacks_utils.lua already checks
  • Remove telescope support entirely