forked from qt-creator/qt-creator
fakevim: fix some indentation when tabs are not expanded
This commit is contained in:
@@ -200,11 +200,11 @@ enum EventResult
|
|||||||
EventPassedToCore
|
EventPassedToCore
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Indentation
|
struct Column
|
||||||
{
|
{
|
||||||
Indentation(int p, int l) : physical(p), logical(l) {}
|
Column(int p, int l) : physical(p), logical(l) {}
|
||||||
int physical; // number of characters
|
int physical; // number of characters in the data
|
||||||
int logical;
|
int logical; // column on screen
|
||||||
};
|
};
|
||||||
|
|
||||||
struct CursorPosition
|
struct CursorPosition
|
||||||
@@ -336,7 +336,9 @@ public:
|
|||||||
// all zero-based counting
|
// all zero-based counting
|
||||||
int cursorLineOnScreen() const;
|
int cursorLineOnScreen() const;
|
||||||
int cursorLineInDocument() const;
|
int cursorLineInDocument() const;
|
||||||
int cursorColumnInDocument() const;
|
int physicalCursorColumnInDocument() const; // as stored in the data
|
||||||
|
int logicalCursorColumnInDocument() const; // as visible on screen
|
||||||
|
Column cursorColumnInDocument() const; // as visible on screen
|
||||||
int firstVisibleLineInDocument() const;
|
int firstVisibleLineInDocument() const;
|
||||||
void scrollToLineInDocument(int line);
|
void scrollToLineInDocument(int line);
|
||||||
void scrollUp(int count);
|
void scrollUp(int count);
|
||||||
@@ -530,7 +532,7 @@ public:
|
|||||||
|
|
||||||
// auto-indent
|
// auto-indent
|
||||||
QString tabExpand(int len) const;
|
QString tabExpand(int len) const;
|
||||||
Indentation indentation(const QString &line) const;
|
Column indentation(const QString &line) const;
|
||||||
void insertAutomaticIndentation(bool goingDown);
|
void insertAutomaticIndentation(bool goingDown);
|
||||||
bool removeAutomaticIndentation(); // true if something removed
|
bool removeAutomaticIndentation(); // true if something removed
|
||||||
// number of autoindented characters
|
// number of autoindented characters
|
||||||
@@ -647,7 +649,7 @@ EventResult FakeVimHandler::Private::handleEvent(QKeyEvent *ev)
|
|||||||
if (m_mode == InsertMode) {
|
if (m_mode == InsertMode) {
|
||||||
int dist = m_tc.position() - m_oldPosition;
|
int dist = m_tc.position() - m_oldPosition;
|
||||||
// Try to compensate for code completion
|
// Try to compensate for code completion
|
||||||
if (dist > 0 && dist <= cursorColumnInDocument()) {
|
if (dist > 0 && dist <= physicalCursorColumnInDocument()) {
|
||||||
Range range(m_oldPosition, m_tc.position());
|
Range range(m_oldPosition, m_tc.position());
|
||||||
m_lastInsertion.append(text(range));
|
m_lastInsertion.append(text(range));
|
||||||
}
|
}
|
||||||
@@ -1107,7 +1109,7 @@ void FakeVimHandler::Private::updateMiniBuffer()
|
|||||||
int linesInDoc = linesInDocument();
|
int linesInDoc = linesInDocument();
|
||||||
int l = cursorLineInDocument();
|
int l = cursorLineInDocument();
|
||||||
QString status;
|
QString status;
|
||||||
const QString pos = QString::fromLatin1("%1,%2").arg(l + 1).arg(cursorColumnInDocument() + 1);
|
const QString pos = QString::fromLatin1("%1,%2").arg(l + 1).arg(physicalCursorColumnInDocument() + 1);
|
||||||
// FIXME: physical "-" logical
|
// FIXME: physical "-" logical
|
||||||
if (linesInDoc != 0) {
|
if (linesInDoc != 0) {
|
||||||
status = FakeVimHandler::tr("%1%2%").arg(pos, -10).arg(l * 100 / linesInDoc, 4);
|
status = FakeVimHandler::tr("%1%2%").arg(pos, -10).arg(l * 100 / linesInDoc, 4);
|
||||||
@@ -2029,13 +2031,15 @@ EventResult FakeVimHandler::Private::handleInsertMode(int key, int,
|
|||||||
m_justAutoIndented = 0;
|
m_justAutoIndented = 0;
|
||||||
if (!m_lastInsertion.isEmpty() || hasConfig(ConfigBackspace, "start")) {
|
if (!m_lastInsertion.isEmpty() || hasConfig(ConfigBackspace, "start")) {
|
||||||
const int line = cursorLineInDocument() + 1;
|
const int line = cursorLineInDocument() + 1;
|
||||||
const int col = cursorColumnInDocument();
|
const Column col = cursorColumnInDocument();
|
||||||
const QString data = lineContents(line);
|
QString data = lineContents(line);
|
||||||
const Indentation ind = indentation(data);
|
const Column ind = indentation(data);
|
||||||
if (col <= ind.logical && col && startsWithWhitespace(data, col)) {
|
if (col.logical <= ind.logical && col.logical
|
||||||
|
&& startsWithWhitespace(data, col.physical)) {
|
||||||
const int ts = config(ConfigTabStop).toInt();
|
const int ts = config(ConfigTabStop).toInt();
|
||||||
const int newcol = col - 1 - (col - 1) % ts;
|
const int newcol = col.logical - 1 - (col.logical - 1) % ts;
|
||||||
setLineContents(line, tabExpand(newcol).append(data.midRef(col)));
|
data.remove(0, col.physical);
|
||||||
|
setLineContents(line, tabExpand(newcol).append(data));
|
||||||
m_lastInsertion.clear(); // FIXME
|
m_lastInsertion.clear(); // FIXME
|
||||||
} else {
|
} else {
|
||||||
m_tc.deletePreviousChar();
|
m_tc.deletePreviousChar();
|
||||||
@@ -2058,7 +2062,7 @@ EventResult FakeVimHandler::Private::handleInsertMode(int key, int,
|
|||||||
} else if (key == Key_Tab && hasConfig(ConfigExpandTab)) {
|
} else if (key == Key_Tab && hasConfig(ConfigExpandTab)) {
|
||||||
m_justAutoIndented = 0;
|
m_justAutoIndented = 0;
|
||||||
const int ts = config(ConfigTabStop).toInt();
|
const int ts = config(ConfigTabStop).toInt();
|
||||||
const int col = cursorColumnInDocument();
|
const int col = physicalCursorColumnInDocument();
|
||||||
QString str = QString(ts - col % ts, ' ');
|
QString str = QString(ts - col % ts, ' ');
|
||||||
m_lastInsertion.append(str);
|
m_lastInsertion.append(str);
|
||||||
m_tc.insertText(str);
|
m_tc.insertText(str);
|
||||||
@@ -2962,19 +2966,45 @@ int FakeVimHandler::Private::cursorLineInDocument() const
|
|||||||
return m_tc.block().blockNumber();
|
return m_tc.block().blockNumber();
|
||||||
}
|
}
|
||||||
|
|
||||||
int FakeVimHandler::Private::cursorColumnInDocument() const
|
int FakeVimHandler::Private::physicalCursorColumnInDocument() const
|
||||||
{
|
{
|
||||||
return m_tc.position() - m_tc.block().position();
|
return m_tc.position() - m_tc.block().position();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int FakeVimHandler::Private::logicalCursorColumnInDocument() const
|
||||||
|
{
|
||||||
|
const int ncols = physicalCursorColumnInDocument();
|
||||||
|
const QString line = m_tc.block().text();
|
||||||
|
const int ts = config(ConfigTabStop).toInt();
|
||||||
|
int physical = 0;
|
||||||
|
int logical = 0;
|
||||||
|
while (physical < ncols) {
|
||||||
|
QChar c = line.at(physical);
|
||||||
|
if (c == QLatin1Char(' '))
|
||||||
|
++logical;
|
||||||
|
else if (c == QLatin1Char('\t'))
|
||||||
|
logical += ts - logical % ts;
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
++physical;
|
||||||
|
}
|
||||||
|
return logical;
|
||||||
|
}
|
||||||
|
|
||||||
|
Column FakeVimHandler::Private::cursorColumnInDocument() const
|
||||||
|
{
|
||||||
|
return Column(physicalCursorColumnInDocument(), logicalCursorColumnInDocument());
|
||||||
|
}
|
||||||
|
|
||||||
int FakeVimHandler::Private::linesInDocument() const
|
int FakeVimHandler::Private::linesInDocument() const
|
||||||
{
|
{
|
||||||
if (m_tc.isNull())
|
if (m_tc.isNull())
|
||||||
return 0;
|
return 0;
|
||||||
const QTextDocument *doc = m_tc.document();
|
const QTextDocument *doc = m_tc.document();
|
||||||
const int count = doc->blockCount();
|
const int count = doc->blockCount();
|
||||||
// Qt inserts an empty line if the last character is a '\n', but that's not how vi does it
|
// Qt inserts an empty line if the last character is a '\n',
|
||||||
return doc->lastBlock().length()<=1 ? count-1 : count;
|
// but that's not how vi does it.
|
||||||
|
return doc->lastBlock().length() <= 1 ? count - 1 : count;
|
||||||
}
|
}
|
||||||
|
|
||||||
void FakeVimHandler::Private::scrollToLineInDocument(int line)
|
void FakeVimHandler::Private::scrollToLineInDocument(int line)
|
||||||
@@ -3440,7 +3470,7 @@ void FakeVimHandler::Private::recordNewUndo()
|
|||||||
//beginEditBlock();
|
//beginEditBlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
Indentation FakeVimHandler::Private::indentation(const QString &line) const
|
Column FakeVimHandler::Private::indentation(const QString &line) const
|
||||||
{
|
{
|
||||||
int ts = config(ConfigTabStop).toInt();
|
int ts = config(ConfigTabStop).toInt();
|
||||||
int physical = 0;
|
int physical = 0;
|
||||||
@@ -3456,7 +3486,7 @@ Indentation FakeVimHandler::Private::indentation(const QString &line) const
|
|||||||
break;
|
break;
|
||||||
++physical;
|
++physical;
|
||||||
}
|
}
|
||||||
return Indentation(physical, logical);
|
return Column(physical, logical);
|
||||||
}
|
}
|
||||||
|
|
||||||
QString FakeVimHandler::Private::tabExpand(int n) const
|
QString FakeVimHandler::Private::tabExpand(int n) const
|
||||||
@@ -3625,13 +3655,13 @@ QWidget *FakeVimHandler::widget()
|
|||||||
// Test only
|
// Test only
|
||||||
int FakeVimHandler::physicalIndentation(const QString &line) const
|
int FakeVimHandler::physicalIndentation(const QString &line) const
|
||||||
{
|
{
|
||||||
Indentation ind = d->indentation(line);
|
Column ind = d->indentation(line);
|
||||||
return ind.physical;
|
return ind.physical;
|
||||||
}
|
}
|
||||||
|
|
||||||
int FakeVimHandler::logicalIndentation(const QString &line) const
|
int FakeVimHandler::logicalIndentation(const QString &line) const
|
||||||
{
|
{
|
||||||
Indentation ind = d->indentation(line);
|
Column ind = d->indentation(line);
|
||||||
return ind.logical;
|
return ind.logical;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user