Using Helix's Global Search
Table of Contents
Table Of Contents
Introduction
This article provides a comprehensive guide on using Helix’s global search, a powerful feature that allows you to search across your entire workspace. You’ll learn how to get started with global search, when to use it, and how to perform basic and advanced searches using regex. Additionally, this article offers tips and tricks to enhance your search efficiency.
Updates in Helix after 24.07
Shortly after 24.07
was released, Helix introduced significant improvements to its pickers, making the global search picker fully interactive. This enhancement is part of the
Pickers “v2” update, which utilizes Nucleo to enhance functionality.
Nucleo, created by Helix’s Pascal Kuthe, is a new fuzzy matching tool similar to fzf
but faster and tailored for Helix. It’s already used for completions and the file picker. Learn more about Nucleo
at the Nucleo homepage.
To access the latest v2
features, you will need to
build Helix from source. All examples in this article are based on v2
, but most information is also applicable to earlier versions.
Getting started with global search
Global search allows you to search across the entire workspace, unlike standard search, which is limited to the current buffer. This makes global search a powerful tool that can complement language server-based features or be used independently when no language server is available.
- Standard search is triggered with the
/
key. - Global search is triggered with
Space-/
.
When to use global search
Consider using a language server before opting for global search. For example:
- Rename a variable across your entire codebase using
Space r
to rename symbols. - Search for a specific symbol, such as a function, using
Space s
to open the workspace symbol picker.
Not all language servers offer this functionality, so consult their respective documentation.
Basic global search
When opening the global search picker with Space /
, if you’ve performed a standard search using /
or ?
, the search term is pre-filled from the contents of the search register. You can accept this suggestion by pressing Enter
, or enter your own search term, which will replace the suggestion.
In the following example, Enter
is pressed to accept the suggestion, and the sentence is found inside a document in the workspace:
Otherwise, to populate the search register in advance with something other than the last standard search, use one of the following methods:
Pre-selecting a search term from the document
Method 1: Copy text to the search register using *
- Select text and press
*
to copy it into the search register, regex-escaped.
Method 2: Yank directly to the search register
- Yank the current selection to the
/
register using"/y
.
This isn’t regex-escaped, unlike when using *
.
Method 3: Use the <Selection Contents>
register
- Select a word with
miw
.
This selection is automatically copied to the <Selection Contents>
register, which uses the .
symbol and always contains the current selection.
- Open the global search picker with
Space /
. - Press
Ctrl-r.
to paste the contents of the<Selection Contents>
register.
Note: The regex isn’t escaped.
Using regex
For complex queries, learn about regex features. Unlike other pickers that use fzf search syntax, global search employs regular expression queries (regex). Regex consists of special characters representing rules used to search and match within every file in your project.
Escape special regex characters in search text with \
To select the first column of a markdown table, you would use ^
to anchor the match at the start of the line and |
for the table character. Since |
is also used in regex to represent alternation, you must escape it. Therefore, the search pattern would be ^\|
.
Here is an example using standard search showing the highlighted selection:
In global search, each line matched would be a separate result:
Commonly used regex characters include:
Regex | Description | Example |
---|---|---|
. |
Matches any single character except newline | a.b -> matches “aab”, “abb”, “acb”… |
* |
Matches zero or more of the preceding element | ab* -> matches “a”, “ab”, “abb” |
+ |
Matches one or more of the preceding element | ab+ -> matches “ab”, “abb” |
? |
Matches zero or one of the preceding element | ab? -> matches “a”, “ab” |
^ |
Anchors the match at the start of a line | ^abc -> matches “abc” at start |
$ |
Anchors the match at the end of a line | abc$ -> matches “abc” at end |
| |
Represents alternation (logical OR) | a|b -> matches “a” or “b” |
Find the full list of supported regex in the Rust regex crate documentation. Here are some examples of useful regex searches:
Regex example 1: Matching whole words
To find whole words, use \b
for word boundaries:
The chimpanzee observed a group of gorillas.
Many gorillas gathered near the chimpanzees.
\bchimpanzee\b
matches only “chimpanzee,” not “chimpanzees.”\bgorillas\b
matches only “gorillas,” not “gorilla.”
Regex example 2: Change case sensitivity on the fly
Helix uses smart-case = true
by default, making regex searches case-insensitive unless the pattern contains uppercase characters:
let userName = "Chimpanzee";
let Username = "Gorilla";
let username = "Orangutan";
- Searching for
username
matchesuserName
,Username
, andusername
. - Searching for
Username
matches onlyUsername
.
To change case sensitivity dynamically, use regex flags directly before the search term:
(?-i)username
: Case-sensitive search, matches onlyusername
.(?i)Username
: Case-insensitive search, matchesuserName
,Username
, andusername
.
Regex example 3: Searching for functions
To find all function calls (for example foo()
, bar()
, baz(arg)
):
\w+\([^)]*\)
- Explanation:
\w+
: Matches one or more word characters (function name).\(
: Matches the opening parenthesis.[^)]*
: Matches any character not a closing parenthesis.\)
: Matches the closing parenthesis.
Narrowing your results by path
Different pickers offer various columns to filter your results. By referencing a specific column and adding another search term, you can refine your search more effectively. In global search, there is one additional column available: path
.
To select the path
column, use the %
character followed by an incremental search term. In this case p
will suffice as there is only one column that begins with p
. Providing your theme supports it, the column should become highlighted in some way.
For example, to search files in your workspace for the string version
and then narrow down the results to only include .json
files, use the following search:
version %p .json
Tips and tricks
Ignoring files
You can ignore files using .gitignore
, global ignore settings, and Helix-specific ignore files, with options for both local and global configurations. Details are in the documentation:
https://docs.helix-editor.com/master/editor.html#editorfile-picker-section
As an example, to stop Helix from searching your node_modules
in a JavaScript project, simply create a .gitignore
in the root of your project:
.gitignore
node_modules/
Reopening the global search picker in its previous state
Use Space '
to reopen the last used picker in its previous state. This is useful for tasks like refactoring using global search, where you revisit a list of items. Avoid opening other pickers to preserve the state.
Opening results in another window or in the background
In pickers, including the global search picker, you can use specific keys for navigation and actions. Details are in the documentation: https://docs.helix-editor.com/master/keymap.html#picker. Of particular interest are:
Alt-Enter
to open the selected result in the background without closing the pickerCtrl-s
to open horizontallyCtrl-v
to open vertically
Using the /
search register in other pickers
The *
key can copy search terms for use in other pickers. For example, to search for file names:
- Select the file name in your document.
- Press
*
to copy it to the search register. - Open the file picker with
Space f
and paste usingCtrl-r/
.
This method works with any picker and the command mode (:
), as you can paste from any register using Ctrl-r
.
Conclusion
The Helix global search picker is a versatile tool that enhances your coding efficiency by allowing comprehensive searches across your workspace. The introduction of Nucleo has further improved its functionality, offering dynamic search results. By understanding how to use regex and pre-select search terms, you can tailor your search queries to suit your specific needs. Additionally, tips like ignoring files, reopening pickers in their previous state, and using search registers in other pickers provide further flexibility and convenience. For more advanced usage, consider exploring the documentation and experimenting with the various features discussed in this article.
Join Our Mailing List, Get 20% Off The Course!
If you are interested in the Mastering the Helix editor course and want to stay updated on the release, we invite you to join our mailing list. By subscribing, you will receive updates on the course progress, release date, and a 20% off discount voucher.
We use Mailchimp for the mailing list, you can unsubscribe at any time by clicking the link in the footer of our emails.