package org.rascalmpl.library.experiments.Compiler.RVM.Interpreter.repl;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.SortedSet;
import java.util.TreeSet;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import org.rascalmpl.interpreter.utils.StringUtils;
import org.rascalmpl.interpreter.utils.StringUtils.OffsetLengthTerm;
import org.rascalmpl.repl.CompletionFunction;
import org.rascalmpl.repl.CompletionResult;
public class RascalCommandCompletion {
private static final Pattern splitCommand = Pattern.compile("^[\\t ]*(?<command>[a-z]*)([\\t ]|$)");
public static CompletionResult complete(String line, int cursor, SortedSet<String> commandOptions, CompletionFunction completeIdentifier, CompletionFunction completeModule, CommandExecutor executor) {
Matcher m = splitCommand.matcher(line);
if (m.find()) {
String currentCommand = m.group("command");
switch(currentCommand) {
case "set": {
OffsetLengthTerm identifier = StringUtils.findRascalIdentifierAtOffset(line, cursor);
if (identifier != null && identifier.offset > m.end("command")) {
int atArg = line.split("\\s+").length - 1;
Collection<String> suggestions = new TreeSet<String>();
if(atArg == 1){
suggestions = commandOptions.stream()
.filter(s -> s.startsWith(identifier.term))
.sorted()
.collect(Collectors.toList());
} else {
if("true".startsWith(identifier.term)){
suggestions.add("true");
} else if("false".startsWith(identifier.term)){
suggestions.add("false");
}
}
if (suggestions != null && ! suggestions.isEmpty()) {
return new CompletionResult(identifier.offset, suggestions);
}
}
else if (line.trim().equals("set")) {
return new CompletionResult(line.length(), commandOptions);
}
return null;
}
case "undeclare": {
OffsetLengthTerm identifier = StringUtils.findRascalIdentifierAtOffset(line, cursor);
if (identifier != null && identifier.offset > m.end("command")) {
Collection<String> suggestions = executor.completeDeclaredIdentifier(identifier.term);
if (suggestions != null && ! suggestions.isEmpty()) {
return new CompletionResult(identifier.offset, suggestions);
}
}
return null;
}
case "edit": {
CompletionResult suggestions = executor.completeModule(line, cursor);
return suggestions;
}
case "unimport":
{
OffsetLengthTerm identifier = StringUtils.findRascalIdentifierAtOffset(line, cursor);
if (identifier != null && identifier.offset > m.end("command")) {
//Collection<String> suggestions = executor.completeImportedIdentifier(identifier.term);
Collection<String> suggestions = executor.completeImportedIdentifier(identifier.term);
if (suggestions != null && ! suggestions.isEmpty()) {
return new CompletionResult(identifier.offset, suggestions);
}
}
return null;
}
case "test":
return executor.completeModule(line, cursor);
case "break": return completeIdentifier.complete(line, cursor);
default: {
if (CompiledRascalREPL.SHELL_VERBS.contains(currentCommand)) {
return null; // nothing to complete after a full command
}
List<String> result = null;
if (currentCommand.isEmpty()) {
result = new ArrayList<>(CompiledRascalREPL.SHELL_VERBS);
}
else {
result = CompiledRascalREPL.SHELL_VERBS.stream()
.filter(s -> s.startsWith(currentCommand))
.collect(Collectors.toList());
}
if (!result.isEmpty()) {
return new CompletionResult(m.start("command"), result);
}
}
}
}
return null;
}
}