void HandleTextOptionsChanged (object sender, EventArgs e) { var policy = Policy.CreateOptions (); var options = Editor.CreateNRefactoryTextEditorOptions (); options.IndentBlankLines = true; IStateMachineIndentEngine indentEngine; try { var csharpIndentEngine = new CSharpIndentEngine (textEditorData.Document, options, policy); //csharpIndentEngine.EnableCustomIndentLevels = true; foreach (var symbol in MonoDevelop.CSharp.Highlighting.CSharpSyntaxMode.GetDefinedSymbols (document.Project)) { csharpIndentEngine.DefineSymbol (symbol); } indentEngine = csharpIndentEngine; } catch (Exception ex) { LoggingService.LogError ("Error while creating the c# indentation engine", ex); indentEngine = new NullIStateMachineIndentEngine (textEditorData.Document); } stateTracker = new CacheIndentEngine (indentEngine); textEditorData.IndentationTracker = new IndentVirtualSpaceManager (textEditorData, stateTracker); if (textEditorData.Options.IndentStyle == IndentStyle.Auto || textEditorData.Options.IndentStyle == IndentStyle.None) { textEditorData.TextPasteHandler = null; } else { textEditorData.TextPasteHandler = new TextPasteIndentEngine (stateTracker, options, policy); } }
// Clone the CSharpIndentEngine - useful if a consumer of this class wants // to test things w/o changing the real indent engine state public object Clone() { CSharpIndentEngine engine = new CSharpIndentEngine(policy, textPolicy); engine.stack = (IndentStack)stack.Clone(); engine.linebuf = new StringBuilder(linebuf.ToString(), linebuf.Capacity); engine.keyword = keyword; engine.curIndent = curIndent; engine.needsReindent = needsReindent; engine.popVerbatim = popVerbatim; engine.canBeLabel = canBeLabel; engine.isEscaped = isEscaped; engine.firstNonLwsp = firstNonLwsp; engine.lastNonLwsp = lastNonLwsp; engine.wordStart = wordStart; engine.prc = prc; engine.pc = pc; engine.rc = rc; engine.curLineNr = curLineNr; engine.cursor = cursor; return(engine); }
public IndentStack (CSharpIndentEngine engine, int capacity) { this.engine = engine; if (capacity < INITIAL_CAPACITY) capacity = INITIAL_CAPACITY; this.stack = new Node [capacity]; this.size = 0; }
public IndentStack(CSharpIndentEngine engine, int capacity) { this.engine = engine; if (capacity < INITIAL_CAPACITY) { capacity = INITIAL_CAPACITY; } this.stack = new Node [capacity]; this.size = 0; }
protected override async void CorrectIndentingImplementation(PolicyContainer policyParent, TextEditor editor, int line) { var lineSegment = editor.GetLine(line); if (lineSegment == null) { return; } try { Microsoft.CodeAnalysis.Options.OptionSet options = null; foreach (var doc in IdeApp.Workbench.Documents) { if (doc.Editor == editor) { options = await doc.AnalysisDocument?.GetOptionsAsync(); break; } } if (options == null) { var policy = policyParent.Get <CSharpFormattingPolicy> (MimeType); var textpolicy = policyParent.Get <TextStylePolicy> (MimeType); options = policy.CreateOptions(textpolicy); } var tracker = new CSharpIndentEngine(options); tracker.Update(IdeApp.Workbench.ActiveDocument.Editor, lineSegment.Offset); for (int i = lineSegment.Offset; i < lineSegment.Offset + lineSegment.Length; i++) { tracker.Push(editor.GetCharAt(i)); } string curIndent = lineSegment.GetIndentation(editor); int nlwsp = curIndent.Length; if (!tracker.LineBeganInsideMultiLineComment || (nlwsp < lineSegment.LengthIncludingDelimiter && editor.GetCharAt(lineSegment.Offset + nlwsp) == '*')) { // Possibly replace the indent string newIndent = tracker.ThisLineIndent; if (newIndent != curIndent) { editor.ReplaceText(lineSegment.Offset, nlwsp, newIndent); } } } catch (Exception e) { LoggingService.LogError("Error while indenting", e); } }
void DoReSmartIndent(int cursor) { if (stateTracker.Engine.LineBeganInsideVerbatimString || stateTracker.Engine.LineBeganInsideMultiLineComment) { return; } string newIndent = string.Empty; DocumentLine line = textEditorData.Document.GetLineByOffset(cursor); // stateTracker.UpdateEngine (line.Offset); // Get context to the end of the line w/o changing the main engine's state CSharpIndentEngine ctx = (CSharpIndentEngine)stateTracker.Engine.Clone(); for (int max = cursor; max < line.EndOffset; max++) { ctx.Push(textEditorData.Document.GetCharAt(max)); } int pos = line.Offset; string curIndent = line.GetIndentation(textEditorData.Document); int nlwsp = curIndent.Length; int offset = cursor > pos + nlwsp ? cursor - (pos + nlwsp) : 0; if (!stateTracker.Engine.LineBeganInsideMultiLineComment || (nlwsp < line.LengthIncludingDelimiter && textEditorData.Document.GetCharAt(line.Offset + nlwsp) == '*')) { // Possibly replace the indent newIndent = ctx.ThisLineIndent; int newIndentLength = newIndent.Length; if (newIndent != curIndent) { if (CompletionWindowManager.IsVisible) { if (pos < CompletionWindowManager.CodeCompletionContext.TriggerOffset) { CompletionWindowManager.CodeCompletionContext.TriggerOffset -= nlwsp; } } newIndentLength = textEditorData.Replace(pos, nlwsp, newIndent); textEditorData.Document.CommitLineUpdate(textEditorData.Caret.Line); // Engine state is now invalid stateTracker.ResetEngineToPosition(pos); } pos += newIndentLength; } else { pos += curIndent.Length; } pos += offset; textEditorData.FixVirtualIndentation(); }
//does re-indenting and cursor positioning void DoReSmartIndent() { string newIndent = string.Empty; int cursor = textEditorData.Caret.Offset; // Get context to the end of the line w/o changing the main engine's state CSharpIndentEngine ctx = (CSharpIndentEngine)stateTracker.Engine.Clone(); LineSegment line = textEditorData.Document.GetLine(textEditorData.Caret.Line); for (int max = line.Offset; max < line.Offset + line.EditableLength; max++) { ctx.Push(textEditorData.Document.GetCharAt(max)); } int pos = line.Offset; string curIndent = line.GetIndentation(textEditorData.Document); int nlwsp = curIndent.Length; int offset = cursor > pos + nlwsp ? cursor - (pos + nlwsp) : 0; if (!stateTracker.Engine.LineBeganInsideMultiLineComment || (nlwsp < line.Length && textEditorData.Document.GetCharAt(line.Offset + nlwsp) == '*')) { // Possibly replace the indent newIndent = ctx.ThisLineIndent; int newIndentLength = newIndent.Length; if (newIndent != curIndent) { if (CompletionWindowManager.IsVisible) { if (pos < CompletionWindowManager.CodeCompletionContext.TriggerOffset) { CompletionWindowManager.CodeCompletionContext.TriggerOffset -= nlwsp; } } newIndentLength = textEditorData.Replace(pos, nlwsp, newIndent); // Engine state is now invalid stateTracker.ResetEngineToPosition(pos); } pos += newIndentLength; } else { pos += curIndent.Length; } pos += offset; textEditorData.Caret.Offset = pos; }
void HandleTextOptionsChanged(object sender, EventArgs e) { var policy = Policy.CreateOptions(); var options = Editor.CreateNRefactoryTextEditorOptions(); options.IndentBlankLines = true; IStateMachineIndentEngine indentEngine; try { indentEngine = new CSharpIndentEngine(textEditorData.Document, options, policy); } catch (Exception ex) { LoggingService.LogError("Error while creating the c# indentation engine", ex); indentEngine = new NullIStateMachineIndentEngine(textEditorData.Document); } if (stateTracker != null) { stateTracker.Dispose(); } stateTracker = new CacheIndentEngine(indentEngine); textEditorData.IndentationTracker = new IndentVirtualSpaceManager(textEditorData, stateTracker); textEditorData.TextPasteHandler = new TextPasteIndentEngine(stateTracker, options, policy); }
public override void CorrectIndenting(PolicyContainer policyParent, IEnumerable <string> mimeTypeChain, TextEditorData data, int line) { DocumentLine lineSegment = data.Document.GetLine(line); if (lineSegment == null) { return; } try { var policy = policyParent.Get <CSharpFormattingPolicy> (mimeTypeChain); var tracker = new CSharpIndentEngine(data.Document, data.CreateNRefactoryTextEditorOptions(), policy.CreateOptions()); tracker.Update(lineSegment.Offset); for (int i = lineSegment.Offset; i < lineSegment.Offset + lineSegment.Length; i++) { tracker.Push(data.Document.GetCharAt(i)); } string curIndent = lineSegment.GetIndentation(data.Document); int nlwsp = curIndent.Length; if (!tracker.LineBeganInsideMultiLineComment || (nlwsp < lineSegment.LengthIncludingDelimiter && data.Document.GetCharAt(lineSegment.Offset + nlwsp) == '*')) { // Possibly replace the indent string newIndent = tracker.ThisLineIndent; if (newIndent != curIndent) { data.Replace(lineSegment.Offset, nlwsp, newIndent); } } } catch (Exception e) { LoggingService.LogError("Error while indenting", e); } }
public IndentStack (CSharpIndentEngine engine) : this (engine, INITIAL_CAPACITY) { }
// Clone the CSharpIndentEngine - useful if a consumer of this class wants // to test things w/o changing the real indent engine state public object Clone () { CSharpIndentEngine engine = new CSharpIndentEngine (policy, textPolicy); engine.stack = (IndentStack) stack.Clone (); engine.linebuf = new StringBuilder (linebuf.ToString (), linebuf.Capacity); engine.keyword = keyword; engine.curIndent = curIndent; engine.needsReindent = needsReindent; engine.popVerbatim = popVerbatim; engine.canBeLabel = canBeLabel; engine.isEscaped = isEscaped; engine.firstNonLwsp = firstNonLwsp; engine.lastNonLwsp = lastNonLwsp; engine.wordStart = wordStart; engine.prc = prc; engine.pc = pc; engine.rc = rc; engine.curLineNr = curLineNr; engine.cursor = cursor; return engine; }
public IndentStack(CSharpIndentEngine engine) : this(engine, INITIAL_CAPACITY) { }
internal static int GetCurrentParameterIndex (MonoDevelop.Ide.Gui.TextEditor editor, int offset, int memberStart) { int cursor = editor.CursorPosition; int i = offset; if (i > cursor) return -1; if (i == cursor) return 1; // parameters are 1 based IEnumerable<string> types = MonoDevelop.Ide.DesktopService.GetMimeTypeInheritanceChain (CSharpFormatter.MimeType); CSharpIndentEngine engine = new CSharpIndentEngine (MonoDevelop.Projects.Policies.PolicyService.GetDefaultPolicy<CSharpFormattingPolicy> (types)); int index = memberStart + 1; int parentheses = 0; int bracket = 0; do { char c = editor.GetCharAt (i - 1); engine.Push (c); switch (c) { case '{': if (!engine.IsInsideOrdinaryCommentOrString) bracket++; break; case '}': if (!engine.IsInsideOrdinaryCommentOrString) bracket--; break; case '(': if (!engine.IsInsideOrdinaryCommentOrString) parentheses++; break; case ')': if (!engine.IsInsideOrdinaryCommentOrString) parentheses--; break; case ',': if (!engine.IsInsideOrdinaryCommentOrString && parentheses == 1 && bracket == 0) index++; break; } i++; } while (i <= cursor && parentheses >= 0); return parentheses != 1 || bracket > 0 ? -1 : index; }