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 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 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 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);
        }