forked from Drive-for-Java/MyCMD
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathInteractiveSearchCommand.java
More file actions
127 lines (106 loc) · 4.45 KB
/
Copy pathInteractiveSearchCommand.java
File metadata and controls
127 lines (106 loc) · 4.45 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
package com.mycmd.commands;
import com.mycmd.Command;
import com.mycmd.ShellContext;
import java.util.List;
import java.util.Scanner;
import java.util.stream.Collectors;
/**
* Interactive history search command (similar to Ctrl+R in bash).
* Usage: isearch
*
* Provides an interactive prompt where users can:
* - Type to filter history in real-time
* - Navigate through matches with numbers
* - Execute a selected command
*/
public class InteractiveSearchCommand implements Command {
@Override
public void execute(String[] args, ShellContext context) {
List<String> history = context.getHistory();
if (history.isEmpty()) {
System.out.println("No command history available.");
return;
}
// ✅ Use shared scanner from ShellContext instead of creating a new one
Scanner scanner = context.getScanner();
System.out.println("=== Interactive History Search ===");
System.out.println("Type to search, 'q' to quit");
System.out.println();
while (true) {
System.out.print("search> ");
String searchTerm = scanner.nextLine().trim();
if (searchTerm.equalsIgnoreCase("q") || searchTerm.equalsIgnoreCase("quit")) {
System.out.println("Search cancelled.");
break;
}
if (searchTerm.isEmpty()) {
System.out.println("Enter a search term or 'q' to quit.");
continue;
}
// Search and display results
List<String> matches = searchHistory(history, searchTerm);
if (matches.isEmpty()) {
System.out.println("No matches found for: '" + searchTerm + "'");
System.out.println();
continue;
}
// Display matches with numbers
System.out.println("\nMatches for '" + searchTerm + "':");
for (int i = 0; i < Math.min(matches.size(), 10); i++) {
System.out.println(" " + (i + 1) + ". " + matches.get(i));
}
if (matches.size() > 10) {
System.out.println(" ... and " + (matches.size() - 10) + " more");
}
// Ask user to select or refine
System.out.println();
System.out.print("Select number to copy (1-" + Math.min(matches.size(), 10) +
"), or press Enter to search again: ");
String selection = scanner.nextLine().trim();
if (selection.isEmpty()) {
continue;
}
try {
int index = Integer.parseInt(selection) - 1;
if (index >= 0 && index < Math.min(matches.size(), 10)) {
String selectedCommand = matches.get(index);
System.out.println("\nSelected command: " + selectedCommand);
System.out.println("(You can now run this command by typing it at the prompt)");
break;
} else {
System.out.println("Invalid selection. Try again.");
}
} catch (NumberFormatException e) {
System.out.println("Invalid input. Enter a number or press Enter.");
}
System.out.println();
}
}
/**
* Search history for commands containing the search term.
* Returns matches in reverse order (most recent first).
*/
private List<String> searchHistory(List<String> history, String searchTerm) {
String lowerSearch = searchTerm.toLowerCase();
// Search in reverse order (most recent first)
return history.stream()
.filter(cmd -> cmd.toLowerCase().contains(lowerSearch))
.collect(Collectors.collectingAndThen(
Collectors.toList(),
list -> {
java.util.Collections.reverse(list);
return list;
}
));
}
@Override
public String description() {
return "Interactive history search (like Ctrl+R)";
}
@Override
public String usage() {
return "isearch\n" +
" Opens an interactive prompt to search command history.\n" +
" Type your search term and select from matching commands.";
}
}