Skip to content
/
Try

Search all files in a project with Skink (grep, replace)

Search every file, then structural search.

Press Alt+S (or Ctrl+Shift+F, or run :grep TEXT) to search every file in the project. Results stream into a tab, grouped by file, and Enter on a result jumps there.

To replace the matches in every file, run :greprep WITH. The changes open in a preview first.

Project search uses the same engine as ripgrep, built in. You do not need rg installed.

Key Typed command Does
Alt+S or Ctrl+Shift+F :grep [TEXT] (:search, :rg) Search the project
:stopsearch Stop a search that is still running

In the search prompt, the same toggles as the find bar apply:

Key Toggles
Alt+R Regex
Alt+C Case-sensitive
Alt+W Whole word
  • Every file under the project root, plus any roots you added with :addroot DIR.
  • .gitignore and .ignore are honoured, so build output and node_modules stay out.
  • The search stops at 5000 matches. Narrow the query if you hit that.

Results are a normal tab, so you can keep them open while you work. After following one, come back with Alt+U (jump back, or :back).

After a search, run:

:greprep NEW_TEXT

Skink replaces the last search’s matches in every file through the refactor preview: a list of files and hunks with checkboxes and a side-by-side diff.

Key in the preview Does
↑ / ↓ Move
Space Check or uncheck
a / n Check all / none
Enter Apply the checked changes (one undo step per file)
Esc Cancel

In regex mode the replacement can use $1 for capture groups.

The changed files stay unsaved, so you can look once more before saving.

:sgrep searches code by its shape rather than its text, using ast-grep patterns. It looks in files of the current file’s language. It also works as :structural.

In a pattern, $NAME matches one syntax node and $$$NAME matches any number of them. Whitespace and comments do not matter.

Command Finds
:sgrep foo($A, $$$REST) Every call to foo with at least one argument
:sgrep $X.unwrap() Every .unwrap() call (Rust)
:sgrep console.log($$$) Every console.log (JS/TS)

:srep rewrites every structural match, through the same preview:

:srep foo($A, $B) => bar($B, $A)

That turns foo(x, y + 1) into bar(y + 1, x) everywhere, whatever the spacing or line breaks.

After an :sgrep, :greprep WITH does the same rewrite with the pattern you searched for. See Refactoring for more refactors that use the preview.

  • Search only the current file: Find and replace.
  • Find a file by name: Alt+P or :recent (quick open). A / in the query matches path segments in order, so s/c/grade finds src/color/grade.rs.
  • Find a symbol: Alt+W (:allsymbols) searches symbols in the whole project, Ctrl+R (:outline) in this file.