private bool OnDollarTyped(ITypingContext context) { var textControl = context.TextControl; if (!IsInAttributeValue(textControl)) { return(false); } int offset = textControl.GetOffset(); textControl.Selection.Delete(); textControl.Document.InsertText(offset, "$"); textControl.Caret.MoveTo(offset + 1, CaretVisualPlacement.DontScrollIfVisible); context.QueueCommand(() => { using (CommandProcessor.UsingCommand("Inserting T4 Macro Parenthesis")) { textControl.Document.InsertText(offset + 1, "()"); textControl.Caret.MoveTo(offset + 2, CaretVisualPlacement.DontScrollIfVisible); } SkippingTypingAssist.SetCharsToSkip(textControl.Document, "("); }); return(true); }
private static bool HandleBrace(ITypingContext context) { // var document = context.TextControl.Document; // var line = context.TextControl.Caret.PositionValue.ToDocLineColumn().Line; context.TextControl.Document.InsertText(context.TextControl.Caret.Offset(), "{//test"); return true; }
private bool HandleLeftBraceTyped(ITypingContext typingContext) { ITextControl textControl = typingContext.TextControl; using (CommandProcessor.UsingCommand("Smart LBRACE")) { typingContext.CallNext(); // check if typed char is a token int charPos = TextControlToLexer(textControl, textControl.Caret.Offset() - 1); CachingLexer lexer = GetCachingLexer(textControl); if (charPos < 0 || !lexer.FindTokenAt(charPos) || lexer.TokenStart != charPos) { return(true); } if (NeedAutoinsertCloseBracket(lexer)) { if (typingContext.EnsureWritable() != EnsureWritableResult.SUCCESS) { return(true); } AutoinsertRBrace(textControl, lexer); int position = charPos + 1; if (position >= 0) { textControl.Caret.MoveTo(position, CaretVisualPlacement.DontScrollIfVisible); } } } return(true); }
private bool OnClosingParenthesisTyped([NotNull] ITypingContext context) { var textControl = context.TextControl; if (!IsInAttributeValue(textControl)) { return(false); } // Get the token type after caret var lexer = GetCachingLexer(textControl); int offset = textControl.Selection.OneDocRangeWithCaret().GetMinOffset(); if (lexer == null || offset <= 0 || !lexer.FindTokenAt(offset)) { return(false); } var tokenType = lexer.TokenType; // If it's not a parenthesis, we don't care, so let the IDE handle it if (tokenType != T4TokenNodeTypes.RIGHT_PARENTHESIS) { return(false); } // If it is, over-type it textControl.Caret.MoveTo(offset + 1, CaretVisualPlacement.DontScrollIfVisible); return(true); }
/// <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); } }
private bool HandleLeftBracketOrParenthTyped(ITypingContext typingContext) { ITextControl textControl = typingContext.TextControl; using (CommandProcessor.UsingCommand("Smart " + typingContext.Char)) { typingContext.CallNext(); using (WriteLockCookie.Create()) { // check if typed char is a token CachingLexer lexer = GetCachingLexer(textControl); int charPos = TextControlToLexer(textControl, textControl.Caret.Offset() - 1); if (charPos < 0 || !lexer.FindTokenAt(charPos) || lexer.TokenStart != charPos) { return(true); } if (lexer.TokenType != PsiTokenType.LBRACKET && lexer.TokenType != PsiTokenType.LPARENTH) { return(true); } // check that next token is good one TokenNodeType nextTokenType = lexer.LookaheadToken(1); if (nextTokenType != null && nextTokenType != PsiTokenType.WHITE_SPACE && nextTokenType != PsiTokenType.NEW_LINE && nextTokenType != PsiTokenType.C_STYLE_COMMENT && nextTokenType != PsiTokenType.END_OF_LINE_COMMENT && nextTokenType != PsiTokenType.SEMICOLON && nextTokenType != PsiTokenType.RBRACKET && nextTokenType != PsiTokenType.RBRACE && nextTokenType != PsiTokenType.RPARENTH) { return(true); } if (NeedAutoinsertCloseBracket(lexer)) { if (typingContext.EnsureWritable() != EnsureWritableResult.SUCCESS) { return(true); } char c = typingContext.Char; int insertPos = charPos; if (insertPos >= 0) { textControl.Document.InsertText(insertPos + 1, c == '(' ? ")" : c == '[' ? "]" : "}"); textControl.Caret.MoveTo(insertPos + 1, CaretVisualPlacement.DontScrollIfVisible); } } } } return(true); }
private bool WrapCppAction(ITypingContext typingContext, Func <ITypingContext, bool> handleLeftBraceTyped) { if (!FindCgContent(typingContext.TextControl, out var lexer)) { return(false); } if (lexer.TokenType is CppTokenNodeType) { return(handleLeftBraceTyped(typingContext)); } return(false); }
/// <summary>When a # is typed, complete code block</summary> private bool OnOctothorpeTyped(ITypingContext context) { if (IsInsertingBlockStart(context)) { InsertBlock(context); return(true); } if (IsInsertingBlockEnd(context)) { InsertBlockEnd(context); return(true); } return(false); }
/// <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.TOKEN) { return(false); } // insert = textControl.Selection.Delete(); 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 void InsertBlockEnd([NotNull] ITypingContext context) { var textControl = context.TextControl; int offset = textControl.GetOffset(); InsertOctothorpe(textControl); context.QueueCommand(() => { using (CommandProcessor.UsingCommand("Inserting >")) { textControl.Document.InsertText(offset + 1, ">"); textControl.Caret.MoveTo(offset + 2, CaretVisualPlacement.DontScrollIfVisible); } SkippingTypingAssist.SetCharsToSkip(textControl.Document, ">"); }); }
// When '%' is typed, insert another private bool OnPercentTyped(ITypingContext context) { var textControl = context.TextControl; if (!IsInAttributeValue(textControl)) { return(false); } // get the token type after % var lexer = GetCachingLexer(textControl); int offset = textControl.Selection.OneDocRangeWithCaret().GetMinOffset(); if (lexer == null || offset <= 0 || !lexer.FindTokenAt(offset)) { return(false); } // If there is already another percent after the %, swallow the typing var tokenType = lexer.TokenType; if (tokenType == T4TokenNodeTypes.PERCENT) { textControl.Caret.MoveTo(offset + 1, CaretVisualPlacement.DontScrollIfVisible); return(true); } // insert the first % textControl.Selection.Delete(); 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); } }); return(true); }
private bool IsInsertingBlockStart([NotNull] ITypingContext context) { var textControl = context.TextControl; var lexer = GetCachingLexer(textControl); if (lexer == null) { return(false); } int offset = textControl.GetOffset(); if (!lexer.FindTokenAt(offset - 1)) { return(false); } string tokenText = lexer.GetTokenText(); return(tokenText.EndsWith("<", StringComparison.Ordinal) && !tokenText.EndsWith("\\<", StringComparison.Ordinal)); }
private bool OnQuoteTyped([NotNull] ITypingContext context) { var textControl = context.TextControl; var cachingLexer = GetCachingLexer(textControl); int offset = textControl.Selection.OneDocRangeWithCaret().GetMinOffset(); if (cachingLexer == null || offset <= 0 || !cachingLexer.FindTokenAt(offset)) { return(false); } var tokenType = cachingLexer.TokenType; // C# is handled by T4CSharpTypingAssist. Text tokens are handled by the platform if (tokenType is ICSharpTokenNodeType || tokenType == T4TokenNodeTypes.RAW_TEXT) { return(false); } // The second quote has already been inserted. Over-type it if (tokenType == T4TokenNodeTypes.QUOTE) { textControl.Caret.MoveTo(offset + 1, CaretVisualPlacement.DontScrollIfVisible); return(true); } // insert the first quote textControl.Selection.Delete(); textControl.FillVirtualSpaceUntilCaret(); textControl.Document.InsertText(offset, "\""); // insert the second quote using (CommandProcessor.UsingCommand("Smart quote in T4")) { textControl.Document.InsertText(offset + 1, "\""); textControl.Caret.MoveTo(offset + 1, CaretVisualPlacement.DontScrollIfVisible); } _codeCompletionSessionManager.ExecuteAutoCompletion <T4AutopopupSettingsKey>(textControl, Solution, key => key.InDirectives); return(true); }
private bool IsInsertingBlockEnd([NotNull] ITypingContext context) { var textControl = context.TextControl; var lexer = GetCachingLexer(textControl); if (lexer == null) { return(false); } int offset = textControl.GetOffset(); var previousToken = FindPreviousToken(GetCachingLexer(textControl), offset); switch (previousToken) { case null: case T4TokenNodeType _: return(false); default: 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); }