/// <summary> /// When a " is typed, insert another ". /// </summary> private bool OnQuoteTyped(ITypingContext context) { ITextControl textControl = context.TextControl; // the " character should be skipped to avoid double insertions if (_skippingTypingAssist.ShouldSkip(textControl.Document, context.Char)) { _skippingTypingAssist.SkipIfNeeded(textControl.Document, context.Char); return(true); } // get the token type after " CachingLexer cachingLexer = GetCachingLexer(textControl); int offset = textControl.Selection.OneDocRangeWithCaret().GetMinOffset(); if (cachingLexer == null || offset <= 0 || !cachingLexer.FindTokenAt(offset)) { return(false); } // there is already another quote after the ", swallow the typing TokenNodeType tokenType = cachingLexer.TokenType; if (tokenType == T4TokenNodeTypes.Quote) { textControl.Caret.MoveTo(offset + 1, CaretVisualPlacement.DontScrollIfVisible); return(true); } // we're inside or after an attribute value, simply do nothing and let the " be typed if (tokenType == T4TokenNodeTypes.Value) { return(false); } // insert the first " TextControlUtil.DeleteSelection(textControl); textControl.FillVirtualSpaceUntilCaret(); textControl.Document.InsertText(offset, "\""); // insert the second " context.QueueCommand(() => { using (CommandProcessor.UsingCommand("Inserting \"")) { textControl.Document.InsertText(offset + 1, "\""); textControl.Caret.MoveTo(offset + 1, CaretVisualPlacement.DontScrollIfVisible); } // ignore if a subsequent " is typed by the user _skippingTypingAssist.SetCharsToSkip(textControl.Document, "\""); // popup auto completion _codeCompletionSessionManager.ExecuteAutoCompletion <T4AutopopupSettingsKey>(textControl, Solution, key => key.InDirectives); }); return(true); }
private bool HandleColonTyped(ITypingContext typingContext) { ITextControl textControl = typingContext.TextControl; if (typingContext.EnsureWritable() != EnsureWritableResult.SUCCESS) { return(false); } using (CommandProcessor.UsingCommand("Smart :")) { TextControlUtil.DeleteSelection(textControl); textControl.FillVirtualSpaceUntilCaret(); int charPos = TextControlToLexer(textControl, textControl.Caret.Offset()); CachingLexer lexer = GetCachingLexer(textControl); if (charPos < 0 || !lexer.FindTokenAt(charPos) || lexer.TokenStart != charPos || lexer.TokenType != PsiTokenType.COLON) { typingContext.CallNext(); } else { int position = charPos + 1; if (position < 0) { return(true); } textControl.Caret.MoveTo(position, CaretVisualPlacement.DontScrollIfVisible); } if (NeedAutoinsertSemicolon(textControl)) { if (typingContext.EnsureWritable() != EnsureWritableResult.SUCCESS) { return(true); } char c = typingContext.Char; int insertPos = charPos; if (insertPos >= 0) { textControl.Document.InsertText(insertPos + 1, ";"); textControl.Caret.MoveTo(insertPos + 1, CaretVisualPlacement.DontScrollIfVisible); } // format statement if (GetTypingAssistOption(textControl, TypingAssistOptions.FormatStatementOnSemicolonExpression)) { DoFormatStatementOnColon(textControl); } } return(true); } }
/// <summary> /// When = is typed, insert "". /// </summary> private bool OnEqualTyped(ITypingContext context) { ITextControl textControl = context.TextControl; // get the token type before = CachingLexer cachingLexer = GetCachingLexer(textControl); int offset = textControl.Selection.OneDocRangeWithCaret().GetMinOffset(); if (cachingLexer == null || offset <= 0 || !cachingLexer.FindTokenAt(offset - 1)) { return(false); } // do nothing if we're not after an attribute name TokenNodeType tokenType = cachingLexer.TokenType; if (tokenType != T4TokenNodeTypes.Name) { return(false); } // insert = TextControlUtil.DeleteSelection(textControl); textControl.FillVirtualSpaceUntilCaret(); textControl.Document.InsertText(offset, "="); textControl.Caret.MoveTo(offset + 1, CaretVisualPlacement.DontScrollIfVisible); // insert "" context.QueueCommand(() => { using (CommandProcessor.UsingCommand("Inserting \"\"")) { textControl.Document.InsertText(offset + 1, "\"\""); textControl.Caret.MoveTo(offset + 2, CaretVisualPlacement.DontScrollIfVisible); } // ignore if a subsequent " is typed by the user _skippingTypingAssist.SetCharsToSkip(textControl.Document, "\""); // popup auto completion _codeCompletionSessionManager.ExecuteAutoCompletion <T4AutopopupSettingsKey>(textControl, Solution, key => key.InDirectives); }); return(true); }
private bool HandleRightBracketTyped(ITypingContext typingContext) { ITextControl textControl = typingContext.TextControl; if (typingContext.EnsureWritable() != EnsureWritableResult.SUCCESS) { return(false); } using (CommandProcessor.UsingCommand("Smart bracket")) { TextControlUtil.DeleteSelection(textControl); int charPos = TextControlToLexer(textControl, textControl.Caret.Offset()); CachingLexer lexer = GetCachingLexer(textControl); if (charPos < 0 || !lexer.FindTokenAt(charPos) || lexer.TokenStart != charPos) { return(false); } if (NeedSkipCloseBracket(lexer, typingContext.Char)) { int position = charPos + 1; if (position >= 0) { textControl.Caret.MoveTo(position, CaretVisualPlacement.DontScrollIfVisible); } } else { typingContext.CallNext(); } } return(true); }
private bool HandleQuoteTyped(ITypingContext typingContext) { ITextControl textControl = typingContext.TextControl; if (typingContext.EnsureWritable() != EnsureWritableResult.SUCCESS) { return(false); } using (CommandProcessor.UsingCommand("Smart quote")) { TextControlUtil.DeleteSelection(textControl); textControl.FillVirtualSpaceUntilCaret(); CachingLexer lexer = GetCachingLexer(textControl); IBuffer buffer = lexer.Buffer; int charPos = TextControlToLexer(textControl, textControl.Caret.Offset()); TokenNodeType correspondingTokenType = PsiTokenType.STRING_LITERAL; if (charPos < 0 || !lexer.FindTokenAt(charPos)) { return(false); } TokenNodeType tokenType = lexer.TokenType; // check if we should skip the typed char if (charPos < buffer.Length && buffer[charPos] == typingContext.Char && tokenType == correspondingTokenType && lexer.TokenStart != charPos && buffer[lexer.TokenStart] != '@') { int position = charPos; if (position >= 0) { textControl.Caret.MoveTo(position + 1, CaretVisualPlacement.DontScrollIfVisible); } return(true); } // check that next token is a good one if (tokenType != null && !IsStopperTokenForStringLiteral(tokenType)) { return(false); } // find next not whitespace token while (lexer.TokenType == PsiTokenType.WHITE_SPACE) { lexer.Advance(); } bool doInsertPairQuote = (lexer.TokenType == correspondingTokenType) && ((lexer.TokenEnd > lexer.TokenStart + 1) && (lexer.Buffer[lexer.TokenStart] == typingContext.Char) && (lexer.Buffer[lexer.TokenEnd - 1] == typingContext.Char)); // do inserting of the requested char and updating of the lexer typingContext.CallNext(); lexer = GetCachingLexer(textControl); // charPos = TextControlToLexer(textControl, textControl.CaretModel.Offset - 1); if (!doInsertPairQuote) { // check if the typed char is the beginning of the corresponding token if (!lexer.FindTokenAt(charPos)) { return(true); } bool isStringWithAt = lexer.TokenType == PsiTokenType.STRING_LITERAL && lexer.TokenStart == charPos - 1 && lexer.Buffer[lexer.TokenStart] == '@'; if ((lexer.TokenStart != charPos) && !isStringWithAt) { return(true); } // check if there is unclosed token of the corresponding type up to the end of the source line int newPos = charPos; if (newPos < 0) { return(true); } DocumentCoords documentCoords = textControl.Document.GetCoordsByOffset(newPos); int offset = textControl.Document.GetLineEndOffsetNoLineBreak(documentCoords.Line) - 1; int lexerOffset = TextControlToLexer(textControl, offset); if (lexerOffset >= 0) { lexer.FindTokenAt(lexerOffset); } if (lexerOffset < 0 || lexer.TokenType == null) { charPos = TextControlToLexer(textControl, textControl.Caret.Offset() - 1); if (charPos >= 0) { lexer.FindTokenAt(charPos); } else { return(true); } } doInsertPairQuote = (lexer.TokenType == correspondingTokenType) && ((lexer.TokenEnd == lexer.TokenStart + 1) || (lexer.Buffer[lexer.TokenEnd - 1] != typingContext.Char) || (isStringWithAt && (lexer.TokenStart == charPos - 1) && (lexer.TokenEnd != charPos + 1))); } // insert paired quote if (doInsertPairQuote) { charPos++; int documentPos = charPos; if (documentPos >= 0) { textControl.Document.InsertText(documentPos, typingContext.Char == '\'' ? "'" : "\""); textControl.Caret.MoveTo(documentPos, CaretVisualPlacement.DontScrollIfVisible); } } } return(true); }