This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
pj.nvim is a Neovim plugin for fast project discovery and navigation using the pj binary. It provides a pluggable picker architecture supporting multiple UI frameworks (Snacks, Telescope, fzf-lua, television, mini.pick).
There is no formal test suite or build system. Testing is done manually:
# Run health check inside Neovim
:checkhealth pj
# Test the plugin
:Pj
:Pj depth=2
:PjCdplugin/pj.lua- Registers user commands (:Pj,:PjCd,:PjCheckUpdates, etc.) and parses command argumentslua/pj/init.lua- Main module withsetup(),open(), andcd()APIs
lua/pj/config.lua- Configuration defaults and deep-merge setuplua/pj/binary.lua- Auto-download, version checking, platform detection for the pj binarylua/pj/finder.lua- Executes pj binary, parses output (text or JSON mode)lua/pj/session.lua- Integrates with auto-session or persistence.nvimlua/pj/depth.lua- State machine for project tree search depth controllua/pj/icons.lua- Maps project markers to filetypes for icon lookup
All pickers in lua/pj/pickers/ implement the same interface: an open(opts) function that:
- Fetches projects via
finder.get_projects() - Displays the picker UI
- Handles actions (open, split, vsplit, tab, depth control)
pickers/init.lua- Registry and selector for configured pickerpickers/snacks.lua- Snacks.nvim (default)pickers/telescope.lua- Telescope.nvimpickers/fzf_lua.lua- fzf-luapickers/tv.lua- Television binarypickers/mini.lua- mini.pick
User Command (:Pj)
→ plugin/pj.lua (parse args)
→ lua/pj/init.lua (binary check, async download if needed)
→ lua/pj/pickers/init.lua (select configured picker)
→ Picker implementation (fetch projects via finder, display UI)
→ On selection: session.lua (load session) or direct cd
- Module pattern: All files export
local M = {}; return M - Configuration: Deep-merged via
vim.tbl_deep_extend("force", defaults, opts) - Async operations: Use
vim.fn.jobstart()for non-blocking binary downloads - Safe library loading: Use
pcall()when checking for optional dependencies - Callbacks: Binary download and updates use callback-based async patterns
- Create
lua/pj/pickers/newpicker.lua - Implement
M.open(opts)function - Add to registry in
pickers/init.lua - Add picker-specific config defaults in
config.lua
~/.local/share/nvim/pj-nvim/bin/pj with metadata stored alongside