10#include "kateconfig.h"
11#include "katedocument.h"
12#include "kateglobal.h"
13#include "katelayoutcache.h"
14#include "kateviinputmode.h"
15#include "ktexteditor/message.h"
16#include <vimode/globalstate.h>
17#include <vimode/inputmodemanager.h>
18#include <vimode/jumps.h>
19#include <vimode/lastchangerecorder.h>
20#include <vimode/marks.h>
21#include <vimode/modes/modebase.h>
22#include <vimode/modes/normalvimode.h>
23#include <vimode/modes/replacevimode.h>
24#include <vimode/modes/visualvimode.h>
25#include <vimode/registers.h>
26#include <vimode/searcher.h>
28#include <KLocalizedString>
29#include <QRegularExpression>
32using namespace KateVi;
44void ModeBase::yankToClipBoard(
QChar chosen_register,
const QString &text)
48 if ((chosen_register ==
QLatin1Char(
'0') || chosen_register ==
QLatin1Char(
'-') || chosen_register == PrependNumberedRegister) && text.
length() > 1
54bool ModeBase::deleteRange(Range &r, OperationMode mode,
bool addToRegister)
58 const QString removedText = getRange(r, mode);
60 if (mode == LineWise) {
62 for (
int i = 0; i < r.endLine - r.startLine + 1; i++) {
63 res = doc()->removeLine(r.startLine);
67 res = doc()->removeText(r.toEditorRange(), mode == Block);
72 QChar chosenRegister = getChosenRegister(UnnamedRegister);
74 fillRegister(chosenRegister, removedText, mode);
78 if (chosenRegister != BlackHoleRegister && (r.startLine != r.endLine || lastChar ==
QLatin1Char(
'\n') || lastChar ==
QLatin1Char(
'\r'))) {
80 fillRegister(PrependNumberedRegister, removedText, mode);
81 chosenRegister = PrependNumberedRegister;
82 }
else if (chosenRegister == UnnamedRegister) {
84 fillRegister(SmallDeleteRegister, removedText, mode);
85 chosenRegister = SmallDeleteRegister;
87 yankToClipBoard(chosenRegister, removedText);
92const QString ModeBase::getRange(Range &r, OperationMode mode)
const
97 if (mode == LineWise) {
99 r.endColumn = getLine(r.endLine).
length();
102 if (r.motionType == InclusiveMotion) {
107 if (mode == LineWise) {
108 s = doc()->textLines(range).join(
QLatin1Char(
'\n'));
110 }
else if (mode == Block) {
111 s = doc()->text(range,
true);
113 s = doc()->text(range);
119const QString ModeBase::getLine(
int line)
const
121 return (line < 0) ? m_view->doc()->line(m_view->cursorPosition().
line()) : doc()->line(line);
124const QChar ModeBase::getCharUnderCursor()
const
128 QString line = getLine(c.line());
130 if (line.
length() == 0 && c.column() >= line.
length()) {
134 return line.
at(c.column());
137const QString ModeBase::getWordUnderCursor()
const
139 return doc()->text(getWordRangeUnderCursor());
147 QChar ch = doc()->characterAt(c);
151 c.setColumn(c.column() + 1);
152 if (c.column() > doc()->lineLength(c.line())) {
154 c.setLine(c.line() + 1);
155 if (c.line() == doc()->lines()) {
160 ch = doc()->characterAt(c);
175KTextEditor::Cursor ModeBase::findNextWordStart(
int fromLine,
int fromColumn,
bool onlyCurrentLine)
const
177 QString line = getLine(fromLine);
180 QString startOfWordPattern = QStringLiteral(
"\\b(\\w");
181 if (m_extraWordCharacters.
length() > 0) {
189 QStringLiteral(
"\\b(?!\\s)\\W"),
198 int c1 = line.
indexOf(startOfWord, c + 1);
199 int c2 = line.
indexOf(nonSpaceAfterSpace, c);
200 int c3 = line.
indexOf(nonWordAfterWord, c + 1);
202 if (c1 == -1 && c2 == -1 && c3 == -1) {
203 if (onlyCurrentLine) {
205 }
else if (l >= doc()->lines() - 1) {
206 c = qMax(line.
length() - 1, 0);
234 c = qMin(c1, qMin(c2, c3));
242KTextEditor::Cursor ModeBase::findNextWORDStart(
int fromLine,
int fromColumn,
bool onlyCurrentLine)
const
253 c = line.
indexOf(startOfWORD, c);
256 if (onlyCurrentLine) {
258 }
else if (l >= doc()->lines() - 1) {
282KTextEditor::Cursor ModeBase::findPrevWordEnd(
int fromLine,
int fromColumn,
bool onlyCurrentLine)
const
284 QString line = getLine(fromLine);
286 QString endOfWordPattern = QStringLiteral(
"\\S\\s|\\S$|\\S\\b|\\w\\W|^$");
288 if (m_extraWordCharacters.
length() > 0) {
302 if (c1 != -1 && c - 1 != -1) {
306 if (onlyCurrentLine) {
322KTextEditor::Cursor ModeBase::findPrevWORDEnd(
int fromLine,
int fromColumn,
bool onlyCurrentLine)
const
324 QString line = getLine(fromLine);
334 int c1 = line.
lastIndexOf(endOfWORDPattern, c - 1);
336 if (c1 != -1 && c - 1 != -1) {
340 if (onlyCurrentLine) {
357KTextEditor::Cursor ModeBase::findPrevWordStart(
int fromLine,
int fromColumn,
bool onlyCurrentLine)
const
359 QString line = getLine(fromLine);
362 QString startOfWordPattern = QStringLiteral(
"\\b(\\w");
363 if (m_extraWordCharacters.
length() > 0) {
371 QStringLiteral(
"\\b(?!\\s)\\W"),
381 int c1 = (c > 0) ? line.
lastIndexOf(startOfWord, c - 1) : -1;
382 int c2 = (c > 1) ? line.
lastIndexOf(nonSpaceAfterSpace, c - 2) : -1;
383 int c3 = (c > 0) ? line.
lastIndexOf(nonWordAfterWord, c - 1) : -1;
384 int c4 = (c > 0) ? line.
lastIndexOf(startOfLine, c - 1) : -1;
386 if (c1 == -1 && c2 == -1 && c3 == -1 && c4 == -1) {
387 if (onlyCurrentLine) {
419 c = qMax(c1, qMax(c2, qMax(c3, c4)));
427KTextEditor::Cursor ModeBase::findPrevWORDStart(
int fromLine,
int fromColumn,
bool onlyCurrentLine)
const
429 QString line = getLine(fromLine);
440 int c1 = (c > 1) ? line.
lastIndexOf(startOfWORD, c - 2) : -1;
441 int c2 = (c > 0) ? line.
lastIndexOf(startOfLineWORD, c - 1) : -1;
443 if (c1 == -1 && c2 == -1) {
444 if (onlyCurrentLine) {
475KTextEditor::Cursor ModeBase::findWordEnd(
int fromLine,
int fromColumn,
bool onlyCurrentLine)
const
477 QString line = getLine(fromLine);
479 QString endOfWordPattern = QStringLiteral(
"\\S\\s|\\S$|\\w\\W|\\S\\b");
481 if (m_extraWordCharacters.
length() > 0) {
493 int c1 = line.
indexOf(endOfWORD, c + 1);
499 if (onlyCurrentLine) {
501 }
else if (l >= doc()->lines() - 1) {
516KTextEditor::Cursor ModeBase::findWORDEnd(
int fromLine,
int fromColumn,
bool onlyCurrentLine)
const
518 QString line = getLine(fromLine);
528 int c1 = line.
indexOf(endOfWORD, c + 1);
534 if (onlyCurrentLine) {
536 }
else if (l >= doc()->lines() - 1) {
551Range innerRange(Range range,
bool inner)
556 const int columnDistance = qAbs(r.startColumn - r.endColumn);
557 if ((r.startLine == r.endLine) && columnDistance == 1) {
559 return Range::invalid();
568Range ModeBase::findSurroundingQuotes(
const QChar &c,
bool inner)
const
572 r.startLine = cursor.line();
573 r.endLine = cursor.line();
575 QString line = doc()->line(cursor.line());
578 if (line.
at(cursor.column()) == c) {
579 int attribute = m_view->doc()->kateTextLine(cursor.line()).attribute(cursor.column());
582 if (doc()->kateTextLine(cursor.line()).attribute(cursor.column() + 1) == attribute
583 && doc()->kateTextLine(cursor.line()).attribute(cursor.column() - 1) != attribute) {
584 r.startColumn = cursor.column();
585 r.endColumn = line.
indexOf(c, cursor.column() + 1);
587 return innerRange(r, inner);
591 if (doc()->kateTextLine(cursor.line()).attribute(cursor.column() + 1) != attribute
592 && doc()->kateTextLine(cursor.line()).attribute(cursor.column() - 1) == attribute) {
593 r.startColumn = line.
lastIndexOf(c, cursor.column() - 1);
594 r.endColumn = cursor.column();
596 return innerRange(r, inner);
599 int c1 = line.
indexOf(c, cursor.column() + 1);
601 r.startColumn = cursor.column();
604 return innerRange(r, inner);
611 r.endColumn = cursor.column();
613 return innerRange(r, inner);
617 return Range::invalid();
620 r.startColumn = line.
lastIndexOf(c, cursor.column());
621 r.endColumn = line.
indexOf(c, cursor.column());
623 if (r.startColumn == -1 || r.endColumn == -1 || r.startColumn > r.endColumn) {
624 return Range::invalid();
627 return innerRange(r, inner);
630Range ModeBase::findSurroundingBrackets(
const QChar &c1,
const QChar &c2,
bool inner,
const QChar &nested1,
const QChar &nested2)
const
633 Range r(cursor, InclusiveMotion);
634 int line = cursor.line();
635 int column = cursor.column();
641 const QString &l = m_view->doc()->line(line);
642 if (column < l.
size() && l.
at(column) == c2) {
644 r.endColumn = column;
646 if (column < l.
size() && l.
at(column) == c1) {
650 for (catalan = 1; line < m_view->doc()->lines(); line++) {
651 const QString &l = m_view->doc()->line(line);
653 for (; column < l.
size(); column++) {
658 }
else if (c == nested2) {
672 return Range::invalid();
675 r.endColumn = column;
679 line = cursor.line();
680 column = cursor.column();
682 if (column < l.
size() && l.
at(column) == c1) {
684 r.startColumn = column;
686 if (column < l.
size() && l.
at(column) == c2) {
690 for (catalan = 1; line >= 0; line--) {
691 const QString &l = m_view->doc()->line(line);
693 for (; column >= 0; column--) {
698 }
else if (c == nested2) {
705 if (!catalan || !line) {
708 column = m_view->doc()->line(line - 1).size() - 1;
711 return Range::invalid();
713 r.startColumn = column;
717 return innerRange(r, inner);
726 int col2 = line.
indexOf(c2, cursor.column());
728 Range r(cursor.line(), col1, cursor.line(), col2, InclusiveMotion);
730 if (col1 == -1 || col2 == -1 || col1 > col2) {
731 return Range::invalid();
742int ModeBase::findLineStartingWitchChar(
const QChar &c,
int count,
bool forward)
const
744 int line = m_view->cursorPosition().
line();
745 int lines = doc()->lines();
754 while (line < lines && line >= 0 && hits < count) {
756 if (l.
length() > 0 && l.
at(0) == c) {
768 if (hits == getCount()) {
777 m_viInputModeManager->updateCursor(c);
783QChar ModeBase::getChosenRegister(
const QChar &defaultReg)
const
785 return (m_register !=
QChar::Null) ? m_register : defaultReg;
790 QString r = m_viInputModeManager->globalState()->registers()->getContent(reg);
793 error(
i18n(
"Nothing in register %1", reg.
toLower()));
799OperationMode ModeBase::getRegisterFlag(
const QChar ®)
const
801 return m_viInputModeManager->globalState()->registers()->getFlag(reg);
804void ModeBase::fillRegister(
const QChar ®,
const QString &text, OperationMode flag)
806 m_viInputModeManager->globalState()->registers()->set(reg, text, flag);
811 return m_viInputModeManager->jumps()->next(cursor);
816 return m_viInputModeManager->jumps()->prev(cursor);
819Range ModeBase::goLineDown()
821 return goLineUpDown(getCount());
824Range ModeBase::goLineUp()
826 return goLineUpDown(-getCount());
833Range ModeBase::goLineUpDown(
int lines)
836 Range r(c, InclusiveMotion);
837 int tabstop = doc()->config()->tabWidth();
849 }
else if (r.endLine > doc()->lines() - 1) {
850 r.endLine = doc()->lines() - 1;
856 int endLineLen = doc()->lineLength(r.endLine) - 1;
858 if (endLineLen < 0) {
866 if (m_stickyColumn == -1) {
868 m_stickyColumn = virtColumnStart;
875 if (r.endColumn > endLineLen) {
876 r.endColumn = endLineLen;
880 if (virtColumnStart > endLineLenVirt) {
881 r.endColumn = endLineLen;
887Range ModeBase::goVisualLineUpDown(
int lines)
890 Range r(c, InclusiveMotion);
891 int tabstop = doc()->config()->tabWidth();
898 KateLayoutCache *cache = m_viInputModeManager->inputAdapter()->layoutCache();
902 int finishVisualLine = cache->
viewLine(m_view->cursorPosition());
903 int finishRealLine = m_view->cursorPosition().
line();
904 int count = qAbs(lines);
905 bool invalidPos =
false;
910 const KateLineLayout *lineLayout = cache->
line(finishRealLine);
911 if (lineLayout && finishVisualLine >= lineLayout->viewLineCount()) {
913 finishVisualLine = 0;
915 if (finishRealLine >= doc()->lines()) {
925 if (finishVisualLine < 0) {
927 if (finishRealLine < 0) {
931 const auto lineLayout = cache->
line(finishRealLine);
933 finishVisualLine = 0;
936 finishVisualLine = lineLayout->viewLineCount() - 1;
948 r.endLine = finishRealLine;
951 if (m_stickyColumn == -1 || !m_lastMotionWasVisualLineUpOrDown) {
953 int startVisualLine = cache->
viewLine(m_view->cursorPosition());
954 int startRealLine = m_view->cursorPosition().
line();
958 const bool isWrappedContinuation = (cache->
textLayout(startRealLine, startVisualLine).lineLayout().
lineNumber() != 0);
959 const int numInvisibleIndentChars = [&] {
960 if (isWrappedContinuation) {
961 auto l = doc()->plainKateTextLine(startRealLine);
967 const int realLineStartColumn = cache->
textLayout(startRealLine, startVisualLine).startCol();
968 const int lineStartVirtualColumn = startLine.
toVirtualColumn(realLineStartColumn, tabstop);
969 const int visualColumnNoInvisibleIndent = startLine.
toVirtualColumn(c.
column(), tabstop) - lineStartVirtualColumn;
970 m_stickyColumn = visualColumnNoInvisibleIndent + numInvisibleIndentChars;
971 Q_ASSERT(m_stickyColumn >= 0);
976 const int realLineStartColumn = cache->
textLayout(finishRealLine, finishVisualLine).startCol();
977 const Kate::TextLine endLine = doc()->plainKateTextLine(r.endLine);
980 const bool isWrappedContinuation = (cache->
textLayout(finishRealLine, finishVisualLine).lineLayout().
lineNumber() != 0);
981 const int numInvisibleIndentChars = [&] {
982 if (isWrappedContinuation) {
983 auto l = doc()->plainKateTextLine(finishRealLine);
988 if (m_stickyColumn == (
unsigned int)KateVi::EOL) {
989 const int visualEndColumn = cache->
textLayout(finishRealLine, finishVisualLine).lineLayout().
textLength() - 1;
990 r.endColumn = endLine.
fromVirtualColumn(visualEndColumn + realLineStartColumn - numInvisibleIndentChars, tabstop);
994 int realOffsetToVisualStickyColumn = 0;
995 const int lineStartVirtualColumn = endLine.
toVirtualColumn(realLineStartColumn, tabstop);
997 const int visualColumn =
998 endLine.
toVirtualColumn(realLineStartColumn + realOffsetToVisualStickyColumn, tabstop) - lineStartVirtualColumn + numInvisibleIndentChars;
999 if (visualColumn >= m_stickyColumn) {
1002 realOffsetToVisualStickyColumn++;
1004 r.endColumn = realLineStartColumn + realOffsetToVisualStickyColumn;
1006 m_currentMotionWasVisualLineUpOrDown =
true;
1011bool ModeBase::startNormalMode()
1017 if (!(m_viInputModeManager->isAnyVisualMode() || m_viInputModeManager->lastChangeRecorder()->isReplaying())) {
1018 m_viInputModeManager->storeLastChangeCommand();
1019 m_viInputModeManager->clearCurrentChangeLog();
1022 m_viInputModeManager->viEnterNormalMode();
1023 m_view->doc()->setUndoMergeAllEdits(
false);
1029bool ModeBase::startInsertMode()
1031 m_viInputModeManager->viEnterInsertMode();
1032 m_view->doc()->setUndoMergeAllEdits(
true);
1038bool ModeBase::startReplaceMode()
1040 m_view->doc()->setUndoMergeAllEdits(
true);
1041 m_viInputModeManager->viEnterReplaceMode();
1047bool ModeBase::startVisualMode()
1049 if (m_viInputModeManager->getCurrentViMode() == ViMode::VisualLineMode) {
1050 m_viInputModeManager->getViVisualMode()->setVisualModeType(ViMode::VisualMode);
1051 m_viInputModeManager->changeViMode(ViMode::VisualMode);
1052 }
else if (m_viInputModeManager->getCurrentViMode() == ViMode::VisualBlockMode) {
1053 m_viInputModeManager->getViVisualMode()->setVisualModeType(ViMode::VisualMode);
1054 m_viInputModeManager->changeViMode(ViMode::VisualMode);
1056 m_viInputModeManager->viEnterVisualMode();
1064bool ModeBase::startVisualBlockMode()
1066 if (m_viInputModeManager->getCurrentViMode() == ViMode::VisualMode) {
1067 m_viInputModeManager->getViVisualMode()->setVisualModeType(ViMode::VisualBlockMode);
1068 m_viInputModeManager->changeViMode(ViMode::VisualBlockMode);
1070 m_viInputModeManager->viEnterVisualMode(ViMode::VisualBlockMode);
1078bool ModeBase::startVisualLineMode()
1080 if (m_viInputModeManager->getCurrentViMode() == ViMode::VisualMode) {
1081 m_viInputModeManager->getViVisualMode()->setVisualModeType(ViMode::VisualLineMode);
1082 m_viInputModeManager->changeViMode(ViMode::VisualLineMode);
1084 m_viInputModeManager->viEnterVisualMode(ViMode::VisualLineMode);
1092void ModeBase::error(
const QString &errorMsg)
1094 delete m_infoMessage;
1098 m_infoMessage->setAutoHide(2000);
1099 m_infoMessage->setView(m_view);
1101 m_view->doc()->postMessage(m_infoMessage);
1104void ModeBase::message(
const QString &msg)
1106 delete m_infoMessage;
1110 m_infoMessage->setAutoHide(2000);
1111 m_infoMessage->setView(m_view);
1113 m_view->doc()->postMessage(m_infoMessage);
1116QString ModeBase::getVerbatimKeys()
const
1118 return m_keysVerbatim;
1121const QChar ModeBase::getCharAtVirtualColumn(
const QString &line,
int virtualColumn,
int tabWidth)
1127 if (line.
length() == 0) {
1131 while (tempCol < virtualColumn) {
1133 tempCol += tabWidth - (tempCol % tabWidth);
1138 if (tempCol <= virtualColumn) {
1141 if (column >= line.
length()) {
1147 if (line.
length() > column) {
1148 return line.
at(column);
1154void ModeBase::addToNumberUnderCursor(
int count)
1163 const int cursorColumn = c.
column();
1164 const int cursorLine = c.
line();
1166 int wordStartPos = prevWordStart.
column();
1167 if (prevWordStart.
line() < cursorLine) {
1171 if (wordStartPos > 0 && line.
at(wordStartPos - 1) ==
QLatin1Char(
'-')) {
1175 int numberStartPos = -1;
1177 static const QRegularExpression numberRegex(QStringLiteral(
"0x[0-9a-fA-F]+|\\-?\\d+"));
1178 auto numberMatchIter = numberRegex.globalMatch(line, wordStartPos);
1179 while (numberMatchIter.hasNext()) {
1180 const auto numberMatch = numberMatchIter.next();
1181 const bool numberEndedBeforeCursor = (numberMatch.capturedStart() + numberMatch.capturedLength() <= cursorColumn);
1182 if (!numberEndedBeforeCursor) {
1184 numberStartPos = numberMatch.capturedStart();
1185 numberAsString = numberMatch.captured();
1190 if (numberStartPos == -1) {
1195 bool parsedNumberSuccessfully =
false;
1200 numberAsString.
toInt(&parsedNumberSuccessfully, 8);
1201 if (parsedNumberSuccessfully) {
1205 const int originalNumber = numberAsString.
toInt(&parsedNumberSuccessfully, base);
1207 if (!parsedNumberSuccessfully) {
1214 basePrefix = QStringLiteral(
"0x");
1215 }
else if (base == 8) {
1216 basePrefix = QStringLiteral(
"0");
1219 const int withoutBaseLength = numberAsString.
length() - basePrefix.
length();
1221 const int newNumber = originalNumber + count;
1225 const QString newNumberPadded =
1226 (base == 10) ? QStringLiteral(
"%1").
arg(newNumber, 0, base) : QStringLiteral(
"%1").
arg(newNumber, withoutBaseLength, base,
QLatin1Char(
'0'));
1227 const QString newNumberText = basePrefix + newNumberPadded;
1231 doc()->removeText(
KTextEditor::Range(cursorLine, numberStartPos, cursorLine, numberStartPos + numberAsString.
length()));
1237void ModeBase::switchView(Direction direction)
1239 std::vector<KTextEditor::ViewPrivate *> visible_views;
1240 for (KTextEditor::ViewPrivate *view :
KTextEditor::EditorPrivate::self()->views()) {
1241 if (view->isVisible()) {
1242 visible_views.push_back(view);
1247 int curr_x1 = current_point.
x();
1248 int curr_x2 = current_point.
x() + m_view->
width();
1249 int curr_y1 = current_point.
y();
1250 int curr_y2 = current_point.
y() + m_view->
height();
1252 const QPoint globalPos = m_view->
mapToGlobal(m_view->cursorToCoordinate(cursorPos));
1253 int curr_cursor_y = globalPos.
y();
1254 int curr_cursor_x = globalPos.
x();
1256 KTextEditor::ViewPrivate *bestview =
nullptr;
1261 int best_center_y = -1;
1262 int best_center_x = -1;
1264 if (direction == Next && visible_views.size() != 1) {
1265 for (
size_t i = 0; i < visible_views.size(); i++) {
1266 if (visible_views.at(i) == m_view) {
1267 if (i != visible_views.size() - 1) {
1268 bestview = visible_views.at(i + 1);
1270 bestview = visible_views.at(0);
1275 for (KTextEditor::ViewPrivate *view : visible_views) {
1276 QPoint point = view->mapToGlobal(view->pos());
1278 int x2 = point.
x() + view->width();
1280 int y2 = point.
y() + m_view->
height();
1281 int center_y = (y1 + y2) / 2;
1282 int center_x = (x1 + x2) / 2;
1284 switch (direction) {
1286 if (view != m_view && x2 <= curr_x1
1287 && (x2 > best_x2 || (x2 == best_x2 && qAbs(curr_cursor_y - center_y) < qAbs(curr_cursor_y - best_center_y)) || bestview ==
nullptr)) {
1290 best_center_y = center_y;
1294 if (view != m_view && x1 >= curr_x2
1295 && (x1 < best_x1 || (x1 == best_x1 && qAbs(curr_cursor_y - center_y) < qAbs(curr_cursor_y - best_center_y)) || bestview ==
nullptr)) {
1298 best_center_y = center_y;
1302 if (view != m_view && y1 >= curr_y2
1303 && (y1 < best_y1 || (y1 == best_y1 && qAbs(curr_cursor_x - center_x) < qAbs(curr_cursor_x - best_center_x)) || bestview ==
nullptr)) {
1306 best_center_x = center_x;
1310 if (view != m_view && y2 <= curr_y1
1311 && (y2 > best_y2 || (y2 == best_y2 && qAbs(curr_cursor_x - center_x) < qAbs(curr_cursor_x - best_center_x)) || bestview ==
nullptr)) {
1314 best_center_x = center_x;
1322 if (bestview !=
nullptr) {
1328Range ModeBase::motionFindPrev()
1330 Searcher *searcher = m_viInputModeManager->searcher();
1331 Range
match = searcher->motionFindPrev(getCount());
1332 if (searcher->lastSearchWrapped()) {
1333 m_view->showSearchWrappedHint(
true);
1339Range ModeBase::motionFindNext()
1341 Searcher *searcher = m_viInputModeManager->searcher();
1342 Range
match = searcher->motionFindNext(getCount());
1343 if (searcher->lastSearchWrapped()) {
1344 m_view->showSearchWrappedHint(
false);
1350void ModeBase::goToPos(
const Range &r)
1361 m_viInputModeManager->jumps()->add(m_view->cursorPosition());
1364 if (c.
line() >= doc()->lines()) {
1365 c.
setLine(doc()->lines() - 1);
1371unsigned int ModeBase::linesDisplayed()
const
1373 return m_viInputModeManager->inputAdapter()->linesDisplayed();
1376void ModeBase::scrollViewLines(
int l)
1378 m_viInputModeManager->inputAdapter()->scrollViewLines(l);
1381int ModeBase::getCount()
const
1383 if (m_oneTimeCountOverride != -1) {
1384 return m_oneTimeCountOverride;
1386 return (m_count > 0) ? m_count : 1;
The Cursor represents a position in a Document.
constexpr int column() const noexcept
Retrieve the column on which this cursor is situated.
void setColumn(int column) noexcept
Set the cursor column to column.
constexpr bool isValid() const noexcept
Returns whether the current position of this cursor is a valid position (line + column must both be >...
void setLine(int line) noexcept
Set the cursor line to line.
constexpr int line() const noexcept
Retrieve the line on which this cursor is situated.
static constexpr Cursor invalid() noexcept
Returns an invalid cursor.
void copyToClipboard(const QString &text, const QString &fileName)
Copy text to clipboard an remember it in the history.
static KTextEditor::EditorPrivate * self()
Kate Part Internal stuff ;)
This class holds a Message to display in Views.
@ BottomInView
show message as view overlay in the bottom right corner.
@ Error
error message type
@ Positive
positive information message
An object representing a section of text, from one Cursor to another.
static constexpr Range invalid() noexcept
Returns an invalid range.
void viewModeChanged(KTextEditor::View *view, KTextEditor::View::ViewMode mode)
This signal is emitted whenever the view mode of view changes.
This class handles Kate's caching of layouting information (in KateLineLayout and KateTextLayout).
KateTextLayout & viewLine(int viewLine)
Returns the layout of the corresponding line in the view.
KateLineLayout * line(int realLine, int virtualLine=-1)
Returns the KateLineLayout for the specified line.
KateTextLayout textLayout(const KTextEditor::Cursor realCursor)
Returns the layout describing the text line which is occupied by realCursor.
Class representing a single text line.
int toVirtualColumn(int column, int tabWidth) const
Returns the column with each tab expanded into tabWidth characters.
int fromVirtualColumn(int column, int tabWidth) const
Returns the "real" column where each tab only counts one character.
QString i18n(const char *text, const TYPE &arg...)
KCOREADDONS_EXPORT Result match(QStringView pattern, QStringView str)
The KTextEditor namespace contains all the public API that is required to use the KTextEditor compone...
bool isLetterOrNumber(char32_t ucs4)
bool isMark(char32_t ucs4)
bool isSpace(char32_t ucs4)
char32_t toLower(char32_t ucs4)
UseUnicodePropertiesOption
QString & append(QChar ch)
QString arg(Args &&... args) const const
const QChar at(qsizetype position) const const
qsizetype indexOf(QChar ch, qsizetype from, Qt::CaseSensitivity cs) const const
bool isEmpty() const const
bool isNull() const const
qsizetype lastIndexOf(QChar ch, Qt::CaseSensitivity cs) const const
qsizetype length() const const
qsizetype size() const const
bool startsWith(QChar c, Qt::CaseSensitivity cs) const const
int toInt(bool *ok, int base) const const
QString trimmed() const const
int lineNumber() const const
int textLength() const const