public override void OnTheFlyFormat(PolicyContainer policyParent, IEnumerable <string> mimeTypeChain, TextEditorData data, int startOffset, int endOffset) { var parser = new MonoDevelop.CSharp.Parser.CSharpParser(); var compilationUnit = parser.Parse(data); bool hadErrors = parser.ErrorReportPrinter.ErrorsCount + parser.ErrorReportPrinter.FatalCounter > 0; var policy = policyParent.Get <CSharpFormattingPolicy> (mimeTypeChain); var domSpacingVisitor = new AstSpacingVisitor(policy, data) { AutoAcceptChanges = false, }; compilationUnit.AcceptVisitor(domSpacingVisitor, null); var domIndentationVisitor = new AstIndentationVisitor(policy, data) { AutoAcceptChanges = false, HadErrors = hadErrors }; compilationUnit.AcceptVisitor(domIndentationVisitor, null); var changes = new List <Change> (); changes.AddRange(domSpacingVisitor.Changes. Concat(domIndentationVisitor.Changes). Where(c => c is TextReplaceChange && (startOffset <= ((TextReplaceChange)c).Offset && ((TextReplaceChange)c).Offset < endOffset))); RefactoringService.AcceptChanges(null, null, changes); }
public override string FormatText(PolicyContainer policyParent, IEnumerable <string> mimeTypeChain, string input, int startOffset, int endOffset) { var data = new TextEditorData(); data.Document.SuppressHighlightUpdate = true; data.Document.MimeType = mimeTypeChain.First(); data.Document.FileName = "toformat.cs"; var textPolicy = policyParent.Get <TextStylePolicy> (mimeTypeChain); data.Options.TabsToSpaces = textPolicy.TabsToSpaces; data.Options.TabSize = textPolicy.TabWidth; data.Options.OverrideDocumentEolMarker = true; data.Options.DefaultEolMarker = textPolicy.GetEolMarker(); data.Text = input; //System.Console.WriteLine ("-----"); //System.Console.WriteLine (data.Text.Replace (" ", ".").Replace ("\t", "->")); //System.Console.WriteLine ("-----"); MonoDevelop.CSharp.Parser.CSharpParser parser = new MonoDevelop.CSharp.Parser.CSharpParser(); var compilationUnit = parser.Parse(data); bool hadErrors = parser.ErrorReportPrinter.ErrorsCount + parser.ErrorReportPrinter.FatalCounter > 0; var policy = policyParent.Get <CSharpFormattingPolicy> (mimeTypeChain); var domSpacingVisitor = new AstSpacingVisitor(policy, data) { AutoAcceptChanges = false }; compilationUnit.AcceptVisitor(domSpacingVisitor, null); var domIndentationVisitor = new AstIndentationVisitor(policy, data) { AutoAcceptChanges = false, HadErrors = hadErrors }; compilationUnit.AcceptVisitor(domIndentationVisitor, null); var changes = new List <Change> (); changes.AddRange(domSpacingVisitor.Changes. Concat(domIndentationVisitor.Changes). Where(c => c is TextReplaceChange && (startOffset <= ((TextReplaceChange)c).Offset && ((TextReplaceChange)c).Offset < endOffset))); RefactoringService.AcceptChanges(null, null, changes); int end = endOffset; foreach (TextReplaceChange c in changes) { end -= c.RemovedChars; if (c.InsertedText != null) { end += c.InsertedText.Length; } } /* System.Console.WriteLine ("-----"); * System.Console.WriteLine (data.Text.Replace (" ", "^").Replace ("\t", "->")); * System.Console.WriteLine ("-----");*/ string result = data.GetTextBetween(startOffset, Math.Min(data.Length, end)); data.Dispose(); return(result); }
public static void Format(PolicyContainer policyParent, IEnumerable <string> mimeTypeChain, MonoDevelop.Ide.Gui.Document data, ProjectDom dom, DomLocation location, bool correctBlankLines, bool runAferCR /* = false*/) { if (data.ParsedDocument == null || data.ParsedDocument.CompilationUnit == null) { return; } var member = data.ParsedDocument.CompilationUnit.GetMemberAt(location.Line + (runAferCR ? -1 : 0), location.Column); if (member == null || member.Location.IsEmpty || member.BodyRegion.End.IsEmpty) { return; } StringBuilder sb = new StringBuilder(); int closingBrackets = 0; DomRegion validRegion = DomRegion.Empty; foreach (var u in data.ParsedDocument.CompilationUnit.Usings.Where(us => us.IsFromNamespace)) { // the dom parser breaks A.B.C into 3 namespaces with the same region, this is filtered here if (u.ValidRegion == validRegion) { continue; } validRegion = u.ValidRegion; sb.Append("namespace Stub {"); closingBrackets++; } var parent = member.DeclaringType; while (parent != null) { sb.Append("class Stub {"); closingBrackets++; parent = parent.DeclaringType; } sb.AppendLine(); int startOffset = sb.Length; int memberStart = data.Editor.LocationToOffset(member.Location.Line, 1); int memberEnd = data.Editor.LocationToOffset(member.BodyRegion.End.Line + (runAferCR ? 1 : 0), member.BodyRegion.End.Column); if (memberEnd < 0) { memberEnd = data.Editor.Length; } sb.Append(data.Editor.GetTextBetween(memberStart, memberEnd)); int endOffset = sb.Length; sb.AppendLine(); sb.Append(new string ('}', closingBrackets)); TextEditorData stubData = new TextEditorData() { Text = sb.ToString() }; stubData.Document.FileName = data.FileName; var parser = new MonoDevelop.CSharp.Parser.CSharpParser(); bool hadErrors = parser.ErrorReportPrinter.ErrorsCount + parser.ErrorReportPrinter.FatalCounter > 0; var compilationUnit = parser.Parse(stubData); var policy = policyParent.Get <CSharpFormattingPolicy> (mimeTypeChain); var domSpacingVisitor = new AstSpacingVisitor(policy, stubData) { AutoAcceptChanges = false, }; compilationUnit.AcceptVisitor(domSpacingVisitor, null); var domIndentationVisitor = new AstIndentationVisitor(policy, stubData) { AutoAcceptChanges = false, HadErrors = hadErrors }; domIndentationVisitor.CorrectBlankLines = correctBlankLines; compilationUnit.AcceptVisitor(domIndentationVisitor, null); var changes = new List <Change> (); changes.AddRange(domSpacingVisitor.Changes.Cast <TextReplaceChange> ().Where(c => startOffset < c.Offset && c.Offset < endOffset)); changes.AddRange(domIndentationVisitor.Changes.Cast <TextReplaceChange> ().Where(c => startOffset < c.Offset && c.Offset < endOffset)); int delta = data.Editor.LocationToOffset(member.Location.Line, 1) - startOffset; HashSet <int> lines = new HashSet <int> (); foreach (TextReplaceChange change in changes) { if (change is AstSpacingVisitor.MyTextReplaceChange) { ((AstSpacingVisitor.MyTextReplaceChange)change).SetTextEditorData(data.Editor); } change.Offset += delta; lines.Add(data.Editor.OffsetToLineNumber(change.Offset)); } // be sensible in documents with parser errors - only correct up to the caret position. if (parser.ErrorReportPrinter.Errors.Any(e => e.ErrorType == ErrorType.Error) || data.ParsedDocument.Errors.Any(e => e.ErrorType == ErrorType.Error)) { var lastOffset = data.Editor.Caret.Offset; changes.RemoveAll(c => ((TextReplaceChange)c).Offset > lastOffset); } RefactoringService.AcceptChanges(null, null, changes); foreach (int line in lines) { data.Editor.Document.CommitLineUpdate(line); } stubData.Dispose(); }