FindItFaster: Sonar
Fork of FindItFaster. Linux + WSL. File/content search powered by What's new
What's different from upstream
Install
(Debian/Ubuntu ships Version thresholds. The only hard requirement is that
At activation the extension probes Missing WSL on Windows
CommandsPrefix:
The Query syntaxEvery command splits its query at
fzf extended-search syntax (Search file, Search within current file)Standard fzf syntax — Examples:
rg regex +
|
| Token | Effect | rg flag |
|---|---|---|
c |
rg type (e.g. .c/.h) |
-t c |
!c |
exclude C files | -T c |
*.c |
glob | -g '*.c' |
!*_test.c |
negated glob | -g '!*_test.c' |
src/** |
top-level src/ only |
-g 'src/**' |
!node_modules/** |
top-level node_modules/ only |
-g '!node_modules/**' |
.md |
shorthand for *.md |
-g '*.md' |
!vendor/ |
exclude vendor/ at any depth |
-g '!**/vendor/**' |
@embedded |
exclude group embedded's entries |
-g '!…' per entry |
@ignore |
honor .gitignore + search.exclude (built in) |
--ignore --no-require-git |
Glob vs type: contains *?/. → glob, otherwise rg type. rg --type-list for types.
Default mode searches everything — .gitignore is NOT honored and hidden files are included (only .git/ itself is skipped). Filtering is opt-in per query, and the two kinds are independent: @group excludes that group's entries, @ignore honors .gitignore + search.exclude. Excluding build directories therefore never hides a gitignored file you deliberately search for; combine them (@embedded @ignore) when you want both. Configure groups with general.excludeDirectoryGroups, or findFiles.defaultGroups to apply them to every Search file run without typing them — see Settings. Tab completes @group names, @ignore included (fzf ≥ 0.45).
Path globs are root-anchored. src/** matches top-level src/ only — use **/src/** for nested. Same for !node_modules/**.
Not available in "Search within open files". rg applies neither --type nor --glob nor ignore rules to explicit file arguments, so // tokens cannot work there — the command says so and refuses rather than returning unfiltered results.
Examples:
todo // c # "todo" in C files
handler // py !*_test.py # "handler" in Python, skip test files
foo // src/** # "foo" under top-level src/ (use **/src/** for nested)
config // *.json !**/dist/** # "config" in JSON, skip dist dirs
cleanup // !vendor/ # skip vendor/ at any depth (dir shorthand)
todo // @embedded # exclude group "embedded"; .gitignore still off
todo // @embedded @ignore # ...and honor .gitignore + search.exclude
todo // @embedded @py c # both groups, C sources only
^import .* from // ts # regex on the left, file filter on the right
Empty pattern: // py matches every line of every .py file — a way to browse a filetype rather
than search it.
Recipes
First word = which command to run.
Find files
Search file .svg$ every SVG
Search file ^src/ .ts$ | .tsx$ TS/TSX under src/
Search file 'README literal "README" in name
Search file migration !.sql$ "migration" but not .sql
Search file !test !spec neither test nor spec
Search file ^docs .md$ markdown under docs/
Search file config | settings .json$ config.json or settings.json
Search within files
Search within files TODO // py TODOs in Python
Search within files ^def\s+\w+ // py Python function defs
Search within files use[A-Z]\w+ // ts React hooks (ts covers .tsx)
Search within files https?://\S+ // md URLs in markdown
Search within files TODO|FIXME|XXX // !*_test.* todos outside tests
Search within files FIXME // src/** !*.lock fixmes under src/, not lockfiles
Search within files // py browse every line of every .py file
Search within current file
Search within current file .error$ lines ending in "error"
Search within current file ^return lines starting with `return`
Search within current file 'throw lines with literal "throw"
Search within current file TODO | FIXME either tag
Fastest: rg pre-filter (large repos)
ctrl+shift+alt+j → "svg" # only .svg files
ctrl+shift+alt+u → "py" # within .py only
Tips
ctrl+p/ctrl+n— fzf's own history binds; the extension gives them 30 entries that survive a reload (~/.cache/find-it-faster/history)ctrl+v— paste from the clipboard (needs fzf ≥ 0.38)ctrl+x— clear the querytab— complete/cycle@groupnames,@ignoreincluded, in Search file and Search within files (needs fzf ≥ 0.45)
Everything else in the picker is stock fzf — see man fzf for the full key list.
Settings
@ext:stoffej.fif-sonar in settings. Keys under fif-sonar.*.
Migrating from FindItFaster
Keys are fif-sonar.*, not find-it-faster.*. VS Code keeps old keys silently, so they
look active while their values revert to this extension's defaults. general.useGitIgnoreExcludes
and general.useWorkspaceSearchExcludes are gone entirely — .gitignore and search.exclude
are now opt-in per query via @ignore (or permanently for Search file via
findFiles.defaultGroups: ["ignore"]).
General
| Key | Default | Purpose |
|---|---|---|
general.hideTerminalAfterSuccess |
true |
Hide terminal after pick. |
general.hideTerminalAfterFail |
true |
Also hide on cancel. |
general.clearTerminalAfterUse |
true |
clear before hiding. |
general.killTerminalAfterUse |
true |
Dispose terminal fully. |
general.showMaximizedTerminal |
false |
Maximize while picking. |
general.excludeDirectoryGroups |
{} |
Named exclude groups for @group query tokens. An entry with */? is a file glob (*.o), anything else a directory name (dist). settings.json only. |
general.batTheme |
"Dracula" |
Preview theme. Matches the fzf colors. |
Find files
| Key | Default | Purpose |
|---|---|---|
findFiles.defaultGroups |
[] |
Groups from general.excludeDirectoryGroups applied to every Search file, plus the built-in "ignore". Empty = list everything. |
defaultGroups: ["ignore"] is the persistent form of typing // @ignore: Search file then
honors .gitignore + search.exclude on every run. It applies to Search file only — Search
within files has // tokens, so you ask for @ignore there per query. And it stays independent
of ordinary groups: ["embedded", "ignore"] excludes the embedded group's entries and follows
.gitignore, while ["embedded"] alone leaves .gitignore off.
Find within files
findWithinFiles has no configurable settings — preview, its command/window layout, and query
matching (always exact, no fuzzing) are fixed.
Advanced
advanced has no configurable settings — the startup preflight never runs, and the query is
always seeded from the editor selection.
Example settings
Every setting, at its default unless noted (Ctrl+Shift+P → Preferences: Open User Settings
(JSON)). Copy the whole block and delete what you don't care about — omitting a key is the same
as leaving it at the value shown.
{
// ---------- Exclude groups ----------
// Each key is a @group name used in queries. A bare entry is a directory
// name matched at any depth ("dist" -> !**/dist/**); an entry containing
// * or ? is a file glob used as-is ("*.o" -> !*.o). A group excludes ONLY
// its own entries — .gitignore is the separate, built-in @ignore token.
// "ignore" is reserved and cannot be used as a group name.
"fif-sonar.general.excludeDirectoryGroups": {
"embedded": ["build", ".pio", "cmake-build-debug", "Debug", "Release"],
"obj": ["*.o", "*.hex"],
"py": [".venv", "__pycache__", ".mypy_cache", "*.pyc"]
},
// ---------- Find files ----------
// Groups applied to every Search file run without typing them. The
// built-in "ignore" belongs here too — it is how you make Search file
// honor .gitignore + search.exclude permanently. Default: []
"fif-sonar.findFiles.defaultGroups": ["embedded", "ignore"],
// ---------- Terminal behavior ----------
"fif-sonar.general.hideTerminalAfterSuccess": true,
"fif-sonar.general.hideTerminalAfterFail": true,
"fif-sonar.general.clearTerminalAfterUse": true,
"fif-sonar.general.killTerminalAfterUse": true,
"fif-sonar.general.showMaximizedTerminal": false,
// ---------- Presentation ----------
"fif-sonar.general.batTheme": "Dracula"
}
With the groups above, todo // @embedded searches for "todo" while skipping build/, .pio/,
etc. — .gitignore stays off unless you add @ignore. todo // @embedded @obj c adds the object
files and limits to C sources. In Search file the two entries in defaultGroups are already
applied, so you only type what you want on top of them.
FAQ
Ctrl+K doesn't move up in fzf. Set "terminal.integrated.allowChords": false.
Files from other folders don't show up. Picker uses terminal cwd. Open the wider folder.
Terminal closes before I can read an error. On precondition failure the extension keeps it open. If it still disappears, a workspace override on hideTerminalAfterFail may be overriding the extension.
Preview empty. bat missing. Install it.
A file I know is .gitignored doesn't show up. Default mode ignores .gitignore — it should show up. Example, with build/output.js gitignored:
| Query | Shows build/output.js? |
Why |
|---|---|---|
output |
yes | default mode searches everything |
output // @ignore |
no | @ignore honors .gitignore |
output // @web (some other group) |
yes | @group excludes only its own entries, not gitignored files |
Still missing with a plain query? ctrl+x clears the query first — Resume last search can silently bring back an old @ignore/@group from a previous search. Then verify outside the extension, from the workspace root:
rg --files --hidden --no-ignore --glob '!**/.git/' | grep -F build/output.js
No match there either → it's an rg/gitignore-pattern interaction (or the file genuinely isn't there), not this extension — that's the exact command the picker runs by default.
Native Windows? Not supported. Use WSL.
Credits
Thanks to Tom Rijndorp for FindItFaster — this fork is built on it.