Usage

Installation

This version of rg is supported on GNU Emacs 26.1 or later on Linux systems. It might work on older Emacsen and on other systems but such configurations are not tested. Patches for other OS:es are welcome.

MELPA

Packages are published on MELPA Stable and MELPA. From within Emacs, run M-x package-install [RET] rg [RET] to install from those sources.

Enable default key bindings:

(rg-enable-default-bindings)

The above will enable the default key map rg-menu under the default prefix key C-c s.

Manual

Releases can alternatively be downloaded from GitHub and installed manually. Put all elisp files in main directory in your load path and require the package in your init file.

(require 'rg)
(rg-enable-default-bindings)

You would also need to make sure all package requirements are met. For this version these are:

  • wgrep 2.1.10

  • transient 0.3.0

  • emacs 26.1

rg is using autoloaded symbols which means it’s also possible to defer loading if you have autoloading setup. That usually comes out of the box with package-install.

Lazy loading

For lazy loading you don’t want to call directly into the package during startup. Use a setup similar to this instead:

(global-set-key (kbd "C-c s") #'rg-menu)
(with-eval-after-load 'rg
   ;; Your settings goes here.
)

If you don’t want to use the transient menu interface, the following is needed to achieve lazy loading:

;; Workaround for emacs' lack of autoloaded keymaps.
;; This is essentially what use-package do.
(defun rg-autoload-keymap ()
  (interactive)
  (if (not (require 'rg nil t))
      (user-error (format "Cannot load rg"))
    (let ((key-vec (this-command-keys-vector)))
      (global-set-key key-vec rg-global-map)
      (setq unread-command-events
        (mapcar (lambda (ev) (cons t ev))
                (listify-key-sequence key-vec))))))

(global-set-key (kbd "C-c s") #'rg-autoload-keymap)
(with-eval-after-load 'rg
   ;; Your settings goes here.
)

wgrep

This package use wgrep for editing capabilities in the rg results buffer. No setup is needed.

Isearch integration

Optional isearch integration can be enabled to allow you to extend isearch to trigger ripgrep searching. Enable it in your configuration with:

(require 'rg-isearch)
(define-key isearch-mode-map "\M-sr" 'rg-isearch-menu)

For the evil use case where isearch-mode is exited after first search hit, users would also want to add the binding to the global-map or similar.

Interaction with the ripgrep configuration file

The ripgrep binary allows using a configuration file to set default values for command line flags. This package requires specific command line flags to function correctly and using a ripgrep configuration may conflict with these requirements. Therefore the configuration file is ignored by default. This can be changed by the rg-ignore-ripgreprc setting.

Note

Using the ripgrep configuration file may break functionality of this package if you are not careful.

Interaction with xterm-color

This package is not written to be used with custom output colors provided by external packages like xterm-color. It relies on the color escape sequences so stripping these will break in unexpected ways. If you are using such packages, the advice is to hook such functionality into compilation-filter-hook instead of advising compilation-filter.

Searching

Searching is done by invoking one of the different frontend commands. This package is built around recursive search based on three parameters; a single directory, file type filter, and a search pattern. These three parameters can interactively be selected or figured out automatically by the package, depending on which command that is used.

The underlying ripgrep binary has the file type filter concept built in. You have a high level of control over which files to search and which to ignore. This is partly what makes it so fast, ignoring uninteresting files.

In addition to the base parameters there are a lot of options that control how a search is done. These are typically selected from the rg-menu interface.

Case sensitivity

Considering case when searching is an important feature of any search tool. This package gives you a lot of control over how to handle case sensitive and case insensitive search. It can be forced to on or off and set to smart case. The latter is similar to the ripgrep --smart-case flag but is not using the flag directly. One thing to note about this is that the case insensitive setting controls the behavior when starting a new search. In the results buffer the setting is fixed to on or off but can be toggled easily with a key binding. See rg-ignore-case customization for the details of the configuration.

Do what I mean

The DWIM family of search commands tries to be smart by figure out the search parameters from the context without prompting. Thanks to ripgrep’s speed, this allows for new ways of searching by invoking a dwim command and then refine the search from the results buffer.

These commands use the word (with the definition of word depending on context) under cursor as the query string. The file type parameter is taken from the type of the currently visited file. If the current file type can not be identified all file types known to ripgrep are used. The fallback can be customized with rg-default-alias-fallback. The directory parameter varies between these commands.

M-x rg-dwim-project-dir

Do a DWIM search in the current project.

M-x rg-dwim-current-dir

Do a DWIM search in the current directory.

M-x rg-dwim-current-file

Do a DWIM search in the current file. The current file in this context is actually a file pattern exactly matching the current file name in a search starting from current directory. Most of the time this means a single file but if there are multiple files with the same name in a sub directory, those will be searched as well.

C-c s d (rg-dwim)

This command combines all the DWIM commands to one. The default search is in the project dir. With one universal argument current directory is used and with double universal arguments a file search is done.

File type aliases

File type aliases are used in ripgrep to filter out the files to search in. The ripgrep binary comes with a default set of aliases that can be extended or overridden from this package by customizing rg-custom-type-aliases.

An alias is a mapping between a name and a list of glob patterns matching the files of interest. Selecting an alias when searching is done with completing read of the defined aliases. It is also possible to enter a custom glob pattern if there is no suitable alias defined for the file type.

rg defines some internal aliases:

Name

Meaning

all

all defined types including rg-custom-type-aliases

everything

all files. No filtering on type is done.

custom

used internally in this package for mapping custom glob patterns.

Warning

Do not use any of the internal aliases in rg-custom-type-aliases. That would interfere with the package internal usage.

The menu

The global prefix key may be bound to a transient prefix command, which means that the key binding will popup a menu. This package is using the same popup menu backend called transient as the magit package. If you are familiar with magit this should feels like home.

The menu is mostly interesting when you want to give specific command line flags to the ripgrep binary. When you just want to do a quick search based on the defaults the menu basically acts as a normal keymap.

Pressing the rg-menu prefix key will popup the menu where command line flags can be selected before triggering the wanted search function. The menu can be customized via the transient API as usual. This package contains some shortcuts to directly add a new command to the menu when defining the command via the rg-define-search macro.

(rg-define-search rg-word
  :format literal
  :flags ("--word-regexp")
  :menu ("Custom" "w" "Word"))

The :menu keyword in the above invocation will trigger insertion of a new menu item bound to key w with description Word. The new menu item will be put under the Custom group. This group is not available in the original menu so it will be created.

The menu can be triggered from the results buffer with the m key. The commands in the menu differs, depending on from where it’s triggered but the available options are the same. The menu does not show all options by default.

The visible options can be controlled by the transient suffix levels documented here. To modify what is enabled at the default level 4 press C-x l to enter edit mode when the menu is visible. Then select the option by pressing the key sequence that activates the option and choose the level 4 for that option. It’s also possible to use the transient edit mode for modifying the overall level of the menu to enable more options at once.

Results buffer

The results of a search is shown in the results buffer. This buffer displays search parameters, the full command line and the output of the ripgrep binary. It supports basic navigation between search results editing of the file contents directly from the search buffer and also modification of the current search. The results buffer is a modified compilation buffer and some key bindings and functionality is inherited from the parent and from grep mode.

History navigation

Each search result is stored in the search history, which is a per results buffer property. History can be navigated back and forward, the forward history is cleared when a new search is done.

C-c < (rg-back-history)

Navigate back in history.

C-c > (rg-forward-history)

Navigate forward in history.

Tip

The key bindings here are slightly inconvenient so invoking this via the menu by pressing m b and m w is more ergonomic.

Edit and apply (wgrep)

The results buffer supports inline editing via the wgrep package. This is setup automatically when rg is loaded.

e (wgrep-change-to-wgrep-mode)

Make the search results editable by enabling wgrep mode. When done press C-c C-c to commit your changes to the underlying files or C-c C-k to drop the changes.

Search management

The result buffer is named *rg* and rg reuse the same result buffer for new searches. If you want to store a search while continuing doing new searches there are two ways of doing that.

Save the search buffer by renaming it to a unique new name. This is available both outside and inside a result buffer. Outside of the result buffer it’s bound to C-c s s.

If you want to keep all search buffers until manually killed you can use this snippet in your init file.

(defadvice rg-run (before rg-run-before activate)
  (rg-save-search))
S (rg-save-search-as-name)

Save the search buffer and interactively give it a specific name. This is available both outside and inside a result buffer. Outside of the result buffer it’s bound to C-c s S.

The default buffer name can be customized with rg-buffer-name. This setting considers dir local variables and it’s even possible to use a function to get a really dynamic setup.

Having a lot of search buffers floating around can easily get messy. To help keeping this under control there is a search manager. The manager is simply a modified ibuffer that lists all the results buffers, shows some data about the searches and make it possible to kill of some unused etc.

L (rg-list-searches)

Open the search manager. This is available both in result buffer and globally bound to C-c s l.

C-c s k (rg-kill-saved-searches)

Kill all saved searches except for the one that matches rg-buffer-name. This is available both in result buffer and globally bound to C-c s k.

Warning

If you have a dynamic rg-buffer-name setup, only one buffer that matches your current criteria (dir locals or project for instance) will be kept. So be careful when killing saved searches to avoid losing important search results.