diff --git a/src/Discord.Net.Commands/CommandParser.cs b/src/Discord.Net.Commands/CommandParser.cs
index 28e36d54d..1b3f6067b 100644
--- a/src/Discord.Net.Commands/CommandParser.cs
+++ b/src/Discord.Net.Commands/CommandParser.cs
@@ -13,6 +13,19 @@ namespace Discord.Commands
Parameter,
QuotedParameter
}
+
+ ///
+ /// Checks to see if the supplied character is a quotation mark
+ /// from either the default " character, or the list of aliases
+ /// if they are provided.
+ ///
+ ///
+ ///
+ private static bool isQuotationChar(char c, char[] aliases)
+ {
+ if (aliases == null) return c == '\"';
+ return Array.Exists(aliases, x => x == c);
+ }
public static async Task ParseArgsAsync(CommandInfo command, ICommandContext context, IServiceProvider services, string input, int startPos)
{
@@ -74,7 +87,7 @@ namespace Discord.Commands
argBuilder.Append(c);
continue;
}
- if (c == '\"')
+ if (isQuotationChar(c, command._quotationAliases))
{
curPart = ParserPart.QuotedParameter;
continue;
@@ -97,7 +110,7 @@ namespace Discord.Commands
}
else if (curPart == ParserPart.QuotedParameter)
{
- if (c == '\"')
+ if (isQuotationChar(c, command._quotationAliases))
{
argString = argBuilder.ToString(); //Remove quotes
lastArgEndPos = curPos + 1;
diff --git a/src/Discord.Net.Commands/CommandService.cs b/src/Discord.Net.Commands/CommandService.cs
index cf2b93277..99d333ee5 100644
--- a/src/Discord.Net.Commands/CommandService.cs
+++ b/src/Discord.Net.Commands/CommandService.cs
@@ -32,6 +32,7 @@ namespace Discord.Commands
internal readonly RunMode _defaultRunMode;
internal readonly Logger _cmdLogger;
internal readonly LogManager _logManager;
+ internal readonly char[] _quotationMarkAliases;
public IEnumerable Modules => _moduleDefs.Select(x => x);
public IEnumerable Commands => _moduleDefs.SelectMany(x => x.Commands);
@@ -44,6 +45,7 @@ namespace Discord.Commands
_throwOnError = config.ThrowOnError;
_separatorChar = config.SeparatorChar;
_defaultRunMode = config.DefaultRunMode;
+ _quotationMarkAliases = config.QuotationMarkAliases;
if (_defaultRunMode == RunMode.Default)
throw new InvalidOperationException("The default run mode cannot be set to Default.");
@@ -276,7 +278,7 @@ namespace Discord.Commands
public async Task ExecuteAsync(ICommandContext context, string input, IServiceProvider services = null, MultiMatchHandling multiMatchHandling = MultiMatchHandling.Exception)
{
services = services ?? EmptyServiceProvider.Instance;
-
+
var searchResult = Search(context, input);
if (!searchResult.IsSuccess)
return searchResult;
diff --git a/src/Discord.Net.Commands/CommandServiceConfig.cs b/src/Discord.Net.Commands/CommandServiceConfig.cs
index b53b0248c..86e05e619 100644
--- a/src/Discord.Net.Commands/CommandServiceConfig.cs
+++ b/src/Discord.Net.Commands/CommandServiceConfig.cs
@@ -15,5 +15,8 @@
/// Determines whether RunMode.Sync commands should push exceptions up to the caller.
public bool ThrowOnError { get; set; } = true;
+
+ /// List of aliases for string parsing
+ public char[] QuotationMarkAliases { get; set; } = new char[] { '“', '”', '\'', '«', '»', '‹', '›' };
}
}
diff --git a/src/Discord.Net.Commands/Info/CommandInfo.cs b/src/Discord.Net.Commands/Info/CommandInfo.cs
index 6bb621f94..e563f904d 100644
--- a/src/Discord.Net.Commands/Info/CommandInfo.cs
+++ b/src/Discord.Net.Commands/Info/CommandInfo.cs
@@ -19,6 +19,7 @@ namespace Discord.Commands
private static readonly ConcurrentDictionary, object>> _arrayConverters = new ConcurrentDictionary, object>>();
private readonly Func _action;
+ internal readonly char[] _quotationAliases;
public ModuleInfo Module { get; }
public string Name { get; }
@@ -64,6 +65,7 @@ namespace Discord.Commands
HasVarArgs = builder.Parameters.Count > 0 ? builder.Parameters[builder.Parameters.Count - 1].IsMultiple : false;
_action = builder.Callback;
+ _quotationAliases = service._quotationMarkAliases;
}
public async Task CheckPreconditionsAsync(ICommandContext context, IServiceProvider services = null)
@@ -107,7 +109,7 @@ namespace Discord.Commands
return PreconditionResult.FromSuccess();
}
- public async Task ParseAsync(ICommandContext context, int startIndex, SearchResult searchResult, PreconditionResult preconditionResult = null, IServiceProvider services = null)
+ public async Task ParseAsync(ICommandContext context, int startIndex, SearchResult searchResult, PreconditionResult preconditionResult = null, IServiceProvider services = null, char[] quotationAliases = null)
{
services = services ?? EmptyServiceProvider.Instance;