Revert "Implement configurable command node separators"pull/423/head
@@ -22,7 +22,6 @@ namespace Discord.Commands | |||||
internal readonly bool _caseSensitive; | internal readonly bool _caseSensitive; | ||||
internal readonly RunMode _defaultRunMode; | internal readonly RunMode _defaultRunMode; | ||||
internal readonly char _splitCharacter; | |||||
public IEnumerable<ModuleInfo> Modules => _moduleDefs.Select(x => x); | public IEnumerable<ModuleInfo> Modules => _moduleDefs.Select(x => x); | ||||
public IEnumerable<CommandInfo> Commands => _moduleDefs.SelectMany(x => x.Commands); | public IEnumerable<CommandInfo> Commands => _moduleDefs.SelectMany(x => x.Commands); | ||||
@@ -61,7 +60,6 @@ namespace Discord.Commands | |||||
_caseSensitive = config.CaseSensitiveCommands; | _caseSensitive = config.CaseSensitiveCommands; | ||||
_defaultRunMode = config.DefaultRunMode; | _defaultRunMode = config.DefaultRunMode; | ||||
_splitCharacter = config.CommandSplitCharacter; | |||||
} | } | ||||
//Modules | //Modules | ||||
@@ -131,7 +129,7 @@ namespace Discord.Commands | |||||
_moduleDefs.Add(module); | _moduleDefs.Add(module); | ||||
foreach (var command in module.Commands) | foreach (var command in module.Commands) | ||||
_map.AddCommand(command, this); | |||||
_map.AddCommand(command); | |||||
foreach (var submodule in module.Submodules) | foreach (var submodule in module.Submodules) | ||||
LoadModuleInternal(submodule); | LoadModuleInternal(submodule); | ||||
@@ -175,7 +173,7 @@ namespace Discord.Commands | |||||
return false; | return false; | ||||
foreach (var cmd in module.Commands) | foreach (var cmd in module.Commands) | ||||
_map.RemoveCommand(cmd, this); | |||||
_map.RemoveCommand(cmd); | |||||
foreach (var submodule in module.Submodules) | foreach (var submodule in module.Submodules) | ||||
{ | { | ||||
@@ -216,7 +214,7 @@ namespace Discord.Commands | |||||
public SearchResult Search(CommandContext context, string input) | public SearchResult Search(CommandContext context, string input) | ||||
{ | { | ||||
string searchInput = _caseSensitive ? input : input.ToLowerInvariant(); | string searchInput = _caseSensitive ? input : input.ToLowerInvariant(); | ||||
var matches = _map.GetCommands(searchInput, this).OrderByDescending(x => x.Priority).ToImmutableArray(); | |||||
var matches = _map.GetCommands(searchInput).OrderByDescending(x => x.Priority).ToImmutableArray(); | |||||
if (matches.Length > 0) | if (matches.Length > 0) | ||||
return SearchResult.FromSuccess(input, matches); | return SearchResult.FromSuccess(input, matches); | ||||
@@ -6,7 +6,5 @@ | |||||
public RunMode DefaultRunMode { get; set; } = RunMode.Sync; | public RunMode DefaultRunMode { get; set; } = RunMode.Sync; | ||||
/// <summary> Should commands be case-sensitive? </summary> | /// <summary> Should commands be case-sensitive? </summary> | ||||
public bool CaseSensitiveCommands { get; set; } = false; | public bool CaseSensitiveCommands { get; set; } = false; | ||||
/// <summary> The character which splits commands </summary> | |||||
public char CommandSplitCharacter { get; set; } = ' '; | |||||
} | } | ||||
} | } |
@@ -44,7 +44,7 @@ namespace Discord.Commands | |||||
// both command and module provide aliases | // both command and module provide aliases | ||||
if (module.Aliases.Count > 0 && builder.Aliases.Count > 0) | if (module.Aliases.Count > 0 && builder.Aliases.Count > 0) | ||||
Aliases = module.Aliases.Permutate(builder.Aliases, (first, second) => second != null ? first + service._splitCharacter + second : first).Select(x => service._caseSensitive ? x : x.ToLowerInvariant()).ToImmutableArray(); | |||||
Aliases = module.Aliases.Permutate(builder.Aliases, (first, second) => second != null ? first + " " + second : first).Select(x => service._caseSensitive ? x : x.ToLowerInvariant()).ToImmutableArray(); | |||||
// only module provides aliases | // only module provides aliases | ||||
else if (module.Aliases.Count > 0) | else if (module.Aliases.Count > 0) | ||||
Aliases = module.Aliases.Select(x => service._caseSensitive ? x : x.ToLowerInvariant()).ToImmutableArray(); | Aliases = module.Aliases.Select(x => service._caseSensitive ? x : x.ToLowerInvariant()).ToImmutableArray(); | ||||
@@ -30,14 +30,14 @@ namespace Discord.Commands | |||||
Remarks = builder.Remarks; | Remarks = builder.Remarks; | ||||
Parent = parent; | Parent = parent; | ||||
Aliases = BuildAliases(builder, service).ToImmutableArray(); | |||||
Aliases = BuildAliases(builder).ToImmutableArray(); | |||||
Commands = builder.Commands.Select(x => x.Build(this, service)); | Commands = builder.Commands.Select(x => x.Build(this, service)); | ||||
Preconditions = BuildPreconditions(builder).ToImmutableArray(); | Preconditions = BuildPreconditions(builder).ToImmutableArray(); | ||||
Submodules = BuildSubmodules(builder, service).ToImmutableArray(); | Submodules = BuildSubmodules(builder, service).ToImmutableArray(); | ||||
} | } | ||||
private static IEnumerable<string> BuildAliases(ModuleBuilder builder, CommandService service) | |||||
private static IEnumerable<string> BuildAliases(ModuleBuilder builder) | |||||
{ | { | ||||
IEnumerable<string> result = null; | IEnumerable<string> result = null; | ||||
@@ -60,9 +60,9 @@ namespace Discord.Commands | |||||
result = level.Aliases.ToList(); //create a shallow copy so we don't overwrite the builder unexpectedly | result = level.Aliases.ToList(); //create a shallow copy so we don't overwrite the builder unexpectedly | ||||
} | } | ||||
else if (result.Count() > level.Aliases.Count) | else if (result.Count() > level.Aliases.Count) | ||||
result = result.Permutate(level.Aliases, (first, second) => first + service._splitCharacter + second); | |||||
result = result.Permutate(level.Aliases, (first, second) => first + " " + second); | |||||
else | else | ||||
result = level.Aliases.Permutate(result, (second, first) => first + service._splitCharacter + second); | |||||
result = level.Aliases.Permutate(result, (second, first) => first + " " + second); | |||||
} | } | ||||
if (result == null) //there were no aliases; default to an empty list | if (result == null) //there were no aliases; default to an empty list | ||||
@@ -12,20 +12,20 @@ namespace Discord.Commands | |||||
_root = new CommandMapNode(""); | _root = new CommandMapNode(""); | ||||
} | } | ||||
public void AddCommand(CommandInfo command, CommandService service) | |||||
public void AddCommand(CommandInfo command) | |||||
{ | { | ||||
foreach (string text in GetAliases(command)) | foreach (string text in GetAliases(command)) | ||||
_root.AddCommand(service, text, 0, command); | |||||
_root.AddCommand(text, 0, command); | |||||
} | } | ||||
public void RemoveCommand(CommandInfo command, CommandService service) | |||||
public void RemoveCommand(CommandInfo command) | |||||
{ | { | ||||
foreach (string text in GetAliases(command)) | foreach (string text in GetAliases(command)) | ||||
_root.RemoveCommand(service, text, 0, command); | |||||
_root.RemoveCommand(text, 0, command); | |||||
} | } | ||||
public IEnumerable<CommandInfo> GetCommands(string text, CommandService service) | |||||
public IEnumerable<CommandInfo> GetCommands(string text) | |||||
{ | { | ||||
return _root.GetCommands(service, text, 0); | |||||
return _root.GetCommands(text, 0); | |||||
} | } | ||||
private IReadOnlyList<string> GetAliases(CommandInfo command) | private IReadOnlyList<string> GetAliases(CommandInfo command) | ||||
@@ -23,9 +23,9 @@ namespace Discord.Commands | |||||
_commands = ImmutableArray.Create<CommandInfo>(); | _commands = ImmutableArray.Create<CommandInfo>(); | ||||
} | } | ||||
public void AddCommand(CommandService service, string text, int index, CommandInfo command) | |||||
public void AddCommand(string text, int index, CommandInfo command) | |||||
{ | { | ||||
int nextSpace = NextWhitespace(service, text, index); | |||||
int nextSpace = NextWhitespace(text, index); | |||||
string name; | string name; | ||||
lock (_lockObj) | lock (_lockObj) | ||||
@@ -44,13 +44,13 @@ namespace Discord.Commands | |||||
name = text.Substring(index, nextSpace - index); | name = text.Substring(index, nextSpace - index); | ||||
var nextNode = _nodes.GetOrAdd(name, x => new CommandMapNode(x)); | var nextNode = _nodes.GetOrAdd(name, x => new CommandMapNode(x)); | ||||
nextNode.AddCommand(service, nextSpace == -1 ? "" : text, nextSpace + 1, command); | |||||
nextNode.AddCommand(nextSpace == -1 ? "" : text, nextSpace + 1, command); | |||||
} | } | ||||
} | } | ||||
} | } | ||||
public void RemoveCommand(CommandService service, string text, int index, CommandInfo command) | |||||
public void RemoveCommand(string text, int index, CommandInfo command) | |||||
{ | { | ||||
int nextSpace = NextWhitespace(service, text, index); | |||||
int nextSpace = NextWhitespace(text, index); | |||||
string name; | string name; | ||||
lock (_lockObj) | lock (_lockObj) | ||||
@@ -67,7 +67,7 @@ namespace Discord.Commands | |||||
CommandMapNode nextNode; | CommandMapNode nextNode; | ||||
if (_nodes.TryGetValue(name, out nextNode)) | if (_nodes.TryGetValue(name, out nextNode)) | ||||
{ | { | ||||
nextNode.RemoveCommand(service, nextSpace == -1 ? "" : text, nextSpace + 1, command); | |||||
nextNode.RemoveCommand(nextSpace == -1 ? "" : text, nextSpace + 1, command); | |||||
if (nextNode.IsEmpty) | if (nextNode.IsEmpty) | ||||
_nodes.TryRemove(name, out nextNode); | _nodes.TryRemove(name, out nextNode); | ||||
} | } | ||||
@@ -75,57 +75,32 @@ namespace Discord.Commands | |||||
} | } | ||||
} | } | ||||
public IEnumerable<CommandInfo> GetCommands(CommandService service, string text, int index) | |||||
public IEnumerable<CommandInfo> GetCommands(string text, int index) | |||||
{ | { | ||||
int nextCommand = NextCommandSegment(service, text, index); | |||||
string name = null; | |||||
int nextSpace = NextWhitespace(text, index); | |||||
string name; | |||||
//got all command segments or base-level command | |||||
if (nextCommand == -1) | |||||
{ | |||||
var commands = _commands; | |||||
for (int i = 0; i < commands.Length; i++) | |||||
yield return _commands[i]; | |||||
var commands = _commands; | |||||
for (int i = 0; i < commands.Length; i++) | |||||
yield return _commands[i]; | |||||
//are we a base-level command? | |||||
int nextSpace = NextWhitespace(service, text, index); | |||||
if (nextSpace != -1) | |||||
{ | |||||
name = text.Substring(index, nextSpace - index); | |||||
} | |||||
else | |||||
{ | |||||
name = text.Substring(index); | |||||
} | |||||
} | |||||
else | |||||
if (text != "") | |||||
{ | { | ||||
name = text.Substring(index, nextCommand - index); | |||||
} | |||||
if (nextSpace == -1) | |||||
name = text.Substring(index); | |||||
else | |||||
name = text.Substring(index, nextSpace - index); | |||||
if (name != null) | |||||
{ | |||||
CommandMapNode nextNode; | CommandMapNode nextNode; | ||||
if (_nodes.TryGetValue(name, out nextNode)) | if (_nodes.TryGetValue(name, out nextNode)) | ||||
{ | { | ||||
foreach (var cmd in nextNode.GetCommands(service, text, nextCommand + 1)) | |||||
foreach (var cmd in nextNode.GetCommands(nextSpace == -1 ? "" : text, nextSpace + 1)) | |||||
yield return cmd; | yield return cmd; | ||||
} | } | ||||
} | } | ||||
} | } | ||||
private static int NextCommandSegment(CommandService service, string text, int startIndex) | |||||
{ | |||||
int lowest = int.MaxValue; | |||||
int index = text.IndexOf(service._splitCharacter, startIndex); | |||||
if (index != -1 && index < lowest) | |||||
lowest = index; | |||||
return (lowest != int.MaxValue) ? lowest : -1; | |||||
} | |||||
private static int NextWhitespace(CommandService service, string text, int startIndex) | |||||
private static int NextWhitespace(string text, int startIndex) | |||||
{ | { | ||||
int lowest = int.MaxValue; | int lowest = int.MaxValue; | ||||
for (int i = 0; i < _whitespaceChars.Length; i++) | for (int i = 0; i < _whitespaceChars.Length; i++) | ||||
@@ -134,7 +109,6 @@ namespace Discord.Commands | |||||
if (index != -1 && index < lowest) | if (index != -1 && index < lowest) | ||||
lowest = index; | lowest = index; | ||||
} | } | ||||
return (lowest != int.MaxValue) ? lowest : -1; | return (lowest != int.MaxValue) ? lowest : -1; | ||||
} | } | ||||
} | } | ||||