Skip to content

Commit

Permalink
TailTipWidget: added descriptions of command options
Browse files Browse the repository at this point in the history
  • Loading branch information
mattirn committed Oct 14, 2019
1 parent bd23dac commit 2ae5901
Show file tree
Hide file tree
Showing 3 changed files with 87 additions and 19 deletions.
86 changes: 72 additions & 14 deletions builtins/src/main/java/org/jline/builtins/Widgets.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,12 @@
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;

import org.jline.keymap.KeyMap;
import org.jline.reader.Binding;
import org.jline.reader.Buffer;
import org.jline.reader.EndOfFileException;
import org.jline.reader.LineReader;
import org.jline.reader.UserInterruptException;
import org.jline.reader.LineReader.SuggestionType;
import org.jline.reader.Reference;
import org.jline.reader.Widget;
Expand Down Expand Up @@ -561,7 +560,7 @@ public enum TipType {
COMBINED
}
private boolean enabled = false;
private Map<String,List<ArgDesc>> tailTips = new HashMap<>();
private Map<String,CmdDesc> tailTips = new HashMap<>();
private TipType tipType;
private int descriptionSize = 0;

Expand All @@ -571,10 +570,10 @@ public enum TipType {
* Status bar for argument descriptions will not be created.
*
* @param reader LineReader.
* @param tailTips Commands positional argument descriptions.
* @param tailTips Commands options and positional argument descriptions.
* @throws IllegalStateException If widgets are already created.
*/
public TailTipWidgets(LineReader reader, Map<String,List<ArgDesc>> tailTips) {
public TailTipWidgets(LineReader reader, Map<String,CmdDesc> tailTips) {
this(reader, tailTips, 0, TipType.COMBINED);
}

Expand All @@ -583,11 +582,11 @@ public TailTipWidgets(LineReader reader, Map<String,List<ArgDesc>> tailTips) {
* Status bar for argument descriptions will not be created.
*
* @param reader LineReader.
* @param tailTips Commands positional argument descriptions.
* @param tailTips Commands options and positional argument descriptions.
* @param tipType Defines which data will be used for suggestions.
* @throws IllegalStateException If widgets are already created.
*/
public TailTipWidgets(LineReader reader, Map<String,List<ArgDesc>> tailTips, TipType tipType) {
public TailTipWidgets(LineReader reader, Map<String,CmdDesc> tailTips, TipType tipType) {
this(reader, tailTips, 0, tipType);
}

Expand All @@ -596,11 +595,11 @@ public TailTipWidgets(LineReader reader, Map<String,List<ArgDesc>> tailTips, Tip
* positional argument names. If argument descriptions do not exists command completer data will be used.
*
* @param reader LineReader.
* @param tailTips Commands positional argument descriptions.
* @param tailTips Commands options and positional argument descriptions.
* @param descriptionSize Size of the status bar.
* @throws IllegalStateException If widgets are already created.
*/
public TailTipWidgets(LineReader reader, Map<String,List<ArgDesc>> tailTips, int descriptionSize) {
public TailTipWidgets(LineReader reader, Map<String,CmdDesc> tailTips, int descriptionSize) {
this(reader, tailTips, descriptionSize, TipType.COMBINED);
}

Expand All @@ -613,7 +612,7 @@ public TailTipWidgets(LineReader reader, Map<String,List<ArgDesc>> tailTips, int
* @param tipType Defines which data will be used for suggestions.
* @throws IllegalStateException If widgets are already created.
*/
public TailTipWidgets(LineReader reader, Map<String,List<ArgDesc>> tailTips, int descriptionSize, TipType tipType) {
public TailTipWidgets(LineReader reader, Map<String,CmdDesc> tailTips, int descriptionSize, TipType tipType) {
super(reader);
if (existsWidget(TT_ACCEPT_LINE)) {
throw new IllegalStateException("TailTipWidgets already created!");
Expand Down Expand Up @@ -704,16 +703,27 @@ private boolean doTailTip(String widget) {
Buffer buffer = buffer();
callWidget(widget);
if (buffer.length() == buffer.cursor()
&& ((!widget.endsWith(LineReader.BACKWARD_DELETE_CHAR) && prevChar().equals(" ")) ||
&& ((!widget.endsWith(LineReader.BACKWARD_DELETE_CHAR) && (prevChar().equals(" ") || prevChar().equals("=") || prevChar().equals("-"))) ||
(widget.endsWith(LineReader.BACKWARD_DELETE_CHAR) && !prevChar().equals(" ")))) {
List<String> bp = args(buffer.toString());
int bpsize = bp.size() + (widget.endsWith(LineReader.BACKWARD_DELETE_CHAR) ? -1 : 0);
int argnum = 0;
for (String a: bp) {
if (!a.startsWith("-")) {
argnum++;
}
}
String lastArg = !prevChar().equals(" ") ? bp.get(bp.size() - 1) : "";
int bpsize = argnum + (!lastArg.startsWith("-") && widget.endsWith(LineReader.BACKWARD_DELETE_CHAR) ? -1 : 0);
List<AttributedString> desc = new ArrayList<>();
if (bpsize > 0 && tailTips.containsKey(bp.get(0))) {
List<ArgDesc> params = tailTips.get(bp.get(0));
List<ArgDesc> params = tailTips.get(bp.get(0)).getArgsDesc();
setSuggestionType(tipType == TipType.COMPLETER ? SuggestionType.COMPLETER : SuggestionType.TAIL_TIP);
if (bpsize - 1 < params.size()) {
desc = params.get(bpsize - 1).getDescription();
if (lastArg.startsWith("-")) {
desc = tailTips.get(bp.get(0)).getOptionDescription(lastArg);
} else {
desc = params.get(bpsize - 1).getDescription();
}
StringBuilder tip = new StringBuilder();
for (int i = bpsize - 1; i < params.size(); i++) {
tip.append(params.get(i).getName());
Expand Down Expand Up @@ -788,6 +798,8 @@ private boolean defaultBindings() {
aliasWidget("." + LineReader.EXPAND_OR_COMPLETE, LineReader.EXPAND_OR_COMPLETE);
KeyMap<Binding> map = getKeyMap(LineReader.MAIN);
map.bind(new Reference(LineReader.SELF_INSERT), " ");
map.bind(new Reference(LineReader.SELF_INSERT), "=");
map.bind(new Reference(LineReader.SELF_INSERT), "-");
setSuggestionType(SuggestionType.NONE);
if (autopairEnabled()) {
callWidget(AP_TOGGLE);
Expand All @@ -807,6 +819,8 @@ private void customBindings() {
aliasWidget("_tailtip-expand-or-complete", LineReader.EXPAND_OR_COMPLETE);
KeyMap<Binding> map = getKeyMap(LineReader.MAIN);
map.bind(new Reference("_tailtip-insert"), " ");
map.bind(new Reference("_tailtip-insert"), "=");
map.bind(new Reference("_tailtip-insert"), "-");
if (tipType != TipType.TAIL_TIP) {
setSuggestionType(SuggestionType.COMPLETER);
} else {
Expand Down Expand Up @@ -847,4 +861,48 @@ public static List<ArgDesc> doArgNames(List<String> names) {
}
}

public static class CmdDesc {
private List<ArgDesc> argsDesc;
private TreeMap<String,List<AttributedString>> optsDesc;

public CmdDesc(List<ArgDesc> argsDesc) {
this(argsDesc, new HashMap<>());
}

public CmdDesc(List<ArgDesc> argsDesc, Map<String,List<AttributedString>> optsDesc) {
this.argsDesc = new ArrayList<>(argsDesc);
this.optsDesc = new TreeMap<>(optsDesc);
}

public List<ArgDesc> getArgsDesc() {
return argsDesc;
}

public List<AttributedString> getOptionDescription(String opt) {
List<AttributedString> out = new ArrayList<>();
if (!opt.startsWith("-")) {
return out;
} else if (opt.startsWith("--")) {
int ind = opt.indexOf("=");
if (ind > 0) {
opt = opt.substring(0, ind);
}
}
if (optsDesc.containsKey(opt)) {
out = new ArrayList<>(optsDesc.get(opt));
} else {
for (Map.Entry<String, List<AttributedString>> entry: optsDesc.entrySet()) {
if (entry.getKey().startsWith(opt)) {
AttributedStringBuilder asb = new AttributedStringBuilder();
asb.append(entry.getKey());
asb.append("\t");
asb.append(entry.getValue().get(0));
out.add(asb.toAttributedString());
}
}
}
return out;
}
}

}
14 changes: 10 additions & 4 deletions builtins/src/test/java/org/jline/example/Example.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import org.jline.builtins.Widgets.TailTipWidgets;
import org.jline.builtins.Widgets.TailTipWidgets.TipType;
import org.jline.builtins.Widgets.ArgDesc;
import org.jline.builtins.Widgets.CmdDesc;
import org.jline.keymap.KeyMap;
import org.jline.reader.*;
import org.jline.reader.LineReader.Option;
Expand Down Expand Up @@ -319,9 +320,14 @@ public void complete(LineReader reader, ParsedLine line, List<Candidate> candida
.build();
AutopairWidgets autopairWidgets = new AutopairWidgets(reader);
AutosuggestionWidgets autosuggestionWidgets = new AutosuggestionWidgets(reader);
Map<String, List<ArgDesc>> tailTips = new HashMap<>();
tailTips.put("foo12", ArgDesc.doArgNames(Arrays.asList("param1", "param2", "[paramN...]")));
tailTips.put("foo11", Arrays.asList(
Map<String, CmdDesc> tailTips = new HashMap<>();
Map<String, List<AttributedString>> optDesc = new HashMap<>();
optDesc.put("--option1", Arrays.asList(new AttributedString("option1 description...")));
optDesc.put("--option2", Arrays.asList(new AttributedString("option2 description...")));
optDesc.put("--option3", Arrays.asList(new AttributedString("option3 description...")
, new AttributedString("line2")));
tailTips.put("foo12", new CmdDesc(ArgDesc.doArgNames(Arrays.asList("param1", "param2", "[paramN...]"))));
tailTips.put("foo11", new CmdDesc(Arrays.asList(
new ArgDesc("param1",Arrays.asList(new AttributedString("Param1 description...")
, new AttributedString("line 2: This is a very long line that does exceed the terminal width."
+" The line will be truncated automatically (by Status class) be before printing out.")
Expand All @@ -334,7 +340,7 @@ public void complete(LineReader reader, ParsedLine line, List<Candidate> candida
, new AttributedString("line 2")
))
, new ArgDesc("param3", new ArrayList<>())
));
), optDesc));
TailTipWidgets tailtipWidgets = new TailTipWidgets(reader, tailTips, TipType.COMPLETER);
if (timer) {
Executors.newScheduledThreadPool(1)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4007,8 +4007,12 @@ public AttributedString getDisplayedBufferWithPrompts(List<AttributedString> sec
if (buf.prevChar() != ' ') {
if (!tailTip.startsWith("[")) {
int idx = tailTip.indexOf(' ');
if (idx > 0) {
int idb = buf.toString().lastIndexOf(' ');
int idd = buf.toString().lastIndexOf('-');
if (idx > 0 && ((idb == -1 && idb == idd) || (idb >= 0 && idb > idd))) {
tailTip = tailTip.substring(idx);
} else if (idb >= 0 && idb < idd) {
sb.append(" ");
}
} else {
sb.append(" ");
Expand Down

0 comments on commit 2ae5901

Please sign in to comment.