void RunFormatter(DocumentLocation location) { if (OnTheFlyFormatting && textEditorData != null && !(textEditorData.CurrentMode is TextLinkEditMode) && !(textEditorData.CurrentMode is InsertionCursorEditMode)) { OnTheFlyFormatter.Format(Document, location); } }
public override void OnTheFlyFormat(MonoDevelop.Ide.Gui.Document doc, int startOffset, int endOffset) { OnTheFlyFormatter.Format(doc, startOffset, endOffset); }
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); }