static void InsertDocumentationComments(ITextEditor editor, int lineNr, int cursorOffset)
        {
            string terminator = DocumentUtilitites.GetLineTerminator(editor.Document, lineNr);

            IDocumentLine currentLine  = editor.Document.GetLine(lineNr);
            IDocumentLine previousLine = (lineNr > 1) ? editor.Document.GetLine(lineNr - 1) : null;

            string curLineText   = currentLine.Text;
            string lineAboveText = previousLine == null ? null : previousLine.Text;

            if (curLineText != null && curLineText.EndsWith("'''", StringComparison.OrdinalIgnoreCase) && (lineAboveText == null || !lineAboveText.Trim().StartsWith("'''", StringComparison.OrdinalIgnoreCase)))
            {
                string indentation = DocumentUtilitites.GetWhitespaceAfter(editor.Document, currentLine.Offset);
                object member      = GetMemberAfter(editor, lineNr);
                if (member != null)
                {
                    StringBuilder sb = new StringBuilder();
                    sb.Append(" <summary>");
                    sb.Append(terminator);
                    sb.Append(indentation);
                    sb.Append("''' ");
                    sb.Append(terminator);
                    sb.Append(indentation);
                    sb.Append("''' </summary>");
                    if (member is IMethod)
                    {
                        IMethod method = (IMethod)member;
                        if (method.Parameters != null && method.Parameters.Count > 0)
                        {
                            for (int i = 0; i < method.Parameters.Count; ++i)
                            {
                                sb.Append(terminator);
                                sb.Append(indentation);
                                sb.Append("''' <param name=\"");
                                sb.Append(method.Parameters[i].Name);
                                sb.Append("\"></param>");
                            }
                        }
                        if (method.ReturnType != null && !method.IsConstructor && method.ReturnType.FullyQualifiedName != "System.Void")
                        {
                            sb.Append(terminator);
                            sb.Append(indentation);
                            sb.Append("''' <returns></returns>");
                        }
                    }
                    editor.Document.Insert(cursorOffset, sb.ToString());
                    editor.Caret.Position = editor.Document.OffsetToPosition(cursorOffset + indentation.Length + "/// ".Length + " <summary>".Length + terminator.Length);
                }
            }
        }
Exemple #2
0
        protected override void Run(ITextEditor editor, string clipboardText)
        {
            string       indentation   = GetIndentation(editor.Document, editor.Caret.Line);
            IAmbience    ambience      = AmbienceService.GetCurrentAmbience();
            int          maxLineLength = editor.Options.VerticalRulerColumn - VisualIndentationLength(editor, indentation);
            StringWriter insertedText  = new StringWriter();

            insertedText.NewLine = DocumentUtilitites.GetLineTerminator(editor.Document, editor.Caret.Line);
            using (StringReader reader = new StringReader(clipboardText)) {
                string line;
                while ((line = reader.ReadLine()) != null)
                {
                    AppendTextLine(indentation, ambience, maxLineLength, insertedText, line);
                }
            }
            IDocument document     = editor.Document;
            int       insertionPos = document.GetLine(editor.Caret.Line).Offset + indentation.Length;

            document.Insert(insertionPos, insertedText.ToString());
        }
