public static FormatStatmentAt ( MonoDevelop data, Mono.TextEditor.DocumentLocation location ) : void | ||
data | MonoDevelop | |
location | Mono.TextEditor.DocumentLocation | |
Résultat | void |
void HandleOnTheFlyFormatting(KeyDescriptor descriptor) { if (descriptor.KeyChar == '{') { return; } SafeUpdateIndentEngine(Editor.CaretOffset); bool skipFormatting = stateTracker.IsInsideOrdinaryCommentOrString; if (!skipFormatting && !(stateTracker.IsInsideComment || stateTracker.IsInsideString)) { if (DocumentContext.ParsedDocument == null || DocumentContext.ParsedDocument.GetAst <SemanticModel> () == null) { return; } var document = DocumentContext.AnalysisDocument; if (document == null) { return; } if (!skipFormatting && service.SupportsFormattingOnTypedCharacter(document, descriptor.KeyChar)) { var caretPosition = Editor.CaretOffset; var token = CSharpEditorFormattingService.GetTokenBeforeTheCaretAsync(document, caretPosition, default(CancellationToken)).Result; if (token.IsMissing || !service.ValidSingleOrMultiCharactersTokenKind(descriptor.KeyChar, token.Kind()) || token.IsKind(SyntaxKind.EndOfFileToken) || token.IsKind(SyntaxKind.None)) { return; } if (CSharpEditorFormattingService.TokenShouldNotFormatOnTypeChar(token)) { return; } using (var undo = Editor.OpenUndoGroup()) { if (OnTheFlyFormatting && Editor != null && Editor.EditMode == EditMode.Edit) { var oldVersion = Editor.Version; OnTheFlyFormatter.FormatStatmentAt(Editor, DocumentContext, Editor.CaretLocation, optionSet: optionSet); if (oldVersion.CompareAge(Editor.Version) != 0) { CompletionWindowManager.HideWindow(); } } } } } if (OnTheFlyFormatting && descriptor.SpecialKey == SpecialKey.Return) { try { FormatOnReturn(); } catch (Exception e) { LoggingService.LogError("Exception while formatting", e); } } }
public override bool KeyPress (Gdk.Key key, char keyChar, Gdk.ModifierType modifier) { bool skipFormatting = StateTracker.IsInsideOrdinaryCommentOrString || StateTracker.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) { SafeUpdateIndentEngine (textEditorData.Caret.Offset); if (stateTracker.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) { ReindentOnTab (); return false; } SafeUpdateIndentEngine (textEditorData.Caret.Offset); if (!stateTracker.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 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); } wasInStringLiteral = stateTracker.IsInsideStringLiteral; 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 ()) { SafeUpdateIndentEngine (textEditorData.Caret.Offset); 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, out reIndent); } else { reIndent = lastCharInserted == '\n'; } } //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 SafeUpdateIndentEngine (textEditorData.Caret.Offset); automaticReindent = (stateTracker.NeedsReindent && lastCharInserted != '\0'); if (key == Gdk.Key.Return && (reIndent || automaticReindent)) { if (textEditorData.Options.IndentStyle == IndentStyle.Virtual) { if (textEditorData.GetLine (textEditorData.Caret.Line).Length == 0) textEditorData.Caret.Column = textEditorData.IndentationTracker.GetVirtualIndentationColumn (textEditorData.Caret.Location); } else { DoReSmartIndent (); } } } if (reIndent || key != Gdk.Key.Return && 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); } } } } SafeUpdateIndentEngine (textEditorData.Caret.Offset); 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); if (key == Gdk.Key.Return || key == Gdk.Key.KP_Enter) { DoReSmartIndent (); } CheckXmlCommentCloseTag (keyChar); if (!skipFormatting && keyChar == '}') RunFormatter (new DocumentLocation (textEditorData.Caret.Location.Line, textEditorData.Caret.Location.Column)); return result; }
public override bool KeyPress(KeyDescriptor descriptor) { completionWindowWasVisible = CompletionWindowManager.IsVisible; cursorPositionBeforeKeyPress = Editor.CaretOffset; bool isSomethingSelected = Editor.IsSomethingSelected; if (descriptor.SpecialKey == SpecialKey.BackSpace && Editor.CaretOffset == lastInsertedSemicolon) { EditActions.Undo(Editor); lastInsertedSemicolon = -1; return(false); } lastInsertedSemicolon = -1; if (descriptor.KeyChar == ';' && Editor.EditMode == EditMode.Edit && !DoInsertTemplate() && !isSomethingSelected && PropertyService.Get( "SmartSemicolonPlacement", false ) && !(stateTracker.IsInsideComment || stateTracker.IsInsideString)) { bool retval = base.KeyPress(descriptor); var curLine = Editor.GetLine(Editor.CaretLine); string text = Editor.GetTextAt(curLine); if (!(text.EndsWith(";", StringComparison.Ordinal) || text.Trim().StartsWith("for", StringComparison.Ordinal))) { int guessedOffset; if (GuessSemicolonInsertionOffset(Editor, curLine, Editor.CaretOffset, out guessedOffset)) { using (var undo = Editor.OpenUndoGroup()) { Editor.RemoveText(Editor.CaretOffset - 1, 1); Editor.CaretOffset = guessedOffset; lastInsertedSemicolon = Editor.CaretOffset + 1; retval = base.KeyPress(descriptor); } } } using (var undo = Editor.OpenUndoGroup()) { if (OnTheFlyFormatting && Editor != null && Editor.EditMode == EditMode.Edit) { OnTheFlyFormatter.FormatStatmentAt(Editor, DocumentContext, Editor.CaretLocation, optionSet: optionSet); } } return(retval); } if (descriptor.SpecialKey == SpecialKey.Tab && descriptor.ModifierKeys == ModifierKeys.None && !CompletionWindowManager.IsVisible) { SafeUpdateIndentEngine(Editor.CaretOffset); if (stateTracker.IsInsideStringLiteral && !Editor.IsSomethingSelected) { var lexer = new ICSharpCode.NRefactory.CSharp.Completion.CSharpCompletionEngineBase.MiniLexer(Editor.GetTextAt(0, Editor.CaretOffset)); lexer.Parse(); if (lexer.IsInString) { Editor.InsertAtCaret("\\t"); return(false); } } } if (descriptor.SpecialKey == SpecialKey.Tab && DefaultSourceEditorOptions.Instance.TabIsReindent && !CompletionWindowManager.IsVisible && Editor.EditMode == EditMode.Edit && !DoInsertTemplate() && !isSomethingSelected) { ReindentOnTab(); return(false); } SafeUpdateIndentEngine(Editor.CaretOffset); if (!stateTracker.IsInsideOrdinaryCommentOrString) { if (descriptor.KeyChar == '@') { var retval = base.KeyPress(descriptor); int cursor = Editor.CaretOffset; if (cursor < Editor.Length && Editor.GetCharAt(cursor) == '"') { ConvertNormalToVerbatimString(Editor, cursor + 1); } return(retval); } } //do the smart indent if (!indentationDisabled) { bool retval; //capture some of the current state int oldBufLen = Editor.Length; int oldLine = Editor.CaretLine + 1; bool reIndent = false; //pass through to the base class, which actually inserts the character //and calls HandleCodeCompletion etc to handles completion using (var undo = Editor.OpenUndoGroup()) { DoPreInsertionSmartIndent(descriptor.SpecialKey); } wasInStringLiteral = stateTracker.IsInsideStringLiteral; bool returnBetweenBraces = descriptor.SpecialKey == SpecialKey.Return && descriptor.ModifierKeys == ModifierKeys.None && Editor.CaretOffset > 0 && Editor.CaretOffset < Editor.Length && Editor.GetCharAt(Editor.CaretOffset - 1) == '{' && Editor.GetCharAt(Editor.CaretOffset) == '}' && !stateTracker.IsInsideOrdinaryCommentOrString; 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(descriptor); if (descriptor.KeyChar == '/' && stateTracker.IsInsideMultiLineComment) { if (Editor.CaretOffset - 3 >= 0 && Editor.GetCharAt(Editor.CaretOffset - 3) == '*' && Editor.GetCharAt(Editor.CaretOffset - 2) == ' ') { using (var undo = Editor.OpenUndoGroup()) { Editor.RemoveText(Editor.CaretOffset - 2, 1); } } } //handle inserted characters if (Editor.CaretOffset <= 0 || Editor.IsSomethingSelected) { return(retval); } lastCharInserted = TranslateKeyCharForIndenter(descriptor.SpecialKey, descriptor.KeyChar, Editor.GetCharAt(Editor.CaretOffset - 1)); if (lastCharInserted == '\0') { return(retval); } using (var undo = Editor.OpenUndoGroup()) { if (returnBetweenBraces) { var oldOffset = Editor.CaretOffset; Editor.InsertAtCaret(Editor.EolMarker); DoReSmartIndent(); Editor.CaretOffset = oldOffset; } SafeUpdateIndentEngine(Editor.CaretOffset); if (descriptor.SpecialKey == SpecialKey.Return && descriptor.ModifierKeys == ModifierKeys.Control) { FixLineStart(Editor, stateTracker, Editor.CaretLine + 1); } else { if (!(oldLine == Editor.CaretLine + 1 && lastCharInserted == '\n') && (oldBufLen != Editor.Length || lastCharInserted != '\0')) { DoPostInsertionSmartIndent(lastCharInserted, out reIndent); } else { reIndent = lastCharInserted == '\n'; } } //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 SafeUpdateIndentEngine(Editor.CaretOffset); // Automatically reindent in text link mode will cause the mode exiting, therefore we need to prevent that. automaticReindent = (stateTracker.NeedsReindent && lastCharInserted != '\0') && Editor.EditMode == EditMode.Edit; if (descriptor.SpecialKey == SpecialKey.Return && (reIndent || automaticReindent)) { if (Editor.Options.IndentStyle == IndentStyle.Virtual) { if (Editor.GetLine(Editor.CaretLine).Length == 0) { Editor.CaretColumn = Editor.GetVirtualIndentationColumn(Editor.CaretLine); } } else { DoReSmartIndent(); } } } const string reindentChars = ";){}"; if (reIndent || descriptor.SpecialKey != SpecialKey.Return && descriptor.SpecialKey != SpecialKey.Tab && automaticReindent && reindentChars.Contains(descriptor.KeyChar)) { using (var undo = Editor.OpenUndoGroup()) { DoReSmartIndent(); } } HandleOnTheFlyFormatting(descriptor); SafeUpdateIndentEngine(Editor.CaretOffset); lastCharInserted = '\0'; CheckXmlCommentCloseTag(descriptor.KeyChar); return(retval); } if (Editor.Options.IndentStyle == IndentStyle.Auto && DefaultSourceEditorOptions.Instance.TabIsReindent && descriptor.SpecialKey == SpecialKey.Tab) { bool retval = base.KeyPress(descriptor); DoReSmartIndent(); CheckXmlCommentCloseTag(descriptor.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(descriptor); if (!indentationDisabled && (descriptor.SpecialKey == SpecialKey.Return)) { DoReSmartIndent(); } CheckXmlCommentCloseTag(descriptor.KeyChar); HandleOnTheFlyFormatting(descriptor); return(result); }