コード例 #1
0
 void RunFormatter(DocumentLocation location)
 {
     if (OnTheFlyFormatting && textEditorData != null && !(textEditorData.CurrentMode is TextLinkEditMode) && !(textEditorData.CurrentMode is InsertionCursorEditMode))
     {
         OnTheFlyFormatter.Format(Document, location);
     }
 }
コード例 #2
0
 public override void OnTheFlyFormat(MonoDevelop.Ide.Gui.Document doc, int startOffset, int endOffset)
 {
     OnTheFlyFormatter.Format(doc, startOffset, endOffset);
 }
コード例 #3
0
        public override bool KeyPress(Gdk.Key key, char keyChar, Gdk.ModifierType modifier)
        {
            bool skipFormatting = StateTracker.Engine.IsInsideOrdinaryCommentOrString ||
                                  StateTracker.Engine.IsInsidePreprocessorDirective;

            cursorPositionBeforeKeyPress = textEditorData.Caret.Offset;
            bool isSomethingSelected = textEditorData.IsSomethingSelected;

            if (key == Gdk.Key.BackSpace && textEditorData.Caret.Offset == lastInsertedSemicolon)
            {
                textEditorData.Document.Undo();
                lastInsertedSemicolon = -1;
                return(false);
            }
            lastInsertedSemicolon = -1;
            if (keyChar == ';' && !(textEditorData.CurrentMode is TextLinkEditMode) && !DoInsertTemplate() && !isSomethingSelected && PropertyService.Get(
                    "SmartSemicolonPlacement",
                    false
                    ))
            {
                bool         retval  = base.KeyPress(key, keyChar, modifier);
                DocumentLine curLine = textEditorData.Document.GetLine(textEditorData.Caret.Line);
                string       text    = textEditorData.Document.GetTextAt(curLine);
                if (!(text.EndsWith(";", StringComparison.Ordinal) || text.Trim().StartsWith("for", StringComparison.Ordinal)))
                {
                    int guessedOffset;

                    if (GuessSemicolonInsertionOffset(textEditorData, curLine, textEditorData.Caret.Offset, out guessedOffset))
                    {
                        using (var undo = textEditorData.OpenUndoGroup()) {
                            textEditorData.Remove(textEditorData.Caret.Offset - 1, 1);
                            textEditorData.Caret.Offset = guessedOffset;
                            lastInsertedSemicolon       = textEditorData.Caret.Offset + 1;
                            retval = base.KeyPress(key, keyChar, modifier);
                        }
                    }
                }
                using (var undo = textEditorData.OpenUndoGroup()) {
                    if (OnTheFlyFormatting && textEditorData != null && !(textEditorData.CurrentMode is TextLinkEditMode) && !(textEditorData.CurrentMode is InsertionCursorEditMode))
                    {
                        OnTheFlyFormatter.FormatStatmentAt(Document, textEditorData.Caret.Location);
                    }
                }
                return(retval);
            }

            if (key == Gdk.Key.Tab)
            {
                stateTracker.UpdateEngine();
                if (stateTracker.Engine.IsInsideStringLiteral && !textEditorData.IsSomethingSelected)
                {
                    var lexer = new CSharpCompletionEngineBase.MiniLexer(textEditorData.Document.GetTextAt(0, textEditorData.Caret.Offset));
                    lexer.Parse();
                    if (lexer.IsInString)
                    {
                        textEditorData.InsertAtCaret("\\t");
                        return(false);
                    }
                }
            }


            if (key == Gdk.Key.Tab && DefaultSourceEditorOptions.Instance.TabIsReindent && !CompletionWindowManager.IsVisible && !(textEditorData.CurrentMode is TextLinkEditMode) && !DoInsertTemplate() && !isSomethingSelected)
            {
                int cursor = textEditorData.Caret.Offset;
                if (stateTracker.Engine.IsInsideVerbatimString && cursor > 0 && cursor < textEditorData.Document.TextLength && textEditorData.GetCharAt(cursor - 1) == '"')
                {
                    stateTracker.UpdateEngine(cursor + 1);
                }

                if (stateTracker.Engine.IsInsideVerbatimString)
                {
                    // insert normal tab inside @" ... "
                    if (textEditorData.IsSomethingSelected)
                    {
                        textEditorData.SelectedText = "\t";
                    }
                    else
                    {
                        textEditorData.Insert(cursor, "\t");
                    }
                    textEditorData.Document.CommitLineUpdate(textEditorData.Caret.Line);
                }
                else if (cursor >= 1)
                {
                    if (textEditorData.Caret.Column > 1)
                    {
                        int delta = cursor - cursorPositionBeforeKeyPress;
                        if (delta < 2 && delta > 0)
                        {
                            textEditorData.Remove(cursor - delta, delta);
                            textEditorData.Caret.Offset = cursor - delta;
                            textEditorData.Document.CommitLineUpdate(textEditorData.Caret.Line);
                        }
                    }
                    stateTracker.UpdateEngine();
                    DoReSmartIndent();
                }
                return(false);
            }

            stateTracker.UpdateEngine();
            if (!stateTracker.Engine.IsInsideOrdinaryCommentOrString)
            {
                if (keyChar == '@')
                {
                    var retval = base.KeyPress(key, keyChar, modifier);
                    int cursor = textEditorData.Caret.Offset;
                    if (cursor < textEditorData.Length && textEditorData.GetCharAt(cursor) == '"')
                    {
                        ConvertNormalToVerbatimString(textEditorData, cursor + 1);
                    }
                    return(retval);
                }
            }


            //do the smart indent
            if (textEditorData.Options.IndentStyle == IndentStyle.Smart || textEditorData.Options.IndentStyle == IndentStyle.Virtual)
            {
                bool retval;
                //capture some of the current state
                int  oldBufLen    = textEditorData.Length;
                int  oldLine      = textEditorData.Caret.Line + 1;
                bool hadSelection = textEditorData.IsSomethingSelected;
                bool reIndent     = false;

                //pass through to the base class, which actually inserts the character
                //and calls HandleCodeCompletion etc to handles completion
                using (var undo = textEditorData.OpenUndoGroup()) {
                    DoPreInsertionSmartIndent(key);
                }

                bool automaticReindent;
                // need to be outside of an undo group - otherwise it interferes with other text editor extension
                // esp. the documentation insertion undo steps.
                retval = base.KeyPress(key, keyChar, modifier);
                //handle inserted characters
                if (textEditorData.Caret.Offset <= 0 || textEditorData.IsSomethingSelected)
                {
                    return(retval);
                }

                lastCharInserted = TranslateKeyCharForIndenter(key, keyChar, textEditorData.GetCharAt(textEditorData.Caret.Offset - 1));
                if (lastCharInserted == '\0')
                {
                    return(retval);
                }

                using (var undo = textEditorData.OpenUndoGroup()) {
                    stateTracker.UpdateEngine();

                    if (key == Gdk.Key.Return && modifier == Gdk.ModifierType.ControlMask)
                    {
                        FixLineStart(textEditorData, stateTracker, textEditorData.Caret.Line + 1);
                    }
                    else
                    {
                        if (!(oldLine == textEditorData.Caret.Line + 1 && lastCharInserted == '\n') && (oldBufLen != textEditorData.Length || lastCharInserted != '\0'))
                        {
                            DoPostInsertionSmartIndent(lastCharInserted, hadSelection, out reIndent);
                        }
                    }
                    //reindent the line after the insertion, if needed
                    //N.B. if the engine says we need to reindent, make sure that it's because a char was
                    //inserted rather than just updating the stack due to moving around

                    stateTracker.UpdateEngine();
                    automaticReindent = (stateTracker.Engine.NeedsReindent && lastCharInserted != '\0');
                    if (key == Gdk.Key.Return && (reIndent || automaticReindent))
                    {
                        DoReSmartIndent();
                    }
                }

                if (key != Gdk.Key.Return && (reIndent || automaticReindent))
                {
                    using (var undo = textEditorData.OpenUndoGroup()) {
                        DoReSmartIndent();
                    }
                }
                if (!skipFormatting)
                {
                    if (keyChar == ';' || keyChar == '}')
                    {
                        using (var undo = textEditorData.OpenUndoGroup()) {
                            if (OnTheFlyFormatting && textEditorData != null && !(textEditorData.CurrentMode is TextLinkEditMode) && !(textEditorData.CurrentMode is InsertionCursorEditMode))
                            {
                                OnTheFlyFormatter.FormatStatmentAt(Document, textEditorData.Caret.Location);
                            }
                        }
                    }
                }

                stateTracker.UpdateEngine();
                lastCharInserted = '\0';
                CheckXmlCommentCloseTag(keyChar);
                return(retval);
            }

            if (textEditorData.Options.IndentStyle == IndentStyle.Auto && DefaultSourceEditorOptions.Instance.TabIsReindent && key == Gdk.Key.Tab)
            {
                bool retval = base.KeyPress(key, keyChar, modifier);
                DoReSmartIndent();
                CheckXmlCommentCloseTag(keyChar);
                return(retval);
            }

            //pass through to the base class, which actually inserts the character
            //and calls HandleCodeCompletion etc to handles completion
            var result = base.KeyPress(key, keyChar, modifier);

            CheckXmlCommentCloseTag(keyChar);

            if (!skipFormatting && keyChar == '}')
            {
                RunFormatter(new DocumentLocation(textEditorData.Caret.Location.Line, textEditorData.Caret.Location.Column));
            }
            return(result);
        }