Exemple #3
0
        /// <summary>
        /// C# only.
        /// </summary>
        public static void AddCodeToMethodStart(IMember m, ITextEditor textArea, string newCode)
        {
            int methodStart = FindMethodStartOffset(textArea.Document, m.BodyRegion);

            if (methodStart < 0)
            {
                return;
            }
            textArea.Select(methodStart, 0);
            using (textArea.Document.OpenUndoGroup()) {
                int startLine = textArea.Caret.Line;
                foreach (string newCodeLine in newCode.Split('\n'))
                {
                    textArea.Document.Insert(textArea.Caret.Offset,
                                             DocumentUtilitites.GetLineTerminator(textArea.Document, textArea.Caret.Line) + newCodeLine);
                }
                int endLine = textArea.Caret.Line;
                textArea.Language.FormattingStrategy.IndentLines(textArea, startLine, endLine);
            }
        }
        public string GetOldVersionFromLine(int lineNumber, out int newStartLine, out bool added)
        {
            LineChangeInfo info = changeList[lineNumber];

            added = info.Change == ChangeType.Added;

            if (info.Change != ChangeType.None && info.Change != ChangeType.Unsaved)
            {
                newStartLine = CalculateNewStartLineNumber(lineNumber);

                if (info.Change == ChangeType.Added)
                {
                    return("");
                }

                var startDocumentLine = baseDocument.GetLine(info.OldStartLineNumber + 1);
                var endLine           = baseDocument.GetLine(info.OldEndLineNumber);

                return(TextUtilities.NormalizeNewLines(baseDocument.GetText(startDocumentLine.Offset, endLine.EndOffset - startDocumentLine.Offset), DocumentUtilitites.GetLineTerminator(document, newStartLine == 0 ? 1 : newStartLine)));
            }

            newStartLine = 0;
            return(null);
        }
        void FormatLineInternal(ITextEditor editor, int lineNr, int cursorOffset, char ch)
        {
            string terminator = DocumentUtilitites.GetLineTerminator(editor.Document, lineNr);

            doCasing    = PropertyService.Get("VBBinding.TextEditor.EnableCasing", true);
            doInsertion = PropertyService.Get("VBBinding.TextEditor.EnableEndConstructs", true);

            IDocumentLine currentLine = editor.Document.GetLine(lineNr);
            IDocumentLine lineAbove   = lineNr > 1 ? editor.Document.GetLine(lineNr - 1) : null;

            string curLineText   = currentLine == null ? "" : currentLine.Text;
            string lineAboveText = lineAbove == null ? "" : lineAbove.Text;

            if (ch == '\'')
            {
                InsertDocumentationComments(editor, lineNr, cursorOffset);
            }

            if (ch == '\n' && lineAboveText != null)
            {
                if (LanguageUtils.IsInsideDocumentationComment(editor, lineAbove, lineAbove.EndOffset))
                {
                    editor.Document.Insert(cursorOffset, "''' ");
                    return;
                }

                string textToReplace = lineAboveText.TrimLine();

                if (doCasing)
                {
                    DoCasingOnLine(lineAbove, textToReplace, editor);
                }

                if (doInsertion)
                {
                    DoInsertionOnLine(terminator, currentLine, lineAbove, textToReplace, editor, lineNr);
                }

                if (IsInString(lineAboveText))
                {
                    if (IsFinishedString(curLineText))
                    {
                        editor.Document.Insert(lineAbove.EndOffset, "\" & _");
                        editor.Document.Insert(currentLine.Offset, "\"");
                    }
                    else
                    {
                        editor.Document.Insert(lineAbove.EndOffset, "\"");
                    }
                }
                else
                {
                    string indent = DocumentUtilitites.GetWhitespaceAfter(editor.Document, lineAbove.Offset);
                    if (indent.Length > 0)
                    {
                        string newLineText = indent + currentLine.Text.Trim();
                        editor.Document.Replace(currentLine.Offset, currentLine.Length, newLineText);
                    }
                    editor.Caret.Column = indent.Length + 1;
                }

                IndentLines(editor, lineNr - 1, lineNr);
            }
            else if (ch == '>')
            {
                if (LanguageUtils.IsInsideDocumentationComment(editor, currentLine, cursorOffset))
                {
                    int column = editor.Caret.Offset - currentLine.Offset;
                    int index  = Math.Min(column - 1, curLineText.Length - 1);

                    while (index > 0 && curLineText[index] != '<')
                    {
                        --index;
                        if (curLineText[index] == '/')
                        {
                            return;                             // the tag was an end tag or already
                        }
                    }

                    if (index > 0)
                    {
                        StringBuilder commentBuilder = new StringBuilder("");
                        for (int i = index; i < curLineText.Length && i < column && !Char.IsWhiteSpace(curLineText[i]); ++i)
                        {
                            commentBuilder.Append(curLineText[i]);
                        }
                        string tag = commentBuilder.ToString().Trim();
                        if (!tag.EndsWith(">", StringComparison.OrdinalIgnoreCase))
                        {
                            tag += ">";
                        }
                        if (!tag.StartsWith("/", StringComparison.OrdinalIgnoreCase))
                        {
                            string endTag = "</" + tag.Substring(1);
                            editor.Document.Insert(editor.Caret.Offset, endTag);
                            editor.Caret.Offset -= endTag.Length;
                        }
                    }
                }
            }
        }
        void FormatLineInternal(ITextEditor textArea, int lineNr, int cursorOffset, char ch)
        {
            IDocumentLine curLine    = textArea.Document.GetLine(lineNr);
            IDocumentLine lineAbove  = lineNr > 1 ? textArea.Document.GetLine(lineNr - 1) : null;
            string        terminator = DocumentUtilitites.GetLineTerminator(textArea.Document, lineNr);

            string curLineText;

            //// local string for curLine segment
            if (ch == '/')
            {
                curLineText = curLine.Text;
                string lineAboveText = lineAbove == null ? "" : lineAbove.Text;
                if (curLineText != null && curLineText.EndsWith("///") && (lineAboveText == null || !lineAboveText.Trim().StartsWith("///")))
                {
                    string indentation = DocumentUtilitites.GetWhitespaceAfter(textArea.Document, curLine.Offset);
                    object member      = GetMemberAfter(textArea, lineNr);
                    if (member != null)
                    {
                        StringBuilder sb = new StringBuilder();
                        sb.Append(" <summary>");
                        sb.Append(terminator);
                        sb.Append(indentation);
                        sb.Append("/// ");
                        sb.Append(terminator);
                        sb.Append(indentation);
                        sb.Append("/// </summary>");

                        if (member is IMethod)
                        {
                            IMethod method = (IMethod)member;
                            if (method.Parameters != null && method.Parameters.Count > 0)
                            {
                                for (int i = 0; i < method.Parameters.Count; ++i)
                                {
                                    sb.Append(terminator);
                                    sb.Append(indentation);
                                    sb.Append("/// <param name=\"");
                                    sb.Append(method.Parameters[i].Name);
                                    sb.Append("\"></param>");
                                }
                            }
                            if (method.ReturnType != null && !method.IsConstructor && method.ReturnType.FullyQualifiedName != "System.Void")
                            {
                                sb.Append(terminator);
                                sb.Append(indentation);
                                sb.Append("/// <returns></returns>");
                            }
                        }
                        textArea.Document.Insert(cursorOffset, sb.ToString());

                        textArea.Caret.Offset = cursorOffset + indentation.Length + "/// ".Length + " <summary>".Length + terminator.Length;
                    }
                }
                return;
            }

            if (ch != '\n' && ch != '>')
            {
                if (IsInsideStringOrComment(textArea, curLine, cursorOffset))
                {
                    return;
                }
            }
            switch (ch)
            {
            case '>':
                if (IsInsideDocumentationComment(textArea, curLine, cursorOffset))
                {
                    curLineText = curLine.Text;
                    int column = cursorOffset - curLine.Offset;
                    int index  = Math.Min(column - 1, curLineText.Length - 1);

                    while (index >= 0 && curLineText[index] != '<')
                    {
                        --index;
                        if (curLineText[index] == '/')
                        {
                            return;                                     // the tag was an end tag or already
                        }
                    }

                    if (index > 0)
                    {
                        StringBuilder commentBuilder = new StringBuilder("");
                        for (int i = index; i < curLineText.Length && i < column && !Char.IsWhiteSpace(curLineText[i]); ++i)
                        {
                            commentBuilder.Append(curLineText[i]);
                        }
                        string tag = commentBuilder.ToString().Trim();
                        if (!tag.EndsWith(">"))
                        {
                            tag += ">";
                        }
                        if (!tag.StartsWith("/"))
                        {
                            textArea.Document.Insert(cursorOffset, "</" + tag.Substring(1), AnchorMovementType.BeforeInsertion);
                        }
                    }
                }
                break;

            case ':':
            case ')':
            case ']':
            case '}':
            case '{':
                //if (textArea.Document.TextEditorProperties.IndentStyle == IndentStyle.Smart) {
                IndentLine(textArea, curLine);
                //}
                break;

            case '\n':
                string lineAboveText = lineAbove == null ? "" : lineAbove.Text;
                //// curLine might have some text which should be added to indentation
                curLineText = curLine.Text;

                if (lineAbove != null && lineAbove.Text.Trim().StartsWith("#region") &&
                    NeedEndregion(textArea.Document))
                {
                    textArea.Document.Insert(cursorOffset, "#endregion");
                    return;
                }

                ISyntaxHighlighter highlighter = textArea.GetService(typeof(ISyntaxHighlighter)) as ISyntaxHighlighter;
                bool isInMultilineComment      = false;
                bool isInMultilineString       = false;
                if (highlighter != null && lineAbove != null)
                {
                    var spanStack = highlighter.GetSpanColorNamesFromLineStart(lineNr);
                    isInMultilineComment = spanStack.Contains(SyntaxHighligherKnownSpanNames.Comment);
                    isInMultilineString  = spanStack.Contains(SyntaxHighligherKnownSpanNames.String);
                }
                bool isInNormalCode = !(isInMultilineComment || isInMultilineString);

                if (lineAbove != null && isInMultilineComment)
                {
                    string lineAboveTextTrimmed = lineAboveText.TrimStart();
                    if (lineAboveTextTrimmed.StartsWith("/*", StringComparison.Ordinal))
                    {
                        textArea.Document.Insert(cursorOffset, " * ");
                        return;
                    }

                    if (lineAboveTextTrimmed.StartsWith("*", StringComparison.Ordinal))
                    {
                        textArea.Document.Insert(cursorOffset, "* ");
                        return;
                    }
                }

                if (lineAbove != null && isInNormalCode)
                {
                    IDocumentLine nextLine     = lineNr + 1 <= textArea.Document.TotalNumberOfLines ? textArea.Document.GetLine(lineNr + 1) : null;
                    string        nextLineText = (nextLine != null) ? nextLine.Text : "";

                    int indexAbove = lineAboveText.IndexOf("///");
                    int indexNext  = nextLineText.IndexOf("///");
                    if (indexAbove > 0 && (indexNext != -1 || indexAbove + 4 < lineAbove.Length))
                    {
                        textArea.Document.Insert(cursorOffset, "/// ");
                        return;
                    }

                    if (IsInNonVerbatimString(lineAboveText, curLineText))
                    {
                        textArea.Document.Insert(cursorOffset, "\"");
                        textArea.Document.Insert(lineAbove.Offset + lineAbove.Length,
                                                 "\" +");
                    }
                }
                if (textArea.Options.AutoInsertBlockEnd && lineAbove != null && isInNormalCode)
                {
                    string oldLineText = lineAbove.Text;
                    if (oldLineText.EndsWith("{"))
                    {
                        if (NeedCurlyBracket(textArea.Document.Text))
                        {
                            int insertionPoint = curLine.Offset + curLine.Length;
                            textArea.Document.Insert(insertionPoint, terminator + "}");
                            IndentLine(textArea, textArea.Document.GetLine(lineNr + 1));
                            textArea.Caret.Offset = insertionPoint;
                        }
                    }
                }
                return;
            }
        }
