Skip to content

Commit 5f2497d

Browse files
committed
SystemHighlighter: highlight command options file values
1 parent 53cd0c0 commit 5f2497d

2 files changed

Lines changed: 105 additions & 16 deletions

File tree

console/src/main/java/org/jline/console/impl/SystemHighlighter.java

Lines changed: 104 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ public class SystemHighlighter extends DefaultHighlighter {
3737
protected final SyntaxHighlighter argsHighlighter;
3838
protected final SyntaxHighlighter langHighlighter;
3939
protected final SystemRegistry systemRegistry;
40-
protected final Set<String> fileHighlight = new HashSet<>();
40+
protected final Map<String, FileHighlightCommand> fileHighlight = new HashMap<>();
4141

4242
public SystemHighlighter(SyntaxHighlighter commandHighlighter, SyntaxHighlighter argsHighlighter
4343
, SyntaxHighlighter langHighlighter) {
@@ -53,7 +53,13 @@ public AttributedString highlight(LineReader reader, String buffer) {
5353
}
5454

5555
public void addFileHighlight(String... commands) {
56-
fileHighlight.addAll(Arrays.asList(commands));
56+
for (String c : commands) {
57+
fileHighlight.put(c, new FileHighlightCommand());
58+
}
59+
}
60+
61+
public void addFileHighlight(String command, String subcommand, Collection<String> fileOptions) {
62+
fileHighlight.put(command, new FileHighlightCommand(subcommand, fileOptions));
5763
}
5864

5965
private boolean doDefaultHighlight(LineReader reader) {
@@ -65,11 +71,16 @@ private boolean doDefaultHighlight(LineReader reader) {
6571
protected AttributedString systemHighlight(LineReader reader, String buffer) {
6672
AttributedString out;
6773
Parser parser = reader.getParser();
68-
String command = parser.getCommand(buffer.trim().split("\\s+")[0]);
74+
String command = parser.getCommand(buffer);
6975
if (buffer.trim().isEmpty()) {
7076
out = new AttributedStringBuilder().append(buffer).toAttributedString();
71-
} else if (fileHighlight.contains(command)) {
72-
out = doFileHighlight(reader, buffer);
77+
} else if (fileHighlight.containsKey(command)) {
78+
FileHighlightCommand fhc = fileHighlight.get(command);
79+
if (!fhc.hasFileOptions()) {
80+
out = doFileArgsHighlight(reader, buffer, fhc);
81+
} else {
82+
out = doFileOptsHighlight(reader, buffer, fhc);
83+
}
7384
} else if (systemRegistry.isCommandOrScript(command) || systemRegistry.isCommandAlias(command)) {
7485
out = doCommandHighlight(buffer);
7586
} else if (langHighlighter != null) {
@@ -80,23 +91,70 @@ protected AttributedString systemHighlight(LineReader reader, String buffer) {
8091
return out;
8192
}
8293

83-
protected AttributedString doFileHighlight(LineReader reader, String buffer) {
84-
int idx = commandIndex(buffer);
94+
protected AttributedString doFileOptsHighlight(LineReader reader, String buffer, FileHighlightCommand fhc) {
95+
int idx0 = commandIndex(buffer);
8596
AttributedStringBuilder asb = new AttributedStringBuilder();
86-
if (idx < 0) {
97+
if (idx0 < 0) {
8798
highlightCommand(buffer, asb);
8899
} else {
89-
highlightCommand(buffer.substring(0, idx), asb);
100+
highlightCommand(buffer.substring(0, idx0), asb);
90101
ParsedLine parsedLine = reader.getParser().parse(buffer, buffer.length() + 1, Parser.ParseContext.COMPLETE);
91102
List<String> words = parsedLine.words();
92-
idx = words.get(0).length();
93-
for (int i = 1; i < words.size(); i++) {
94-
int nextIdx = buffer.substring(idx).indexOf(words.get(i)) + idx;
95-
for (int j = idx; j < nextIdx; j++) {
96-
asb.append(buffer.charAt(j));
103+
if (!fhc.isSubcommand() || (words.size() > 2 && fhc.getSubcommand().equals(words.get(1)))) {
104+
int firstArg = fhc.isSubcommand() ? 1 : 0;
105+
int idx = buffer.indexOf(words.get(firstArg)) + words.get(firstArg).length() + 1;
106+
highlightArgs(buffer.substring(idx0, idx), asb);
107+
boolean fileOption = false;
108+
for (int i = firstArg + 1; i < words.size(); i++) {
109+
int nextIdx = buffer.substring(idx).indexOf(words.get(i)) + idx;
110+
for (int j = idx; j < nextIdx; j++) {
111+
asb.append(buffer.charAt(j));
112+
}
113+
String word = words.get(i);
114+
if (word.contains("=") && fhc.getFileOptions().contains(word.substring(0, word.indexOf("=")))) {
115+
highlightArgs(word.substring(0, word.indexOf("=") + 1), asb);
116+
highlightFileArg(reader, word.substring(word.indexOf("=") + 1), asb);
117+
} else if (fhc.getFileOptions().contains(word)) {
118+
highlightArgs(word, asb);
119+
fileOption = true;
120+
} else if (fileOption) {
121+
highlightFileArg(reader, word, asb);
122+
} else {
123+
highlightArgs(word, asb);
124+
fileOption = false;
125+
}
126+
idx = nextIdx + word.length();
97127
}
98-
highlightFileArg(reader, words.get(i), asb);
99-
idx = nextIdx + words.get(i).length();
128+
} else {
129+
highlightArgs(buffer.substring(idx0), asb);
130+
}
131+
}
132+
return asb.toAttributedString();
133+
}
134+
135+
protected AttributedString doFileArgsHighlight(LineReader reader, String buffer, FileHighlightCommand fhc) {
136+
int idx0 = commandIndex(buffer);
137+
AttributedStringBuilder asb = new AttributedStringBuilder();
138+
if (idx0 < 0) {
139+
highlightCommand(buffer, asb);
140+
} else {
141+
highlightCommand(buffer.substring(0, idx0), asb);
142+
ParsedLine parsedLine = reader.getParser().parse(buffer, buffer.length() + 1, Parser.ParseContext.COMPLETE);
143+
List<String> words = parsedLine.words();
144+
if (!fhc.isSubcommand() || (words.size() > 2 && fhc.getSubcommand().equals(words.get(1)))) {
145+
int firstArg = fhc.isSubcommand() ? 1 : 0;
146+
int idx = buffer.indexOf(words.get(firstArg)) + words.get(firstArg).length();
147+
highlightArgs(buffer.substring(idx0, idx), asb);
148+
for (int i = firstArg + 1; i < words.size(); i++) {
149+
int nextIdx = buffer.substring(idx).indexOf(words.get(i)) + idx;
150+
for (int j = idx; j < nextIdx; j++) {
151+
asb.append(buffer.charAt(j));
152+
}
153+
highlightFileArg(reader, words.get(i), asb);
154+
idx = nextIdx + words.get(i).length();
155+
}
156+
} else {
157+
highlightArgs(buffer.substring(idx0), asb);
100158
}
101159
}
102160
return asb.toAttributedString();
@@ -211,4 +269,34 @@ private void highlightCommand(String command, AttributedStringBuilder asb) {
211269
asb.append(command);
212270
}
213271
}
272+
273+
protected static class FileHighlightCommand {
274+
private final String subcommand;
275+
private final List<String> fileOptions = new ArrayList<>();
276+
277+
public FileHighlightCommand() {
278+
this(null, new ArrayList<>());
279+
}
280+
281+
public FileHighlightCommand(String subcommand, Collection<String> fileOptions) {
282+
this.subcommand = subcommand;
283+
this.fileOptions.addAll(fileOptions);
284+
}
285+
286+
public boolean isSubcommand() {
287+
return subcommand != null;
288+
}
289+
290+
public boolean hasFileOptions() {
291+
return !fileOptions.isEmpty();
292+
}
293+
294+
public String getSubcommand() {
295+
return subcommand;
296+
}
297+
298+
public List<String> getFileOptions() {
299+
return fileOptions;
300+
}
301+
}
214302
}

demo/src/main/java/org/jline/demo/Repl.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -290,6 +290,7 @@ public static void main(String[] args) {
290290
SyntaxHighlighter groovyHighlighter = SyntaxHighlighter.build(jnanorc,"Groovy");
291291
SystemHighlighter highlighter = new SystemHighlighter(commandHighlighter, argsHighlighter, groovyHighlighter);
292292
highlighter.addFileHighlight("nano", "less", "slurp");
293+
highlighter.addFileHighlight("groovy", "classloader", Arrays.asList("-a", "--add"));
293294
LineReader reader = LineReaderBuilder.builder()
294295
.terminal(terminal)
295296
.completer(systemRegistry.completer())

0 commit comments

Comments
 (0)