On this pageOverview
Workspace

Search and the omnibox

Jump to any file, command, symbol or line from one box, search and replace across the project, and edit every match at once in a Search Editor.

The omnibox

One box finds everything. Press Cmd+P to open it on files, or Cmd+K to open it on commands. What it searches depends on the first character you type:

Prefix Searches
(none) Files in the project
> Commands
@ Symbols in the open file
# Symbols across the project
: A line number to jump to
? What the prefixes do
Try it
srcrank.tsLn 16
1import { bm25 } from "./index/bm25";
2import { tokenize } from "./index/tokenize";
3import type { Doc, Hit } from "./index/store";
4import { corpus } from "./corpus";
5
6export type Weights = { title: number; body: number };
7
8export const DEFAULT_WEIGHTS: Weights = { title: 2.5, body: 1 };
9
10export function score(doc: Doc, terms: string[], w: Weights): number {
11 const title = bm25(terms, tokenize(doc.title));
12 const body = bm25(terms, tokenize(doc.body));
13 return title * w.title + body * w.body;
14}
15
16export function rank(docs: Doc[], q: string, w = DEFAULT_WEIGHTS): Hit[] {
17 const terms = tokenize(q);
18 const hits: Hit[] = [];
19 for (const doc of docs) {
20 const s = score(doc, terms, w);
21 if (s > 0) hits.push({ id: doc.id, score: s });
22 }
23 return hits.sort((a, b) => b.score - a.score);
24}
25
26export function ids(q: string): string[] {
27 return rank(corpus(), q).map((h) => h.id);
28}
The omnibox over hooli-search's fix/search-ranking. Type a prefix to switch what it searches, use the arrow keys and Enter to pick, and press Escape to close it. Cmd+P or Cmd+K brings it back. Commit and push stay disabled, with the reason, until you stage a file.

Move with ArrowUp and ArrowDown, press Enter to go, Escape to close. Delete the prefix to switch back to files.

Files

With nothing typed, the list starts with the files you visited most recently, then files you open often, before the rest of the project. Typing matches loosely, so sgnts finds src/sign.ts. Inside a Topic, every member is searched at once and each result names its repository.

Commands

> lists every command in Tori: the git commands, layout, editor actions, the language server, the debugger, and a Preferences: entry for every setting, which opens Settings on that row. Each shows its shortcut when it has one. A command that cannot run right now, such as Push to origin with nothing to push, is shown greyed out with the reason under it rather than hidden. Read Selection Aloud is the exception: it is listed only when text was selected as you opened the palette. See Read a reply aloud.

Symbols and lines

@ lists the functions, classes and other symbols in the file in front of you; # searches symbols across the project. Both come from the file’s language server, so they need one running. :42 jumps to line 42 of the open file.

Search across the project

Press Cmd+Shift+F, or open Search in the right panel, to search every file in the project.

  1. Type in Search. Results come as you type, grouped by file, with each match’s line.
  2. Narrow it with the toggles in the box: Match Case, Match Whole Word and Use Regular Expression.
  3. Click Toggle Search Details for files to include and files to exclude (globs such as src/**/*.ts or **/*.test.ts) and Search Only in Open Editors.
  4. Click a match to open the file at that line.

The top bar has Refresh, Open New Search Editor, Saved Searches, a switch between a flat list and a tree, and more. Inside a Topic, the results are one section per member, and the member chips narrow the search to the members you pick.

To search one folder, right-click it in the Files tree and choose Find in Folder….

Work with results

Right-click a match or a file in the results:

Item What it does
Copy, Copy All Copies the match, or every result
Copy Path, Copy Relative Path Copies the file’s path
Open to the Side Opens the file in the other pane
Reveal in Files Shows it in the Files tree
Restrict Search to Folder Adds the folder to files to include
Exclude Folder from Search Adds it to files to exclude
Replace, Replace All Replaces in this match or this file, with replace open
Dismiss Hides this result from the list

Replace

Click Toggle Replace to show the Replace field. Preserve Case keeps the case of each match, so replacing user with account turns User into Account. Then replace one match, one file, or Replace All.

Replacing across files writes to disk and cannot be undone from Search, so Tori asks first, Replace N occurrences, and checks every file before writing: it has to be inside the project, unchanged since the search ran, and the replacements must not overlap. A file that fails any check is skipped whole and reported, never half replaced. An open file is reloaded afterwards, so a later save does not put the old text back.

Saved searches

Click Saved Searches and Name this search to keep the current query. Saved searches can be renamed or deleted from the same list, and each opens in a Search Editor.

Search Editor

A Search Editor opens the results as one editable buffer in an editor tab: every match with its file and line. Use it for a change too irregular for find and replace.

  1. Click Open New Search Editor in the Search panel, or open a saved search.
  2. Search as usual. Use More context lines, Fewer context lines or Toggle Context Lines for more or less of each file around the matches.
  3. Edit the lines in the buffer, with multiple cursors, find and replace or vim keys.
  4. Press Cmd+S, or Write every edited line back to the file it came from.

Each edit is checked against what its line said when the search ran. If the file has changed underneath, that edit is refused instead of landing on the wrong line. Search Again rebuilds the buffer from disk, and asks before dropping edits you have not written back.

Find in a file

Cmd+F in an editor opens find over the editor’s top right corner, Cmd+Opt+F opens find and replace. In a terminal, Cmd+F searches that terminal’s output.