Exemple #7
0
        void DisplayTooltip(MouseEventArgs e)
        {
            int line = GetLineFromMousePosition(e);

            if (line == 0)
            {
                return;
            }

            int    startLine;
            bool   added;
            string oldText = changeWatcher.GetOldVersionFromLine(line, out startLine, out added);

            TextEditor editor = this.TextView.Services.GetService(typeof(TextEditor)) as TextEditor;

            markerService = this.TextView.Services.GetService(typeof(ITextMarkerService)) as ITextMarkerService;

            LineChangeInfo zeroLineInfo = changeWatcher.GetChange(0);

            int  offset, length;
            bool hasNewVersion = changeWatcher.GetNewVersionFromLine(line, out offset, out length);

            if (line == 1 && zeroLineInfo.Change == ChangeType.Deleted)
            {
                int zeroStartLine; bool zeroAdded;
                startLine = 1;
                string deletedText = changeWatcher.GetOldVersionFromLine(0, out zeroStartLine, out zeroAdded);
                var    docLine     = editor.Document.GetLineByNumber(line);
                string newLine     = DocumentUtilitites.GetLineTerminator(changeWatcher.CurrentDocument, 1);
                deletedText += newLine;
                deletedText += editor.Document.GetText(docLine.Offset, docLine.Length);
                if (oldText != null)
                {
                    oldText = deletedText + newLine + oldText;
                }
                else
                {
                    oldText = deletedText;
                }

                if (!hasNewVersion)
                {
                    offset        = 0;
                    length        = docLine.Length;
                    hasNewVersion = true;
                }
            }

            if (hasNewVersion)
            {
                if (marker != null)
                {
                    markerService.Remove(marker);
                }
                if (length <= 0)
                {
                    marker = null;
                    length = 0;
                }
                else
                {
                    marker = markerService.Create(offset, length);
                    marker.BackgroundColor = Colors.LightGreen;
                }
            }

            if (oldText != null)
            {
                LineChangeInfo currLineInfo = changeWatcher.GetChange(startLine);

                if (currLineInfo.Change == ChangeType.Deleted && !(line == 1 && zeroLineInfo.Change == ChangeType.Deleted))
                {
                    var docLine = editor.Document.GetLineByNumber(startLine);
                    if (docLine.DelimiterLength == 0)
                    {
                        oldText = DocumentUtilitites.GetLineTerminator(changeWatcher.CurrentDocument, startLine) + oldText;
                    }
                    oldText = editor.Document.GetText(docLine.Offset, docLine.TotalLength) + oldText;
                }

                DiffControl differ = new DiffControl();
                differ.editor.SyntaxHighlighting            = editor.SyntaxHighlighting;
                differ.editor.HorizontalScrollBarVisibility = ScrollBarVisibility.Hidden;
                differ.editor.VerticalScrollBarVisibility   = ScrollBarVisibility.Hidden;
                differ.editor.Document.Text = oldText;
                differ.Background           = Brushes.White;

                if (oldText == string.Empty)
                {
                    differ.editor.Visibility     = Visibility.Collapsed;
                    differ.copyButton.Visibility = Visibility.Collapsed;
                }
                else
                {
                    var baseDocument = new TextDocument(DocumentUtilitites.GetTextSource(changeWatcher.BaseDocument));
                    if (differ.editor.SyntaxHighlighting != null)
                    {
                        var mainHighlighter  = new DocumentHighlighter(baseDocument, differ.editor.SyntaxHighlighting.MainRuleSet);
                        var popupHighlighter = differ.editor.TextArea.GetService(typeof(IHighlighter)) as DocumentHighlighter;

                        popupHighlighter.InitialSpanStack = mainHighlighter.GetSpanStack(currLineInfo.OldStartLineNumber);
                    }
                }

                differ.revertButton.Click += delegate {
                    if (hasNewVersion)
                    {
                        Document.Replace(offset, length, oldText);
                        tooltip.IsOpen = false;
                    }
                };

                tooltip.Child = new Border()
                {
                    Child           = differ,
                    BorderBrush     = Brushes.Black,
                    BorderThickness = new Thickness(1)
                };

                if (tooltip.IsOpen)
                {
                    tooltip.IsOpen = false;
                }

                tooltip.IsOpen = true;

                tooltip.Closed += delegate {
                    if (marker != null)
                    {
                        markerService.Remove(marker);
                    }
                };
                tooltip.HorizontalOffset = -10;
                tooltip.VerticalOffset   =
                    TextView.GetVisualTopByDocumentLine(startLine) - TextView.ScrollOffset.Y;
                tooltip.Placement       = PlacementMode.Top;
                tooltip.PlacementTarget = this.TextView;
            }
        }
        void FormatLineInternal(ITextEditor textArea, int lineNr, int cursorOffset, char ch)
        {
            IDocumentLine curLine    = textArea.Document.GetLine(lineNr);
            IDocumentLine lineAbove  = lineNr > 1 ? textArea.Document.GetLine(lineNr - 1) : null;
            string        terminator = DocumentUtilitites.GetLineTerminator(textArea.Document, lineNr);

            string curLineText;

            //// local string for curLine segment
            if (ch == '-')
            {
                curLineText = curLine.Text;
                string lineAboveText = lineAbove == null ? "" : lineAbove.Text;
                if (curLineText != null && curLineText.EndsWith("---") && (lineAboveText == null || !lineAboveText.Trim().StartsWith("---")))
                {
                    string        indentation = DocumentUtilitites.GetWhitespaceAfter(textArea.Document, curLine.Offset);
                    StringBuilder sb          = new StringBuilder();
                    sb.Append(" <summary>");
                    sb.Append(terminator);
                    sb.Append(indentation);
                    sb.Append("--- ");
                    sb.Append(terminator);
                    sb.Append(indentation);
                    sb.Append("--- </summary>");

                    //sb.Append(terminator);
                    //sb.Append(indentation);
                    //sb.Append("--- <returns></returns>");
                    textArea.Document.Insert(cursorOffset, sb.ToString());

                    textArea.Caret.Offset = cursorOffset + indentation.Length + "--- ".Length + " <summary>".Length + terminator.Length;
                }
                else if (curLineText != null && curLineText.Trim() == "-" && (lineAboveText != null && lineAboveText.Trim().StartsWith("---")))
                {
                    StringBuilder sb = new StringBuilder();
                    sb.Append("-- ");

                    //sb.Append(terminator);
                    //sb.Append(indentation);
                    //sb.Append("--- <returns></returns>");
                    textArea.Document.Insert(cursorOffset, sb.ToString());

                    textArea.Caret.Offset = cursorOffset + "-- ".Length;
                }
                return;
            }

            if (ch != '\n' && ch != '>')
            {
                if (IsInsideStringOrComment(textArea, curLine, cursorOffset))
                {
                    return;
                }
            }

            if (IsInsideStringOrComment(textArea, curLine, cursorOffset) == false &&
                textArea.Caret.Offset == curLine.EndOffset && // end of line, not editing something inside the line
                (curLine.Text.TrimEnd().EndsWith("then") ||
                 curLine.Text.TrimEnd().EndsWith("do")))
            {
                string        indentation = DocumentUtilitites.GetWhitespaceAfter(textArea.Document, curLine.Offset);
                StringBuilder sb          = new StringBuilder();
                sb.Append(terminator);
                sb.Append(indentation + textArea.Options.IndentationString);
                sb.Append(terminator);
                sb.Append(indentation);
                sb.Append("end");
                textArea.Document.Insert(cursorOffset, sb.ToString());
                textArea.Caret.Offset =
                    cursorOffset
                    + terminator.Length  // end of line
                    + indentation.Length // indentation
                    + textArea.Options.IndentationString.Length
                ;
            }

            if (IsInsideStringOrComment(textArea, curLine, cursorOffset) == false &&
                textArea.Caret.Offset == curLine.EndOffset && // end of line, not editing something inside the line
                curLine.Text.TrimStart().StartsWith("repeat"))
            {
                string        indentation = DocumentUtilitites.GetWhitespaceAfter(textArea.Document, curLine.Offset);
                StringBuilder sb          = new StringBuilder();
                sb.Append(terminator);
                sb.Append(indentation + textArea.Options.IndentationString);
                sb.Append(terminator);
                sb.Append(indentation);
                sb.Append("until ");
                textArea.Document.Insert(cursorOffset, sb.ToString());

                textArea.Caret.Offset =
                    cursorOffset
                    + indentation.Length
                    + terminator.Length // line 1
                    + indentation.Length
                    + textArea.Options.IndentationString.Length
                    + terminator.Length // line 2
                    + "until ".Length
                ;
            }

            switch (ch)
            {
            case '>':
                if (IsInsideDocumentationComment(textArea, curLine, cursorOffset))
                {
                    curLineText = curLine.Text;
                    int column = cursorOffset - curLine.Offset;
                    int index  = Math.Min(column - 1, curLineText.Length - 1);

                    while (index >= 0 && curLineText[index] != '<')
                    {
                        --index;
                        if (curLineText[index] == '/')
                        {
                            return;     // the tag was an end tag or already
                        }
                    }

                    if (index > 0)
                    {
                        StringBuilder commentBuilder = new StringBuilder("");
                        for (int i = index; i < curLineText.Length && i < column && !Char.IsWhiteSpace(curLineText[i]); ++i)
                        {
                            commentBuilder.Append(curLineText[i]);
                        }
                        string tag = commentBuilder.ToString().Trim();
                        if (!tag.EndsWith(">"))
                        {
                            tag += ">";
                        }
                        if (!tag.StartsWith("/"))
                        {
                            textArea.Document.Insert(cursorOffset, "</" + tag.Substring(1), AnchorMovementType.BeforeInsertion);
                        }
                    }
                }
                break;

            case ')':
                if (curLine.Text.TrimStart().StartsWith("function"))
                {
                    string        indentation = DocumentUtilitites.GetWhitespaceAfter(textArea.Document, curLine.Offset);
                    StringBuilder sb          = new StringBuilder();
                    sb.Append(terminator);
                    sb.Append(indentation + textArea.Options.IndentationString);
                    sb.Append(terminator);
                    sb.Append(indentation);
                    sb.Append("end");
                    textArea.Document.Insert(cursorOffset, sb.ToString());
                    textArea.Caret.Offset =
                        cursorOffset
                        + terminator.Length     // end of line
                        + indentation.Length    // indentation
                        + textArea.Options.IndentationString.Length
                    ;
                }
                else
                {
                    IndentLine(textArea, curLine);
                }
                break;

            case ':':
            case ']':
            case '}':
            case '{':
                IndentLine(textArea, curLine);
                break;

            case '\n':
                string lineAboveText = lineAbove == null ? "" : lineAbove.Text;
                //// curLine might have some text which should be added to indentation
                curLineText = curLine.Text;


                ISyntaxHighlighter highlighter = textArea.GetService(typeof(ISyntaxHighlighter)) as ISyntaxHighlighter;
                bool isInMultilineComment      = false;
                bool isInMultilineString       = false;
                if (highlighter != null && lineAbove != null)
                {
                    var spanStack = highlighter.GetSpanColorNamesFromLineStart(lineNr);
                    isInMultilineComment = spanStack.Contains(SyntaxHighligherKnownSpanNames.Comment);
                    isInMultilineString  = spanStack.Contains(SyntaxHighligherKnownSpanNames.String);
                }
                bool isInNormalCode = !(isInMultilineComment || isInMultilineString);

                if (lineAbove != null && isInMultilineComment)
                {
                    string lineAboveTextTrimmed = lineAboveText.TrimStart();
                    if (lineAboveTextTrimmed.StartsWith("--[[", StringComparison.Ordinal))
                    {
                        textArea.Document.Insert(cursorOffset, " - ");
                        return;
                    }

                    if (lineAboveTextTrimmed.StartsWith("-", StringComparison.Ordinal))
                    {
                        textArea.Document.Insert(cursorOffset, "- ");
                        return;
                    }
                }

                if (lineAbove != null && isInNormalCode)
                {
                    IDocumentLine nextLine     = lineNr + 1 <= textArea.Document.TotalNumberOfLines ? textArea.Document.GetLine(lineNr + 1) : null;
                    string        nextLineText = (nextLine != null) ? nextLine.Text : "";

                    int indexAbove = lineAboveText.IndexOf("---");
                    int indexNext  = nextLineText.IndexOf("---");
                    if (indexAbove > 0 && (indexNext != -1 || indexAbove + 4 < lineAbove.Length))
                    {
                        textArea.Document.Insert(cursorOffset, "--- ");
                        return;
                    }

                    if (IsInNonVerbatimString(lineAboveText, curLineText))
                    {
                        textArea.Document.Insert(cursorOffset, "\"");
                        textArea.Document.Insert(lineAbove.Offset + lineAbove.Length,
                                                 "\" +");
                    }
                }
                return;
            }
        }
