From 22df54122058ceb63e8a855db5727d22e5520ea8 Mon Sep 17 00:00:00 2001 From: Olivier Guinart Date: Sat, 14 Jan 2017 18:56:21 -0800 Subject: [PATCH] Fixed with regex improvements. Also enabled ELUP detection for autocompletion --- Coloring/Merlin32CodeHelper.cs | 101 ++++++++++++++++++--------- Intellisense/CompletionController.cs | 3 +- Resources/directives.Designer.cs | 2 +- Resources/directives.resx | 2 +- 4 files changed, 71 insertions(+), 37 deletions(-) diff --git a/Coloring/Merlin32CodeHelper.cs b/Coloring/Merlin32CodeHelper.cs index 09f3279..dfc83d9 100644 --- a/Coloring/Merlin32CodeHelper.cs +++ b/Coloring/Merlin32CodeHelper.cs @@ -8,29 +8,34 @@ namespace VSMerlin32.Coloring { internal class Merlin32CodeHelper { - const string COMMENT_REG = @"((\u003B)|(\u002A))(.*)"; // ; - const string TEXT_REG = @"(""|')[^']*(""|')"; - // OPCODE_REG is initialized dynamically below. - static string OPCODE_REG = ""; - static string DIRECTIVE_REG = ""; - static string DATADEFINE_REG = ""; + const string CommentRegex = @"((\u003B)|(\u002A))(.*)"; // ; + const string TextRegex = @"(""|')[^']*(""|')"; + // OPCODE_REG and below are initialized dynamically below. + const string RegexBoilerplate = @"(\b|\s)(?<{0}>{1})(\b|\s)"; + const string Opcode = "OPCODE"; + const string Data = "DATA"; + const string Directive = "DIRECTIVE"; + const string Elup = "ELUP"; + static string OpcodeRegex = ""; + static string DirectiveRegex = ""; + static string DataRegex = ""; public static IEnumerable GetTokens(SnapshotSpan span) { - string strTempRegex; // temp var string + string TempRegex; // temp var string ITextSnapshotLine containingLine = span.Start.GetContainingLine(); int curLoc = containingLine.Start.Position; string formattedLine = containingLine.GetText(); int commentMatch = int.MaxValue; - Regex reg = new Regex(COMMENT_REG); + Regex reg = new Regex(CommentRegex); foreach (Match match in reg.Matches(formattedLine)) { commentMatch = match.Index < commentMatch ? match.Index : commentMatch; 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)) { if (match.Index < commentMatch) @@ -39,55 +44,83 @@ namespace VSMerlin32.Coloring // OG NEW // OPCODES - strTempRegex = ""; + TempRegex = ""; foreach (Merlin32Opcodes token in Enum.GetValues(typeof(Merlin32Opcodes))) { - strTempRegex += (token.ToString() + ("|")); + TempRegex += (token.ToString() + ("|")); } // we remove the last "|" added - strTempRegex = strTempRegex.Remove(strTempRegex.LastIndexOf("|")); - OPCODE_REG = string.Format(@"\b({0})\b", strTempRegex); + TempRegex = TempRegex.Remove(TempRegex.LastIndexOf("|")); + OpcodeRegex = string.Format(RegexBoilerplate, Opcode, TempRegex); - reg = new Regex(OPCODE_REG,RegexOptions.IgnoreCase); - foreach (Match match in reg.Matches(formattedLine)) + reg = new Regex(OpcodeRegex,RegexOptions.IgnoreCase); + Match opcodeMatch = reg.Match(formattedLine); + if (opcodeMatch.Success) { - if (match.Index < commentMatch) - yield return new SnapshotHelper(new SnapshotSpan(new SnapshotPoint(span.Snapshot, match.Index + curLoc), match.Length), Merlin32TokenTypes.Merlin32Opcode); + foreach (Capture opcode in opcodeMatch.Groups[Opcode].Captures) + { + // 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 // DIRECTIVES - strTempRegex = ""; + TempRegex = ""; + string ElupDirective = Resources.directives.ELUP; foreach (Merlin32Directives token in Enum.GetValues(typeof(Merlin32Directives))) { - if (token.ToString() != Resources.directives.ELUP) - strTempRegex += (token.ToString() + ("|")); + if (token.ToString() != ElupDirective) + TempRegex += (token.ToString() + ("|")); } - DIRECTIVE_REG = string.Format(@"\b({0})\b|{1}", strTempRegex, Resources.directives.ELUPRegex); - - reg = new Regex(DIRECTIVE_REG, RegexOptions.IgnoreCase); - foreach (Match match in reg.Matches(formattedLine)) + // we remove the last "|" added + TempRegex = TempRegex.Remove(TempRegex.LastIndexOf("|")); + DirectiveRegex = string.Format(RegexBoilerplate, Directive, TempRegex); + + reg = new Regex(DirectiveRegex, RegexOptions.IgnoreCase); + Match DirectiveMatch = reg.Match(formattedLine); + if (DirectiveMatch.Success) { - if (match.Index < commentMatch) - yield return new SnapshotHelper(new SnapshotSpan(new SnapshotPoint(span.Snapshot, match.Index + curLoc), match.Length), Merlin32TokenTypes.Merlin32Directive); + foreach (Capture directive in DirectiveMatch.Groups[Directive].Captures) + { + 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 // DATADEFINES - strTempRegex = ""; + TempRegex = ""; foreach (Merlin32DataDefines token in Enum.GetValues(typeof(Merlin32DataDefines))) { - strTempRegex += (token.ToString() + ("|")); + TempRegex += (token.ToString() + ("|")); } // we remove the last "|" added - strTempRegex = strTempRegex.Remove(strTempRegex.LastIndexOf("|")); - DATADEFINE_REG = string.Format(@"\b({0})\b", strTempRegex); + TempRegex = TempRegex.Remove(TempRegex.LastIndexOf("|")); + DataRegex = string.Format(RegexBoilerplate, Data, TempRegex); - reg = new Regex(DATADEFINE_REG, RegexOptions.IgnoreCase); - foreach (Match match in reg.Matches(formattedLine)) + reg = new Regex(DataRegex, RegexOptions.IgnoreCase); + Match dataMatch = reg.Match(formattedLine); + if (dataMatch.Success) { - if (match.Index < commentMatch) - yield return new SnapshotHelper(new SnapshotSpan(new SnapshotPoint(span.Snapshot, match.Index + curLoc), match.Length), Merlin32TokenTypes.Merlin32DataDefine); + foreach (Capture data in dataMatch.Groups[Data].Captures) + { + if (data.Index < commentMatch) + yield return new SnapshotHelper(new SnapshotSpan(new SnapshotPoint(span.Snapshot, data.Index + curLoc), data.Length), Merlin32TokenTypes.Merlin32DataDefine); + } } } } diff --git a/Intellisense/CompletionController.cs b/Intellisense/CompletionController.cs index 0a04460..b188f1c 100644 --- a/Intellisense/CompletionController.cs +++ b/Intellisense/CompletionController.cs @@ -107,7 +107,8 @@ namespace VSMerlin32 //pass along the command so the char is added to the buffer int retVal = m_nextCommandHandler.Exec(ref pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut); 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 { diff --git a/Resources/directives.Designer.cs b/Resources/directives.Designer.cs index eff2724..6134741 100644 --- a/Resources/directives.Designer.cs +++ b/Resources/directives.Designer.cs @@ -151,7 +151,7 @@ namespace VSMerlin32.Resources { } /// - /// Looks up a localized string similar to (--\^). + /// Looks up a localized string similar to (^|\s)(?<ELUP>--\^)(\s|$). /// internal static string ELUPRegex { get { diff --git a/Resources/directives.resx b/Resources/directives.resx index 07d9f1f..aa598b8 100644 --- a/Resources/directives.resx +++ b/Resources/directives.resx @@ -148,7 +148,7 @@ End of LUP - (--\^) + (^|\s)(?<ELUP>--\^)(\s|$) --^