Skip to content

quasilyte/vscode-gogrep

Repository files navigation

Version Installs

Search for Go code using AST patterns. Uses github.com/mvdan/gogrep tool under the hood.

Features

  • Search Go code using smart matching instead of regexps
  • Find similar code fragments
  • AST-based replace for quick and precise refactoring
  • Advanced search filters (to be implemented)

If you have a feature request (or a bug report), consider to open the issue on the GitHub.

Overview

This extension exposes gogrep search commands (Ctrl+Shift+P).

Every command creates a search pattern prompt.

Search results are printed to the output channel named gogrep.

The pattern language syntax is extended Go syntax. Variables with $ prefix have special meaning.

A pattern is a piece of Go code which may include dollar expressions. It can be a number of statements, a number of expressions, a declaration, or an entire file. A dollar expression consists of '$' and a name. Dollar expressions with the same name within a query always match the same node, excluding "_".

Instead of matching a literal variable, every $<name> matches all kinds of nodes. A pattern, like $x would match any expression (or statement). If a single variable used more than once in a pattern, all occurrences must match identical nodes. So, $x=$x finds all self-assignments. Use $_ if you don't want to name a variable (repeated $_ variables do not cause submatch comparison).

Some example search patterns:

  • +$x - find usages of unary plus operator
  • strings.Replace($_, $_, $_, -1) - find places where strings.ReplaceAll can be used
  • $x != $_ || $x != $y - find || operators where comparison with $y may be redundant
  • copy($x, $x) - find copy calls where dst and src arguments are identical
  • $x = $x + 1 - find all statements that can be written as $x++
  • map[$_]$_{$*_, $k: $_, $*_, $k: $_, $*_} - find maps with at least 1 duplicated key
  • len($_) >= 0 - find sloppy length checks (this one is always true)
  • json.NewDecoder($_).Decode($_) - find potentially erroneous usages of JSON decoder

To run find similar query, run any main search command (e.g. gogrep.searchFile) with non-empty selection. The selected text will be used as a search pattern.

To perform a search-and-replace, use $find -> $replace pattern syntax. Both $find and $replace are normal gogrep patterns. To write changes back to the source files, end pattern with !. So, $x+=1 -> $x++ ! replaces all $x += 1 statements with $x++. If ! is omitted, replacements are printed to the output channel.

Additional learning resources:

Demo

Running $x = append($x, $_); $x = append($x, $_) pattern that finds consecutive appends to the same slice:

Doing a search-and-replace for with $x+=1 -> $x++ ! pattern:

Extension Settings

  • gogrep.binary: gogrep binary path (default "gogrep")
  • gogrep.gopath: whether to set gogrep process GOPATH to go.gopath (default false)

By default, we rely on Go modules. If it's not working for you, it's possible to try the GOPATH approach. To do that, set gogrep.gopath option to true. It will use the Go mode go.gopath config value to set the spawned gogrep process GOPATH environment variable.

Requirements

Note that this extension usually comes with precompiled binaries for some platforms. If there is no binary for your platform, you'll have to build gogrep from the source.

Optional/recommended:

Contributing

The easiest, though a very good way to contribute and show gratitude is to put a ⭐️ to
mvdan/gogrep and quasilyte/vscode-gogrep. :)

Contributions can be made to either of the referenced projects. PRs, bug reports, and feature requests are welcome.