Implementation:Getgauge Taiko ReplSearch
| Knowledge Sources | |
|---|---|
| Domains | Browser_Automation, REPL_History_Search |
| Last Updated | 2026-02-12 03:00 GMT |
Overview
The ReplSearch module implements bash-style reverse incremental history search (Ctrl+R) for Taiko's interactive REPL, enabling users to quickly find and re-execute previous commands.
Description
ReplSearch adds reverse history search capability to Node.js REPL instances. When the user presses Ctrl+R, the module enters search mode: it intercepts all subsequent keypress events, builds a search query character by character, and displays matching history entries in real time. The prompt changes to the familiar (reverse-i-search)`query': format used by bash and other Unix shells.
The module achieves this by managing the REPL's keypress listener stack. On entering search mode, it saves and removes all existing keypress listeners from the REPL's input stream, replacing them with its own search handler. When the user exits search mode (by pressing any non-character key such as Enter or Escape), the original listeners are restored, and the matched history line becomes the current input. This listener swap pattern ensures that the REPL's normal key handling (cursor movement, line editing, tab completion) does not interfere with the search interaction.
The search itself is a simple linear scan through the REPL's history array using indexOf for substring matching. Pressing Ctrl+R again while in search mode advances to the next match (cycling through older history entries). Backspace removes characters from the search query, and any non-control character appends to the query.
Usage
Use ReplSearch when initializing a Taiko REPL session. It is called once with initSearch(repl) during REPL setup. After initialization, users can press Ctrl+R at any time during the REPL session to search through their command history. This is particularly useful for recalling complex Taiko commands involving selectors and options.
Code Reference
Source Location
- Repository: Getgauge_Taiko
- File: lib/repl/repl-search.js
- Lines: 1-79
Signature
function initSearch(repl) -> void
Import
const { initSearch } = require("./repl/repl-search");
I/O Contract
initSearch(repl)
| Parameter | Type | Description |
|---|---|---|
repl |
REPLServer |
A Node.js REPL server instance. Must have inputStream, history, historyIndex, line, cursor, setPrompt, prompt, and _refreshLine properties.
|
| Side Effects | Description |
|---|---|
| Keypress listener | Registers a persistent keypress listener on repl.inputStream that intercepts Ctrl+R to activate search mode.
|
| Prompt modification | Changes the REPL prompt to (reverse-i-search)`query': during search mode and restores to > on exit.
|
| History navigation | Modifies repl.historyIndex, repl.line, and repl.cursor when a match is found.
|
Internal Functions
| Function | Parameters | Description |
|---|---|---|
isCtrlR(k) |
k: KeyEvent |
Returns true if the key event represents Ctrl+R (ctrl pressed, no meta, no shift, name is "r").
|
isControlChar(c) |
c: string |
Returns true if the character code is 0-31 (ASCII control characters).
|
search(query, repl, next) |
query: string, repl: REPLServer, next: boolean |
Scans repl.history for the first entry containing query (via indexOf). When next is true, starts searching from the entry after the current match to cycle through hits. Updates repl.historyIndex and repl.cursor.
|
setPrompt(repl, query) |
repl: REPLServer, query: string |
Sets the REPL prompt to the reverse-i-search format showing the current query. |
resetPrompt(repl) |
repl: REPLServer |
Restores the REPL prompt to the default > .
|
Algorithm
State Machine
The keypress handler implements a two-state machine:
State: NORMAL (searching = false)
- On Ctrl+R:
1. Save existing keypress listeners
2. Remove existing keypress listeners from inputStream
3. Set searching = true, query = ""
4. Display search prompt
-> Transition to SEARCHING
State: SEARCHING (searching = true)
- On Ctrl+R (again):
1. If query is non-empty, call search(query, repl, true) to find next match
- On Backspace:
1. Remove last character from query
2. Update search prompt
- On printable character:
1. Append character to query
2. Update search prompt
3. Call search(query, repl, false) to find first match
4. Set repl.line to the matched history entry
- On any other key (Enter, Escape, arrow keys, etc.):
1. Set searching = false
2. Refresh the REPL line display
3. Restore all saved keypress listeners
4. Forward the current key event to restored listeners
5. Reset prompt to default
-> Transition to NORMAL
Search Algorithm
function search(query, repl, next) {
const currentHit = repl.historyIndex;
const start = currentHit === -1 ? 0 : next ? currentHit + 1 : currentHit;
for (let i = start; i < repl.history.length; i++) {
const hit = repl.history[i].indexOf(query);
if (hit !== -1 && (!next || repl.history[i] !== repl.line)) {
repl.historyIndex = i;
repl.cursor = hit;
break;
}
}
if (repl.historyIndex !== -1) {
return repl.history[repl.historyIndex];
}
}
The search starts from position 0 for fresh searches, or from the current match position for continued searches. When cycling (next = true), it starts one position after the current match and also requires the result to differ from the current line to avoid returning the same match repeatedly.
Usage Examples
// Initialize reverse search on a REPL instance
const repl = require("node:repl");
const { initSearch } = require("./repl/repl-search");
const replServer = repl.start({ prompt: "> " });
initSearch(replServer);
// User interaction flow:
// 1. User types commands: click("Login"), write("user@example.com"), ...
// 2. User presses Ctrl+R
// 3. Prompt changes to: (reverse-i-search)`':
// 4. User types "click"
// 5. Prompt shows: (reverse-i-search)`'click':
// 6. REPL line shows: click("Login")
// 7. User presses Ctrl+R again to cycle to earlier "click" commands
// 8. User presses Enter to execute the matched command
Related Pages
- Getgauge_Taiko_REPL_History_Search -- Principle page for REPL history search concepts
- Getgauge_Taiko_REPL -- Main REPL module that calls
initSearchduring setup - Getgauge_Taiko_Recorder -- REPL command recorder that populates the history being searched