public override bool Handle (TextEditor editor, DocumentContext ctx, KeyDescriptor descriptor) { char closingBrace; if (!IsSupportedOpeningBrace (descriptor.KeyChar, out closingBrace) || !CheckCodeContext (editor, ctx, editor.CaretOffset - 1, descriptor.KeyChar, default (CancellationToken))) return false; var session = CreateEditorSession (editor, ctx, editor.CaretOffset, descriptor.KeyChar, default (CancellationToken)); session.SetEditor (editor); if (session == null | !((ICheckPointEditSession)session).CheckOpeningPoint (editor, ctx, default (CancellationToken))) return false; using (var undo = editor.OpenUndoGroup ()) { editor.EnsureCaretIsNotVirtual (); editor.InsertAtCaret (closingBrace.ToString ()); editor.CaretOffset--; editor.StartSession (session); } return true; }
public bool FixLineStart (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 (); textEditorData.InsertText (prevLine.Offset + prevLine.Length, "\" +"); int indentSize = textEditorData.CaretOffset - line.Offset; var insertedText = prevLine.GetIndentation (textEditorData) + (trimmedPreviousLine.StartsWith ("\"", StringComparison.Ordinal) ? "" : "\t") + "\""; textEditorData.ReplaceText (line.Offset, indentSize, insertedText); return true; } } return false; }
public override bool Handle (TextEditor editor, DocumentContext ctx, KeyDescriptor descriptor) { int braceIndex = openBrackets.IndexOf (descriptor.KeyChar); if (braceIndex < 0) return false; var extEditor = ((SourceEditorView)editor.Implementation).SourceEditorWidget.TextEditor; var line = extEditor.Document.GetLine (extEditor.Caret.Line); if (line == null) return false; bool inStringOrComment = false; var stack = line.StartSpan.Clone (); var sm = extEditor.Document.SyntaxMode as SyntaxMode; if (sm != null) // extEditor.Caret.Offset - 1 means we care if we were inside string // before typing current char Mono.TextEditor.Highlighting.SyntaxModeService.ScanSpans (extEditor.Document, sm, sm, stack, line.Offset, extEditor.Caret.Offset - 1); foreach (var span in stack) { if (string.IsNullOrEmpty (span.Color)) continue; if (span.Color.StartsWith ("String", StringComparison.Ordinal) || span.Color.StartsWith ("Comment", StringComparison.Ordinal) || span.Color.StartsWith ("Xml Attribute Value", StringComparison.Ordinal)) { inStringOrComment = true; break; } } char insertionChar = '\0'; bool insertMatchingBracket = false; if (!inStringOrComment) { char closingBrace = closingBrackets [braceIndex]; char openingBrace = openBrackets [braceIndex]; int count = 0; foreach (char curCh in ExtensibleTextEditor.GetTextWithoutCommentsAndStrings(extEditor.Document, 0, extEditor.Document.TextLength)) { if (curCh == openingBrace) { count++; } else if (curCh == closingBrace) { count--; } } if (count >= 0) { insertMatchingBracket = true; insertionChar = closingBrace; } } if (insertMatchingBracket) { using (var undo = editor.OpenUndoGroup ()) { editor.EnsureCaretIsNotVirtual (); editor.InsertAtCaret (insertionChar.ToString ()); editor.CaretOffset--; editor.StartSession (new SkipCharSession (insertionChar)); } return true; } return false; }