Posted on ::

I just added gr to my colas-bash-lib collection. It is one of the essential tools I use under emacs.

The problem🔗

I am always somewhere deep in a project, and I want to search the whole project, not just the current directory, and quickly go to found hits inside emacs, ignoring ancillary data inside .git dirs and similar.

The solution🔗

gr walks up from the current directory until it finds a mark — a file or directory named .git, .hg, .jj, .ugrep or .gr, indicating the root of the current project — and runs ug (ugrep, a better grep) recursively from there. So from anywhere in the tree:

~/src/foo/sub/sub$ gr max_connections
config/app.conf:12:4:MaxConnections = 100
src/server.go:45:1:maxConnections := ...

The output is the classic file:line:column:line format of compiler errors understood by emacs, with -I skipping binaries and --color=never keeping it clean for piping.

Emacs🔗

The whole thing is designed to play with emacs compile mode. gr prints the header gr: Entering directory \...'— in the exact format emacs expects, and only when it actually changes directory — so the relative paths in the output resolve correctly. Then it is justM-x compilefollowed bynext-error(Ctrl-x) to jump from match to match through the whole project. The precise header matters: emacs is confused by anything that does not follow its convention.

A tip: I mapped F1/F2/F3 for easy use of emacs compile mode:

;; compile: f1 search / f2 next hit / Shift-f2 previous hit
(global-set-key [f1] 'compile)
(global-set-key [f2] 'next-error)
(global-set-key (kbd "<S-f2>") 'previous-error)

Custom marks🔗

For a non-git project — or to define a sub-project root inside a monorepo — just place a .gr (or .ugrep) marker there and gr stops at it. Extra mark names are added with GR_MARKS:

export GR_MARKS='svn cvs bzr fossil vscode env'

Why I like it🔗

  • One command, from anywhere: no need to know where the repo root is.
  • Searches everything, tracked or not — which git grep can't do.
  • Emacs-ready output: browse and jump to the matches instead of eyeballing.
  • Fast: it is ug under the hood, so no grep -r slowness.

Installation, Usage, and more info🔗

github.com/ColasNahaboo/colas-bash-lib

AI co-written: don't like, don't use.

Table of Contents