Skip to content

Commit

Permalink
Check syntax errors on closing parenthesis
Browse files Browse the repository at this point in the history
  • Loading branch information
mattirn committed Oct 31, 2019
1 parent 8e47654 commit 9e2741c
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 61 deletions.
92 changes: 50 additions & 42 deletions builtins/src/main/java/org/jline/builtins/Widgets.java
Original file line number Diff line number Diff line change
Expand Up @@ -128,8 +128,8 @@ public void replaceBuffer(Buffer buffer) {
reader.getBuffer().copyFrom(buffer);
}

public List<String> args(String line) {
return reader.getParser().parse(line, 0, ParseContext.COMPLETE).words();
public List<String> args() {
return reader.getParser().parse(buffer().toString(), 0, ParseContext.COMPLETE).words();
}

public String prevChar() {
Expand Down Expand Up @@ -762,7 +762,7 @@ private boolean doTailTip(String widget) {
Buffer buffer = buffer();
callWidget(widget);
if (buffer.length() == buffer.cursor()) {
List<String> args = args(buffer.toString());
List<String> args = args();
Pair<String,Boolean> cmdkey = cmdDescs.evaluateCommandLine(buffer.toString(), args);
CmdDesc cmdDesc = cmdDescs.getDescription(cmdkey.getU());
if (cmdDesc == null) {
Expand Down Expand Up @@ -964,7 +964,7 @@ public CommandDescriptions(Function<CmdLine,CmdDesc> descFun) {
}

public Pair<String,Boolean> evaluateCommandLine(String line, int curPos) {
return evaluateCommandLine(line, new ArrayList<>(), curPos);
return evaluateCommandLine(line, args(), curPos);
}

public Pair<String,Boolean> evaluateCommandLine(String line, List<String> args) {
Expand All @@ -973,56 +973,63 @@ public Pair<String,Boolean> evaluateCommandLine(String line, List<String> args)

private Pair<String,Boolean> evaluateCommandLine(String line, List<String> args, int curPos) {
String cmd = null;
boolean command = false;
CmdLine.DescriptionType descType = CmdLine.DescriptionType.METHOD;
String head = line.substring(0, curPos);
String tail = line.substring(curPos);
if (line.length() == curPos) {
cmd = args != null && (args.size() > 1 || (args.size() == 1
&& line.endsWith(" "))) ? args.get(0) : null;
command = true;
}
int brackets = 0;
for (int i = head.length() - 1; i >= 0; i--) {
if (head.charAt(i) == ')') {
brackets++;
} else if (head.charAt(i) == '(') {
brackets--;
}
if (brackets < 0) {
command = false;
head = head.substring(0, i);
cmd = head;
break;
if (prevChar().equals(")")) {
descType = CmdLine.DescriptionType.SYNTAX;
cmd = head;
} else {
if (line.length() == curPos) {
cmd = args != null && (args.size() > 1 || (args.size() == 1
&& line.endsWith(" "))) ? args.get(0) : null;
descType = CmdLine.DescriptionType.COMMAND;
}
}
if (!command) {
brackets = 0;
for (int i = 0; i < tail.length(); i++) {
if (tail.charAt(i) == ')') {
int brackets = 0;
for (int i = head.length() - 1; i >= 0; i--) {
if (head.charAt(i) == ')') {
brackets++;
} else if (tail.charAt(i) == '(') {
} else if (head.charAt(i) == '(') {
brackets--;
}
if (brackets > 0) {
tail = tail.substring(i + 1);
if (brackets < 0) {
descType = CmdLine.DescriptionType.METHOD;
head = head.substring(0, i);
cmd = head;
break;
}
}
if (descType == CmdLine.DescriptionType.METHOD) {
brackets = 0;
for (int i = 0; i < tail.length(); i++) {
if (tail.charAt(i) == ')') {
brackets++;
} else if (tail.charAt(i) == '(') {
brackets--;
}
if (brackets > 0) {
tail = tail.substring(i + 1);
break;
}
}
}
}
if (cmd != null && !descriptions.containsKey(cmd) && !temporaryDescs.containsKey(cmd)
&& descFun != null) {
if (command) {
CmdDesc c = descFun.apply(new CmdLine(line, head, tail, args, command));
if (descType == CmdLine.DescriptionType.COMMAND) {
CmdDesc c = descFun.apply(new CmdLine(line, head, tail, args, descType));
if (c != null) {
descriptions.put(cmd, c);
} else {
temporaryDescs.put(cmd, c);
}
} else if (descType == CmdLine.DescriptionType.METHOD) {
temporaryDescs.put(cmd, descFun.apply(new CmdLine(line, head, tail, args, descType)));
} else {
temporaryDescs.put(cmd, descFun.apply(new CmdLine(line, head, tail, args, command)));
temporaryDescs.put(cmd, descFun.apply(new CmdLine(line, head, tail, args, descType)));
}
}
return new Pair<String,Boolean>(cmd, new Boolean(command));
return new Pair<String,Boolean>(cmd, descType == CmdLine.DescriptionType.COMMAND ? true : false);
}

public CmdDesc getDescription(String command) {
Expand All @@ -1043,26 +1050,27 @@ public void clearTemporaryDescs() {
}

public static class CmdLine {
public enum DescriptionType {COMMAND, METHOD, SYNTAX};
private String line;
private String head;
private String tail;
private List<String> args;
private boolean command;
private DescriptionType descType;

/**
* CmdLine class constructor.
* @param line Command line
* @param head Command line til cursor, method parameters and parenthesis before the cursor are removed.
* @param tail Command line after cursor, method parameters and parenthesis after the cursor are removed.
* @param head Command line til cursor, method parameters and opening parenthesis before the cursor are removed.
* @param tail Command line after cursor, method parameters and closing parenthesis after the cursor are removed.
* @param args Parsed command line.
* @param command true if command line is not script statement.
* @param descType Request COMMAND, METHOD or SYNTAX description
*/
public CmdLine(String line, String head, String tail, List<String> args, boolean command) {
public CmdLine(String line, String head, String tail, List<String> args, DescriptionType descType) {
this.line = line;
this.head = head;
this.tail = tail;
this.args = new ArrayList<>(args);
this.command = command;
this.descType = descType;
}

public String getLine() {
Expand All @@ -1081,8 +1089,8 @@ public List<String> getArgs() {
return args;
}

public boolean isCommand() {
return command;
public DescriptionType getDescriptionType() {
return descType;
}
}

Expand Down
40 changes: 21 additions & 19 deletions builtins/src/test/java/org/jline/example/Example.java
Original file line number Diff line number Diff line change
Expand Up @@ -223,10 +223,15 @@ else if ("ttop".equals(command)) {

CmdDesc commandDescription(CmdLine line) {
CmdDesc out = null;
if (line.isCommand()) {
switch (line.getDescriptionType()) {
case COMMAND:
out = commandDescription(line.getArgs().get(0));
} else {
break;
case METHOD:
out = methodDescription(line);
break;
case SYNTAX:
break;
}
return out;
}
Expand All @@ -243,23 +248,15 @@ private CmdDesc methodDescription(CmdLine line) {
// For example if using groovy you can create involved object
// dynamically from line string and then inspect method's
// parameters using reflection
if (line.getLine().length() > 200) {
throw new IllegalArgumentException("Failed to create object from source: " + line);
}
for (String s: line.getHead().split("\n")) {
mainDesc.add(new AttributedString(s));

}
mainDesc.add(new AttributedString("----------------------------------------"));
for (String s: line.getTail().split("\n")) {
mainDesc.add(new AttributedString(s));
if (line.getLine().length() > 20) {
throw new IllegalArgumentException("Failed to create object from source: " + line.getLine());
}
// mainDesc = Arrays.asList(new AttributedString("method1(int arg1, List<String> arg2)")
// , new AttributedString("method1(int arg1, Map<String,Object> arg2)")
// );
mainDesc = Arrays.asList(new AttributedString("method1(int arg1, List<String> arg2)")
, new AttributedString("method1(int arg1, Map<String,Object> arg2)")
);
} catch (Exception e) {
for (String s: e.getMessage().split("\n")) {
mainDesc.add(new AttributedString(e.getMessage(), AttributedStyle.DEFAULT.foreground(AttributedStyle.RED)));
mainDesc.add(new AttributedString(s, AttributedStyle.DEFAULT.foreground(AttributedStyle.RED)));
}
}
return new CmdDesc(mainDesc, new ArrayList<>(), new HashMap<>());
Expand Down Expand Up @@ -325,6 +322,7 @@ public static void main(String[] args) throws IOException {
String trigger = null;
boolean color = false;
boolean timer = false;
boolean argument = false;

TerminalBuilder builder = TerminalBuilder.builder();

Expand Down Expand Up @@ -403,6 +401,7 @@ public static void main(String[] args) throws IOException {
});
break;
case "argument":
argument = true;
completer = new ArgumentCompleter(
new Completer() {
@Override
Expand Down Expand Up @@ -520,9 +519,12 @@ public void complete(LineReader reader, ParsedLine line, List<Candidate> candida

AutopairWidgets autopairWidgets = new AutopairWidgets(reader);
AutosuggestionWidgets autosuggestionWidgets = new AutosuggestionWidgets(reader);

// TailTipWidgets tailtipWidgets = new TailTipWidgets(reader, compileTailTips(), 5, TipType.COMPLETER);
TailTipWidgets tailtipWidgets = new TailTipWidgets(reader, executor::commandDescription, 5, TipType.COMPLETER);
TailTipWidgets tailtipWidgets = null;
if (argument) {
tailtipWidgets = new TailTipWidgets(reader, compileTailTips(), 5, TipType.COMPLETER);
} else {
tailtipWidgets = new TailTipWidgets(reader, executor::commandDescription, 5, TipType.COMPLETER);
}

if (timer) {
Executors.newScheduledThreadPool(1)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1119,6 +1119,7 @@ protected String finish(String str) {
}

protected void handleSignal(Signal signal) {
doAutosuggestion = false;
if (signal == Signal.WINCH) {
Status status = Status.getStatus(terminal, false);
if (status != null) {
Expand Down

0 comments on commit 9e2741c

Please sign in to comment.