SI Search
A Source Insight-style code search extension for VS Code, designed for C/C++ developers working on large-scale codebases.
SI Search builds a symbol index using tree-sitter parsing, enabling instant symbol lookup across your entire workspace. When the index doesn't cover a query, it falls back to ripgrep full-text search seamlessly.
Features
Symbol Index (Sync)
SI Search uses tree-sitter (WASM) to parse all C/C++ source files in your workspace and extract symbol definitions:
- Functions —
int main(), void foo()
- Structs —
struct device
- Enums —
enum state
- Typedefs —
typedef unsigned int uint32_t
- Macros —
#define MAX_SIZE 1024, #define INIT(x) ...
- Classes (C++) —
class Widget
- Namespaces (C++) —
namespace std
- Unions —
union data
The index is persisted to disk (.sisearch/index.json in the workspace root) and automatically restored on VS Code restart—no re-scanning needed.
Press Ctrl+Shift+S or click the sync button in the Search panel title bar to build/update the index.
Two-Tier Search Strategy
- Index search (instant) — When the symbol index is ready, queries are matched against the in-memory index with O(1) exact lookup or fast substring/regex scan.
- Ripgrep fallback — If the index has no results (e.g., searching for a string literal rather than a symbol name), SI Search automatically falls back to ripgrep full-text search.
This hybrid approach gives you the speed of pre-built indexes with the coverage of full-text search.
Search Results Panel
- Syntax-highlighted preview — Hover over any result's code portion to see a multi-line preview with full syntax highlighting (powered by shiki), matching your current VS Code color theme.
- Jump to source — Click the arrow icon on any result to open the file at the exact line.
- Result navigation — Step through results one by one with
Ctrl+Shift+F4 / Ctrl+Shift+F3.
- Gutter indicators — Source files that contain search results show blue triangle markers in the editor gutter.
- CodeLens links — "Jump to Search Result" CodeLens appears on matched lines, allowing quick navigation back to the results panel.
Manual Highlights
- Press
Ctrl+Shift+F8 to highlight the selected text (or trigger a selection prompt in the results panel).
- Multiple highlight colors cycle automatically.
- Highlights appear both in the results panel and in all open editors.
- The Highlights tree view in the sidebar shows all active highlights with remove buttons.
Incremental File Watching
SI Search monitors your workspace for file changes:
- Modified/created files are marked as dirty; the status bar shows "stale".
- Deleted files are removed from the index.
- Re-sync (
Ctrl+Shift+S) only re-parses changed files, not the entire workspace.
Architecture
File System ── SymbolParser (web-tree-sitter WASM) ── SymbolIndex (Memory + Disk)
|
SearchEngine
/ \
Index Search Ripgrep Fallback
File Watcher ── marks dirty/deleted files ── SymbolIndex
Key components:
| Component |
File |
Purpose |
| SymbolParser |
src/symbolParser.ts |
Tree-sitter WASM initialization, grammar loading, symbol extraction via S-expression queries |
| SymbolIndex |
src/symbolIndex.ts |
Dual-map in-memory index (symbolsByFile + nameIndex), full/incremental sync, disk persistence |
| FileWatcher |
src/fileWatcher.ts |
VS Code FileSystemWatcher wrapper, tracks dirty/deleted files |
| SearchEngine |
src/searchEngine.ts |
Ripgrep wrapper + executeSearchWithIndex() hybrid dispatcher |
| SyntaxHighlight |
src/syntaxHighlight.ts |
Shiki-based tokenization for hover preview, with VS Code theme integration |
Commands
| Command |
Title |
Default Keybinding |
siSearch.focusSearchPanel |
SI Search: Focus Search Panel |
Ctrl+/ (Cmd+/ on macOS) |
siSearch.toggleResultsPanel |
SI Search: Toggle Results Panel |
Ctrl+Shift+/ (Cmd+Shift+/) |
siSearch.syncIndex |
SI Search: Synchronize Files |
Ctrl+Shift+S (Cmd+Shift+S) |
siSearch.clearIndex |
SI Search: Clear Symbol Index |
— |
siSearch.nextResult |
SI Search: Next Result |
Ctrl+Shift+F4 (Cmd+Shift+F4) |
siSearch.previousResult |
SI Search: Previous Result |
Ctrl+Shift+F3 (Cmd+Shift+F3) |
siSearch.highlightSelection |
SI Search: Highlight Selection |
Ctrl+Shift+F8 (Cmd+Shift+F8) |
siSearch.clearAllHighlights |
SI Search: Clear All Highlights |
— |
siSearch.jumpToResult |
SI Search: Jump to Result from Source |
Alt+J |
siSearch.clearResults |
Clear Search Results |
— |
siSearch.removeHighlight |
Remove Highlight |
— |
Configuration
All settings are under the siSearch.* namespace in VS Code settings.
| Setting |
Type |
Default |
Description |
siSearch.includeFileExtensions |
string[] |
[".c", ".h", ".cpp", ".hpp", ".cc", ".cxx", ".hxx", ".inl"] |
File extensions to include in search and symbol indexing. |
siSearch.excludePatterns |
string[] |
["**/build/**", "**/.git/**", "**/node_modules/**"] |
Glob patterns to exclude from search. |
siSearch.previewContextLines |
number |
5 |
Number of context lines shown above and below the matched line in hover preview. |
siSearch.highlightColors |
string[] |
["cyan", "pink", "lightgreen", "magenta", "cornflowerblue", "orange", "green", "red"] |
Color palette for manual highlight marking. Colors cycle in order. |
siSearch.highlightBox |
boolean |
true |
When true, highlights use a border-only box style; when false, highlights use solid background fill. |
siSearch.navigationWrap |
boolean |
true |
Wrap around to the first/last result when navigating past the end/beginning. |
siSearch.autoSyncOnSave |
boolean |
false |
Automatically re-sync dirty files when saving. |
Search Options
The search input supports three toggle options:
- Case Sensitive (
Aa) — Match exact letter casing.
- Whole Word (
W) — Match whole words only (maps to ripgrep --word-regexp or index exact name match).
- Regex (
.*) — Interpret the query as a regular expression.
SI Search contributes two views to its own activity bar container:
| View |
ID |
Description |
| Search |
siSearch.searchPanel |
Webview with search input, options, and search history list. |
| Highlights |
siSearch.highlightsView |
Tree view showing all active manual highlights with per-item remove buttons. |
Status Bar
The status bar item (bottom-left) shows the current index state:
| State |
Display |
Meaning |
| None |
$(database) Index: None |
No index built yet. Click to sync. |
| Building |
$(sync~spin) Index: Syncing... |
Index build in progress. |
| Ready |
$(database) 15,234 symbols |
Index ready with symbol count. |
| Stale |
$(database) 15,234 symbols (stale) |
Files changed since last sync. Click to re-sync. |
How It Works
Symbol Parsing
SI Search loads tree-sitter WASM grammars for C and C++ at runtime. For each source file, it runs tree-sitter S-expression queries to extract symbol definitions:
;; Example: extract function names
(function_definition
declarator: (function_declarator
declarator: (identifier) @name)) @def
Each extracted symbol records: name, kind, file path, line number, column, and the line's text content.
Index Structure
The in-memory index uses two maps for different access patterns:
symbolsByFile (Map<relativePath, SymbolEntry[]>) — Enables O(1) per-file removal during incremental updates.
nameIndex (Map<lowerCaseName, SymbolEntry[]>) — Enables O(1) exact lookup and fast substring scanning.
Disk Persistence
The index is serialized to {workspaceRoot}/.sisearch/index.json as a JSON file containing:
{
"version": 1,
"createdAt": 1712700000000,
"workspaceRoot": "/path/to/workspace",
"files": [{ "relativePath": "...", "mtime": ..., "size": ..., "symbolCount": ... }],
"symbols": [{ "name": "...", "kind": "function", "filePath": "...", ... }]
}
On VS Code startup, the index is loaded from disk. The version field ensures forward compatibility—if the format changes, old indexes are discarded and rebuilt.
Incremental Sync
During sync, SI Search compares each file's mtime and size against the stored metadata. Only files that are new, modified, or deleted are processed. This makes re-syncing a large codebase (e.g., Linux kernel) take seconds instead of minutes.
Requirements
- VS Code 1.85.0 or later.
- No external dependencies required. All tree-sitter WASM grammars and the ripgrep binary are bundled with the extension.
Build from Source
Prerequisites
Install Dependencies
npm install
Compile
npm run compile
This runs tsc -p ./ to compile TypeScript to out/.
Watch Mode (for development)
npm run watch
Package as VSIX
npx @vscode/vsce package
This will:
- Copy WASM files from
node_modules to wasm/ (npm run copy-wasm)
- Compile TypeScript (
npm run compile)
- Package everything into
sisearch-<version>.vsix
Install VSIX
code --install-extension sisearch-<version>.vsix
Or in VS Code: Ctrl+Shift+P → Extensions: Install from VSIX...
Known Limitations
- Symbol indexing currently supports C and C++ only. Other languages fall back to ripgrep full-text search.
- The hover preview renders code using the current VS Code theme via shiki. Some custom themes may not render perfectly.
- The
.sisearch/ directory is created in the workspace root. Add it to your .gitignore if needed.
License
MIT