A pi extension that adds a file-tree aside panel with treesitter symbol extraction powered by your existing neovim installation.
- File tree aside — right-anchored overlay (40% width, full height) that keeps your prompt visible
- Treesitter symbols — expand code files to see functions, classes, structs, enums, interfaces, methods with line numbers
- Zero extra dependencies — uses your neovim's already-installed treesitter parsers (
.sogrammars) - Parser auto-detection — scans
~/.local/share/nvim/site/parser/and nvim runtime paths on every open; install a new:TSInstallgrammar and it's immediately available - fzf integration — when
fzfis on$PATH,/fileswith no argument opens a fuzzy directory picker; partial args are fuzzy-matched viafzf --filter - Multi-select — pick multiple files and symbols with
Space; selections are appended to your pi prompt on close - Parent navigation —
..entry at the top of the tree; Enter on it re-roots to the parent directory
Clone into your pi extensions directory:
git clone https://github.com/YOUR_USER/pi-file-tree ~/.pi/agent/extensions/file-treeOr symlink from a working copy:
git clone https://github.com/YOUR_USER/pi-file-tree ~/CODE/pi-file-tree
ln -s ~/CODE/pi-file-tree ~/.pi/agent/extensions/file-treeThen /reload in pi.
- pi coding agent
- neovim (on
$PATH) with treesitter parsers installed — the extension works without nvim but symbol extraction is disabled - fzf (optional) — enables fuzzy directory picking
| Command | Description |
|---|---|
/files |
Open file tree at project root. If fzf is available, shows a fuzzy directory picker first. |
/files src/utils |
Open file tree rooted at src/utils/ |
/files util |
Fuzzy-match util against all directories (requires fzf) |
| Key | Description |
|---|---|
Alt+C |
Open file tree aside (from pi prompt) |
| Key | Action |
|---|---|
↑ ↓ |
Navigate |
Enter |
Expand/collapse — directories toggle, .. goes up, files with parser show symbols |
← → |
Fold / unfold (same as Enter, plus Left jumps to parent) |
Space |
Toggle selection on file, directory, or symbol |
Ctrl+U Ctrl+D |
Half-page scroll |
Home End |
Jump to top / bottom |
Esc or q |
Close aside — selected items are appended to your pi prompt |
| Icon | Meaning |
|---|---|
▸ / ▾ |
Collapsed / expanded directory or file |
← .. |
Parent directory navigation |
ƒ |
Function |
● |
Class |
■ |
Struct |
◆ |
Enum |
◇ |
Interface / type |
→ |
Method |
◈ |
Module |
◉ |
Const / static |
✔ |
Selected (green) |
On each aside open, the extension:
- Checks for
nvimon$PATH - Scans standard parser directories for
.so/.dylib/.dllgrammars:~/.local/share/nvim/site/parser/~/.local/share/nvim/lazy/nvim-treesitter/parser/- Any additional paths reported by
nvim --headlessviavim.api.nvim_get_runtime_file()
- Maps file extensions to parser names (40+ languages supported)
- Files with a matching parser show the
▸expand affordance
When you expand a code file, the extension runs:
nvim --headless --noplugin -n <file> -c "luafile symbols.lua"
The symbols.lua script:
- Detects filetype via
vim.bo.filetype - Maps filetype to treesitter language (with a built-in fallback table for
--nopluginmode, e.g.typescriptreact→tsx) - Walks the AST looking for definition nodes (functions, classes, structs, enums, interfaces, methods, etc.)
- Outputs a JSON array of
{ name, kind, line }to stdout - Deduplicates by name+line
Symbols are cached per-file for the lifetime of the aside.
Any language with a neovim treesitter parser installed. The extension maps these file extensions to parser names:
.ts .tsx .js .jsx .py .rs .go .lua .c .h .cpp .java .kt .rb .sh .json .yaml .toml .md .html .css .vim .xml .sql .zig .ex .erl .hs .ml .swift .dart .r .scala .svelte .vue .tf .nix
file-tree/
├── index.ts # Pi extension — command, shortcut, TUI component, fzf/treesitter integration
├── symbols.lua # Neovim lua script — treesitter symbol extraction
└── README.md
MIT