private void ExtractSelectionAndIncludes(EnvDTE.Document document, TrialAndErrorRemovalOptionsPage settings, out ITextBuffer textBuffer, out Formatter.IncludeLineInfo[] includeLinesArray) { // Parsing. document.Activate(); var documentTextView = VSUtils.GetCurrentTextViewHost(); textBuffer = documentTextView.TextView.TextBuffer; string documentText = documentTextView.TextView.TextSnapshot.GetText(); IEnumerable <Formatter.IncludeLineInfo> includeLines = Formatter.IncludeLineInfo.ParseIncludes(documentText, Formatter.ParseOptions.IgnoreIncludesInPreprocessorConditionals | Formatter.ParseOptions.KeepOnlyValidIncludes); // Optionally skip top most include. if (settings.IgnoreFirstInclude) { includeLines = includeLines.Skip(1); } // Skip everything with preserve flag. includeLines = includeLines.Where(x => !x.ShouldBePreserved); // Apply filter ignore regex. { string documentName = Path.GetFileNameWithoutExtension(document.FullName); string[] ignoreRegexList = RegexUtils.FixupRegexes(settings.IgnoreList, documentName); includeLines = includeLines.Where(line => !ignoreRegexList.Any(regexPattern => new System.Text.RegularExpressions.Regex(regexPattern).Match(line.IncludeContent).Success)); } // Reverse order if necessary. if (settings.RemovalOrder == TrialAndErrorRemovalOptionsPage.IncludeRemovalOrder.BottomToTop) { includeLines = includeLines.Reverse(); } includeLinesArray = includeLines.ToArray(); }
private void ApplyTasks(Dictionary <string, FormatTask> tasks) { var dte = VSUtils.GetDTE(); foreach (KeyValuePair <string, FormatTask> entry in tasks) { string filename = entry.Key.Replace('/', '\\'); // Classy. But Necessary. EnvDTE.Window fileWindow = dte.ItemOperations.OpenFile(filename); if (fileWindow == null) { Output.Instance.ErrorMsg("Failed to open File {0}", filename); continue; } fileWindow.Activate(); var viewHost = VSUtils.GetCurrentTextViewHost(); using (var edit = viewHost.TextView.TextBuffer.CreateEdit()) { var originalLines = edit.Snapshot.Lines.ToArray(); // Add lines. { // Find last include. // Will find even if commented out, but we don't care. int lastIncludeLine = -1; for (int line = originalLines.Length - 1; line >= 0; --line) { if (originalLines[line].GetText().Contains("#include")) { lastIncludeLine = line; break; } } // Insert lines. int insertPosition = 0; if (lastIncludeLine >= 0 && lastIncludeLine < originalLines.Length) { insertPosition = originalLines[lastIncludeLine].EndIncludingLineBreak; } StringBuilder stringToInsert = new StringBuilder(); foreach (string lineToAdd in entry.Value.linesToAdd) { stringToInsert.Clear(); stringToInsert.Append(lineToAdd); stringToInsert.Append("\n"); // todo: Consistent new lines? edit.Insert(insertPosition, stringToInsert.ToString()); } } // Remove lines. // It should safe to do that last since we added includes at the bottom, this way there is no confusion with the text snapshot. { foreach (int lineToRemove in entry.Value.linesToRemove.Reverse()) { edit.Delete(originalLines[lineToRemove].ExtentIncludingLineBreak); } } edit.Apply(); } // For Debugging: //Output.Instance.WriteLine(""); //Output.Instance.WriteLine(entry.Key); //Output.Instance.WriteLine(entry.Value.ToString()); } }