forked from qt-creator/qt-creator
Merge branch 'master' of ssh://codereview.qt-project.org:29418/qt-creator/qt-creator
This commit is contained in:
@@ -215,6 +215,22 @@ void FakeVimPlugin::test_vim_movement()
|
|||||||
KEYS("e", "123" N "45" "." "6" N "" N " " N "78" X "9");
|
KEYS("e", "123" N "45" "." "6" N "" N " " N "78" X "9");
|
||||||
KEYS("ge", "123" N "45" "." "6" N X "" N " " N "789");
|
KEYS("ge", "123" N "45" "." "6" N X "" N " " N "789");
|
||||||
KEYS("2ge", "123" N "45" X "." "6" N "" N " " N "789");
|
KEYS("2ge", "123" N "45" X "." "6" N "" N " " N "789");
|
||||||
|
|
||||||
|
// do not move behind end of line in normal mode
|
||||||
|
data.setText("abc def" N "ghi");
|
||||||
|
KEYS("$h", "abc d" X "ef" N "ghi");
|
||||||
|
data.setText("abc def" N "ghi");
|
||||||
|
KEYS("4e", "abc def" N "gh" X "i");
|
||||||
|
data.setText("abc def" N "ghi");
|
||||||
|
KEYS("$i", "abc de" X "f" N "ghi");
|
||||||
|
|
||||||
|
// move behind end of line in insert mode
|
||||||
|
data.setText("abc def" N "ghi");
|
||||||
|
KEYS("i<end>", "abc def" X N "ghi");
|
||||||
|
data.setText("abc def" N "ghi");
|
||||||
|
KEYS("A", "abc def" X N "ghi");
|
||||||
|
data.setText("abc def" N "ghi");
|
||||||
|
KEYS("$a", "abc def" X N "ghi");
|
||||||
}
|
}
|
||||||
|
|
||||||
void FakeVimPlugin::test_vim_fFtT()
|
void FakeVimPlugin::test_vim_fFtT()
|
||||||
@@ -314,6 +330,18 @@ void FakeVimPlugin::test_vim_delete()
|
|||||||
KEYS("3dw", X "jkl");
|
KEYS("3dw", X "jkl");
|
||||||
data.setText("abc " N " def" N " ghi" N "jkl");
|
data.setText("abc " N " def" N " ghi" N "jkl");
|
||||||
KEYS("d3w", X "jkl");
|
KEYS("d3w", X "jkl");
|
||||||
|
|
||||||
|
// delete empty line
|
||||||
|
data.setText("a" N X "" N " b");
|
||||||
|
KEYS("dd", "a" N " " X "b");
|
||||||
|
|
||||||
|
// delete on an empty line
|
||||||
|
data.setText("a" N X "" N " b");
|
||||||
|
KEYS("d$", "a" N X "" N " b");
|
||||||
|
|
||||||
|
// delete in empty document
|
||||||
|
data.setText("");
|
||||||
|
KEYS("dd", X);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FakeVimPlugin::test_vim_delete_inner_word()
|
void FakeVimPlugin::test_vim_delete_inner_word()
|
||||||
@@ -426,6 +454,60 @@ void FakeVimPlugin::test_vim_change_a_word()
|
|||||||
KEYS("3caw#", "#" X N " jkl");
|
KEYS("3caw#", "#" X N " jkl");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FakeVimPlugin::test_vim_change_replace()
|
||||||
|
{
|
||||||
|
TestData data;
|
||||||
|
setup(&data);
|
||||||
|
|
||||||
|
// preserve lines in replace mode
|
||||||
|
data.setText("abc" N "def");
|
||||||
|
KEYS("llvjhrX", "ab" X "X" N "XXf");
|
||||||
|
|
||||||
|
// change empty line
|
||||||
|
data.setText("a" N X "" N " b");
|
||||||
|
KEYS("ccABC", "a" N "ABC" X N " b");
|
||||||
|
|
||||||
|
// change on empty line
|
||||||
|
data.setText("a" N X "" N " b");
|
||||||
|
KEYS("c$ABC<esc>", "a" N "AB" X "C" N " b");
|
||||||
|
KEYS("u", "a" N X "" N " b");
|
||||||
|
KEYS("rA", "a" N X "" N " b");
|
||||||
|
|
||||||
|
// change in empty document
|
||||||
|
data.setText("");
|
||||||
|
KEYS("ccABC", "ABC" X);
|
||||||
|
KEYS("u", "");
|
||||||
|
KEYS("SABC", "ABC" X);
|
||||||
|
KEYS("u", "");
|
||||||
|
KEYS("sABC", "ABC" X);
|
||||||
|
KEYS("u", "");
|
||||||
|
KEYS("rA", "" X);
|
||||||
|
|
||||||
|
// indentation with change
|
||||||
|
data.doCommand("set expandtab");
|
||||||
|
data.doCommand("set shiftwidth=2");
|
||||||
|
data.setText("int main()" N
|
||||||
|
"{" N
|
||||||
|
" " X " return 0;" N
|
||||||
|
"}" N
|
||||||
|
"");
|
||||||
|
|
||||||
|
KEYS("cc" "int i = 0;",
|
||||||
|
"int main()" N
|
||||||
|
"{" N
|
||||||
|
" int i = 0;" X N
|
||||||
|
"}" N
|
||||||
|
"");
|
||||||
|
|
||||||
|
KEYS("uS" "int i = 0;" N "int j = 1;",
|
||||||
|
"int main()" N
|
||||||
|
"{" N
|
||||||
|
" int i = 0;" N
|
||||||
|
" int j = 1;" X N
|
||||||
|
"}" N
|
||||||
|
"");
|
||||||
|
}
|
||||||
|
|
||||||
void FakeVimPlugin::test_vim_block_selection()
|
void FakeVimPlugin::test_vim_block_selection()
|
||||||
{
|
{
|
||||||
TestData data;
|
TestData data;
|
||||||
@@ -458,6 +540,11 @@ void FakeVimPlugin::test_vim_block_selection()
|
|||||||
|
|
||||||
data.setText("{" N " { " N " } " N "}");
|
data.setText("{" N " { " N " } " N "}");
|
||||||
KEYS("di{", "{" N "}");
|
KEYS("di{", "{" N "}");
|
||||||
|
|
||||||
|
data.setText("(" X "())");
|
||||||
|
KEYS("di(", "((" X "))");
|
||||||
|
data.setText("\"\"");
|
||||||
|
KEYS("di\"", "\"" X "\"");
|
||||||
}
|
}
|
||||||
|
|
||||||
void FakeVimPlugin::test_vim_repeat()
|
void FakeVimPlugin::test_vim_repeat()
|
||||||
@@ -817,6 +904,92 @@ void FakeVimPlugin::test_vim_undo_redo()
|
|||||||
KEYS("u", "abc" N " " X "def" N "ghi");
|
KEYS("u", "abc" N " " X "def" N "ghi");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FakeVimPlugin::test_vim_letter_case()
|
||||||
|
{
|
||||||
|
TestData data;
|
||||||
|
setup(&data);
|
||||||
|
|
||||||
|
// upper- and lower-case
|
||||||
|
data.setText("abc DEF");
|
||||||
|
KEYS("lv3l~", "a" X "BC dEF");
|
||||||
|
KEYS("v4lU", "a" X "BC DEF");
|
||||||
|
KEYS("v4$u", "a" X "bc def");
|
||||||
|
KEYS("v4$gU", "a" X "BC DEF");
|
||||||
|
KEYS("gu$", "a" X "bc def");
|
||||||
|
KEYS("lg~~", X "ABC DEF");
|
||||||
|
KEYS(".", X "abc def");
|
||||||
|
KEYS("gUiw", X "ABC def");
|
||||||
|
|
||||||
|
data.setText(" ab" X "c" N "def");
|
||||||
|
KEYS("2gUU", " " X "ABC" N "DEF");
|
||||||
|
KEYS("u", " " X "abc" N "def");
|
||||||
|
KEYS("<c-r>", " " X "ABC" N "DEF");
|
||||||
|
}
|
||||||
|
|
||||||
|
void FakeVimPlugin::test_vim_code_autoindent()
|
||||||
|
{
|
||||||
|
TestData data;
|
||||||
|
setup(&data);
|
||||||
|
|
||||||
|
data.doCommand("set expandtab");
|
||||||
|
data.doCommand("set shiftwidth=3");
|
||||||
|
|
||||||
|
data.setText("int main()" N
|
||||||
|
X "{" N
|
||||||
|
"}" N
|
||||||
|
"");
|
||||||
|
KEYS("o" "return 0;",
|
||||||
|
"int main()" N
|
||||||
|
"{" N
|
||||||
|
" return 0;" X N
|
||||||
|
"}" N
|
||||||
|
"");
|
||||||
|
KEYS("O" "int i = 0;",
|
||||||
|
"int main()" N
|
||||||
|
"{" N
|
||||||
|
" int i = 0;" X N
|
||||||
|
" return 0;" N
|
||||||
|
"}" N
|
||||||
|
"");
|
||||||
|
KEYS("ddO" "int i = 0;" N "int j = 0;",
|
||||||
|
"int main()" N
|
||||||
|
"{" N
|
||||||
|
" int i = 0;" N
|
||||||
|
" int j = 0;" X N
|
||||||
|
" return 0;" N
|
||||||
|
"}" N
|
||||||
|
"");
|
||||||
|
KEYS("^i" "int x = 1;" N,
|
||||||
|
"int main()" N
|
||||||
|
"{" N
|
||||||
|
" int i = 0;" N
|
||||||
|
" int x = 1;" N
|
||||||
|
" " X "int j = 0;" N
|
||||||
|
" return 0;" N
|
||||||
|
"}" N
|
||||||
|
"");
|
||||||
|
KEYS("c2k" "if (true) {" N ";" N "}",
|
||||||
|
"int main()" N
|
||||||
|
"{" N
|
||||||
|
" if (true) {" N
|
||||||
|
" ;" N
|
||||||
|
" }" X N
|
||||||
|
" return 0;" N
|
||||||
|
"}" N
|
||||||
|
"");
|
||||||
|
KEYS("jci{" "return 1;",
|
||||||
|
"int main()" N
|
||||||
|
"{" N
|
||||||
|
" return 1;" X N
|
||||||
|
"}" N
|
||||||
|
"");
|
||||||
|
KEYS("di{",
|
||||||
|
"int main()" N
|
||||||
|
"{" N
|
||||||
|
X "}" N
|
||||||
|
"");
|
||||||
|
}
|
||||||
|
|
||||||
void FakeVimPlugin::test_vim_code_folding()
|
void FakeVimPlugin::test_vim_code_folding()
|
||||||
{
|
{
|
||||||
TestData data;
|
TestData data;
|
||||||
|
@@ -165,7 +165,9 @@ enum SubMode
|
|||||||
RegisterSubMode, // Used for "
|
RegisterSubMode, // Used for "
|
||||||
ShiftLeftSubMode, // Used for <
|
ShiftLeftSubMode, // Used for <
|
||||||
ShiftRightSubMode, // Used for >
|
ShiftRightSubMode, // Used for >
|
||||||
TransformSubMode, // Used for ~/gu/gU
|
InvertCaseSubMode, // Used for g~
|
||||||
|
DownCaseSubMode, // Used for gu
|
||||||
|
UpCaseSubMode, // Used for gU
|
||||||
WindowSubMode, // Used for Ctrl-w
|
WindowSubMode, // Used for Ctrl-w
|
||||||
YankSubMode, // Used for y
|
YankSubMode, // Used for y
|
||||||
ZSubMode, // Used for z
|
ZSubMode, // Used for z
|
||||||
@@ -185,9 +187,6 @@ enum SubSubMode
|
|||||||
MarkSubSubMode, // Used for m.
|
MarkSubSubMode, // Used for m.
|
||||||
BackTickSubSubMode, // Used for `.
|
BackTickSubSubMode, // Used for `.
|
||||||
TickSubSubMode, // Used for '.
|
TickSubSubMode, // Used for '.
|
||||||
InvertCaseSubSubMode, // Used for ~.
|
|
||||||
DownCaseSubSubMode, // Used for gu.
|
|
||||||
UpCaseSubSubMode, // Used for gU.
|
|
||||||
TextObjectSubSubMode, // Used for thing like iw, aW, as etc.
|
TextObjectSubSubMode, // Used for thing like iw, aW, as etc.
|
||||||
SearchSubSubMode
|
SearchSubSubMode
|
||||||
};
|
};
|
||||||
@@ -601,7 +600,7 @@ public:
|
|||||||
|
|
||||||
bool isReturn() const
|
bool isReturn() const
|
||||||
{
|
{
|
||||||
return m_key == Key_Return || m_key == Key_Enter;
|
return m_key == '\n' || m_key == Key_Return || m_key == Key_Enter;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isEscape() const
|
bool isEscape() const
|
||||||
@@ -1156,6 +1155,7 @@ public:
|
|||||||
EventResult handleCloseSquareSubMode(const Input &);
|
EventResult handleCloseSquareSubMode(const Input &);
|
||||||
EventResult handleSearchSubSubMode(const Input &);
|
EventResult handleSearchSubSubMode(const Input &);
|
||||||
EventResult handleCommandSubSubMode(const Input &);
|
EventResult handleCommandSubSubMode(const Input &);
|
||||||
|
void fixSelection(); // Fix selection according to current range, move and command modes.
|
||||||
void finishMovement(const QString &dotCommandMovement = QString());
|
void finishMovement(const QString &dotCommandMovement = QString());
|
||||||
void finishMovement(const QString &dotCommandMovement, int count);
|
void finishMovement(const QString &dotCommandMovement, int count);
|
||||||
void resetCommandMode();
|
void resetCommandMode();
|
||||||
@@ -1175,7 +1175,7 @@ public:
|
|||||||
bool atBlockStart() const { return cursor().atBlockStart(); }
|
bool atBlockStart() const { return cursor().atBlockStart(); }
|
||||||
bool atBlockEnd() const { return cursor().atBlockEnd(); }
|
bool atBlockEnd() const { return cursor().atBlockEnd(); }
|
||||||
bool atEndOfLine() const { return atBlockEnd() && block().length() > 1; }
|
bool atEndOfLine() const { return atBlockEnd() && block().length() > 1; }
|
||||||
bool atDocumentEnd() const { return cursor().atEnd(); }
|
bool atDocumentEnd() const { return position() >= lastPositionInDocument(); }
|
||||||
bool atDocumentStart() const { return cursor().atStart(); }
|
bool atDocumentStart() const { return cursor().atStart(); }
|
||||||
|
|
||||||
bool atEmptyLine(const QTextCursor &tc = QTextCursor()) const;
|
bool atEmptyLine(const QTextCursor &tc = QTextCursor()) const;
|
||||||
@@ -1186,7 +1186,7 @@ public:
|
|||||||
bool atWordEnd(bool simple, const QTextCursor &tc = QTextCursor()) const;
|
bool atWordEnd(bool simple, const QTextCursor &tc = QTextCursor()) const;
|
||||||
bool isFirstNonBlankOnLine(int pos);
|
bool isFirstNonBlankOnLine(int pos);
|
||||||
|
|
||||||
int lastPositionInDocument() const; // Returns last valid position in doc.
|
int lastPositionInDocument(bool ignoreMode = false) const; // Returns last valid position in doc.
|
||||||
int firstPositionInLine(int line, bool onlyVisibleLines = true) const; // 1 based line, 0 based pos
|
int firstPositionInLine(int line, bool onlyVisibleLines = true) const; // 1 based line, 0 based pos
|
||||||
int lastPositionInLine(int line, bool onlyVisibleLines = true) const; // 1 based line, 0 based pos
|
int lastPositionInLine(int line, bool onlyVisibleLines = true) const; // 1 based line, 0 based pos
|
||||||
int lineForPosition(int pos) const; // 1 based line, 0 based pos
|
int lineForPosition(int pos) const; // 1 based line, 0 based pos
|
||||||
@@ -2184,7 +2184,7 @@ void FakeVimHandler::Private::moveBehindEndOfLine()
|
|||||||
{
|
{
|
||||||
emit q->fold(1, false);
|
emit q->fold(1, false);
|
||||||
int pos = qMin(block().position() + block().length() - 1,
|
int pos = qMin(block().position() + block().length() - 1,
|
||||||
lastPositionInDocument());
|
lastPositionInDocument() + 1);
|
||||||
setPosition(pos);
|
setPosition(pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2198,6 +2198,73 @@ void FakeVimHandler::Private::moveToStartOfLine()
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FakeVimHandler::Private::fixSelection()
|
||||||
|
{
|
||||||
|
if (m_movetype == MoveExclusive) {
|
||||||
|
if (anchor() != position() && atBlockStart()) {
|
||||||
|
// Exlusive motion ending at the beginning of line
|
||||||
|
// becomes inclusive and end is moved to end of previous line.
|
||||||
|
m_movetype = MoveInclusive;
|
||||||
|
moveToStartOfLine();
|
||||||
|
moveLeft();
|
||||||
|
|
||||||
|
// Exclusive motion ending at the beginning of line and
|
||||||
|
// starting at or before first non-blank on a line becomes linewise.
|
||||||
|
if (anchor() < block().position() && isFirstNonBlankOnLine(anchor())) {
|
||||||
|
m_movetype = MoveLineWise;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_movetype == MoveLineWise)
|
||||||
|
m_rangemode = (m_submode == ChangeSubMode)
|
||||||
|
? RangeLineModeExclusive
|
||||||
|
: RangeLineMode;
|
||||||
|
|
||||||
|
if (m_movetype == MoveInclusive) {
|
||||||
|
if (anchor() <= position()) {
|
||||||
|
if (!atBlockEnd())
|
||||||
|
setPosition(position() + 1); // correction
|
||||||
|
|
||||||
|
// Omit first character in selection if it's line break on non-empty line.
|
||||||
|
int start = anchor();
|
||||||
|
int end = position();
|
||||||
|
if (document()->characterAt(start) == ParagraphSeparator
|
||||||
|
&& start > 0 && document()->characterAt(start - 1) != ParagraphSeparator) {
|
||||||
|
start = qMin(start + 1, end);
|
||||||
|
if (m_submode == DeleteSubMode && !atDocumentEnd())
|
||||||
|
setAnchorAndPosition(start, end + 1);
|
||||||
|
else
|
||||||
|
setAnchorAndPosition(start, end);
|
||||||
|
}
|
||||||
|
|
||||||
|
// If more than one line is selected and all are selected completely
|
||||||
|
// movement becomes linewise.
|
||||||
|
if (start < block().position() && isFirstNonBlankOnLine(start) && atBlockEnd()) {
|
||||||
|
if (m_submode != ChangeSubMode) {
|
||||||
|
moveRight();
|
||||||
|
if (atEmptyLine())
|
||||||
|
moveRight();
|
||||||
|
}
|
||||||
|
m_movetype = MoveLineWise;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
setAnchorAndPosition(anchor() + 1, position());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_positionPastEnd) {
|
||||||
|
const int anc = anchor();
|
||||||
|
moveBehindEndOfLine();
|
||||||
|
moveRight();
|
||||||
|
setAnchorAndPosition(anc, position());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_anchorPastEnd) {
|
||||||
|
setAnchorAndPosition(anchor() + 1, position());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void FakeVimHandler::Private::finishMovement(const QString &dotCommandMovement, int count)
|
void FakeVimHandler::Private::finishMovement(const QString &dotCommandMovement, int count)
|
||||||
{
|
{
|
||||||
finishMovement(dotCommandMovement.arg(count));
|
finishMovement(dotCommandMovement.arg(count));
|
||||||
@@ -2217,69 +2284,20 @@ void FakeVimHandler::Private::finishMovement(const QString &dotCommandMovement)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
//if (isVisualMode())
|
|
||||||
// setMark('>', position());
|
|
||||||
|
|
||||||
if (m_submode == ChangeSubMode
|
if (m_submode == ChangeSubMode
|
||||||
|| m_submode == DeleteSubMode
|
|| m_submode == DeleteSubMode
|
||||||
|| m_submode == YankSubMode
|
|| m_submode == YankSubMode
|
||||||
|| m_submode == TransformSubMode) {
|
|| m_submode == InvertCaseSubMode
|
||||||
|
|| m_submode == DownCaseSubMode
|
||||||
if (m_movetype == MoveExclusive) {
|
|| m_submode == UpCaseSubMode) {
|
||||||
if (anchor() != position() && atBlockStart()) {
|
|
||||||
// Exlusive motion ending at the beginning of line
|
|
||||||
// becomes inclusive and end is moved to end of previous line.
|
|
||||||
m_movetype = MoveInclusive;
|
|
||||||
moveToStartOfLine();
|
|
||||||
moveLeft();
|
|
||||||
|
|
||||||
// Exclusive motion ending at the beginning of line and
|
|
||||||
// starting at or before first non-blank on a line becomes linewise.
|
|
||||||
if (anchor() < block().position() && isFirstNonBlankOnLine(anchor())) {
|
|
||||||
m_movetype = MoveLineWise;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_submode != YankSubMode)
|
if (m_submode != YankSubMode)
|
||||||
beginEditBlock();
|
beginEditBlock();
|
||||||
|
|
||||||
if (m_movetype == MoveLineWise)
|
fixSelection();
|
||||||
m_rangemode = (m_submode == ChangeSubMode)
|
|
||||||
? RangeLineModeExclusive
|
|
||||||
: RangeLineMode;
|
|
||||||
|
|
||||||
if (m_movetype == MoveInclusive) {
|
if (m_submode != InvertCaseSubMode
|
||||||
if (anchor() <= position()) {
|
&& m_submode != DownCaseSubMode
|
||||||
if (!atBlockEnd())
|
&& m_submode != UpCaseSubMode) {
|
||||||
setPosition(position() + 1); // correction
|
|
||||||
|
|
||||||
// If more than one line is selected and all are selected completely
|
|
||||||
// movement becomes linewise.
|
|
||||||
int start = anchor();
|
|
||||||
if (start < block().position() && isFirstNonBlankOnLine(start) && atBlockEnd()) {
|
|
||||||
moveRight();
|
|
||||||
if (atEmptyLine())
|
|
||||||
moveRight();
|
|
||||||
m_movetype = MoveLineWise;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
setAnchorAndPosition(anchor() + 1, position());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_positionPastEnd) {
|
|
||||||
const int anc = anchor();
|
|
||||||
moveBehindEndOfLine();
|
|
||||||
moveRight();
|
|
||||||
setAnchorAndPosition(anc, position());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_anchorPastEnd) {
|
|
||||||
setAnchorAndPosition(anchor() + 1, position());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_submode != TransformSubMode) {
|
|
||||||
yankText(currentRange(), m_register);
|
yankText(currentRange(), m_register);
|
||||||
if (m_movetype == MoveLineWise)
|
if (m_movetype == MoveLineWise)
|
||||||
setRegister(m_register, registerContents(m_register), RangeLineMode);
|
setRegister(m_register, registerContents(m_register), RangeLineMode);
|
||||||
@@ -2288,33 +2306,29 @@ void FakeVimHandler::Private::finishMovement(const QString &dotCommandMovement)
|
|||||||
m_positionPastEnd = m_anchorPastEnd = false;
|
m_positionPastEnd = m_anchorPastEnd = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString dotCommand;
|
||||||
if (m_submode == ChangeSubMode) {
|
if (m_submode == ChangeSubMode) {
|
||||||
if (m_rangemode == RangeLineMode)
|
if (m_rangemode == RangeLineMode)
|
||||||
m_rangemode = RangeLineModeExclusive;
|
m_rangemode = RangeLineModeExclusive;
|
||||||
removeText(currentRange());
|
removeText(currentRange());
|
||||||
if (!dotCommandMovement.isEmpty())
|
dotCommand = QString('c');
|
||||||
setDotCommand(QLatin1Char('c') + dotCommandMovement);
|
|
||||||
if (m_movetype == MoveLineWise)
|
if (m_movetype == MoveLineWise)
|
||||||
insertAutomaticIndentation(true);
|
insertAutomaticIndentation(true);
|
||||||
endEditBlock();
|
endEditBlock();
|
||||||
enterInsertMode();
|
enterInsertMode();
|
||||||
m_submode = NoSubMode;
|
|
||||||
} else if (m_submode == DeleteSubMode) {
|
} else if (m_submode == DeleteSubMode) {
|
||||||
setUndoPosition();
|
setUndoPosition();
|
||||||
Range range = currentRange();
|
Range range = currentRange();
|
||||||
removeText(range);
|
removeText(range);
|
||||||
if (!dotCommandMovement.isEmpty())
|
dotCommand = QString('d');
|
||||||
setDotCommand(QLatin1Char('d') + dotCommandMovement);
|
|
||||||
if (m_movetype == MoveLineWise)
|
if (m_movetype == MoveLineWise)
|
||||||
handleStartOfLine();
|
handleStartOfLine();
|
||||||
m_submode = NoSubMode;
|
|
||||||
if (atEndOfLine())
|
if (atEndOfLine())
|
||||||
moveLeft();
|
moveLeft();
|
||||||
else
|
else
|
||||||
setTargetColumn();
|
setTargetColumn();
|
||||||
endEditBlock();
|
endEditBlock();
|
||||||
} else if (m_submode == YankSubMode) {
|
} else if (m_submode == YankSubMode) {
|
||||||
m_submode = NoSubMode;
|
|
||||||
const int la = lineForPosition(anchor());
|
const int la = lineForPosition(anchor());
|
||||||
const int lp = lineForPosition(position());
|
const int lp = lineForPosition(position());
|
||||||
if (m_register != '"') {
|
if (m_register != '"') {
|
||||||
@@ -2326,54 +2340,49 @@ void FakeVimHandler::Private::finishMovement(const QString &dotCommandMovement)
|
|||||||
}
|
}
|
||||||
if (la != lp)
|
if (la != lp)
|
||||||
showMessage(MessageInfo, QString("%1 lines yanked").arg(qAbs(la - lp) + 1));
|
showMessage(MessageInfo, QString("%1 lines yanked").arg(qAbs(la - lp) + 1));
|
||||||
} else if (m_submode == TransformSubMode) {
|
} else if (m_submode == InvertCaseSubMode
|
||||||
if (m_subsubmode == InvertCaseSubSubMode) {
|
|| m_submode == UpCaseSubMode
|
||||||
|
|| m_submode == DownCaseSubMode) {
|
||||||
|
if (m_submode == InvertCaseSubMode) {
|
||||||
invertCase(currentRange());
|
invertCase(currentRange());
|
||||||
if (!dotCommandMovement.isEmpty())
|
dotCommand = QString("g~");
|
||||||
setDotCommand(QLatin1Char('~') + dotCommandMovement);
|
} else if (m_submode == DownCaseSubMode) {
|
||||||
} else if (m_subsubmode == UpCaseSubSubMode) {
|
|
||||||
upCase(currentRange());
|
|
||||||
if (!dotCommandMovement.isEmpty())
|
|
||||||
setDotCommand("gU" + dotCommandMovement);
|
|
||||||
} else if (m_subsubmode == DownCaseSubSubMode) {
|
|
||||||
downCase(currentRange());
|
downCase(currentRange());
|
||||||
if (!dotCommandMovement.isEmpty())
|
dotCommand = QString("gu");
|
||||||
setDotCommand("gu" + dotCommandMovement);
|
} else if (m_submode == UpCaseSubMode) {
|
||||||
|
upCase(currentRange());
|
||||||
|
dotCommand = QString("gU");
|
||||||
}
|
}
|
||||||
m_submode = NoSubMode;
|
|
||||||
m_subsubmode = NoSubSubMode;
|
|
||||||
setPosition(qMin(anchor(), position()));
|
|
||||||
if (m_movetype == MoveLineWise)
|
if (m_movetype == MoveLineWise)
|
||||||
handleStartOfLine();
|
handleStartOfLine();
|
||||||
endEditBlock();
|
endEditBlock();
|
||||||
} else if (m_submode == IndentSubMode) {
|
} else if (m_submode == IndentSubMode
|
||||||
|
|| m_submode == ShiftRightSubMode
|
||||||
|
|| m_submode == ShiftLeftSubMode) {
|
||||||
recordJump();
|
recordJump();
|
||||||
setUndoPosition();
|
setUndoPosition();
|
||||||
indentSelectedText();
|
if (m_submode == IndentSubMode) {
|
||||||
m_submode = NoSubMode;
|
indentSelectedText();
|
||||||
if (!dotCommandMovement.isEmpty())
|
dotCommand = QString('=');
|
||||||
setDotCommand('=' + dotCommandMovement);
|
} else if (m_submode == ShiftRightSubMode) {
|
||||||
} else if (m_submode == ShiftRightSubMode) {
|
shiftRegionRight(1);
|
||||||
recordJump();
|
dotCommand = QString('>');
|
||||||
setUndoPosition();
|
} else if (m_submode == ShiftLeftSubMode) {
|
||||||
shiftRegionRight(1);
|
shiftRegionLeft(1);
|
||||||
m_submode = NoSubMode;
|
dotCommand = QString('<');
|
||||||
if (!dotCommandMovement.isEmpty())
|
}
|
||||||
setDotCommand('>' + dotCommandMovement);
|
|
||||||
} else if (m_submode == ShiftLeftSubMode) {
|
|
||||||
recordJump();
|
|
||||||
setUndoPosition();
|
|
||||||
shiftRegionLeft(1);
|
|
||||||
m_submode = NoSubMode;
|
|
||||||
if (!dotCommandMovement.isEmpty())
|
|
||||||
setDotCommand('<' + dotCommandMovement);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!dotCommand.isEmpty() && !dotCommandMovement.isEmpty())
|
||||||
|
setDotCommand(dotCommand + dotCommandMovement);
|
||||||
|
|
||||||
resetCommandMode();
|
resetCommandMode();
|
||||||
}
|
}
|
||||||
|
|
||||||
void FakeVimHandler::Private::resetCommandMode()
|
void FakeVimHandler::Private::resetCommandMode()
|
||||||
{
|
{
|
||||||
|
m_subsubmode = NoSubSubMode;
|
||||||
|
m_submode = NoSubMode;
|
||||||
m_movetype = MoveInclusive;
|
m_movetype = MoveInclusive;
|
||||||
m_mvcount.clear();
|
m_mvcount.clear();
|
||||||
m_opcount.clear();
|
m_opcount.clear();
|
||||||
@@ -2504,7 +2513,10 @@ static bool subModeCanUseTextObjects(int submode)
|
|||||||
|| submode == ChangeSubMode
|
|| submode == ChangeSubMode
|
||||||
|| submode == IndentSubMode
|
|| submode == IndentSubMode
|
||||||
|| submode == ShiftLeftSubMode
|
|| submode == ShiftLeftSubMode
|
||||||
|| submode == ShiftRightSubMode;
|
|| submode == ShiftRightSubMode
|
||||||
|
|| submode == InvertCaseSubMode
|
||||||
|
|| submode == DownCaseSubMode
|
||||||
|
|| submode == UpCaseSubMode;
|
||||||
}
|
}
|
||||||
|
|
||||||
EventResult FakeVimHandler::Private::handleCommandSubSubMode(const Input &input)
|
EventResult FakeVimHandler::Private::handleCommandSubSubMode(const Input &input)
|
||||||
@@ -2545,10 +2557,14 @@ EventResult FakeVimHandler::Private::handleCommandSubSubMode(const Input &input)
|
|||||||
else if (input.is('"') || input.is('\'') || input.is('`'))
|
else if (input.is('"') || input.is('\'') || input.is('`'))
|
||||||
selectQuotedStringTextObject(m_subsubdata.is('i'), input.asChar());
|
selectQuotedStringTextObject(m_subsubdata.is('i'), input.asChar());
|
||||||
m_subsubmode = NoSubSubMode;
|
m_subsubmode = NoSubSubMode;
|
||||||
finishMovement(QString("%1%2%3")
|
if (cursor().hasSelection()) {
|
||||||
.arg(count())
|
finishMovement(QString("%1%2%3")
|
||||||
.arg(m_subsubdata.text())
|
.arg(count())
|
||||||
.arg(input.text()));
|
.arg(m_subsubdata.text())
|
||||||
|
.arg(input.text()));
|
||||||
|
} else {
|
||||||
|
resetCommandMode();
|
||||||
|
}
|
||||||
} else if (m_subsubmode == MarkSubSubMode) {
|
} else if (m_subsubmode == MarkSubSubMode) {
|
||||||
setMark(input.asChar().unicode(), position());
|
setMark(input.asChar().unicode(), position());
|
||||||
m_subsubmode = NoSubSubMode;
|
m_subsubmode = NoSubSubMode;
|
||||||
@@ -2642,10 +2658,11 @@ EventResult FakeVimHandler::Private::handleCommandMode(const Input &input)
|
|||||||
m_rangemode = RangeCharMode;
|
m_rangemode = RangeCharMode;
|
||||||
leaveVisualMode();
|
leaveVisualMode();
|
||||||
Range range = currentRange();
|
Range range = currentRange();
|
||||||
|
if (m_rangemode == RangeCharMode)
|
||||||
|
++range.endPos;
|
||||||
Transformation tr =
|
Transformation tr =
|
||||||
&FakeVimHandler::Private::replaceByCharTransform;
|
&FakeVimHandler::Private::replaceByCharTransform;
|
||||||
transformText(range, tr, input.asChar());
|
transformText(range, tr, input.asChar());
|
||||||
setPosition(range.beginPos);
|
|
||||||
} else if (count() <= rightDist()) {
|
} else if (count() <= rightDist()) {
|
||||||
setUndoPosition();
|
setUndoPosition();
|
||||||
setAnchor();
|
setAnchor();
|
||||||
@@ -2665,27 +2682,20 @@ EventResult FakeVimHandler::Private::handleCommandMode(const Input &input)
|
|||||||
}
|
}
|
||||||
m_submode = NoSubMode;
|
m_submode = NoSubMode;
|
||||||
finishMovement();
|
finishMovement();
|
||||||
} else if (m_submode == ChangeSubMode && input.is('c')) { // tested
|
} else if ((m_submode == ChangeSubMode && input.is('c'))
|
||||||
|
|| (m_submode == DeleteSubMode && input.is('d'))) { // tested
|
||||||
m_movetype = MoveLineWise;
|
m_movetype = MoveLineWise;
|
||||||
setUndoPosition();
|
setUndoPosition();
|
||||||
const int line = cursorLine() + 1;
|
const int line = cursorLine() + 1;
|
||||||
const int anc = firstPositionInLine(line);
|
const int anc = firstPositionInLine(line);
|
||||||
const int pos = lastPositionInLine(line + count() - 1);
|
const int pos = lastPositionInLine(line + count() - 1);
|
||||||
setAnchorAndPosition(anc, pos);
|
setAnchorAndPosition(anc, pos);
|
||||||
m_lastInsertion.clear();
|
if (m_submode == ChangeSubMode) {
|
||||||
setDotCommand("%1cc", count());
|
m_lastInsertion.clear();
|
||||||
finishMovement();
|
setDotCommand("%1cc", count());
|
||||||
} else if (m_submode == DeleteSubMode && input.is('d')) { // tested
|
} else {
|
||||||
m_movetype = MoveLineWise;
|
setDotCommand("%1dd", count());
|
||||||
setUndoPosition();
|
}
|
||||||
int endPos = lastPositionInLine(cursorLine() + count());
|
|
||||||
Range range(position(), endPos, RangeLineMode);
|
|
||||||
yankText(range);
|
|
||||||
removeText(range);
|
|
||||||
setDotCommand("%1dd", count());
|
|
||||||
m_submode = NoSubMode;
|
|
||||||
handleStartOfLine();
|
|
||||||
setTargetColumn();
|
|
||||||
finishMovement();
|
finishMovement();
|
||||||
} else if (m_submode == ZSubMode) {
|
} else if (m_submode == ZSubMode) {
|
||||||
//qDebug() << "Z_MODE " << cursorLine() << linesOnScreen();
|
//qDebug() << "Z_MODE " << cursorLine() << linesOnScreen();
|
||||||
@@ -2933,7 +2943,14 @@ EventResult FakeVimHandler::Private::handleCommandMode1(const Input &input)
|
|||||||
leaveVisualMode();
|
leaveVisualMode();
|
||||||
}
|
}
|
||||||
} else if (input.is('%')) {
|
} else if (input.is('%')) {
|
||||||
moveToMatchingParanthesis();
|
if (count() == 1) {
|
||||||
|
moveToMatchingParanthesis();
|
||||||
|
} else {
|
||||||
|
// set cursor position in percentage - formula taken from Vim help
|
||||||
|
setPosition(firstPositionInLine((count() * linesInDocument() + 99) / 100));
|
||||||
|
moveToTargetColumn();
|
||||||
|
handleStartOfLine();
|
||||||
|
}
|
||||||
finishMovement();
|
finishMovement();
|
||||||
} else if ((!isVisualMode() && input.is('a')) || (isVisualMode() && input.is('A'))) {
|
} else if ((!isVisualMode() && input.is('a')) || (isVisualMode() && input.is('A'))) {
|
||||||
leaveVisualMode();
|
leaveVisualMode();
|
||||||
@@ -3257,7 +3274,6 @@ EventResult FakeVimHandler::Private::handleCommandMode2(const Input &input)
|
|||||||
bool insertAfter = input.is('o');
|
bool insertAfter = input.is('o');
|
||||||
setDotCommand(insertAfter ? "%1o" : "%1O", count());
|
setDotCommand(insertAfter ? "%1o" : "%1O", count());
|
||||||
setUndoPosition();
|
setUndoPosition();
|
||||||
breakEditBlock();
|
|
||||||
enterInsertMode();
|
enterInsertMode();
|
||||||
// Insert new line so that command can be repeated [count] times inserting new line
|
// Insert new line so that command can be repeated [count] times inserting new line
|
||||||
// each time without unfolding any lines.
|
// each time without unfolding any lines.
|
||||||
@@ -3270,11 +3286,12 @@ EventResult FakeVimHandler::Private::handleCommandMode2(const Input &input)
|
|||||||
} else {
|
} else {
|
||||||
setPosition(block.position());
|
setPosition(block.position());
|
||||||
}
|
}
|
||||||
handleInsertMode(Input('\n'));
|
beginEditBlock();
|
||||||
|
insertText(QString("\n"));
|
||||||
if (!appendLine)
|
if (!appendLine)
|
||||||
moveLeft();
|
moveUp();
|
||||||
joinPreviousEditBlock();
|
|
||||||
insertAutomaticIndentation(insertAfter);
|
insertAutomaticIndentation(insertAfter);
|
||||||
|
setTargetColumn();
|
||||||
endEditBlock();
|
endEditBlock();
|
||||||
} else if (input.isControl('o')) {
|
} else if (input.isControl('o')) {
|
||||||
jump(-count());
|
jump(-count());
|
||||||
@@ -3353,7 +3370,7 @@ EventResult FakeVimHandler::Private::handleCommandMode2(const Input &input)
|
|||||||
m_subsubdata = input;
|
m_subsubdata = input;
|
||||||
} else if (input.isControl('t')) {
|
} else if (input.isControl('t')) {
|
||||||
handleExCommand("pop");
|
handleExCommand("pop");
|
||||||
} else if (!m_gflag && input.is('u')) {
|
} else if (!m_gflag && input.is('u') && !isVisualMode() && m_submode == NoSubMode) {
|
||||||
int repeat = count();
|
int repeat = count();
|
||||||
while (--repeat >= 0)
|
while (--repeat >= 0)
|
||||||
undo();
|
undo();
|
||||||
@@ -3376,29 +3393,20 @@ EventResult FakeVimHandler::Private::handleCommandMode2(const Input &input)
|
|||||||
toggleVisualMode(VisualLineMode);
|
toggleVisualMode(VisualLineMode);
|
||||||
} else if (input.isControl('v')) {
|
} else if (input.isControl('v')) {
|
||||||
toggleVisualMode(VisualBlockMode);
|
toggleVisualMode(VisualBlockMode);
|
||||||
} else if (input.is('w')) { // tested
|
} else if (input.is('w') || input.is('W')) { // tested
|
||||||
// Special case: "cw" and "cW" work the same as "ce" and "cE" if the
|
// Special case: "cw" and "cW" work the same as "ce" and "cE" if the
|
||||||
// cursor is on a non-blank - except if the cursor is on the last
|
// cursor is on a non-blank - except if the cursor is on the last
|
||||||
// character of a word: only the current word will be changed
|
// character of a word: only the current word will be changed
|
||||||
|
bool simple = input.is('W');
|
||||||
if (m_submode == ChangeSubMode) {
|
if (m_submode == ChangeSubMode) {
|
||||||
moveToWordEnd(count(), false, true);
|
moveToWordEnd(count(), simple, true);
|
||||||
m_movetype = MoveInclusive;
|
m_movetype = MoveInclusive;
|
||||||
} else {
|
} else {
|
||||||
moveToNextWordStart(count(), false, true);
|
moveToNextWordStart(count(), simple, true);
|
||||||
m_movetype = MoveExclusive;
|
m_movetype = MoveExclusive;
|
||||||
}
|
}
|
||||||
setTargetColumn();
|
setTargetColumn();
|
||||||
finishMovement("%1w", count());
|
finishMovement(simple ? "%1W" : "%1w", count());
|
||||||
} else if (input.is('W')) {
|
|
||||||
if (m_submode == ChangeSubMode) {
|
|
||||||
moveToWordEnd(count(), true, true);
|
|
||||||
m_movetype = MoveInclusive;
|
|
||||||
} else {
|
|
||||||
moveToNextWordStart(count(), true, true);
|
|
||||||
m_movetype = MoveExclusive;
|
|
||||||
}
|
|
||||||
setTargetColumn();
|
|
||||||
finishMovement("%1W", count());
|
|
||||||
} else if (input.isControl('w')) {
|
} else if (input.isControl('w')) {
|
||||||
m_submode = WindowSubMode;
|
m_submode = WindowSubMode;
|
||||||
} else if (input.is('x') && isNoVisualMode()) { // = "dl"
|
} else if (input.is('x') && isNoVisualMode()) { // = "dl"
|
||||||
@@ -3463,22 +3471,31 @@ EventResult FakeVimHandler::Private::handleCommandMode2(const Input &input)
|
|||||||
m_submode = ZSubMode;
|
m_submode = ZSubMode;
|
||||||
} else if (input.is('Z')) {
|
} else if (input.is('Z')) {
|
||||||
m_submode = CapitalZSubMode;
|
m_submode = CapitalZSubMode;
|
||||||
} else if (!m_gflag && input.is('~') && !isVisualMode()) {
|
} else if ((m_submode == InvertCaseSubMode && input.is('~'))
|
||||||
|
|| (m_submode == DownCaseSubMode && input.is('u'))
|
||||||
|
|| (m_submode == UpCaseSubMode && input.is('U'))) {
|
||||||
|
if (!isFirstNonBlankOnLine(position())) {
|
||||||
|
moveToStartOfLine();
|
||||||
|
moveToFirstNonBlankOnLine();
|
||||||
|
}
|
||||||
|
setTargetColumn();
|
||||||
|
setUndoPosition();
|
||||||
|
setAnchor();
|
||||||
|
setPosition(lastPositionInLine(cursorLine() + count()) + 1);
|
||||||
|
finishMovement(QString("%1%2").arg(count()).arg(input.raw()));
|
||||||
|
} else if (!m_gflag && (input.is('~') || input.is('u') || input.is('U')) && !isVisualMode()) {
|
||||||
m_movetype = MoveExclusive;
|
m_movetype = MoveExclusive;
|
||||||
if (!atEndOfLine()) {
|
if (!atEndOfLine()) {
|
||||||
beginEditBlock();
|
beginEditBlock();
|
||||||
setAnchor();
|
setAnchor();
|
||||||
moveRight(qMin(count(), rightDist()));
|
moveRight(qMin(count(), rightDist()));
|
||||||
if (input.is('~')) {
|
if (input.is('~'))
|
||||||
invertCase(currentRange());
|
invertCase(currentRange());
|
||||||
setDotCommand("%1~", count());
|
else if (input.is('u'))
|
||||||
} else if (input.is('u')) {
|
|
||||||
downCase(currentRange());
|
downCase(currentRange());
|
||||||
setDotCommand("%1gu", count());
|
else if (input.is('U'))
|
||||||
} else if (input.is('U')) {
|
|
||||||
upCase(currentRange());
|
upCase(currentRange());
|
||||||
setDotCommand("%1gU", count());
|
setDotCommand("%1" + input.raw(), count());
|
||||||
}
|
|
||||||
endEditBlock();
|
endEditBlock();
|
||||||
}
|
}
|
||||||
finishMovement();
|
finishMovement();
|
||||||
@@ -3490,16 +3507,15 @@ EventResult FakeVimHandler::Private::handleCommandMode2(const Input &input)
|
|||||||
if (atEndOfLine())
|
if (atEndOfLine())
|
||||||
moveLeft();
|
moveLeft();
|
||||||
setAnchor();
|
setAnchor();
|
||||||
m_submode = TransformSubMode;
|
|
||||||
if (input.is('~'))
|
if (input.is('~'))
|
||||||
m_subsubmode = InvertCaseSubSubMode;
|
m_submode = InvertCaseSubMode;
|
||||||
if (input.is('u'))
|
if (input.is('u'))
|
||||||
m_subsubmode = DownCaseSubSubMode;
|
m_submode = DownCaseSubMode;
|
||||||
else if (input.is('U'))
|
else if (input.is('U'))
|
||||||
m_subsubmode = UpCaseSubSubMode;
|
m_submode = UpCaseSubMode;
|
||||||
} else if ((input.is('~') && isVisualMode())
|
} else if ((input.is('~') && isVisualMode())
|
||||||
|| (m_gflag && input.is('u') && isVisualMode())
|
|| (input.is('u') && isVisualMode())
|
||||||
|| (m_gflag && input.is('U') && isVisualMode())) {
|
|| (input.is('U') && isVisualMode())) {
|
||||||
m_gflag = false;
|
m_gflag = false;
|
||||||
m_movetype = MoveExclusive;
|
m_movetype = MoveExclusive;
|
||||||
if (isVisualLineMode())
|
if (isVisualLineMode())
|
||||||
@@ -3507,13 +3523,12 @@ EventResult FakeVimHandler::Private::handleCommandMode2(const Input &input)
|
|||||||
else if (isVisualBlockMode())
|
else if (isVisualBlockMode())
|
||||||
m_rangemode = RangeBlockMode;
|
m_rangemode = RangeBlockMode;
|
||||||
leaveVisualMode();
|
leaveVisualMode();
|
||||||
m_submode = TransformSubMode;
|
|
||||||
if (input.is('~'))
|
if (input.is('~'))
|
||||||
m_subsubmode = InvertCaseSubSubMode;
|
m_submode = InvertCaseSubMode;
|
||||||
else if (input.is('u'))
|
else if (input.is('u'))
|
||||||
m_subsubmode = DownCaseSubSubMode;
|
m_submode = DownCaseSubMode;
|
||||||
else if (input.is('U'))
|
else if (input.is('U'))
|
||||||
m_subsubmode = UpCaseSubSubMode;
|
m_submode = UpCaseSubMode;
|
||||||
finishMovement();
|
finishMovement();
|
||||||
} else if (input.is('[')) {
|
} else if (input.is('[')) {
|
||||||
m_submode = OpenSquareSubMode;
|
m_submode = OpenSquareSubMode;
|
||||||
@@ -4728,7 +4743,7 @@ void FakeVimHandler::Private::search(const SearchData &sd, bool showMessages)
|
|||||||
|
|
||||||
if (tc.isNull()) {
|
if (tc.isNull()) {
|
||||||
if (hasConfig(ConfigWrapScan)) {
|
if (hasConfig(ConfigWrapScan)) {
|
||||||
int startPos = sd.forward ? 0 : lastPositionInDocument();
|
int startPos = sd.forward ? 0 : lastPositionInDocument(true);
|
||||||
tc = document()->find(needleExp, startPos, flags);
|
tc = document()->find(needleExp, startPos, flags);
|
||||||
while (!tc.isNull() && --repeat >= 1)
|
while (!tc.isNull() && --repeat >= 1)
|
||||||
tc = document()->find(needleExp, tc, flags);
|
tc = document()->find(needleExp, tc, flags);
|
||||||
@@ -4842,15 +4857,11 @@ void FakeVimHandler::Private::indentSelectedText(QChar typedChar)
|
|||||||
|
|
||||||
void FakeVimHandler::Private::indentText(const Range &range, QChar typedChar)
|
void FakeVimHandler::Private::indentText(const Range &range, QChar typedChar)
|
||||||
{
|
{
|
||||||
int beginLine = lineForPosition(range.beginPos);
|
int beginBlock = document()->findBlock(range.beginPos).blockNumber();
|
||||||
int endLine = lineForPosition(range.endPos);
|
int endBlock = document()->findBlock(range.endPos).blockNumber();
|
||||||
if (beginLine > endLine)
|
if (beginBlock > endBlock)
|
||||||
qSwap(beginLine, endLine);
|
qSwap(beginBlock, endBlock);
|
||||||
|
emit q->indentRegion(beginBlock, endBlock, typedChar);
|
||||||
// LineForPosition has returned 1-based line numbers.
|
|
||||||
emit q->indentRegion(beginLine - 1, endLine - 1, typedChar);
|
|
||||||
if (beginLine != endLine)
|
|
||||||
showMessage(MessageError, "MARKS ARE OFF NOW");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FakeVimHandler::Private::isElectricCharacter(QChar c) const
|
bool FakeVimHandler::Private::isElectricCharacter(QChar c) const
|
||||||
@@ -5260,10 +5271,10 @@ void FakeVimHandler::Private::scrollUp(int count)
|
|||||||
scrollToLine(cursorLine() - cursorLineOnScreen() - count);
|
scrollToLine(cursorLine() - cursorLineOnScreen() - count);
|
||||||
}
|
}
|
||||||
|
|
||||||
int FakeVimHandler::Private::lastPositionInDocument() const
|
int FakeVimHandler::Private::lastPositionInDocument(bool ignoreMode) const
|
||||||
{
|
{
|
||||||
QTextBlock block = document()->lastBlock();
|
return document()->characterCount()
|
||||||
return block.position() + block.length() - 1;
|
- (ignoreMode || isVisualMode() || m_mode == InsertMode || m_mode == ReplaceMode ? 1 : 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
QString FakeVimHandler::Private::selectText(const Range &range) const
|
QString FakeVimHandler::Private::selectText(const Range &range) const
|
||||||
@@ -5279,7 +5290,7 @@ QString FakeVimHandler::Private::selectText(const Range &range) const
|
|||||||
int firstPos = firstPositionInLine(lineForPosition(range.beginPos));
|
int firstPos = firstPositionInLine(lineForPosition(range.beginPos));
|
||||||
int lastLine = lineForPosition(range.endPos);
|
int lastLine = lineForPosition(range.endPos);
|
||||||
bool endOfDoc = lastLine == lineNumber(document()->lastBlock());
|
bool endOfDoc = lastLine == lineNumber(document()->lastBlock());
|
||||||
int lastPos = endOfDoc ? lastPositionInDocument() : firstPositionInLine(lastLine + 1);
|
int lastPos = endOfDoc ? lastPositionInDocument(true) : firstPositionInLine(lastLine + 1);
|
||||||
tc.setPosition(firstPos, MoveAnchor);
|
tc.setPosition(firstPos, MoveAnchor);
|
||||||
tc.setPosition(lastPos, KeepAnchor);
|
tc.setPosition(lastPos, KeepAnchor);
|
||||||
return tc.selection().toPlainText() + QString((endOfDoc? "\n" : ""));
|
return tc.selection().toPlainText() + QString((endOfDoc? "\n" : ""));
|
||||||
@@ -5323,6 +5334,7 @@ void FakeVimHandler::Private::transformText(const Range &range,
|
|||||||
Transformation transformFunc, const QVariant &extra)
|
Transformation transformFunc, const QVariant &extra)
|
||||||
{
|
{
|
||||||
QTextCursor tc = cursor();
|
QTextCursor tc = cursor();
|
||||||
|
int posAfter = range.beginPos;
|
||||||
switch (range.rangemode) {
|
switch (range.rangemode) {
|
||||||
case RangeCharMode: {
|
case RangeCharMode: {
|
||||||
// This can span multiple lines.
|
// This can span multiple lines.
|
||||||
@@ -5331,10 +5343,9 @@ void FakeVimHandler::Private::transformText(const Range &range,
|
|||||||
tc.setPosition(range.endPos, KeepAnchor);
|
tc.setPosition(range.endPos, KeepAnchor);
|
||||||
TransformationData td(tc.selectedText(), extra);
|
TransformationData td(tc.selectedText(), extra);
|
||||||
(this->*transformFunc)(&td);
|
(this->*transformFunc)(&td);
|
||||||
tc.removeSelectedText();
|
|
||||||
tc.insertText(td.to);
|
tc.insertText(td.to);
|
||||||
endEditBlock();
|
endEditBlock();
|
||||||
return;
|
break;
|
||||||
}
|
}
|
||||||
case RangeLineMode:
|
case RangeLineMode:
|
||||||
case RangeLineModeExclusive: {
|
case RangeLineModeExclusive: {
|
||||||
@@ -5362,10 +5373,10 @@ void FakeVimHandler::Private::transformText(const Range &range,
|
|||||||
}
|
}
|
||||||
TransformationData td(tc.selectedText(), extra);
|
TransformationData td(tc.selectedText(), extra);
|
||||||
(this->*transformFunc)(&td);
|
(this->*transformFunc)(&td);
|
||||||
tc.removeSelectedText();
|
posAfter = tc.anchor();
|
||||||
tc.insertText(td.to);
|
tc.insertText(td.to);
|
||||||
endEditBlock();
|
endEditBlock();
|
||||||
return;
|
break;
|
||||||
}
|
}
|
||||||
case RangeBlockAndTailMode:
|
case RangeBlockAndTailMode:
|
||||||
case RangeBlockMode: {
|
case RangeBlockMode: {
|
||||||
@@ -5386,13 +5397,16 @@ void FakeVimHandler::Private::transformText(const Range &range,
|
|||||||
tc.setPosition(block.position() + eCol, KeepAnchor);
|
tc.setPosition(block.position() + eCol, KeepAnchor);
|
||||||
TransformationData td(tc.selectedText(), extra);
|
TransformationData td(tc.selectedText(), extra);
|
||||||
(this->*transformFunc)(&td);
|
(this->*transformFunc)(&td);
|
||||||
tc.removeSelectedText();
|
|
||||||
tc.insertText(td.to);
|
tc.insertText(td.to);
|
||||||
block = block.previous();
|
block = block.previous();
|
||||||
}
|
}
|
||||||
endEditBlock();
|
endEditBlock();
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setPosition(posAfter);
|
||||||
|
setTargetColumn();
|
||||||
}
|
}
|
||||||
|
|
||||||
void FakeVimHandler::Private::insertText(const Register ®)
|
void FakeVimHandler::Private::insertText(const Register ®)
|
||||||
@@ -5459,7 +5473,13 @@ void FakeVimHandler::Private::replaceByStringTransform(TransformationData *td)
|
|||||||
|
|
||||||
void FakeVimHandler::Private::replaceByCharTransform(TransformationData *td)
|
void FakeVimHandler::Private::replaceByCharTransform(TransformationData *td)
|
||||||
{
|
{
|
||||||
td->to = QString(td->from.size(), td->extraData.toChar());
|
// Replace each character but preserve lines.
|
||||||
|
const int len = td->from.size();
|
||||||
|
td->to = QString(len, td->extraData.toChar());
|
||||||
|
for (int i = 0; i < len; ++i) {
|
||||||
|
if (td->from.at(i) == ParagraphSeparator)
|
||||||
|
td->to[i] = ParagraphSeparator;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void FakeVimHandler::Private::pasteText(bool afterCursor)
|
void FakeVimHandler::Private::pasteText(bool afterCursor)
|
||||||
@@ -5500,10 +5520,14 @@ void FakeVimHandler::Private::pasteText(bool afterCursor)
|
|||||||
switch (rangeMode) {
|
switch (rangeMode) {
|
||||||
case RangeCharMode: {
|
case RangeCharMode: {
|
||||||
m_targetColumn = 0;
|
m_targetColumn = 0;
|
||||||
|
const int pos = position() + 1;
|
||||||
if (pasteAfter && rightDist() > 0)
|
if (pasteAfter && rightDist() > 0)
|
||||||
moveRight();
|
moveRight();
|
||||||
insertText(text.repeated(count()));
|
insertText(text.repeated(count()));
|
||||||
moveLeft();
|
if (text.contains('\n'))
|
||||||
|
setPosition(pos);
|
||||||
|
else
|
||||||
|
moveLeft();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case RangeLineMode:
|
case RangeLineMode:
|
||||||
@@ -5514,16 +5538,21 @@ void FakeVimHandler::Private::pasteText(bool afterCursor)
|
|||||||
else
|
else
|
||||||
moveToStartOfLine();
|
moveToStartOfLine();
|
||||||
m_targetColumn = 0;
|
m_targetColumn = 0;
|
||||||
|
bool lastLine = false;
|
||||||
if (pasteAfter) {
|
if (pasteAfter) {
|
||||||
bool lastLine = document()->lastBlock() == this->block();
|
lastLine = document()->lastBlock() == this->block();
|
||||||
if (lastLine) {
|
if (lastLine) {
|
||||||
tc.movePosition(EndOfLine, MoveAnchor);
|
tc.movePosition(EndOfLine, MoveAnchor);
|
||||||
tc.insertBlock();
|
tc.insertBlock();
|
||||||
}
|
}
|
||||||
moveDown();
|
moveDown();
|
||||||
}
|
}
|
||||||
const int pos = position();
|
const int pos = position() - lastLine;
|
||||||
insertText(text.repeated(count()));
|
// do not insert empty line at the end of document
|
||||||
|
if (lastLine)
|
||||||
|
insertText(text.repeated(count()).left(text.size() * count() - 1));
|
||||||
|
else
|
||||||
|
insertText(text.repeated(count()));
|
||||||
setPosition(pos);
|
setPosition(pos);
|
||||||
moveToFirstNonBlankOnLine();
|
moveToFirstNonBlankOnLine();
|
||||||
break;
|
break;
|
||||||
@@ -5584,7 +5613,6 @@ void FakeVimHandler::Private::setLineContents(int line, const QString &contents)
|
|||||||
const int len = block.length();
|
const int len = block.length();
|
||||||
tc.setPosition(begin);
|
tc.setPosition(begin);
|
||||||
tc.setPosition(begin + len - 1, KeepAnchor);
|
tc.setPosition(begin + len - 1, KeepAnchor);
|
||||||
tc.removeSelectedText();
|
|
||||||
tc.insertText(contents);
|
tc.insertText(contents);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -5678,20 +5706,21 @@ int FakeVimHandler::Private::firstPositionInLine(int line, bool onlyVisibleLines
|
|||||||
|
|
||||||
int FakeVimHandler::Private::lastPositionInLine(int line, bool onlyVisibleLines) const
|
int FakeVimHandler::Private::lastPositionInLine(int line, bool onlyVisibleLines) const
|
||||||
{
|
{
|
||||||
|
QTextBlock block;
|
||||||
if (onlyVisibleLines) {
|
if (onlyVisibleLines) {
|
||||||
// respect folds
|
// respect folds
|
||||||
QTextBlock block = document()->findBlockByLineNumber(line);
|
block = document()->findBlockByLineNumber(line);
|
||||||
if (block.isValid()) {
|
if (block.isValid()) {
|
||||||
if (line > 0)
|
if (line > 0)
|
||||||
block = block.previous();
|
block = block.previous();
|
||||||
} else {
|
} else {
|
||||||
block = document()->lastBlock();
|
block = document()->lastBlock();
|
||||||
}
|
}
|
||||||
return block.position() + block.length() - 1;
|
} else {
|
||||||
|
block = document()->findBlockByNumber(line - 1);
|
||||||
}
|
}
|
||||||
|
return block.position() + qMax(2, block.length())
|
||||||
QTextBlock block = document()->findBlockByNumber(line - 1);
|
- (isVisualMode() || m_mode == InsertMode || m_mode == ReplaceMode ? 1 : 2);
|
||||||
return block.position() + block.length() - 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int FakeVimHandler::Private::lineForPosition(int pos) const
|
int FakeVimHandler::Private::lineForPosition(int pos) const
|
||||||
@@ -6118,7 +6147,7 @@ void FakeVimHandler::Private::selectBlockTextObject(bool inner,
|
|||||||
|
|
||||||
if (inner) {
|
if (inner) {
|
||||||
p1 += sleft.size();
|
p1 += sleft.size();
|
||||||
--p2;
|
p2 = qMax(p1, p2 - 1);
|
||||||
} else {
|
} else {
|
||||||
p2 -= sright.size() - 1;
|
p2 -= sright.size() - 1;
|
||||||
}
|
}
|
||||||
@@ -6136,7 +6165,7 @@ void FakeVimHandler::Private::changeNumberTextObject(int count)
|
|||||||
{
|
{
|
||||||
QTextCursor tc = cursor();
|
QTextCursor tc = cursor();
|
||||||
int pos = tc.position();
|
int pos = tc.position();
|
||||||
const int n = lastPositionInLine(lineForPosition(pos));
|
const int n = lastPositionInLine(lineForPosition(pos)) + 1;
|
||||||
QTextDocument *doc = document();
|
QTextDocument *doc = document();
|
||||||
QChar c = doc->characterAt(pos);
|
QChar c = doc->characterAt(pos);
|
||||||
while (!c.isNumber()) {
|
while (!c.isNumber()) {
|
||||||
@@ -6160,7 +6189,7 @@ void FakeVimHandler::Private::changeNumberTextObject(int count)
|
|||||||
value += count;
|
value += count;
|
||||||
QString repl = QString::fromLatin1("%1").arg(value);
|
QString repl = QString::fromLatin1("%1").arg(value);
|
||||||
replaceText(currentRange(), repl);
|
replaceText(currentRange(), repl);
|
||||||
moveLeft();
|
setPosition(p1 + repl.size() - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FakeVimHandler::Private::selectQuotedStringTextObject(bool inner,
|
void FakeVimHandler::Private::selectQuotedStringTextObject(bool inner,
|
||||||
@@ -6183,7 +6212,7 @@ void FakeVimHandler::Private::selectQuotedStringTextObject(bool inner,
|
|||||||
int p1 = tc1.position();
|
int p1 = tc1.position();
|
||||||
int p2 = tc2.position();
|
int p2 = tc2.position();
|
||||||
if (inner) {
|
if (inner) {
|
||||||
p2 -= sz + 1;
|
p2 = qMax(p1, p2 - sz - 1);
|
||||||
if (document()->characterAt(p1) == ParagraphSeparator)
|
if (document()->characterAt(p1) == ParagraphSeparator)
|
||||||
++p1;
|
++p1;
|
||||||
} else {
|
} else {
|
||||||
|
@@ -859,7 +859,7 @@ private slots:
|
|||||||
void highlightMatches(const QString &needle);
|
void highlightMatches(const QString &needle);
|
||||||
void moveToMatchingParenthesis(bool *moved, bool *forward, QTextCursor *cursor);
|
void moveToMatchingParenthesis(bool *moved, bool *forward, QTextCursor *cursor);
|
||||||
void checkForElectricCharacter(bool *result, QChar c);
|
void checkForElectricCharacter(bool *result, QChar c);
|
||||||
void indentRegion(int beginLine, int endLine, QChar typedChar);
|
void indentRegion(int beginBlock, int endBlock, QChar typedChar);
|
||||||
void handleExCommand(bool *handled, const ExCommand &cmd);
|
void handleExCommand(bool *handled, const ExCommand &cmd);
|
||||||
|
|
||||||
void writeSettings();
|
void writeSettings();
|
||||||
@@ -1778,7 +1778,7 @@ void FakeVimPluginPrivate::moveToMatchingParenthesis(bool *moved, bool *forward,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void FakeVimPluginPrivate::indentRegion(int beginLine, int endLine,
|
void FakeVimPluginPrivate::indentRegion(int beginBlock, int endBlock,
|
||||||
QChar typedChar)
|
QChar typedChar)
|
||||||
{
|
{
|
||||||
FakeVimHandler *handler = qobject_cast<FakeVimHandler *>(sender());
|
FakeVimHandler *handler = qobject_cast<FakeVimHandler *>(sender());
|
||||||
@@ -1796,14 +1796,14 @@ void FakeVimPluginPrivate::indentRegion(int beginLine, int endLine,
|
|||||||
? TabSettings::SpacesOnlyTabPolicy : TabSettings::TabsOnlyTabPolicy;
|
? TabSettings::SpacesOnlyTabPolicy : TabSettings::TabsOnlyTabPolicy;
|
||||||
|
|
||||||
QTextDocument *doc = bt->document();
|
QTextDocument *doc = bt->document();
|
||||||
QTextBlock startBlock = doc->findBlockByNumber(beginLine);
|
QTextBlock startBlock = doc->findBlockByNumber(beginBlock);
|
||||||
|
|
||||||
// Record line lenghts for mark adjustments
|
// Record line lenghts for mark adjustments
|
||||||
QVector<int> lineLengths(endLine - beginLine + 1);
|
QVector<int> lineLengths(endBlock - beginBlock + 1);
|
||||||
QTextBlock block = startBlock;
|
QTextBlock block = startBlock;
|
||||||
|
|
||||||
for (int i = beginLine; i <= endLine; ++i) {
|
for (int i = beginBlock; i <= endBlock; ++i) {
|
||||||
lineLengths[i - beginLine] = block.text().length();
|
lineLengths[i - beginBlock] = block.text().length();
|
||||||
if (typedChar == 0 && block.text().simplified().isEmpty()) {
|
if (typedChar == 0 && block.text().simplified().isEmpty()) {
|
||||||
// clear empty lines
|
// clear empty lines
|
||||||
QTextCursor cursor(block);
|
QTextCursor cursor(block);
|
||||||
|
@@ -67,6 +67,7 @@ private slots:
|
|||||||
void test_vim_delete_inner_word();
|
void test_vim_delete_inner_word();
|
||||||
void test_vim_delete_a_word();
|
void test_vim_delete_a_word();
|
||||||
void test_vim_change_a_word();
|
void test_vim_change_a_word();
|
||||||
|
void test_vim_change_replace();
|
||||||
void test_vim_block_selection();
|
void test_vim_block_selection();
|
||||||
void test_vim_repeat();
|
void test_vim_repeat();
|
||||||
void test_vim_search();
|
void test_vim_search();
|
||||||
@@ -74,6 +75,8 @@ private slots:
|
|||||||
void test_vim_marks();
|
void test_vim_marks();
|
||||||
void test_vim_copy_paste();
|
void test_vim_copy_paste();
|
||||||
void test_vim_undo_redo();
|
void test_vim_undo_redo();
|
||||||
|
void test_vim_letter_case();
|
||||||
|
void test_vim_code_autoindent();
|
||||||
void test_vim_code_folding();
|
void test_vim_code_folding();
|
||||||
void test_advanced_commands();
|
void test_advanced_commands();
|
||||||
void test_map();
|
void test_map();
|
||||||
|
Reference in New Issue
Block a user