Commit e5c7d0f1 authored by Erik Verbruggen's avatar Erik Verbruggen
Browse files

Fixed the QML indenting.

Done with Roberto Raggi.
parent ac150dfa
......@@ -70,6 +70,7 @@ enum {
using namespace QmlJS;
using namespace QmlJS::AST;
using namespace SharedTools;
namespace QmlEditor {
namespace Internal {
......@@ -634,49 +635,81 @@ bool ScriptEditor::isElectricCharacter(const QChar &ch) const
return false;
}
void ScriptEditor::indentBlock(QTextDocument *, QTextBlock block, QChar typedChar)
bool ScriptEditor::isClosingBrace(const QList<QScriptIncrementalScanner::Token> &tokens) const
{
TextEditor::TabSettings ts = tabSettings();
if (typedChar == QLatin1Char('}') || typedChar == QLatin1Char(']')
|| (typedChar == QChar::Null
&& (block.text().trimmed() == "}" || block.text().trimmed() == "]"))) {
if (tokens.size() == 1) {
const QScriptIncrementalScanner::Token firstToken = tokens.first();
QTextCursor tc(block);
return firstToken.is(QScriptIncrementalScanner::Token::RightBrace) || firstToken.is(QScriptIncrementalScanner::Token::RightBracket);
}
if (typedChar == QLatin1Char('}') || typedChar == QLatin1Char(']'))
tc = textCursor();
return false;
}
if (TextEditor::TextBlockUserData::findPreviousBlockOpenParenthesis(&tc)) {
const QString text = tc.block().text();
int indent = ts.columnAt(text, ts.firstNonSpace(text));
ts.indentLine(block, indent);
return;
}
}
static int blockBraceDepth(const QTextBlock &block)
{
int state = block.userState();
if (state == -1)
return 0;
return (state >> 8) & 0xFF;
}
int indent = 0;
int extraIndent = 0;
static int blockStartState(const QTextBlock &block)
{
int state = block.userState();
if (block.previous().isValid()) {
const int braceDepth = qMax(0, block.previous().userState() >> 8);
const int previousBraceDepth = qMax(0, block.previous().previous().userState() >> 8);
if (state == -1)
return 0;
else
return state & 0xff;
}
if (braceDepth > previousBraceDepth)
extraIndent = ts.m_indentSize * (braceDepth - previousBraceDepth);
void ScriptEditor::indentBlock(QTextDocument *, QTextBlock block, QChar typedChar)
{
TextEditor::TabSettings ts = tabSettings();
QTextCursor tc(block);
const QString blockText = block.text();
int startState = blockStartState(block.previous());
QScriptIncrementalScanner scanner;
const QList<QScriptIncrementalScanner::Token> tokens = scanner(blockText, startState);
if (! tokens.isEmpty()) {
const QScriptIncrementalScanner::Token tk = tokens.first();
if (tk.is(QScriptIncrementalScanner::Token::RightBrace)
|| tk.is(QScriptIncrementalScanner::Token::RightBracket)) {
if (TextEditor::TextBlockUserData::findPreviousBlockOpenParenthesis(&tc)) {
const QString text = tc.block().text();
int indent = ts.columnAt(text, ts.firstNonSpace(text));
ts.indentLine(block, indent);
return;
}
}
}
int initialIndent = 0;
QTextBlock it = block.previous();
for (; it.isValid(); it = it.previous()) {
const QString text = it.text();
if (! text.isEmpty()) {
indent = ts.columnAt(text, ts.firstNonSpace(text));
initialIndent = ts.columnAt(text, ts.firstNonSpace(text));
break;
}
}
ts.indentLine(block, extraIndent + indent);
// default indent is initialIndent ..
const int braceDepth = blockBraceDepth(block.previous());
const int previousBraceDepth = blockBraceDepth(block.previous().previous());
const int delta = qMax(0, braceDepth - previousBraceDepth);
int indent = initialIndent + (delta * ts.m_indentSize);
ts.indentLine(block, indent);
}
TextEditor::BaseTextEditorEditable *ScriptEditor::createEditableInterface()
......
......@@ -35,6 +35,7 @@
#include "qmljsastfwd_p.h"
#include "qmljsengine_p.h"
#include "qmldocument.h"
#include "qscriptincrementalscanner.h"
QT_BEGIN_NAMESPACE
class QComboBox;
......@@ -134,6 +135,7 @@ protected:
private:
virtual bool isElectricCharacter(const QChar &ch) const;
virtual void indentBlock(QTextDocument *doc, QTextBlock block, QChar typedChar);
bool isClosingBrace(const QList<SharedTools::QScriptIncrementalScanner::Token> &tokens) const;
QString wordUnderCursor() const;
......
......@@ -58,7 +58,7 @@ bool QScriptHighlighter::isDuiEnabled() const
void QScriptHighlighter::highlightBlock(const QString &text)
{
m_scanner(onBlockStart(), text);
m_scanner(text, onBlockStart());
QTextCharFormat emptyFormat;
int lastEnd = 0;
......
......@@ -19,7 +19,7 @@ void QScriptIncrementalScanner::reset()
m_tokens.clear();
}
void QScriptIncrementalScanner::operator()(int startState, const QString &text)
QList<QScriptIncrementalScanner::Token> QScriptIncrementalScanner::operator()(const QString &text, int startState)
{
reset();
......@@ -78,7 +78,7 @@ void QScriptIncrementalScanner::operator()(int startState, const QString &text)
int state = startState;
if (text.isEmpty()) {
blockEnd(state, 0);
return;
return m_tokens;
}
int input = -1;
......@@ -268,6 +268,8 @@ void QScriptIncrementalScanner::operator()(int startState, const QString &text)
}
blockEnd(state, firstNonSpace);
return m_tokens;
}
void QScriptIncrementalScanner::insertToken(int start, int length, Token::Kind kind, bool forceNewToken)
......
......@@ -35,6 +35,8 @@ public:
inline Token(int o, int l, Kind k): offset(o), length(l), kind(k) {}
inline int end() const { return offset + length; }
inline bool is(int k) const { return k == kind; }
inline bool isNot(int k) const { return k != kind; }
};
public:
......@@ -46,7 +48,7 @@ public:
void reset();
void operator()(int startState, const QString &text);
QList<QScriptIncrementalScanner::Token> operator()(const QString &text, int startState = 0);
int endState() const
{ return m_endState; }
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment