![JAR search and dependency download from the Maven repository](/logo.png)
org.ow2.petals.cli.shell.completer.CommandCompleter Maven / Gradle / Ivy
/**
* Copyright (c) 2010-2012 EBM WebSourcing, 2012-2016 Linagora
*
* This program/library is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 2.1 of the License, or (at your
* option) any later version.
*
* This program/library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program/library; If not, see http://www.gnu.org/licenses/
* for the GNU Lesser General Public License version 2.1.
*/
package org.ow2.petals.cli.shell.completer;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.apache.commons.cli.Option;
import org.apache.commons.cli.Options;
import org.ow2.petals.cli.api.command.Command;
import jline.console.completer.Completer;
import jline.console.completer.StringsCompleter;
/**
* @author Nicolas Oddoux - EBM WebSourcing
*/
public class CommandCompleter implements Completer {
private final Map commands;
public CommandCompleter(final Map commands) {
this.commands = commands;
}
@Override
public int complete(final String buffer, final int cursor, final List candidates) {
if (this.commands != null) {
// TODO handle quotes
final String lineBegin = buffer.substring(0, cursor);
final int lastSpaceIndex = lineBegin.lastIndexOf(" ");
if (lastSpaceIndex == -1) {
// first word of the line => completion for the command
final String cmdName = lineBegin.substring(0, cursor);
final Completer cmdCompleter = new StringsCompleter(this.commands.keySet());
final int completionIndex = cmdCompleter.complete(cmdName, cursor, candidates);
removeUselessSpace(buffer, cursor, candidates);
return completionIndex;
} else if (lastSpaceIndex == cursor - 1) {
// the previous character is a space
return completeOptionOrArgument(buffer, cursor, candidates, lineBegin, lastSpaceIndex, "");
} else {
// completion for the argument and the options
final String lastWordToComplete = lineBegin.substring(lastSpaceIndex + 1, cursor);
return completeOptionOrArgument(buffer, cursor, candidates, lineBegin, lastSpaceIndex,
lastWordToComplete);
}
} else {
return -1;
}
}
protected int completeOptionOrArgument(final String buffer, final int cursor, final List candidates,
final String lineBegin, final int lastSpaceIndex, final String lastWordToComplete) {
final int firstSpaceIndex = buffer.indexOf(" ");
final String cmdName = buffer.substring(0, firstSpaceIndex);
String lLineBegin = lineBegin;
int lLastSpaceIndex = lastSpaceIndex;
if (this.commands.containsKey(cmdName)) {
final Command command = this.commands.get(cmdName);
// looking for the previous option
int optionArgNb = 0;
int previousSpaceIndex = lLastSpaceIndex;
String previousWord = null;
do {
lLineBegin = lLineBegin.substring(0, previousSpaceIndex);
optionArgNb++;
lLastSpaceIndex = previousSpaceIndex;
previousSpaceIndex = lLineBegin.lastIndexOf(" ");
if (previousSpaceIndex == -1) {
// there is no option in the previous words
return completeOptionPossibilityOrAgument(buffer, cursor, candidates, command,
lastWordToComplete);
}
previousWord = lLineBegin.substring(previousSpaceIndex + 1, lLastSpaceIndex);
} while (!previousWord.startsWith("-"));
final Options options = command.getOptions();
if (options.hasOption(previousWord)) {
// use short option to get the completer in the map
final Option option = options.getOption(previousWord);
if (option.getArgs() >= optionArgNb) {
return completeOptionValue(buffer, cursor, candidates, command,
option, lLastSpaceIndex);
} else {
return completeOptionPossibilityOrAgument(buffer, cursor, candidates, command,
lastWordToComplete);
}
}
}
return -1;
}
protected static final int completeOptionValue(final String buffer, final int cursor,
final List candidates, final Command command, final Option option, final int lastSpaceIndex) {
final Map optionCompleters = command.getOptionCompleters();
if (optionCompleters != null) {
final Completer completer;
if (option.getOpt() != null) {
completer = optionCompleters.get(option.getOpt());
} else if (option.getLongOpt() != null) {
completer = optionCompleters.get(option.getLongOpt());
} else {
completer = null;
}
if (completer != null) {
// use the option completer
final String expressionToComplete = buffer.substring(lastSpaceIndex + 1, cursor);
final int completionIndex = completer.complete(expressionToComplete, cursor, candidates);
removeUselessSpace(buffer, cursor, candidates);
return cursor - expressionToComplete.length() + completionIndex;
} else {
return -1;
}
} else {
return -1;
}
}
private static final int completeOptionPossibilityOrAgument(final String buffer, final int cursor,
final List candidates, final Command command, final String lastWordToComplete) {
if (lastWordToComplete.startsWith("-")) {
// the last word is an option => use a string completer with all the possible options
final Options options = command.getOptions();
if (options != null) {
final List optionStrings = new ArrayList<>();
for (Object optionObj : options.getOptions()) {
final Option option = (Option) optionObj;
final String shortOption = option.getOpt();
if (shortOption != null) {
final String opt = "-" + shortOption;
optionStrings.add(opt);
}
final String longOpt = option.getLongOpt();
if (longOpt != null) {
final String opt = "--" + longOpt;
optionStrings.add(opt);
}
}
final Completer optionCompleter = new StringsCompleter(optionStrings);
final int completionIndex = optionCompleter.complete(lastWordToComplete, cursor, candidates);
removeUselessSpace(buffer, cursor, candidates);
return cursor - lastWordToComplete.length() + completionIndex;
}
} else {
// the last word is not an option => use the default completer
final Completer completer = command.getDefaultCompleter();
if (completer != null) {
final int completionIndex = completer.complete(lastWordToComplete, cursor, candidates);
removeUselessSpace(buffer, cursor, candidates);
return cursor - lastWordToComplete.length() + completionIndex;
}
}
return -1;
}
private static final void removeUselessSpace(final String buffer, final int cursor,
final List candidates) {
if (cursor < buffer.length() && candidates.size() == 1 && buffer.charAt(cursor) == ' ') {
CharSequence candidate = candidates.get(0);
candidate = candidate.subSequence(0, candidate.length() - 1);
candidates.set(0, candidate);
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy