Fixed with regex improvements. Also enabled ELUP detection for autocompletion

This commit is contained in:
Olivier Guinart 2017-01-14 18:56:21 -08:00
parent a7a3708a53
commit 22df541220
4 changed files with 71 additions and 37 deletions

View File

@ -8,29 +8,34 @@ namespace VSMerlin32.Coloring
{ {
internal class Merlin32CodeHelper internal class Merlin32CodeHelper
{ {
const string COMMENT_REG = @"((\u003B)|(\u002A))(.*)"; // ; const string CommentRegex = @"((\u003B)|(\u002A))(.*)"; // ;
const string TEXT_REG = @"(""|')[^']*(""|')"; const string TextRegex = @"(""|')[^']*(""|')";
// OPCODE_REG is initialized dynamically below. // OPCODE_REG and below are initialized dynamically below.
static string OPCODE_REG = ""; const string RegexBoilerplate = @"(\b|\s)(?<{0}>{1})(\b|\s)";
static string DIRECTIVE_REG = ""; const string Opcode = "OPCODE";
static string DATADEFINE_REG = ""; const string Data = "DATA";
const string Directive = "DIRECTIVE";
const string Elup = "ELUP";
static string OpcodeRegex = "";
static string DirectiveRegex = "";
static string DataRegex = "";
public static IEnumerable<SnapshotHelper> GetTokens(SnapshotSpan span) public static IEnumerable<SnapshotHelper> GetTokens(SnapshotSpan span)
{ {
string strTempRegex; // temp var string string TempRegex; // temp var string
ITextSnapshotLine containingLine = span.Start.GetContainingLine(); ITextSnapshotLine containingLine = span.Start.GetContainingLine();
int curLoc = containingLine.Start.Position; int curLoc = containingLine.Start.Position;
string formattedLine = containingLine.GetText(); string formattedLine = containingLine.GetText();
int commentMatch = int.MaxValue; int commentMatch = int.MaxValue;
Regex reg = new Regex(COMMENT_REG); Regex reg = new Regex(CommentRegex);
foreach (Match match in reg.Matches(formattedLine)) foreach (Match match in reg.Matches(formattedLine))
{ {
commentMatch = match.Index < commentMatch ? match.Index : commentMatch; commentMatch = match.Index < commentMatch ? match.Index : commentMatch;
yield return new SnapshotHelper(new SnapshotSpan(new SnapshotPoint(span.Snapshot, match.Index + curLoc), match.Length), Merlin32TokenTypes.Merlin32Comment); yield return new SnapshotHelper(new SnapshotSpan(new SnapshotPoint(span.Snapshot, match.Index + curLoc), match.Length), Merlin32TokenTypes.Merlin32Comment);
} }
reg = new Regex(TEXT_REG); reg = new Regex(TextRegex);
foreach (Match match in reg.Matches(formattedLine)) foreach (Match match in reg.Matches(formattedLine))
{ {
if (match.Index < commentMatch) if (match.Index < commentMatch)
@ -39,55 +44,83 @@ namespace VSMerlin32.Coloring
// OG NEW // OG NEW
// OPCODES // OPCODES
strTempRegex = ""; TempRegex = "";
foreach (Merlin32Opcodes token in Enum.GetValues(typeof(Merlin32Opcodes))) foreach (Merlin32Opcodes token in Enum.GetValues(typeof(Merlin32Opcodes)))
{ {
strTempRegex += (token.ToString() + ("|")); TempRegex += (token.ToString() + ("|"));
} }
// we remove the last "|" added // we remove the last "|" added
strTempRegex = strTempRegex.Remove(strTempRegex.LastIndexOf("|")); TempRegex = TempRegex.Remove(TempRegex.LastIndexOf("|"));
OPCODE_REG = string.Format(@"\b({0})\b", strTempRegex); OpcodeRegex = string.Format(RegexBoilerplate, Opcode, TempRegex);
reg = new Regex(OPCODE_REG,RegexOptions.IgnoreCase); reg = new Regex(OpcodeRegex,RegexOptions.IgnoreCase);
foreach (Match match in reg.Matches(formattedLine)) Match opcodeMatch = reg.Match(formattedLine);
if (opcodeMatch.Success)
{ {
if (match.Index < commentMatch) foreach (Capture opcode in opcodeMatch.Groups[Opcode].Captures)
yield return new SnapshotHelper(new SnapshotSpan(new SnapshotPoint(span.Snapshot, match.Index + curLoc), match.Length), Merlin32TokenTypes.Merlin32Opcode); {
// An opcode after within a comment doesn't get a SnapShotSpan...
if (opcode.Index < commentMatch)
yield return new SnapshotHelper(new SnapshotSpan(new SnapshotPoint(span.Snapshot, opcode.Index + curLoc), opcode.Length), Merlin32TokenTypes.Merlin32Opcode);
}
} }
// OG NEW // OG NEW
// DIRECTIVES // DIRECTIVES
strTempRegex = ""; TempRegex = "";
string ElupDirective = Resources.directives.ELUP;
foreach (Merlin32Directives token in Enum.GetValues(typeof(Merlin32Directives))) foreach (Merlin32Directives token in Enum.GetValues(typeof(Merlin32Directives)))
{ {
if (token.ToString() != Resources.directives.ELUP) if (token.ToString() != ElupDirective)
strTempRegex += (token.ToString() + ("|")); TempRegex += (token.ToString() + ("|"));
} }
DIRECTIVE_REG = string.Format(@"\b({0})\b|{1}", strTempRegex, Resources.directives.ELUPRegex); // we remove the last "|" added
TempRegex = TempRegex.Remove(TempRegex.LastIndexOf("|"));
reg = new Regex(DIRECTIVE_REG, RegexOptions.IgnoreCase); DirectiveRegex = string.Format(RegexBoilerplate, Directive, TempRegex);
foreach (Match match in reg.Matches(formattedLine))
reg = new Regex(DirectiveRegex, RegexOptions.IgnoreCase);
Match DirectiveMatch = reg.Match(formattedLine);
if (DirectiveMatch.Success)
{ {
if (match.Index < commentMatch) foreach (Capture directive in DirectiveMatch.Groups[Directive].Captures)
yield return new SnapshotHelper(new SnapshotSpan(new SnapshotPoint(span.Snapshot, match.Index + curLoc), match.Length), Merlin32TokenTypes.Merlin32Directive); {
if (directive.Index < commentMatch)
yield return new SnapshotHelper(new SnapshotSpan(new SnapshotPoint(span.Snapshot, directive.Index + curLoc), directive.Length), Merlin32TokenTypes.Merlin32Directive);
}
}
// We also need to check for special ELUP directive...
reg = new Regex(Resources.directives.ELUPRegex);
Match ElupMatch = reg.Match(formattedLine);
if (ElupMatch.Success)
{
foreach (Capture elup in ElupMatch.Groups[Elup].Captures)
{
if (elup.Index < commentMatch)
yield return new SnapshotHelper(new SnapshotSpan(new SnapshotPoint(span.Snapshot, elup.Index + curLoc), elup.Length), Merlin32TokenTypes.Merlin32Directive);
}
} }
// OG NEW // OG NEW
// DATADEFINES // DATADEFINES
strTempRegex = ""; TempRegex = "";
foreach (Merlin32DataDefines token in Enum.GetValues(typeof(Merlin32DataDefines))) foreach (Merlin32DataDefines token in Enum.GetValues(typeof(Merlin32DataDefines)))
{ {
strTempRegex += (token.ToString() + ("|")); TempRegex += (token.ToString() + ("|"));
} }
// we remove the last "|" added // we remove the last "|" added
strTempRegex = strTempRegex.Remove(strTempRegex.LastIndexOf("|")); TempRegex = TempRegex.Remove(TempRegex.LastIndexOf("|"));
DATADEFINE_REG = string.Format(@"\b({0})\b", strTempRegex); DataRegex = string.Format(RegexBoilerplate, Data, TempRegex);
reg = new Regex(DATADEFINE_REG, RegexOptions.IgnoreCase); reg = new Regex(DataRegex, RegexOptions.IgnoreCase);
foreach (Match match in reg.Matches(formattedLine)) Match dataMatch = reg.Match(formattedLine);
if (dataMatch.Success)
{ {
if (match.Index < commentMatch) foreach (Capture data in dataMatch.Groups[Data].Captures)
yield return new SnapshotHelper(new SnapshotSpan(new SnapshotPoint(span.Snapshot, match.Index + curLoc), match.Length), Merlin32TokenTypes.Merlin32DataDefine); {
if (data.Index < commentMatch)
yield return new SnapshotHelper(new SnapshotSpan(new SnapshotPoint(span.Snapshot, data.Index + curLoc), data.Length), Merlin32TokenTypes.Merlin32DataDefine);
}
} }
} }
} }

View File

@ -107,7 +107,8 @@ namespace VSMerlin32
//pass along the command so the char is added to the buffer //pass along the command so the char is added to the buffer
int retVal = m_nextCommandHandler.Exec(ref pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut); int retVal = m_nextCommandHandler.Exec(ref pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut);
bool handled = false; bool handled = false;
if (!typedChar.Equals(char.MinValue) && ((char.IsLetterOrDigit(typedChar)) || ((typedChar == '\'') || (typedChar == '"')))) // Test for '-' is to catch ELUP (--^)
if (!typedChar.Equals(char.MinValue) && ((char.IsLetterOrDigit(typedChar)) || ((typedChar == '\'') || (typedChar == '"') || (typedChar == '-'))))
{ {
if (m_session == null || m_session.IsDismissed) // If there is no active session, bring up completion if (m_session == null || m_session.IsDismissed) // If there is no active session, bring up completion
{ {

View File

@ -151,7 +151,7 @@ namespace VSMerlin32.Resources {
} }
/// <summary> /// <summary>
/// Looks up a localized string similar to (--\^). /// Looks up a localized string similar to (^|\s)(?&lt;ELUP&gt;--\^)(\s|$).
/// </summary> /// </summary>
internal static string ELUPRegex { internal static string ELUPRegex {
get { get {

View File

@ -148,7 +148,7 @@
<value>End of LUP</value> <value>End of LUP</value>
</data> </data>
<data name="ELUPRegex" xml:space="preserve"> <data name="ELUPRegex" xml:space="preserve">
<value>(--\^)</value> <value>(^|\s)(?&lt;ELUP&gt;--\^)(\s|$)</value>
</data> </data>
<data name="ELUPValue" xml:space="preserve"> <data name="ELUPValue" xml:space="preserve">
<value>--^</value> <value>--^</value>