protected async override Task CorrectIndentingImplementationAsync(Ide.Editor.TextEditor editor, DocumentContext context, int startLine, int endLine, CancellationToken cancellationToken)
        {
            if (editor.IndentationTracker == null)
            {
                return;
            }
            var startSegment = editor.GetLine(startLine);

            if (startSegment == null)
            {
                return;
            }
            var endSegment = startLine != endLine?editor.GetLine(endLine) : startSegment;

            if (endSegment == null)
            {
                return;
            }

            try {
                var document = context.AnalysisDocument;

                var formattingService = document.GetLanguageService <IEditorFormattingService> ();
                if (formattingService == null || !formattingService.SupportsFormatSelection)
                {
                    return;
                }

                var formattingRules = new List <AbstractFormattingRule> ();
                formattingRules.Add(ContainedDocumentPreserveFormattingRule.Instance);
                formattingRules.AddRange(Formatter.GetDefaultFormattingRules(document));

                var workspace = document.Project.Solution.Workspace;
                var root      = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);

                var options = await document.GetOptionsAsync(cancellationToken).ConfigureAwait(false);

                var changes = Formatter.GetFormattedTextChanges(
                    root, new TextSpan [] { new TextSpan(startSegment.Offset, endSegment.EndOffset - startSegment.Offset) },
                    workspace, options, formattingRules, cancellationToken);

                if (changes == null)
                {
                    return;
                }
                await Runtime.RunInMainThread(delegate {
                    editor.ApplyTextChanges(changes);
                    editor.FixVirtualIndentation();
                });
            } catch (Exception e) {
                LoggingService.LogError("Error while indenting", e);
            }
        }
