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);
			}
		}
Example #2
0
        // 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;
            }
Example #5
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);
            }
        }
Example #6
0
        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();
        }
Example #7
0
        //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);
        }
Example #9
0
        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;
		}