Rode’s find and replace feature provides powerful text manipulation capabilities with an intuitive interface.
Opening Find & Replace
Press Cmd+F to open the find and replace panel.
The panel appears above the editor with two input fields:
- Find: Text to search for
- Replace: Text to replace matches with
Basic Search
Open Panel
Press Cmd+F to activate the find and replace panel.
Enter Search Term
Type your search query in the “Find” field.
View Matches
The status shows current match position and total count (e.g., “2 of 5”).
Navigate Results
Use the next/previous buttons or keyboard shortcuts to jump between matches.
Match Counter
The find panel displays match information in real-time:
pub fn match_status(&self) -> String {
if self.find_text.is_empty() {
String::new()
} else if self.match_count > 0 {
format!("{} of {}", self.current_match + 1, self.match_count)
} else {
"No matches".to_string()
}
}
Status messages:
- Empty when no search term
- “2 of 5” when matches are found
- “No matches” when search has no results
Case Sensitivity
Toggle case-sensitive matching with the case sensitivity button.
Matches text regardless of capitalization:
- “hello” matches “Hello”, “HELLO”, “hello”
- “Test” matches “test”, “TEST”, “Test”
Matches text exactly as typed:
- “hello” matches only “hello”
- “Test” matches only “Test”
pub fn find_matches(&mut self, text: &str) -> Vec<usize> {
if self.find_text.is_empty() {
self.matches.clear();
self.match_count = 0;
return Vec::new();
}
let mut found_matches = Vec::new();
let search_text = if self.case_sensitive {
text.to_string()
} else {
text.to_lowercase()
};
let find = if self.case_sensitive {
self.find_text.clone()
} else {
self.find_text.to_lowercase()
};
let mut start = 0;
while let Some(pos) = search_text[start..].find(&find) {
found_matches.push(start + pos);
start += pos + 1;
}
self.matches = found_matches.clone();
self.match_count = found_matches.len();
found_matches
}
Keyboard Shortcut
| Action | Shortcut |
|---|
| Toggle case sensitivity | Click case button in panel |
Toggling case sensitivity automatically re-runs the search with the new setting.
Match Navigation
Quickly jump between search results.
Next Match
Navigate to the next occurrence:
- Click the “Next” button
- Use keyboard shortcut (if configured)
pub fn go_to_next_match(&mut self) {
if !self.matches.is_empty() {
self.current_match = (self.current_match + 1) % self.matches.len();
}
}
Previous Match
Navigate to the previous occurrence:
- Click the “Previous” button
- Use keyboard shortcut (if configured)
pub fn go_to_prev_match(&mut self) {
if !self.matches.is_empty() {
if self.current_match == 0 {
self.current_match = self.matches.len() - 1;
} else {
self.current_match -= 1;
}
}
}
Navigation behavior:
- Wraps around (next from last match goes to first)
- Updates match counter automatically
- Preserves selection on the current match
Replace Operations
Rode offers both single and bulk replace operations.
Replace Single Match
Replace the currently selected match:
Navigate to Match
Use next/previous to highlight the match you want to replace.
Enter Replacement
Type the replacement text in the “Replace” field.
Replace One
Click “Replace” to replace only the current match.
pub fn replace_next(&mut self, text: &mut String) -> bool {
if self.matches.is_empty() || self.current_match >= self.matches.len() {
return false;
}
let pos = self.matches[self.current_match];
let end = pos + self.find_text.len();
text.replace_range(pos..end, &self.replace_text);
self.find_matches(text);
if self.current_match >= self.matches.len() && !self.matches.is_empty() {
self.current_match = self.matches.len() - 1;
}
true
}
After replacement:
- Match list is updated
- Current match advances to next occurrence (or stays on last if at end)
- Document is marked as modified
Replace All Matches
Replace every occurrence in the document:
Verify Search
Ensure your search term finds the correct matches.
Enter Replacement
Type the replacement text in the “Replace” field.
Replace All
Click “Replace All” to replace every match in the document.
pub fn replace_all(&mut self, text: &mut String) -> usize {
if self.find_text.is_empty() {
return 0;
}
let count = self.matches.len();
for &pos in self.matches.iter().rev() {
let end = pos + self.find_text.len();
text.replace_range(pos..end, &self.replace_text);
}
self.matches.clear();
self.match_count = 0;
self.current_match = 0;
count
}
Replace All is not undoable! Make sure your search matches the intended text before replacing all occurrences.
Replace All behavior:
- Processes matches in reverse order (to maintain position accuracy)
- Clears the match list after completion
- Returns the number of replacements made
- Marks document as modified
Keyboard Shortcuts
| Shortcut | Action |
|---|
Cmd+F | Open find and replace |
Escape | Close find and replace |
| (buttons) | Next match |
| (buttons) | Previous match |
| (buttons) | Replace one |
| (buttons) | Replace all |
| (button) | Toggle case sensitivity |
Use Cases
Rename Variables
Find all instances of a variable name and replace with a new name
Update URLs
Change domain names or paths across documentation
Fix Typos
Search for common misspellings and correct them
Refactor Code
Update function names, class names, or constants
Feature State
The find and replace panel maintains state:
Whether the panel is currently visible
Text to replace matches with
Whether matching is case-sensitive
Total number of matches found
Index of the currently highlighted match (0-based)
Positions of all matches in the document
pub struct FindReplace {
pub open: bool,
pub find_text: String,
pub replace_text: String,
pub case_sensitive: bool,
pub match_count: usize,
pub current_match: usize,
pub matches: Vec<usize>,
}
impl Default for FindReplace {
fn default() -> Self {
Self {
open: false,
find_text: String::new(),
replace_text: String::new(),
case_sensitive: false,
match_count: 0,
current_match: 0,
matches: Vec::new(),
}
}
}
Tips & Best Practices
Review Before Replace All
Use next/previous to review matches before doing a bulk replace. This helps catch unintended replacements.
Case Sensitivity for Precision
Enable case-sensitive search when working with code to avoid matching variable names with different cases.
Empty Replace for Deletion
Leave the replace field empty to delete all matches of the search term.
The match counter (“X of Y”) helps verify you’re finding what you expect before replacing.
The find and replace feature works on the currently active file only. To search across multiple files, use the workspace search feature (Cmd+Shift+T).