Beispiel #2
0
        public override string GetIndentationString(int lineNumber)
        {
            if (lineNumber < 1 || lineNumber > editor.LineCount)
            {
                return("");
            }
            var doc = context.AnalysisDocument;

            if (doc == null)
            {
                return(editor.GetLineIndent(lineNumber));
            }
            var snapshot    = editor.TextView.TextBuffer.CurrentSnapshot;
            var caretLine   = snapshot.GetLineFromLineNumber(lineNumber - 1);
            int?indentation = smartIndentationService.GetDesiredIndentation(editor.TextView, caretLine);

            if (indentation.HasValue && indentation.Value > 0)
            {
                return(CalculateIndentationString(indentation.Value));
            }

            var line = editor.GetLine(lineNumber);

            if (line == null)
            {
                return(editor.GetLineIndent(lineNumber));
            }
            try {
                if (line.Contains(editor.CaretOffset))
                {
                    var syntaxRoot = doc.GetSyntaxRootSynchronously(default);
Beispiel #3
0
        string GetIndentationString(DocumentLocation loc)
        {
            var line = data.GetLine(loc.Line);

            if (line == null)
            {
                return("");
            }
            // Get context to the end of the line w/o changing the main engine's state
            var    offset    = line.Offset;
            string curIndent = line.GetIndentation(data);

            try {
                stateTracker.Update(data, Math.Min(data.Length, offset + Math.Min(line.Length, loc.Column - 1)));
                int nlwsp = curIndent.Length;
                if (!stateTracker.LineBeganInsideMultiLineComment || (nlwsp < line.LengthIncludingDelimiter && data.GetCharAt(offset + nlwsp) == '*'))
                {
                    return(stateTracker.ThisLineIndent);
                }
            } catch (Exception e) {
                LoggingService.LogError("Error while indenting at " + loc, e);
            }
            return(curIndent);
        }
Beispiel #4
0
        public bool FixLineStart(Ide.Editor.TextEditor textEditorData, ICSharpCode.NRefactory6.CSharp.IStateMachineIndentEngine stateTracker, int lineNumber)
        {
            if (lineNumber > 1)
            {
                var line = textEditorData.GetLine(lineNumber);
                if (line == null)
                {
                    return(false);
                }

                var prevLine = textEditorData.GetLine(lineNumber - 1);
                if (prevLine == null)
                {
                    return(false);
                }
                string trimmedPreviousLine = textEditorData.GetTextAt(prevLine).TrimStart();

                //xml doc comments
                //check previous line was a doc comment
                //check there's a following line?
                if (trimmedPreviousLine.StartsWith("///", StringComparison.Ordinal))
                {
                    if (textEditorData.GetTextAt(line.Offset, line.Length).TrimStart().StartsWith("///", StringComparison.Ordinal))
                    {
                        return(false);
                    }
                    //check that the newline command actually inserted a newline
                    textEditorData.EnsureCaretIsNotVirtual();
                    var    nextLineSegment = textEditorData.GetLine(lineNumber + 1);
                    string nextLine        = nextLineSegment != null?textEditorData.GetTextAt(nextLineSegment).TrimStart() : "";

                    if (trimmedPreviousLine.Length > "///".Length || nextLine.StartsWith("///", StringComparison.Ordinal))
                    {
                        var insertionPoint = textEditorData.CaretOffset;
                        textEditorData.InsertText(insertionPoint, "/// ");
                        textEditorData.CaretOffset = insertionPoint + "/// ".Length;
                        return(true);
                    }
                    //multi-line comments
                }
                else if (stateTracker.IsInsideMultiLineComment)
                {
                    if (textEditorData.GetTextAt(line.Offset, line.Length).TrimStart().StartsWith("*", StringComparison.Ordinal))
                    {
                        return(false);
                    }
                    textEditorData.EnsureCaretIsNotVirtual();
                    string commentPrefix = string.Empty;
                    if (trimmedPreviousLine.StartsWith("* ", StringComparison.Ordinal))
                    {
                        commentPrefix = "* ";
                    }
                    else if (trimmedPreviousLine.StartsWith("/**", StringComparison.Ordinal) || trimmedPreviousLine.StartsWith("/*", StringComparison.Ordinal))
                    {
                        commentPrefix = " * ";
                    }
                    else if (trimmedPreviousLine.StartsWith("*", StringComparison.Ordinal))
                    {
                        commentPrefix = "*";
                    }

                    int indentSize   = line.GetIndentation(textEditorData).Length;
                    var insertedText = prevLine.GetIndentation(textEditorData) + commentPrefix;
                    textEditorData.ReplaceText(line.Offset, indentSize, insertedText);
                    textEditorData.CaretOffset = line.Offset + insertedText.Length;
                    return(true);
                }
                else if (wasInStringLiteral)
                {
                    var lexer = new ICSharpCode.NRefactory.CSharp.Completion.CSharpCompletionEngineBase.MiniLexer(textEditorData.GetTextAt(0, prevLine.EndOffset).TrimEnd());
                    lexer.Parse();
                    if (!lexer.IsInString)
                    {
                        return(false);
                    }
                    textEditorData.EnsureCaretIsNotVirtual();
                    var insertedText = "\" +";
                    textEditorData.InsertText(prevLine.Offset + prevLine.Length, insertedText);
                    var lineOffset = line.Offset + insertedText.Length;
                    int indentSize = textEditorData.CaretOffset - lineOffset;
                    insertedText = prevLine.GetIndentation(textEditorData) + (trimmedPreviousLine.StartsWith("\"", StringComparison.Ordinal) ? "" : "\t") + "\"";
                    textEditorData.ReplaceText(lineOffset, indentSize, insertedText);
                    return(true);
                }
            }
            return(false);
        }
Beispiel #5
0
        public override void HandleSpecialSelectionKey(uint unicodeKey)
        {
            string start, end;

            ((SelectionSurroundingProvider)this).GetSelectionSurroundings(unicodeKey, out start, out end);

            if (editor.SelectionMode == SelectionMode.Block)
            {
                var selection = editor.SelectionRegion;
                int startCol  = System.Math.Min(selection.Begin.Column, selection.End.Column) - 1;
                int endCol    = System.Math.Max(selection.Begin.Column, selection.End.Column);

                int minLine = System.Math.Min(selection.Begin.Line, selection.End.Line);
                int maxLine = System.Math.Max(selection.BeginLine, selection.End.Line);

                var changes = new List <TextChange> ();
                for (int lineNumber = minLine; lineNumber <= maxLine; lineNumber++)
                {
                    var lineSegment = editor.GetLine(lineNumber);

                    if (lineSegment.Offset + startCol < lineSegment.EndOffset)
                    {
                        changes.Add(new TextChange(new TextSpan(lineSegment.Offset + startCol, 0), start));
                    }
                    if (lineSegment.Offset + endCol < lineSegment.EndOffset)
                    {
                        changes.Add(new TextChange(new TextSpan(lineSegment.Offset + endCol, 0), end));
                    }
                }

                editor.ApplyTextChanges(changes);

//				textEditorData.MainSelection = new Selection (
//					new DocumentLocation (selection.Anchor.Line, endCol == selection.Anchor.Column ? endCol + start.Length : startCol + 1 + start.Length),
//					new DocumentLocation (selection.Lead.Line, endCol == selection.Anchor.Column ? startCol + 1 + start.Length : endCol + start.Length),
//					MonoDevelop.Ide.Editor.SelectionMode.Block);
            }
            else
            {
                var selectionRange = editor.SelectionRange;
                int anchorOffset   = selectionRange.Offset;
                int leadOffset     = selectionRange.EndOffset;
                var text           = editor.GetTextAt(selectionRange);

                var formattingService = context.AnalysisDocument.GetLanguageService <IEditorFormattingService> ();


                if (editor.Options.GenerateFormattingUndoStep)
                {
                    using (var undo = editor.OpenUndoGroup()) {
                        editor.ReplaceText(selectionRange, start);
                    }
                    using (var undo = editor.OpenUndoGroup()) {
                        editor.ReplaceText(anchorOffset, 1, start + text + end);
                        editor.SetSelection(anchorOffset + start.Length, leadOffset + start.Length + end.Length);
                    }
                    if (unicodeKey == '{')
                    {
                        if (formattingService != null)
                        {
                            var changes = formattingService.GetFormattingChangesAsync(context.AnalysisDocument, TextSpan.FromBounds(anchorOffset + start.Length - 1, leadOffset + start.Length + end.Length), CancellationToken.None).WaitAndGetResult(CancellationToken.None);
                            editor.ApplyTextChanges(changes);
                        }
                    }
                }
                else
                {
                    using (var undo = editor.OpenUndoGroup()) {
                        editor.InsertText(anchorOffset, start);
                        editor.InsertText(leadOffset >= anchorOffset ? leadOffset + start.Length : leadOffset, end);
                        if (unicodeKey == '{')
                        {
                            if (formattingService != null)
                            {
                                var changes = formattingService.GetFormattingChangesAsync(context.AnalysisDocument, TextSpan.FromBounds(anchorOffset + start.Length, leadOffset + start.Length), CancellationToken.None).WaitAndGetResult(CancellationToken.None);
                                editor.ApplyTextChanges(changes);
                            }
                        }
                        else
                        {
                            editor.SetSelection(anchorOffset + start.Length, leadOffset + start.Length + end.Length);
                        }
                    }
                }
            }
        }