Skip to content

Commit

Permalink
refactor!: indentationAt API now returns int
Browse files Browse the repository at this point in the history
The `indentationAtLine` and `...AtPosition` methods now return `int`, in
accordance to the `indent` and `setIndentation` methods.

The old behavior is still accessible via the `indentTextAtLine` and
`indentTextAtPosition` functions.
It turned out to still be useful, as there are a few situation where you
just want to copy the indentation from another line.
Getting access to the original indentation is useful there, as it can
deal better with cases where Knuts indentation settings don't match up
with the actual indentation in the file.
  • Loading branch information
LeonMatthesKDAB committed Dec 5, 2024
1 parent 6e4dff2 commit 7924cde
Show file tree
Hide file tree
Showing 7 changed files with 100 additions and 37 deletions.
29 changes: 23 additions & 6 deletions docs/API/knut/textdocument.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,10 @@ Inherited properties: [Document properties](../knut/document.md#properties)
|bool |**[hasSelection](#hasSelection)**()|
||**[indent](#indent)**(int count)|
||**[indentLine](#indentLine)**(int count, int line)|
||**[indentationAtLine](#indentationAtLine)**(int line = -1)|
||**[indentationAtPosition](#indentationAtPosition)**(int pos)|
|string |**[indentTextAtLine](#indentTextAtLine)**(int line = -1)|
|string |**[indentTextAtPosition](#indentTextAtPosition)**(int pos)|
|int |**[indentationAtLine](#indentationAtLine)**(int line = -1)|
|int |**[indentationAtPosition](#indentationAtPosition)**(int pos)|
||**[insert](#insert)**(string text)|
||**[insertAtLine](#insertAtLine)**(string text, int line = -1)|
||**[insertAtPosition](#insertAtPosition)**(string text, int pos)|
Expand Down Expand Up @@ -322,16 +324,31 @@ Indents the `line` `count` times.

See also: [`indent`](#indent)

#### <a name="indentationAtLine"></a>**indentationAtLine**(int line = -1)
#### <a name="indentTextAtLine"></a>string **indentTextAtLine**(int line = -1)

Returns the indentation at the given line.
Returns the indentation text at the given line.

If `line` is -1 it will return the indentation at the current line.
If `line` is larger than the number of lines in the document, it will return an empty string

#### <a name="indentationAtPosition"></a>**indentationAtPosition**(int pos)
Note: To get the level of indentation, use [`indentationAtLine`](#indentationAtLine).

Returns the indentation at the given position.
#### <a name="indentTextAtPosition"></a>string **indentTextAtPosition**(int pos)

Returns the indentation text at the given position.

Note: To get the level of indentation, use [`indentationAtPosition`](#indentationAtPosition).

#### <a name="indentationAtLine"></a>int **indentationAtLine**(int line = -1)

Returns the indentation level at the given line.

If `line` is -1 it will return the indentation at the current line.
If `line` is larger than the number of lines in the document, it will return 0

#### <a name="indentationAtPosition"></a>int **indentationAtPosition**(int pos)

Returns the indentation level at the given position.

#### <a name="insert"></a>**insert**(string text)

Expand Down
6 changes: 3 additions & 3 deletions src/core/cppdocument.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1339,12 +1339,12 @@ CppDocument::addMemberOrMethod(const QString &memberInfo, const QString &classNa
const auto fields = match.getAll("field");
if (!fields.isEmpty()) {
const auto &pos = fields.last();
const auto indent = indentationAtPosition(pos.end());
const auto indent = indentTextAtPosition(pos.end());
insertAtPosition("\n" + indent + memberText, pos.end());
} else {
const auto access = match.getAll("access");
const auto &pos = access.last();
const auto indent = indentationAtPosition(pos.end());
const auto indent = indentTextAtPosition(pos.end());
insertAtPosition("\n" + indent + memberText, pos.end());
}
} else {
Expand Down Expand Up @@ -1519,7 +1519,7 @@ bool CppDocument::addSpecifierSection(const QString &memberText, const QString &
if (!result.isEmpty()) {
const auto &match = result.last();
const auto pos = match.get("pos");
const auto indent = indentationAtPosition(pos.end());
const auto indent = indentTextAtPosition(pos.end());

const QString newSpecifier = QString("\n\n%1:").arg(accessSpecifierMap.value(specifier));

Expand Down
60 changes: 48 additions & 12 deletions src/core/textdocument.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1534,6 +1534,11 @@ static int firstNonSpace(const QString &text)
return i;
}

static QString indentToString(int indentSize, const TabSettings &settings)
{
return settings.insertSpaces ? QString(indentSize * settings.tabSize, ' ') : QString(indentSize, '\t');
}

static int indentOneLine(QTextCursor &cursor, int tabCount, const TabSettings &settings, bool relative)
{
QString text = cursor.selectedText();
Expand All @@ -1546,10 +1551,7 @@ static int indentOneLine(QTextCursor &cursor, int tabCount, const TabSettings &s
const int indentSize = qMax(relative ? (currentIndent + tabCount) : tabCount, 0);

text.remove(0, firstChar);
if (settings.insertSpaces)
text = QString(indentSize * settings.tabSize, ' ') + text;
else
text = QString(indentSize, '\t') + text;
text = indentToString(indentSize, settings) + text;

cursor.insertText(text);
return text.size() - oldSize;
Expand Down Expand Up @@ -1694,12 +1696,15 @@ void TextDocument::setLineEnding(LineEnding newLineEnding)
}

/*!
* \qmlmethod TextDocument::indentationAtPosition(int pos)
* Returns the indentation at the given position.
* \qmlmethod string TextDocument::indentTextAtPosition(int pos)
* Returns the indentation text at the given position.
*
* Note: To get the level of indentation, use [`indentationAtPosition`](#indentationAtPosition).
*/
QString TextDocument::indentationAtPosition(int pos)
QString TextDocument::indentTextAtPosition(int pos) const
{
LOG(LOG_ARG("position", pos));

auto cursor = m_document->textCursor();
cursor.setPosition(pos);
cursor.movePosition(QTextCursor::StartOfLine);
Expand All @@ -1709,13 +1714,15 @@ QString TextDocument::indentationAtPosition(int pos)
}

/*!
* \qmlmethod TextDocument::indentationAtLine(int line = -1)
* Returns the indentation at the given line.
* \qmlmethod string TextDocument::indentTextAtLine(int line = -1)
* Returns the indentation text at the given line.
*
* If `line` is -1 it will return the indentation at the current line.
* If `line` is larger than the number of lines in the document, it will return an empty string
*
* Note: To get the level of indentation, use [`indentationAtLine`](#indentationAtLine).
*/
QString TextDocument::indentationAtLine(int line /* = -1 */)
QString TextDocument::indentTextAtLine(int line /* = -1 */) const
{
LOG(LOG_ARG("line", line));

Expand All @@ -1728,9 +1735,38 @@ QString TextDocument::indentationAtLine(int line /* = -1 */)

const QTextBlock &block = m_document->document()->findBlockByNumber(blockNumber);
if (block.isValid()) {
return indentationAtPosition(block.position());
return indentTextAtPosition(block.position());
}
return "";
return 0;
}

/*!
* \qmlmethod int TextDocument::indentationAtPosition(int pos)
* Returns the indentation level at the given position.
*/
int TextDocument::indentationAtPosition(int pos) const
{
LOG(LOG_ARG("position", pos));

const auto indentText = indentTextAtPosition(pos);
const auto settings = Core::Settings::instance()->value<Core::TabSettings>(Core::Settings::Tab);
return columnAt(indentText, indentText.size(), settings.tabSize) / settings.tabSize;
}

/*!
* \qmlmethod int TextDocument::indentationAtLine(int line = -1)
* Returns the indentation level at the given line.
*
* If `line` is -1 it will return the indentation at the current line.
* If `line` is larger than the number of lines in the document, it will return 0
*/
int TextDocument::indentationAtLine(int line /* = -1 */) const
{
LOG(LOG_ARG("line", line));

const auto indentText = indentTextAtLine(line);
const auto settings = Core::Settings::instance()->value<Core::TabSettings>(Core::Settings::Tab);
return columnAt(indentText, indentText.size(), settings.tabSize) / settings.tabSize;
}

} // namespace Core
6 changes: 4 additions & 2 deletions src/core/textdocument.h
Original file line number Diff line number Diff line change
Expand Up @@ -194,8 +194,10 @@ public slots:
void removeIndentAtLine(int count, int line);
void setIndentation(int indent);
void setIndentationAtLine(int indent, int line);
QString indentationAtPosition(int pos);
QString indentationAtLine(int line = -1);
int indentationAtPosition(int pos) const;
int indentationAtLine(int line = -1) const;
QString indentTextAtPosition(int pos) const;
QString indentTextAtLine(int line = -1) const;

signals:
void positionChanged();
Expand Down
4 changes: 2 additions & 2 deletions test_data/tst_textdocument/indent/indent.txt.expected
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
Quisque convallis ipsum ac odio aliquet tincidunt.

Mauris ut magna vitae mauris fringilla condimentum.
Expand Down Expand Up @@ -26,4 +26,4 @@ Mauris ut magna vitae mauris fringilla condimentum.
Quisque convallis ipsum ac odio aliquet tincidunt.

Mauris ut magna vitae mauris fringilla condimentum.
Proin non mi placerat, ultricies diam sit amet, ultricies nisi.
Proin non mi placerat, ultricies diam sit amet, ultricies nisi.
4 changes: 2 additions & 2 deletions test_data/tst_textdocument/indent/indent.txt.original
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
Quisque convallis ipsum ac odio aliquet tincidunt.

Mauris ut magna vitae mauris fringilla condimentum.
Expand Down Expand Up @@ -26,4 +26,4 @@ Lorem ipsum dolor sit amet, consectetur adipiscing elit.
Quisque convallis ipsum ac odio aliquet tincidunt.

Mauris ut magna vitae mauris fringilla condimentum.
Proin non mi placerat, ultricies diam sit amet, ultricies nisi.
Proin non mi placerat, ultricies diam sit amet, ultricies nisi.
28 changes: 18 additions & 10 deletions tests/tst_textdocument.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -352,34 +352,40 @@ private slots:
auto spaces = [](int count) {
return QString(count, ' ');
};
#define COMPARE_LINE_INDENT(LINE, TEXT, INDENT) \
QCOMPARE(document.indentTextAtLine(LINE), TEXT); \
QCOMPARE(document.indentationAtLine(LINE), INDENT);

#define COMPARE_CURRENT_INDENT(TEXT, INDENT) \
QCOMPARE(document.indentationAtPosition(document.position()), INDENT); \
QCOMPARE(document.indentationAtLine(-1), INDENT); \
QCOMPARE(document.indentTextAtPosition(document.position()), TEXT); \
QCOMPARE(document.indentTextAtLine(-1), TEXT);

Test::FileTester file(Test::testDataPath() + "/tst_textdocument/indent/indent.txt");
{
Core::KnutCore core;
Core::TextDocument document;
document.load(file.fileName());

QCOMPARE(document.indentationAtLine(1), spaces(4));
QCOMPARE(document.indentationAtLine(7), " \t\t\t\t");
QCOMPARE(document.indentationAtLine(29), spaces(2));
COMPARE_LINE_INDENT(1, spaces(2), 0);
COMPARE_LINE_INDENT(7, " \t\t\t\t", 4);
COMPARE_LINE_INDENT(29, spaces(4), 1);
// If the line number is larger than the line count, an empty string is returned
QVERIFY(document.indentationAtLine(50).isEmpty());
COMPARE_LINE_INDENT(50, "", 0);

document.gotoLine(4);
document.indent();
QCOMPARE(document.indentationAtPosition(document.position()), spaces(4));
QCOMPARE(document.indentationAtLine(-1), spaces(4));
COMPARE_CURRENT_INDENT(spaces(4), 1)

// Test that we can correctly detect columns in mixed tabs and spaces.
// In this test, the first column contains 2 spaces and a tab.
// Because our tabsize is 4 spaces, the first 2 spaces and the tab combine into the first column.
// When we remove 2 levels of indentation, that will result in 2 columns left (aka. 8 spaces).
document.gotoLine(7, 4);
QCOMPARE(document.indentationAtPosition(document.position()), " \t\t\t\t");
QCOMPARE(document.indentationAtLine(-1), " \t\t\t\t");
COMPARE_CURRENT_INDENT(" \t\t\t\t", 4)
document.removeIndent(2);
QCOMPARE(document.indentationAtPosition(document.position()), spaces(8));
QCOMPARE(document.indentationAtLine(-1), spaces(8));
COMPARE_CURRENT_INDENT(spaces(8), 2)

document.gotoLine(10);
document.selectNextLine();
Expand All @@ -401,6 +407,8 @@ private slots:

QVERIFY(file.compare());
}
#undef COMPARE_CURRENT_INDENT
#undef COMPARE_LINE_INDENT
}

void findReplace()
Expand Down

0 comments on commit 7924cde

Please sign in to comment.