History
Æsh Readline provides flexible history management for command input.
History Interface
public interface History {
void push(String line);
String get(int index);
List<String> getAll();
int size();
void clear();
boolean isEnabled();
void enable();
void disable();
String previous();
String next();
String first();
String last();
int getCurrentIndex();
void setCurrentIndex(int index);
}InMemoryHistory
History stored in memory:
import org.aesh.readline.history.InMemoryHistory;
History history = new InMemoryHistory(100); // Max 100 entries
history.push("command1");
history.push("command2");
String previous = history.previous();
String next = history.next();FileHistory
History persisted to file:
import org.aesh.readline.history.FileHistory;
import java.io.File;
File historyFile = new File(".aesh_history");
History history = new FileHistory(historyFile, 500); // Max 500 entries
history.push("command1"); // Automatically saved to fileUsing History with ReadlineBuilder
import org.aesh.readline.ReadlineBuilder;
Readline readline = ReadlineBuilder.builder()
.history(new FileHistory(new File(".history"), 100))
.enableHistory(true)
.build();Programmatic History
History history = ...;
// Add to history
history.push("git status");
history.push("git add .");
history.push("git commit -m 'fix'");
// Navigate history
String cmd1 = history.previous(); // "git commit -m 'fix'"
String cmd2 = history.previous(); // "git add ."
String cmd3 = history.next(); // "git commit -m 'fix'"
// Get all
List<String> allCommands = history.getAll();
// Get by index
String specificCommand = history.get(2);
// Get current position
int currentIndex = history.getCurrentIndex();
// Clear
history.clear();Enable/Disable History
History history = ...;
history.enable(); // Enable history
history.disable(); // Disable history
boolean enabled = history.isEnabled();History Search
Fuzzy Search (Ctrl+R)
Press Ctrl+R to open an interactive fuzzy history search inspired by fzf. Type to filter results, use ↑/↓ to navigate, and Enter to select. See Fuzzy History Search for full documentation.
Traditional Search (Ctrl+S)
The traditional incremental forward search is available via Ctrl+S. The old Ctrl+R reverse incremental search can be restored by rebinding the key – see Fuzzy History Search for details.
Programmatic Search
Access history for search operations:
History history = ...;
List<String> allHistory = history.getAll();
for (int i = 0; i < allHistory.size(); i++) {
String cmd = allHistory.get(i);
if (cmd.startsWith("git")) {
// Found a git command
String found = history.get(i);
}
}History Persistence
FileHistory automatically persists to file:
File historyFile = new File(".cmdline_history");
History history = new FileHistory(historyFile, 1000);
// These commands are automatically persisted
history.push("command1");
history.push("command2");
// History is loaded from file on constructionTimestamps
Both InMemoryHistory and FileHistory track when each command was added. Timestamps are persisted to the history file and restored on load, so they survive across sessions.
History history = ...;
// Timestamps are parallel to getAll() — same size and order
List<Long> timestamps = history.getTimestamps();
if (timestamps != null) {
for (int i = 0; i < history.size(); i++) {
long epochMillis = timestamps.get(i);
System.out.println(new Date(epochMillis) + " — " + history.get(i));
}
}Timestamps are displayed in the fuzzy history search UI and are preserved when the history file is saved and reloaded.
The history file uses a backward-compatible format: new files store timestamps alongside commands, while legacy history files (from older versions) are read with the file’s modification time as a fallback timestamp.
History Size Limits
// In-memory with limit
History memoryHistory = new InMemoryHistory(50);
// File-based with limit
History fileHistory = new FileHistory(new File(".history"), 200);When the limit is reached, oldest entries are removed.
Ignore Patterns
Commands matching ignore patterns are silently excluded from history. This is useful for preventing sensitive commands (passwords, tokens) from being persisted.
Patterns support simple wildcards:
| Pattern | Matches |
|---|---|
" *" | Commands starting with a space (shell convention for private commands) |
"*password*" | Commands containing “password” anywhere |
"*token*" | Commands containing “token” anywhere |
"exit" | Exact match only |
"sudo *" | Commands starting with “sudo " |
Using ReadlineBuilder
Readline readline = ReadlineBuilder.builder()
.enableHistory(true)
.historyIgnore(" *") // ignore commands starting with space
.historyIgnore("*password*") // ignore commands containing "password"
.historyIgnore("*token*") // ignore commands containing "token"
.build();Programmatic Configuration
History history = new InMemoryHistory(500);
history.setIgnorePatterns(Arrays.asList(" *", "*password*", "*secret*"));
history.push("git status"); // Added
history.push(" secret command"); // Ignored (starts with space)
history.push("set password mysecret"); // Ignored (contains "password")
history.push("git push"); // AddedEmpty Input
Empty input is not added to history by default:
history.push(""); // Not added (empty)
history.push(" "); // Not added (whitespace only)
history.push("cmd"); // Added