Case sensitive tab completion.
This commit is contained in:
parent
e6de76fb1f
commit
98ba8cda53
@ -85,16 +85,25 @@ public abstract class ARAbstract<T> implements AR<T>
|
|||||||
@Override
|
@Override
|
||||||
public List<String> getTabListFiltered(CommandSender sender, String arg)
|
public List<String> getTabListFiltered(CommandSender sender, String arg)
|
||||||
{
|
{
|
||||||
// Filter them to start with what the user typed in.
|
// Get the raw tab list.
|
||||||
Collection<String> raw = this.getTabList(sender, arg);
|
Collection<String> raw = this.getTabList(sender, arg);
|
||||||
|
|
||||||
|
// Handle null case.
|
||||||
if (raw == null || raw.isEmpty()) return Collections.emptyList();
|
if (raw == null || raw.isEmpty()) return Collections.emptyList();
|
||||||
|
|
||||||
|
// Only keep the suggestions that starts with what the user already typed in.
|
||||||
|
// This is the first basic step of tab completion.
|
||||||
|
// "Ca" can complete into "Cayorion".
|
||||||
|
// "Ma" can complete into "Madus"
|
||||||
|
// "Ca" can not complete into "Madus" because it does not start with ignore case.
|
||||||
List<String> ret = Txt.getStartsWithIgnoreCase(raw, arg);
|
List<String> ret = Txt.getStartsWithIgnoreCase(raw, arg);
|
||||||
|
|
||||||
|
// Initial simple cleanup of suggestions.
|
||||||
|
cleanSuggestions(ret);
|
||||||
|
|
||||||
// Here we do a lot of things related to spaces.
|
// Here we do a lot of things related to spaces.
|
||||||
// Because spaces and tab completion desn't go well together.
|
// Because spaces and tab completion doesn'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, arg);
|
ret = prepareForSpaces(ret, arg);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
@ -104,17 +113,30 @@ public abstract class ARAbstract<T> implements AR<T>
|
|||||||
// PRIVATE: TAB COMPLETE CALCULATIONS
|
// PRIVATE: TAB COMPLETE CALCULATIONS
|
||||||
// -------------------------------------------- //
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
// This method performs an initial cleanup of suggestions.
|
||||||
|
// Currently we just throw away nulls and empty strings.
|
||||||
|
private static void cleanSuggestions(List<String> suggestions)
|
||||||
|
{
|
||||||
|
ListIterator<String> iter = suggestions.listIterator();
|
||||||
|
while (iter.hasNext())
|
||||||
|
{
|
||||||
|
String suggestion = iter.next();
|
||||||
|
if (suggestion == null || suggestion.isEmpty())
|
||||||
|
{
|
||||||
|
iter.remove();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static List<String> prepareForSpaces(List<String> suggestions, String arg)
|
public static List<String> prepareForSpaces(List<String> suggestions, String arg)
|
||||||
{
|
{
|
||||||
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 some things 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.
|
||||||
final String prefix = getPrefix(suggestions);
|
final String prefix = getPrefix(suggestions);
|
||||||
|
|
||||||
// This is all the suggetions without the common prefix.
|
// This is all the suggestions without the common prefix.
|
||||||
List<String> ret = withoutPreAndSuffix(suggestions, 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())
|
||||||
@ -142,15 +164,41 @@ public abstract class ARAbstract<T> implements AR<T>
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void cleanSuggestions(List<String> suggestions)
|
private static String getPrefix(List<String> suggestions)
|
||||||
{
|
{
|
||||||
for (ListIterator<String> it = suggestions.listIterator(); it.hasNext();)
|
String prefix = null;
|
||||||
|
|
||||||
|
for (String suggestion : suggestions)
|
||||||
{
|
{
|
||||||
String suggestion = it.next();
|
prefix = getOkay(prefix, suggestion);
|
||||||
if (suggestion == null) it.remove();
|
|
||||||
else if (suggestion.isEmpty()) it.remove();
|
|
||||||
else it.set(suggestion.toLowerCase());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (prefix == null) return "";
|
||||||
|
int lastSpace = prefix.lastIndexOf(" ");
|
||||||
|
if (lastSpace == -1) return "";
|
||||||
|
|
||||||
|
return prefix.substring(0, lastSpace + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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.length(), compared.length());
|
||||||
|
StringBuilder ret = new StringBuilder();
|
||||||
|
|
||||||
|
for (int i = 0; i < size; i++)
|
||||||
|
{
|
||||||
|
if (Character.toLowerCase(compared.charAt(i)) != Character.toLowerCase(original.charAt(i))) break;
|
||||||
|
ret.append(compared.charAt(i));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ret.length() == 0) return "";
|
||||||
|
|
||||||
|
int lastSpace = ret.lastIndexOf(" ");
|
||||||
|
if (lastSpace == -1) return "";
|
||||||
|
|
||||||
|
return ret.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static List<String> withoutPreAndSuffix(List<String> suggestions, String prefix)
|
private static List<String> withoutPreAndSuffix(List<String> suggestions, String prefix)
|
||||||
@ -177,42 +225,4 @@ public abstract class ARAbstract<T> implements AR<T>
|
|||||||
return new ArrayList<String>(ret);
|
return new ArrayList<String>(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String getPrefix(List<String> suggestions)
|
|
||||||
{
|
|
||||||
String prefix = null;
|
|
||||||
|
|
||||||
for (String suggestion : suggestions)
|
|
||||||
{
|
|
||||||
prefix = getOkay(prefix, suggestion);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (prefix == null) return "";
|
|
||||||
int lastSpace = prefix.lastIndexOf(" ");
|
|
||||||
if (lastSpace == -1) return "";
|
|
||||||
|
|
||||||
return prefix.substring(0, lastSpace+1);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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.length(), compared.length());
|
|
||||||
StringBuilder ret = new StringBuilder();
|
|
||||||
|
|
||||||
for (int i = 0; i < size; i++)
|
|
||||||
{
|
|
||||||
if (Character.toLowerCase(compared.charAt(i)) != Character.toLowerCase(original.charAt(i))) break;
|
|
||||||
ret.append(compared.charAt(i));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ret.length() == 0) return "";
|
|
||||||
|
|
||||||
int lastSpace = ret.lastIndexOf(" ");
|
|
||||||
if (lastSpace == -1) return "";
|
|
||||||
|
|
||||||
return ret.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -582,16 +582,19 @@ public class Txt
|
|||||||
// FILTER
|
// FILTER
|
||||||
// -------------------------------------------- //
|
// -------------------------------------------- //
|
||||||
|
|
||||||
public static <T> List<T> getFiltered(Collection<T> elements, Predictate<T> predictate)
|
public static <T> List<T> getFiltered(Iterable<T> elements, Predictate<T> predictate)
|
||||||
{
|
{
|
||||||
|
// Create Ret
|
||||||
List<T> ret = new ArrayList<T>();
|
List<T> ret = new ArrayList<T>();
|
||||||
|
|
||||||
|
// Fill Ret
|
||||||
for (T element : elements)
|
for (T element : elements)
|
||||||
{
|
{
|
||||||
if ( ! predictate.apply(element)) continue;
|
if ( ! predictate.apply(element)) continue;
|
||||||
ret.add(element);
|
ret.add(element);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Return Ret
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -600,7 +603,7 @@ public class Txt
|
|||||||
return getFiltered(Arrays.asList(elements), predictate);
|
return getFiltered(Arrays.asList(elements), predictate);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static List<String> getStartsWithIgnoreCase(Collection<String> elements, String prefix)
|
public static List<String> getStartsWithIgnoreCase(Iterable<String> elements, String prefix)
|
||||||
{
|
{
|
||||||
return getFiltered(elements, PredictateStartsWithIgnoreCase.get(prefix));
|
return getFiltered(elements, PredictateStartsWithIgnoreCase.get(prefix));
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user