diff --git a/src/main/java/com/annimon/ownlang/parser/Lexer.java b/src/main/java/com/annimon/ownlang/parser/Lexer.java index ca4332a..e0ca7ab 100644 --- a/src/main/java/com/annimon/ownlang/parser/Lexer.java +++ b/src/main/java/com/annimon/ownlang/parser/Lexer.java @@ -5,6 +5,7 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Set; /** * @@ -105,6 +106,10 @@ public final class Lexer { KEYWORDS.put("include", TokenType.INCLUDE); } + public static Set getKeywords() { + return KEYWORDS.keySet(); + } + private final String input; private final int length; diff --git a/src/main/java/com/annimon/ownlang/utils/Repl.java b/src/main/java/com/annimon/ownlang/utils/Repl.java index 43d3986..551bc1e 100644 --- a/src/main/java/com/annimon/ownlang/utils/Repl.java +++ b/src/main/java/com/annimon/ownlang/utils/Repl.java @@ -14,6 +14,7 @@ import com.annimon.ownlang.parser.ast.BlockStatement; import com.annimon.ownlang.parser.ast.Statement; import com.annimon.ownlang.parser.visitors.PrintVisitor; import com.annimon.ownlang.utils.repl.JLineConsole; +import com.annimon.ownlang.utils.repl.OwnLangCompleter; import com.annimon.ownlang.utils.repl.ReplConsole; import com.annimon.ownlang.utils.repl.SystemConsole; import java.io.IOException; @@ -22,6 +23,7 @@ import java.util.List; import java.util.Locale; import java.util.Map; import java.util.stream.Collectors; +import jline.console.completer.CandidateListCompletionHandler; public final class Repl { @@ -91,7 +93,12 @@ public final class Repl { private static ReplConsole initReplConsole() { try { - return new JLineConsole(); + JLineConsole jline = new JLineConsole(); + CandidateListCompletionHandler handler = new CandidateListCompletionHandler(); + handler.setPrintSpaceAfterFullCompletion(false); + jline.getConsole().setCompletionHandler(handler); + jline.getConsole().addCompleter(new OwnLangCompleter(HELP, VARS, FUNCS, SOURCE, RESET, EXIT)); + return jline; } catch (IOException ioe) { return new SystemConsole(); } diff --git a/src/main/java/com/annimon/ownlang/utils/repl/OwnLangCompleter.java b/src/main/java/com/annimon/ownlang/utils/repl/OwnLangCompleter.java new file mode 100644 index 0000000..e0a2f9e --- /dev/null +++ b/src/main/java/com/annimon/ownlang/utils/repl/OwnLangCompleter.java @@ -0,0 +1,34 @@ +package com.annimon.ownlang.utils.repl; + +import com.annimon.ownlang.lib.Functions; +import com.annimon.ownlang.lib.Variables; +import com.annimon.ownlang.parser.Lexer; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import jline.console.completer.StringsCompleter; + +public final class OwnLangCompleter extends StringsCompleter { + + private final Set staticCandidates; + + public OwnLangCompleter(String... candidates) { + staticCandidates = new HashSet<>(); + Collections.addAll(staticCandidates, candidates); + } + + @Override + public int complete(String buffer, int cursor, List candidates) { + updateCandidates(); + return super.complete(buffer, cursor, candidates); + } + + private void updateCandidates() { + getStrings().clear(); + getStrings().addAll(Lexer.getKeywords()); + getStrings().addAll(staticCandidates); + getStrings().addAll(Variables.variables().keySet()); + getStrings().addAll(Functions.getFunctions().keySet()); + } +}