diff --git a/src/libs/cplusplus/MatchingText.cpp b/src/libs/cplusplus/MatchingText.cpp
index 0ae26f5b1229ee8369a1f5ddf7c3d3bf66683f81..0ee23ac4e8837b34110245c656aef49d1b93f80e 100644
--- a/src/libs/cplusplus/MatchingText.cpp
+++ b/src/libs/cplusplus/MatchingText.cpp
@@ -109,7 +109,7 @@ QString MatchingText::insertMatchingBrace(const QTextCursor &cursor, const QStri
     QTextDocument *doc = tc.document();
     QString text = textToProcess;
 
-    const QString blockText = tc.block().text().mid(tc.columnNumber());
+    const QString blockText = tc.block().text().mid(tc.positionInBlock());
     const int length = qMin(blockText.length(), textToProcess.length());
 
     const QChar previousChar = doc->characterAt(tc.selectionEnd() - 1);
@@ -219,7 +219,7 @@ QString MatchingText::insertParagraphSeparator(const QTextCursor &tc) const
     if (tk[index - 1].isNot(T_LBRACE))
         return QString(); // nothing to do.
 
-    const QString textBlock = tc.block().text().mid(tc.columnNumber()).trimmed();
+    const QString textBlock = tc.block().text().mid(tc.positionInBlock()).trimmed();
     if (! textBlock.isEmpty())
         return QString();
 
diff --git a/src/plugins/cppeditor/cppeditor.cpp b/src/plugins/cppeditor/cppeditor.cpp
index f68f3286d4141899a31e4d8064de7175a4abfcff..19c92b21a76e718d116fa1e5cdc2653e3bd702ed 100644
--- a/src/plugins/cppeditor/cppeditor.cpp
+++ b/src/plugins/cppeditor/cppeditor.cpp
@@ -1421,6 +1421,37 @@ bool CPPEditor::contextAllowsAutoParentheses(const QTextCursor &cursor,
     return true;
 }
 
+bool CPPEditor::contextAllowsElectricCharacters(const QTextCursor &cursor) const
+{
+    const SimpleToken tk = tokenCache()->tokenUnderCursor(cursor);
+
+    // XXX Duplicated from CPPEditor::isInComment to avoid tokenizing twice
+    if (tk.isComment()) {
+        const int pos = cursor.selectionEnd() - cursor.block().position();
+
+        if (pos == tk.end()) {
+            if (tk.is(T_CPP_COMMENT) || tk.is(T_CPP_DOXY_COMMENT))
+                return false;
+
+            const int state = cursor.block().userState() & 0xFF;
+            if (state > 0)
+                return false;
+        }
+
+        if (pos < tk.end())
+            return false;
+    }
+    else if (tk.is(T_STRING_LITERAL) || tk.is(T_WIDE_STRING_LITERAL)
+        || tk.is(T_CHAR_LITERAL) || tk.is(T_WIDE_CHAR_LITERAL)) {
+
+        const int pos = cursor.selectionEnd() - cursor.block().position();
+        if (pos <= tk.end())
+            return false;
+    }
+
+    return true;
+}
+
 bool CPPEditor::isInComment(const QTextCursor &cursor) const
 {
     const SimpleToken tk = tokenCache()->tokenUnderCursor(cursor);
@@ -1557,7 +1588,7 @@ void CPPEditor::contextMenuEvent(QContextMenuEvent *e)
     // ### enable
     // updateSemanticInfo(m_semanticHighlighter->semanticInfo(currentSource()));
 
-    QMenu *menu = new QMenu();
+    QMenu *menu = new QMenu;
 
     Core::ActionManager *am = Core::ICore::instance()->actionManager();
     Core::ActionContainer *mcontext = am->actionContainer(CppEditor::Constants::M_CONTEXT);
diff --git a/src/plugins/cppeditor/cppeditor.h b/src/plugins/cppeditor/cppeditor.h
index 2ecba1e0760d07c7757408893cb5bc3caea98d2f..54dce843a5b905bcf97be3f11858f086e763557d 100644
--- a/src/plugins/cppeditor/cppeditor.h
+++ b/src/plugins/cppeditor/cppeditor.h
@@ -231,6 +231,7 @@ protected:
 
     virtual bool contextAllowsAutoParentheses(const QTextCursor &cursor,
                                               const QString &textToInsert = QString()) const;
+    virtual bool contextAllowsElectricCharacters(const QTextCursor &cursor) const;
 
     virtual bool isInComment(const QTextCursor &cursor) const;
 
diff --git a/src/plugins/debugger/watchutils.cpp b/src/plugins/debugger/watchutils.cpp
index 7dd096a85b2e5268b252b95bc0242810faa5a800..9c8ed75979bfd0bfe1c6de22cd68b2d3e7a9d281 100644
--- a/src/plugins/debugger/watchutils.cpp
+++ b/src/plugins/debugger/watchutils.cpp
@@ -748,11 +748,11 @@ QString cppExpressionAt(TextEditor::ITextEditor *editor, int pos,
         // Fetch the expression's code.
         CPlusPlus::ExpressionUnderCursor expressionUnderCursor(modelManager->tokenCache(editor));
         expr = expressionUnderCursor(tc);
-        *column = tc.columnNumber();
+        *column = tc.positionInBlock();
         *line = tc.blockNumber();
     } else {
         const QTextCursor tc = plaintext->textCursor();
-        *column = tc.columnNumber();
+        *column = tc.positionInBlock();
         *line = tc.blockNumber();
     }
 
diff --git a/src/plugins/fakevim/fakevimhandler.cpp b/src/plugins/fakevim/fakevimhandler.cpp
index 8d039d9486eeb9e5f0563a3c060f1e12f9679642..27c7c48a649d4a8d421e6fbd9fd0fb44cb1bbef1 100644
--- a/src/plugins/fakevim/fakevimhandler.cpp
+++ b/src/plugins/fakevim/fakevimhandler.cpp
@@ -1464,8 +1464,8 @@ void FakeVimHandler::Private::updateSelection()
         } else if (isVisualBlockMode()) {
             QTextCursor tc = m_tc;
             tc.setPosition(anchorPos);
-            int anchorColumn = tc.columnNumber();
-            int cursorColumn = m_tc.columnNumber();
+            int anchorColumn = tc.positionInBlock();
+            int cursorColumn = m_tc.positionInBlock();
             int anchorRow    = tc.blockNumber();
             int cursorRow    = m_tc.blockNumber();
             int startColumn  = qMin(anchorColumn, cursorColumn);
diff --git a/src/plugins/qmlinspector/components/expressionquerywidget.cpp b/src/plugins/qmlinspector/components/expressionquerywidget.cpp
index 4aa2f1b7c9b871070737a9268b86048aa6f36569..830ce28756404b5397653ae3de2855a366379a7e 100644
--- a/src/plugins/qmlinspector/components/expressionquerywidget.cpp
+++ b/src/plugins/qmlinspector/components/expressionquerywidget.cpp
@@ -283,7 +283,7 @@ bool ExpressionQueryWidget::eventFilter(QObject *obj, QEvent *event)
                     bool atLastLine = !(cursor.block().next().isValid());
                     if (!atLastLine)
                         return true;
-                    if (cursor.columnNumber() <= m_prompt.count())
+                    if (cursor.positionInBlock() <= m_prompt.count())
                         return true;
                     cursor.deletePreviousChar();
                     m_expr = cursor.block().text().mid(m_prompt.count());
diff --git a/src/plugins/qmljseditor/qmlexpressionundercursor.cpp b/src/plugins/qmljseditor/qmlexpressionundercursor.cpp
index d5a82a5eccbf30d308e895a7714ebaad09286095..d6b2604eb4f3e73bf119436892b84704ba450785 100644
--- a/src/plugins/qmljseditor/qmlexpressionundercursor.cpp
+++ b/src/plugins/qmljseditor/qmlexpressionundercursor.cpp
@@ -102,7 +102,7 @@ public:
         _cursor = cursor;
 
         QTextBlock block = _cursor.block();
-        const QString blockText = block.text().left(cursor.columnNumber());
+        const QString blockText = block.text().left(cursor.positionInBlock());
 
         scanner.setScanComments(false);
         const QList<Token> tokens = scanner(blockText, startState(block));
diff --git a/src/plugins/qmljseditor/qmljscodecompletion.cpp b/src/plugins/qmljseditor/qmljscodecompletion.cpp
index c99696474478297ab83abcd11bcde027d010a25c..1c5e80fcabd71bd0d6b0a97e87c24c76e785d659 100644
--- a/src/plugins/qmljseditor/qmljscodecompletion.cpp
+++ b/src/plugins/qmljseditor/qmljscodecompletion.cpp
@@ -523,7 +523,7 @@ bool CodeCompletion::triggersCompletion(TextEditor::ITextEditable *editor)
 
             QTextCursor tc = ed->textCursor();
             QTextBlock block = tc.block();
-            const int column = tc.columnNumber();
+            const int column = tc.positionInBlock();
             const int blockState = qMax(0, block.previous().userState()) & 0xff;
             const QString blockText = block.text();
 
diff --git a/src/plugins/qmljseditor/qmljseditor.cpp b/src/plugins/qmljseditor/qmljseditor.cpp
index c730c616406376a008ed00bbef426c985ccca9e5..e87b91b1992f03f5f16027ee04b9b6c293033a19 100644
--- a/src/plugins/qmljseditor/qmljseditor.cpp
+++ b/src/plugins/qmljseditor/qmljseditor.cpp
@@ -1103,6 +1103,34 @@ static bool isCompleteStringLiteral(const QStringRef &text)
     return false;
 }
 
+static Token tokenUnderCursor(const QTextCursor &cursor)
+{
+    const QString blockText = cursor.block().text();
+    const int blockState = blockStartState(cursor.block());
+
+    Scanner tokenize;
+    const QList<Token> tokens = tokenize(blockText, blockState);
+    const int pos = cursor.positionInBlock();
+
+    int tokenIndex = 0;
+    for (; tokenIndex < tokens.size(); ++tokenIndex) {
+        const Token &token = tokens.at(tokenIndex);
+
+        if (token.is(Token::Comment) || token.is(Token::String)) {
+            if (pos > token.begin() && pos <= token.end())
+                break;
+        } else {
+            if (pos >= token.begin() && pos < token.end())
+                break;
+        }
+    }
+
+    if (tokenIndex != tokens.size())
+        return tokens.at(tokenIndex);
+
+    return Token();
+}
+
 bool QmlJSTextEditor::contextAllowsAutoParentheses(const QTextCursor &cursor, const QString &textToInsert) const
 {
     QChar ch;
@@ -1132,56 +1160,45 @@ bool QmlJSTextEditor::contextAllowsAutoParentheses(const QTextCursor &cursor, co
         return false;
     } // end of switch
 
-    const QString blockText = cursor.block().text();
-    const int blockState = blockStartState(cursor.block());
+    const Token token = tokenUnderCursor(cursor);
+    switch (token.kind) {
+    case Token::Comment:
+        return false;
 
-    Scanner tokenize;
-    const QList<Token> tokens = tokenize(blockText, blockState);
-    const int pos = cursor.columnNumber();
+    case Token::String: {
+        const QString blockText = cursor.block().text();
+        const QStringRef tokenText = blockText.midRef(token.offset, token.length);
+        const QChar quote = tokenText.at(0);
 
-    int tokenIndex = 0;
-    for (; tokenIndex < tokens.size(); ++tokenIndex) {
-        const Token &token = tokens.at(tokenIndex);
-
-        if (pos >= token.begin()) {
-            if (pos < token.end())
-                break;
+        if (ch != quote || isCompleteStringLiteral(tokenText))
+            break;
 
-            else if (pos == token.end() && (token.is(Token::Comment) ||
-                                            token.is(Token::String)))
-                break;
-        }
+        return false;
     }
 
-    if (tokenIndex != tokens.size()) {
-        const Token &token = tokens.at(tokenIndex);
-
-        switch (token.kind) {
-        case Token::Comment:
-            return false;
-
-        case Token::String: {
-            const QStringRef tokenText = blockText.midRef(token.offset, token.length);
-            const QChar quote = tokenText.at(0);
-
-            if (ch != quote || isCompleteStringLiteral(tokenText))
-                break;
+    default:
+        break;
+    } // end of switch
 
-            return false;
-        }
+    return true;
+}
 
-        default:
-            break;
-        } // end of switch
+bool QmlJSTextEditor::contextAllowsElectricCharacters(const QTextCursor &cursor) const
+{
+    Token token = tokenUnderCursor(cursor);
+    qDebug() << cursor.positionInBlock() << token.begin() << token.end();
+    switch (token.kind) {
+    case Token::Comment:
+    case Token::String:
+        return false;
+    default:
+        return true;
     }
-
-    return true;
 }
 
-bool QmlJSTextEditor::isInComment(const QTextCursor &) const
+bool QmlJSTextEditor::isInComment(const QTextCursor &cursor) const
 {
-    // ### implement me
-    return false;
+    return tokenUnderCursor(cursor).is(Token::Comment);
 }
 
 QString QmlJSTextEditor::insertMatchingBrace(const QTextCursor &tc, const QString &text, QChar, int *skippedChars) const
diff --git a/src/plugins/qmljseditor/qmljseditor.h b/src/plugins/qmljseditor/qmljseditor.h
index 486170c40d78388982b9b76a8fbfd58f068c5228..22b06ddcc891dd299eedd75623751a2ad70ba3d1 100644
--- a/src/plugins/qmljseditor/qmljseditor.h
+++ b/src/plugins/qmljseditor/qmljseditor.h
@@ -248,6 +248,7 @@ protected:
 
     //// brace matching
     virtual bool contextAllowsAutoParentheses(const QTextCursor &cursor, const QString &textToInsert = QString()) const;
+    virtual bool contextAllowsElectricCharacters(const QTextCursor &cursor) const;
     virtual bool isInComment(const QTextCursor &cursor) const;
     virtual QString insertMatchingBrace(const QTextCursor &tc, const QString &text, QChar la, int *skippedChars) const;
     virtual QString insertParagraphSeparator(const QTextCursor &tc) const;
diff --git a/src/plugins/texteditor/basetexteditor.cpp b/src/plugins/texteditor/basetexteditor.cpp
index 2612647ab4c038981625a2326b65a8b1477a064c..249666b2ac710056fd0d5f03db35abf64a52e1a8 100644
--- a/src/plugins/texteditor/basetexteditor.cpp
+++ b/src/plugins/texteditor/basetexteditor.cpp
@@ -1351,7 +1351,7 @@ void BaseTextEditor::keyPressEvent(QKeyEvent *e)
             cursor.insertText(autoText);
             cursor.setPosition(pos);
         }
-        if (!electricChar.isNull())
+        if (!electricChar.isNull() && contextAllowsElectricCharacters(cursor))
             indent(document(), cursor, electricChar);
 
         if (doEditBlock)
@@ -3824,6 +3824,11 @@ bool BaseTextEditor::contextAllowsAutoParentheses(const QTextCursor &cursor,
     return false;
 }
 
+bool BaseTextEditor::contextAllowsElectricCharacters(const QTextCursor &cursor) const
+{
+    return contextAllowsAutoParentheses(cursor);
+}
+
 bool BaseTextEditor::isInComment(const QTextCursor &cursor) const
 {
     Q_UNUSED(cursor);
diff --git a/src/plugins/texteditor/basetexteditor.h b/src/plugins/texteditor/basetexteditor.h
index 79058bd38903b0981717518ef2c5009585231130..e375375dec1f8ae1550bc14a9dc65684057340ef 100644
--- a/src/plugins/texteditor/basetexteditor.h
+++ b/src/plugins/texteditor/basetexteditor.h
@@ -407,6 +407,7 @@ public:
     virtual void reindent(QTextDocument *doc, const QTextCursor &cursor);
 
     virtual bool contextAllowsAutoParentheses(const QTextCursor &cursor, const QString &textToInsert = QString()) const;
+    virtual bool contextAllowsElectricCharacters(const QTextCursor &cursor) const;
 
     // Returns true if the cursor is inside a comment.
     virtual bool isInComment(const QTextCursor &cursor) const;
diff --git a/src/plugins/texteditor/tabsettings.cpp b/src/plugins/texteditor/tabsettings.cpp
index 20e80446634bf934333d798595fc1b20bc24acd1..9c7864a9cbd86b828663e881d76eb643f80a29d5 100644
--- a/src/plugins/texteditor/tabsettings.cpp
+++ b/src/plugins/texteditor/tabsettings.cpp
@@ -192,7 +192,7 @@ bool TabSettings::tabShouldIndent(const QTextDocument *document, QTextCursor cur
         return true;
     if (document->characterAt(tc.position()).isSpace()) {
         tc.movePosition(QTextCursor::WordRight);
-        if (tc.columnNumber() >= cursor.columnNumber()) {
+        if (tc.positionInBlock() >= cursor.positionInBlock()) {
             if (suggestedPosition)
                 *suggestedPosition = tc.position(); // Suggest position after whitespace
             if (m_tabKeyBehavior == TabLeadingWhitespaceIndents)