Exemple #9
0
        void DisplayTooltip(MouseEventArgs e)
        {
            int line = GetLineFromMousePosition(e);

            if (line == 0)
            {
                return;
            }

            int    startLine;
            bool   added;
            string oldText = changeWatcher.GetOldVersionFromLine(line, out startLine, out added);

            TextEditor editor = this.TextView.Services.GetService(typeof(TextEditor)) as TextEditor;

            markerService = this.TextView.Services.GetService(typeof(ITextMarkerService)) as ITextMarkerService;

            int  offset, length;
            bool hasNewVersion = changeWatcher.GetNewVersionFromLine(line, out offset, out length);

            if (hasNewVersion)
            {
                if (marker != null)
                {
                    markerService.Remove(marker);
                }
                if (length <= 0)
                {
                    marker = null;
                    length = 0;
                }
                else
                {
                    marker = markerService.Create(offset, length);
                    marker.BackgroundColor = Colors.LightGreen;
                }
            }

            if (oldText != null)
            {
                DiffControl differ = new DiffControl();
                differ.editor.SyntaxHighlighting            = editor.SyntaxHighlighting;
                differ.editor.HorizontalScrollBarVisibility = ScrollBarVisibility.Hidden;
                differ.editor.VerticalScrollBarVisibility   = ScrollBarVisibility.Hidden;
                differ.editor.Document.Text = oldText;
                differ.Background           = Brushes.White;

                // TODO : deletions on line 0 cannot be displayed.

                LineChangeInfo prevLineInfo = changeWatcher.GetChange(startLine - 1);
                LineChangeInfo lineInfo     = changeWatcher.GetChange(startLine);

                if (prevLineInfo.Change == ChangeType.Deleted)
                {
                    var docLine = editor.Document.GetLineByNumber(startLine - 1);
                    differ.editor.Document.Insert(0, editor.Document.GetText(docLine.Offset, docLine.TotalLength));
                }

                if (oldText == string.Empty)
                {
                    differ.editor.Visibility     = Visibility.Collapsed;
                    differ.copyButton.Visibility = Visibility.Collapsed;
                }
                else
                {
                    var baseDocument = new TextDocument(changeWatcher.BaseDocument.Text);
                    if (differ.editor.SyntaxHighlighting != null)
                    {
                        var mainHighlighter  = new DocumentHighlighter(baseDocument, differ.editor.SyntaxHighlighting.MainRuleSet);
                        var popupHighlighter = differ.editor.TextArea.GetService(typeof(IHighlighter)) as DocumentHighlighter;

                        if (prevLineInfo.Change == ChangeType.Deleted)
                        {
                            popupHighlighter.InitialSpanStack = mainHighlighter.GetSpanStack(prevLineInfo.OldStartLineNumber);
                        }
                        else
                        {
                            popupHighlighter.InitialSpanStack = mainHighlighter.GetSpanStack(lineInfo.OldStartLineNumber);
                        }
                    }
                }

                differ.revertButton.Click += delegate {
                    if (hasNewVersion)
                    {
                        int          delimiter = 0;
                        DocumentLine l         = Document.GetLineByOffset(offset + length);
                        if (added)
                        {
                            delimiter = l.DelimiterLength;
                        }
                        if (length == 0)
                        {
                            oldText += DocumentUtilitites.GetLineTerminator(new AvalonEditDocumentAdapter(Document, null), l.LineNumber);
                        }
                        Document.Replace(offset, length + delimiter, oldText);
                        tooltip.IsOpen = false;
                    }
                };

                tooltip.Child = new Border()
                {
                    Child           = differ,
                    BorderBrush     = Brushes.Black,
                    BorderThickness = new Thickness(1)
                };

                if (tooltip.IsOpen)
                {
                    tooltip.IsOpen = false;
                }

                tooltip.IsOpen = true;

                tooltip.Closed += delegate {
                    if (marker != null)
                    {
                        markerService.Remove(marker);
                    }
                };
                tooltip.HorizontalOffset = -10;
                tooltip.VerticalOffset   =
                    TextView.GetVisualTopByDocumentLine(startLine) - TextView.ScrollOffset.Y;
                tooltip.Placement       = PlacementMode.Top;
                tooltip.PlacementTarget = this.TextView;
            }
        }