Way more than a simple Find & Replace, a versatile tool for search and bulk operations:
- Search in page with an instant highlighting
- Search in graph with plain text or block references extraction
- Find & Replace either local, in blocks selection, page, workspace, or global, in the whole graph, with complete support of regular expressions.
- Extract highlights in selection or page, and other advanced extraction features.
- Block <=> Page conversion, replacing in bulk their references.
- Bulk change format of selected blocks (header, alignment, view, case)
- Bulk append/prepend strings, ie. at the beginning or/and at the end of a set of selected blocks.
- π Bulk change of page names or simple pages search, supporting Regex.
- Full regular expressions support
See changelog here for an overview of updates and new features __
π‘ All the commands are available via the command palette (Cmd-Ctrl + P). Enter "Find & R..." and you will see all of them.
Press Ctrl + S
to open a search box similar to the browsers' search box usually called with Ctrl+F: the search results are instantly highlighted in the current page and switching from one to the other automatically scrolls the display.
But this search box is specially designed for Roam Research since it detects the words hidden in the collapsed blocks and expands them automatically, by checking an option. The search can also be extended to the whole workspace, linked references and pages in the sidebar.
You can also specify a logic operator if you enter multiple words: by default, the whole string is searched, but you can search each word separated by a spaces with the OR operator (at least one word) or the AND operator (all words must be present in the block, in any order). AND+ is an experimental feature, it's like AND but it includes first level children blocks.
You can have a quick overview of the search results (including hidden blocks) by clicking ποΈ
and copied in the clipboard as plain text (block references are resolved). Or you can copy the block references with '((π))' and paste them anywhere in your graph.
The search engine support regular expressions, so that any kind of pattern can be found. See below for more details and examples.
Open the global search box with Find & Replace: Whole graph search
in the command Palette (just enter 'wg'). It provides very quickly an overview of the results, even in large amounts (like 2000 matches in 2 seconds), if you display them in plain text with ποΈ
. Then you can easely open any of them in the right sidebar by pressing the β
at the end of each block. As with search in page, you can copy the results to clipboard, as plain text or as block references. You can also open them all in the sidebar with the button ποΈβ¨
In option, search results can be sorted by page or page last edit date (the most recent first).
Replace a given string with another at once or step by step, thanks to the π highlighting feature.
The range of application depends on two factors:
-
the range of selection: if you have selected a set of blocks (blue highlighted with mouse or Shift + Up or Down), only the selected blocks and their expanded children will be processed. If you are using the recent multiselect feature with checkboxes on the right (enabled with Ctrl + m), only checked blocks will be processed. Otherwise, the current page will be processed, including the linked references and the blocks or pages opened in the right sidebar if you click on 'workspace' option.
-
the 'Include collapsed blocks' option (in the setting panel): if it's enabled, expanded AND collapsed blocks will be processed when clicking on 'Replace all' button. Otherwise, only the visible blocks will be processed. If you check 'Auto-expand blocks' option in the dialog box, collapsed blocks containing a matching string will be expanded and can be processed even if the former option is disabled.
π‘ Find & Replace can be used to remove some content in bulk: enter the content to remove in the Find field, and let the Replace field blank.
It can also be used to replace different writings of a word in a given alias. Suppose that you have written 'word', 'Word', 'words' and 'Words' in your graph and that you want to replace the last three by an alias to [[word]], e.g. [Word]([[word]])
. You have just to write this regex in the find field: /Words?|words/
and this in the replace field: [$RegEx]([[word]])
.
With great caution
For more safety, the new ποΈ
feature allows you to have a quick overview of blocks that will be changed before doing it.
After a Find & Replace operation, you can insert anywhere in your graph the list of changed blocks (as block references). It's also available in the 'Undo' popup after each operation: if you click on Display changed blocks in sidebar
, the list of changed blocks will be inserted on the [[roam/depot/find & replace]]
page, with date and timestamp.
In option, you can keep a copy of each changed block in its old state, and display a table that compares the blocks before and after the Find & Replace operation, to identify unintended changes and to have a backup of critical changes. Each old version is copied as a child block of the block reference of the new version - and is therefore easily accessible thought inline rerence counter.
Extract highlights in selection or page
command in the command palette extract only the highlighted strings, and add an alias to the original block.
On the same principle, but for advanced users, it's possible to extract only strings matching the regular expression in the find field, accordingly to the pattern in the replace field.
If this option is enabled (in the setting panel), not the entire blocks but only the matching strings will be displayed in plain text with ποΈ
or copied to the clipboard with '((π))'. The replace field plays the rΓ΄le of a template with placeholders ($RegEx
for the matching strings, $1
, $2
for capture groups).
Convert a given page in a block, and replace in bulk all its references in block references, or the opposite ! It's now as easy as a simple Find & Replace: enter the name of the page (or block reference), then enter a block reference where the page will be converted as the original block to witch all the references will linked (or a new page name).
Options:
- If you enter 'DNP' in the block reference field (or let it blank), the page will be converted in a new block created on the today's daily note page.
- If 'move source content' is checked, all the block in the page will be moved under the new block (or all the children of the block will be move in the new page).
- If you run the
Convert this block => [[page]]
command from the contextual menu of a given block, the original block reference and the page name will be automatically completed. - If you have a block reference like
((9jO7A7MwG))
or a page reference like[[page]]
in the clipboard, and run one of the conversion command with the command palette, the corresponding fields will be auto-completed.
Since it's a quite dangerous operation, it will be safer to check the impacted blocks first, with the ποΈ
button.
Apply to a selection of blocks (and only the visible ones), you can bulk change:
- the header level (1, 2 or 3)
- the alignment of the text (right, left, center, justify),
- the view of the children (bullets, numbers, document),
- the case of the text (all as Upper case, all as lower case, capitalize the first letter of the block or capitalize the first letter of each word or (π new in v.3) capitalize each sentence - excluding page references, tags, attributs and block references, of course).
Insert some string (e.g. a tag) in bulk, at the beginning (prepend) or the end (append) of selected blocks. Only expanded blocks are concerned.
Enter the pattern to change in multiple page names (it can be a simple string as Project
) and the replacing string. Before any change in your graph, you will see the list of page names containing this pattern and have the possibility to select or unselect page names to update. You can easily copy this page list to the clipboard or display it in the right sidebar.
In the input field, you can enter a /regex/ to match more precisely some pattern (ex: /(Project)/A.*
/`) (without escape character) will match 'Project' only if it has a namespace beginning by 'A'. 'Project' here is a capture group (by the use of parenthesis), so the replacing string will only replace this captured group. See next section for more detials on how Regex and placeholders for matching pattern or capture groups can be used.
Regular Expressions (often abbreviated to regex) are a powerful system to express and match any form of character pattern you can imagine. The general idea is that a given regex allows to express several sequences of characters. For example, we have seen above that /Words?|words/
allows to identify 'Word', 'Words' and 'words', but not 'word' (that we don't want to change). So with a single expression in the search field, you can find and modify different words in your graph simultaneously.
The syntax of regular expressions is very strict. Understanding the science behind them is not indispensable (it is a pure mathematical formalism), but you have to learn the syntax and experiment with it before using it in Find & Replace (you can for example, learn and test your formulas here), unless you restrict yourself to reproducing a few simple examples like the ones below. Be very cautious because their effects is not always easy to grasp and can have a dangerous impact on your data. Don't use regex if you don't know what you do.
The most accessible feature is using the variable $RegEx
as a placeholder for formating the replacement of matching strings:
in Replace field, you can insert $RegEx
in the replacing string. E.g., to bold all matching strings, enter: **$RegEx**
There is 4 possible formating of the main variable (pay attention to upper and lower case letters):
$RegEx
leaves the machting string in its initial case. (R and second E are upper case)$REGEX
capitalizes all letters.$regex
set to lower case all letters.$Regex
capitalize first letter. Capture groups $1 and $2 can also be (multi-) used, assuming that the RegEx formula includes groups in parenthesis.
You can click on ?
button in Find & Replace dialog box to see these examples:
Regex have to be written between /
slashes/
with simple \
backslash before special character to escape. Flag for global search (/g) is always set by default, you doesn't need to mention it.
In Find field:
/words?/
, matches all 'word' (singular) or 'words' (plural) occurences,/sk(y|ies)/
, matches all 'sky' (singular) or 'skies' (plural) occurences,/cheese|cake/
, matches all 'cheese' OR 'cake',/[A-Z]\w+/
, matches all words beginning with a capital letter,/.*/
matches all text,/\(\([^\)]{9}\)\)/
matches all block references,/\[\[([^\[^\]]*)\]\]/
matches all page references (not nested) and capture page name,/\[([^\]]*)\]\(\(\([^\)]{9}\)\)\)/
matches[alias](((refs)))
and capture alias.
In Replace field:
$RegEx
is the placeholder corresponding to the machting strings (pay attention to the case),$REGEX
capitalizes all letters of the mathcing strings,$regex
set to lower case all letters,$Regex
capitalize first letter,[$RegEx]([[page]])
make each machting string as an alias of [[page]],$1
replace each matching string (e.g. page references) by the first capture group (e.g. the page name),**$1** nΒ°$2
insert two capture groups in a new formated string (only 2 capture groups are supported)
-
limits of auto-expand blocks feature: Auto-expand blocks in Search in page or Find & Replace doesn't works always properly. The API command to expand blocks doesn't seem to be 100% reliable when there is an important amount of indented blocks to open. You may have to click on refresh button
β»
until the counter indicates that there are no more words in a folded blocks. Anyway it's only a matter of block display: all matching words will be replaced if you click on 'Replace all'. -
limits of live highlight on page feature: Text in code blocks are not highlighted. Likewise, if your search for strings including markdown syntax, or if the matching string is hidden by some markdown syntax (like the link in an alias), it will not be highlighted. A counter indicate how many strings can't be highlighted. You can see them with in plain text with the
ποΈ
button. But in any case, the words will be correctly detected and replaced. -
limits around the logic operators: The count of matching elements is not fully reliable with AND or AND+ operators. AND+ is not yet applied to the whole graph search, the algorithm must be optimized to give a result in a reasonable time.
For any question or suggestion, DM me on Twitter and follow me to be informed of updates and new extensions: @fbgallet or Roam Slack.