@@ -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}
0 commit comments