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