Simplify README to focus on quick start and essential usage. Rename configuration.md to advanced.md for clearer positioning. Add v0.1.2 changelog entry. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
9.5 KiB
Advanced Configuration
This document describes the main configuration options and rule schema for lazy-project-search.nvim.
Basic setup
require("project_search").setup({
keymap = "<leader>sP",
auto_init = true,
storage_dir = vim.fn.stdpath("data") .. "/project-search/rules",
template_dirs = {
vim.fn.stdpath("config") .. "/project-search/templates",
vim.fn.stdpath("data") .. "/project-search/templates",
},
root = nil,
root_markers = {
".git",
"package.json",
"pnpm-workspace.yaml",
"pnpm-lock.yaml",
"yarn.lock",
"package-lock.json",
"lazy-lock.json",
"stylua.toml",
"selene.toml",
},
default_excludes = {
".git",
"node_modules",
"dist",
"build",
".next",
".nuxt",
"coverage",
},
templates = {
common = true,
react = true,
vue = true,
nest = true,
user = {},
},
picker = {
title = "Project Search",
layout = "default",
},
})
If you define keymaps through lazy.nvim, set:
keymap = false
This avoids registering the same key twice.
Options
keymap
Type:
string | false
Default:
"<leader>sP"
When set to a string, Project Search registers a normal-mode keymap for :ProjectSearch.
When set to false, no keymap is registered.
Recommended LazyVim usage:
opts = {
keymap = false,
}
Then define the key through lazy.nvim:
keys = {
{
"<C-p>",
"<cmd>ProjectSearch<cr>",
desc = "Project Search",
},
}
auto_init
Type:
boolean
Default:
true
When enabled, the first :ProjectSearch call creates a project rules file automatically if none exists.
storage_dir
Type:
string
Default:
vim.fn.stdpath("data") .. "/project-search/rules"
Directory used to store per-project rule files.
Rules are stored outside your source repository to avoid accidentally committing project-local search configuration.
template_dirs
Type:
string[]
Default:
{
vim.fn.stdpath("config") .. "/project-search/templates",
vim.fn.stdpath("data") .. "/project-search/templates",
}
Directories used to load user templates.
User templates are JSON files that can be enabled from:
templates = {
user = { "my-template" },
}
or:
templates = {
user = true,
}
When user = true, all user templates found in template_dirs are loaded.
root
Type:
string | fun(): string | nil
Default:
nil
Overrides project root detection.
Example:
root = function()
return vim.fs.root(0, { ".git", "package.json" }) or vim.fn.getcwd()
end
root_markers
Type:
string[]
Used when root is not provided.
Project Search searches upward from the current working directory and buffer path to find one of these markers.
default_excludes
Type:
string[]
Default excludes applied to supported search runners.
Common defaults include:
{
".git",
"node_modules",
"dist",
"build",
".next",
".nuxt",
"coverage",
}
templates
Type:
{
common = boolean,
react = boolean,
vue = boolean,
nest = boolean,
user = boolean | string[],
}
Controls which templates are used during rule initialization.
Example:
templates = {
common = true,
react = true,
vue = false,
nest = false,
user = { "frontend-team" },
}
picker
Type:
{
title = string,
layout = string,
}
Controls the picker title and layout passed to Snacks Picker.
Rule file structure
A rule file looks like this:
{
"version": 1,
"meta": {
"projectRoot": "/path/to/project",
"template": "react",
"createdAt": "2026-05-20T00:00:00Z",
"note": "This file is stored outside your project. Edit presets to customize Project Search."
},
"presets": []
}
Only version and presets are required for validation.
Preset common fields
Every preset can use these fields:
{
"id": "react.query_key",
"name": "React: queryKey",
"description": "Search TanStack Query queryKey usage.",
"type": "grep",
"group": "React",
"tags": ["react", "query"],
"order": 10,
"enabled": true
}
id
Stable identifier for the rule.
If omitted, Project Search falls back to:
preset.<index>
Recommended format:
domain.feature
Examples:
react.query_key
react.hooks.kebab
project.service_files
name
Human-readable picker label.
description
Optional explanation shown in previews.
type
Required.
Allowed values:
files
grep
files_regex
group
Optional picker group name.
Examples:
Common
React
TanStack
Service
Router
Manage
tags
Optional string array for future filtering and organization.
Can be written as a string or string array:
"tags": "react"
or:
"tags": ["react", "query"]
order
Optional number used for sorting inside groups.
Lower values appear earlier.
enabled
Optional boolean.
Default:
true
When set to false, the preset is ignored.
files presets
Use files when you want to open a file picker rooted at a project directory.
{
"id": "common.files.src",
"name": "Files: src",
"description": "Open a file picker rooted at src.",
"type": "files",
"group": "Common",
"order": 10,
"cwd": "src"
}
Fields:
cwd optional directory used as picker cwd
dirs optional fallback directory list
hidden include hidden files
ignored include ignored files
grep presets
Use grep when you want to search inside files.
{
"id": "react.query_key",
"name": "React: queryKey",
"description": "Search TanStack Query queryKey usage.",
"type": "grep",
"group": "React",
"order": 20,
"search": "queryKey",
"dirs": ["src", "app"],
"glob": ["*.ts", "*.tsx"]
}
Regex grep:
{
"id": "react.query_hooks",
"name": "TanStack Query: hooks",
"description": "Search query-related React hooks.",
"type": "grep",
"group": "TanStack",
"order": 10,
"regex": true,
"search": "useQuery|useMutation|useInfiniteQuery",
"dirs": ["src"],
"glob": ["*.ts", "*.tsx"]
}
Live grep:
{
"id": "project.service_content",
"name": "Search: service content",
"description": "Live grep under src/service.",
"type": "grep",
"group": "Service",
"live": true,
"regex": true,
"search": "",
"dirs": ["src/service"],
"glob": ["*.ts", "*.tsx"]
}
Fields:
search search query
regex boolean, default false
live boolean, default false
dirs directory or directory list
glob glob or glob list
exclude exclude pattern or pattern list
args extra rg args
hidden include hidden files
ignored include ignored files
files_regex presets
Use files_regex when you want to find files by path convention.
It is backed by fd / fdfind.
{
"id": "react.hooks.kebab",
"name": "Hooks: use-* kebab files",
"description": "Find hook files such as hooks/use-claw-history-panel.ts.",
"type": "files_regex",
"group": "React",
"order": 10,
"regex": "(^|/)hooks/use-[a-z0-9-]+\\.(ts|tsx|js|jsx)$",
"dirs": ["src", "app", "packages"],
"exclude": ["node_modules", "dist", "build", ".next"]
}
Fields:
regex required fd-compatible regex string
dirs directory or directory list
exclude exclude pattern or pattern list
hidden include hidden files
ignored include ignored files
Important: fd uses Rust regex syntax. Look-around is not supported.
Avoid:
{
"regex": "service/[^/]+(?<!\\.test|\\.spec)\\.(ts|tsx)$"
}
Prefer:
{
"regex": "service/[^/]+\\.(ts|tsx)$",
"exclude": ["*.test.ts", "*.test.tsx", "*.spec.ts", "*.spec.tsx"]
}
Validation
Validate the current project rules from Neovim:
:ProjectSearch validate
Run repository checks locally:
make check
make check runs:
format-check
validate
test
test-runner
Recommended React preset example
{
"version": 1,
"presets": [
{
"id": "react.files.src",
"name": "Files: src",
"description": "Open files under src.",
"type": "files",
"group": "Common",
"order": 10,
"cwd": "src"
},
{
"id": "react.class_name",
"name": "React: className",
"description": "Search JSX className usage.",
"type": "grep",
"group": "React",
"order": 20,
"search": "className",
"dirs": ["src", "app"],
"glob": ["*.tsx", "*.jsx"]
},
{
"id": "react.query_key",
"name": "React: queryKey",
"description": "Search TanStack Query queryKey usage.",
"type": "grep",
"group": "TanStack",
"order": 10,
"search": "queryKey",
"dirs": ["src", "app"],
"glob": ["*.ts", "*.tsx"]
},
{
"id": "react.hooks.kebab",
"name": "Hooks: use-* kebab files",
"description": "Find hook files such as hooks/use-claw-history-panel.ts.",
"type": "files_regex",
"group": "React",
"order": 30,
"regex": "(^|/)hooks/use-[a-z0-9-]+\\.(ts|tsx|js|jsx)$",
"dirs": ["src", "app", "packages"]
},
{
"id": "project.service_files",
"name": "Service: API layer files",
"description": "Find service files while excluding tests.",
"type": "files_regex",
"group": "Service",
"order": 10,
"regex": "service/[^/]+\\.(ts|tsx)$",
"dirs": ["src"],
"exclude": ["*.test.ts", "*.test.tsx", "*.spec.ts", "*.spec.tsx"]
}
]
}