Attempt to fix space tab completion.
This commit is contained in:
parent
0bc46a0818
commit
78e272cdb4
@ -93,4 +93,4 @@ public class MassiveCoreMConf extends Entity<MassiveCoreMConf>
|
||||
public String variableBuffer = "***buffer***";
|
||||
public boolean usingVariableBuffer = true;
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -1,14 +1,14 @@
|
||||
package com.massivecraft.massivecore.cmd.arg;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.ListIterator;
|
||||
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.massivecraft.massivecore.MassiveException;
|
||||
import com.massivecraft.massivecore.util.Txt;
|
||||
|
||||
@ -95,7 +95,7 @@ public abstract class ARAbstract<T> implements AR<T>
|
||||
// Because spaces and tab completion desn't go well together.
|
||||
// In the future we might be able to do something better,
|
||||
// but MineCraft has its limitations.
|
||||
ret = prepareForSpaces(ret);
|
||||
ret = prepareForSpaces(ret, arg);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -104,17 +104,18 @@ public abstract class ARAbstract<T> implements AR<T>
|
||||
// PRIVATE: TAB COMPLETE CALCULATIONS
|
||||
// -------------------------------------------- //
|
||||
|
||||
public static List<String> prepareForSpaces(List<String> suggestions)
|
||||
public static List<String> prepareForSpaces(List<String> suggestions, String arg)
|
||||
{
|
||||
List<List<String>> suggestionParts = getParts(suggestions);
|
||||
cleanSuggestions(suggestions);
|
||||
|
||||
// This will get the common prefix for all passed in suggestions.
|
||||
// This will allow us to tab complete somethings with spaces
|
||||
// if we know they all start with the same value,
|
||||
// so we don't have to replace all of it.
|
||||
List<String> prefix = getPrefix(suggestionParts);
|
||||
final String prefix = getPrefix(suggestions);
|
||||
|
||||
// This is all the suggetions without the common prefix.
|
||||
List<String> ret = withoutPreAndSuffix(suggestionParts, prefix);
|
||||
List<String> ret = withoutPreAndSuffix(suggestions, prefix);
|
||||
// If it isn't empty and there is a prefix...
|
||||
if ( ! ret.isEmpty() && ! prefix.isEmpty())
|
||||
{
|
||||
@ -122,36 +123,43 @@ public abstract class ARAbstract<T> implements AR<T>
|
||||
// That prefix is not removed automatically,
|
||||
// due to how tab completion works.
|
||||
final String current = ret.get(0);
|
||||
final String prefixStr = Txt.implode(prefix, " ");
|
||||
String result = prefixStr;
|
||||
if ( ! current.isEmpty()) result += " " + current;
|
||||
String result = prefix;
|
||||
if ( ! current.isEmpty())
|
||||
{
|
||||
if (result.charAt(result.length()-1) != ' ') result += ' ';
|
||||
result += current;
|
||||
}
|
||||
|
||||
int unwantedPrefixLength = arg.lastIndexOf(' ');
|
||||
if (unwantedPrefixLength != -1)
|
||||
{
|
||||
unwantedPrefixLength++;
|
||||
result = result.substring(unwantedPrefixLength);
|
||||
}
|
||||
ret.set(0, result);
|
||||
}
|
||||
|
||||
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
// This things splits up the arguments at spaces.
|
||||
private static List<List<String>> getParts(List<String> list)
|
||||
private static void cleanSuggestions(List<String> suggestions)
|
||||
{
|
||||
List<List<String>> ret = Lists.newArrayList();
|
||||
|
||||
for (String str : list)
|
||||
for (ListIterator<String> it = suggestions.listIterator(); it.hasNext();)
|
||||
{
|
||||
if (str == null) continue;
|
||||
if (str.isEmpty()) continue;
|
||||
ret.add(Arrays.asList(str.split("\\s+")));
|
||||
String suggestion = it.next();
|
||||
if (suggestion == null) it.remove();
|
||||
else if (suggestion.isEmpty()) it.remove();
|
||||
else it.set(suggestion.toLowerCase());
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
private static List<String> withoutPreAndSuffix(List<List<String>> suggestionParts, List<String> prefix)
|
||||
|
||||
private static List<String> withoutPreAndSuffix(List<String> suggestions, String prefix)
|
||||
{
|
||||
List<String> ret = new ArrayList<String>(suggestionParts.size());
|
||||
LinkedHashSet<String> ret = new LinkedHashSet<String>(suggestions.size());
|
||||
boolean includesPrefix = false; // Sometimes a suggestion is equal to the prefix.
|
||||
for (List<String> suggestion : suggestionParts)
|
||||
for (String suggestion : suggestions)
|
||||
{
|
||||
if (suggestion.equals(prefix) && !includesPrefix)
|
||||
{
|
||||
@ -162,42 +170,51 @@ public abstract class ARAbstract<T> implements AR<T>
|
||||
// We remove the prefix because we only want that once.
|
||||
// But we can't keep things after the first part either
|
||||
// because of spaces and stuff.
|
||||
if (suggestion.size() <= prefix.size()) continue;
|
||||
ret.add(suggestion.get(prefix.size()));
|
||||
if (suggestion.length() <= prefix.length()) continue;
|
||||
int lastSpace = prefix.indexOf(' ', prefix.length());
|
||||
int lastIndex = lastSpace != -1 ? lastSpace : suggestion.length();
|
||||
ret.add(suggestion.substring(prefix.length(), lastIndex));
|
||||
}
|
||||
|
||||
return ret;
|
||||
return new ArrayList<String>(ret);
|
||||
}
|
||||
|
||||
private static List<String> getPrefix(List<List<String>> suggestionParts)
|
||||
private static String getPrefix(List<String> suggestions)
|
||||
{
|
||||
List<String> prefix = null;
|
||||
String prefix = null;
|
||||
|
||||
for (List<String> suggestion : suggestionParts)
|
||||
for (String suggestion : suggestions)
|
||||
{
|
||||
prefix = getOkay(prefix, suggestion);
|
||||
}
|
||||
|
||||
return prefix;
|
||||
if (prefix == null) return "";
|
||||
int lastSpace = prefix.lastIndexOf(" ");
|
||||
if (lastSpace == -1) return "";
|
||||
|
||||
return prefix.substring(0, lastSpace+1);
|
||||
}
|
||||
|
||||
// This method return a new array only including
|
||||
// the first parts that are equal.
|
||||
private static List<String> getOkay(List<String> original, List<String> compared)
|
||||
// This method return a new string only including
|
||||
// the first characters that are equal.
|
||||
private static String getOkay(String original, String compared)
|
||||
{
|
||||
if (original == null) return compared;
|
||||
|
||||
final int size = Math.min(original.size(), compared.size());
|
||||
List<String> ret = new ArrayList<String>(size);
|
||||
final int size = Math.min(original.length(), compared.length());
|
||||
StringBuilder ret = new StringBuilder();
|
||||
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
if (compared.get(i) == null || original.get(i) == null) break;
|
||||
if ( ! compared.get(i).equals(original.get(i))) break;
|
||||
ret.add(original.get(i));
|
||||
if (Character.toLowerCase(compared.charAt(i)) != Character.toLowerCase(original.charAt(i))) break;
|
||||
ret.append(compared.charAt(i));
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
||||
if (ret.length() == 0) return "";
|
||||
|
||||
int lastSpace = ret.lastIndexOf(" ");
|
||||
if (lastSpace == -1) return "";
|
||||
|
||||
return ret.toString();
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user