[frameworks/ktexteditor] /: vi-mode: Implement column cursor swap for v-block mode
Christoph Cullmann <[email protected]>
| Newsgroups | gmane.comp.kde.cvs |
|---|---|
| Message-ID | <[email protected]> |
Git commit 44219ecbbb44734a223b4367b09fbd1c02855032 by Christoph Cullmann, on behalf of Ismael Asensio.
Committed on 20/07/2026 at 21:35.
Pushed by cullmann into branch 'master'.
vi-mode: Implement column cursor swap for v-block mode
In visual modes, the command `o` moves the cursor to the other edge of
the selection range.
Implement also the uppercase command `O`. On visual block mode, it swaps
only the column of the selection range, keeping the cursor on the same
line, so one can reach all the four edges of the range.
On the other visual modes it behaves as the `o` command.
See: https://vimdoc.sourceforge.net/htmldoc/visual.html#visual-change
M +6 -0 autotests/src/vimode/modes.cpp
M +1 -1 src/view/kateview.h
M +10 -0 src/vimode/modes/normalvimode.cpp
M +1 -0 src/vimode/modes/normalvimode.h
M +11 -3 src/vimode/modes/visualvimode.cpp
M +1 -1 src/vimode/modes/visualvimode.h
https://invent.kde.org/frameworks/ktexteditor/-/commit/44219ecbbb44734a223b4367b09fbd1c02855032
diff --git a/autotests/src/vimode/modes.cpp b/autotests/src/vimode/modes.cpp
index b871ea5e8..2449c3087 100644
--- a/autotests/src/vimode/modes.cpp
+++ b/autotests/src/vimode/modes.cpp
@@ -1318,6 +1318,12 @@ void ModesTest::VisualCommandsTests()
DoTest("foobar", "lv2lo2ld", "fooar");
DoTest("foo\nbar", "jvllokld", "f");
DoTest("12\n12", "\\ctrl-vjlold", "1\n1");
+ DoTest("123\n456\n789", "\\ctrl-v2j2lojld", "123\n4\n7");
+
+ // Testing "O"
+ DoTest("foobar", "lv2lO2ld", "fooar");
+ DoTest("foo\nbar", "jvllOkld", "f");
+ DoTest("123\n456\n789", "\\ctrl-v2j2lOkld", "1\n4\n789");
// Testing "~"
DoTest("foobar", "lv2l~", "fOOBar");
diff --git a/src/view/kateview.h b/src/view/kateview.h
index e3cecad92..2d71d12ad 100644
--- a/src/view/kateview.h
+++ b/src/view/kateview.h
@@ -1257,7 +1257,7 @@ public:
int firstDisplayedLineInternal(LineType lineType) const;
int lastDisplayedLineInternal(LineType lineType) const;
-
+
int visibleToRealLineInternal(int visibleLine) const;
int realToVisibleLineInternal(int realLine) const;
diff --git a/src/vimode/modes/normalvimode.cpp b/src/vimode/modes/normalvimode.cpp
index f5abefdf6..b391c2f2d 100644
--- a/src/vimode/modes/normalvimode.cpp
+++ b/src/vimode/modes/normalvimode.cpp
@@ -635,6 +635,16 @@ bool NormalViMode::commandToOtherEnd()
return false;
}
+bool NormalViMode::commandToOtherEndColumn()
+{
+ if (m_viInputModeManager->isAnyVisualMode()) {
+ m_viInputModeManager->getViVisualMode()->switchStartEnd(true);
+ return true;
+ }
+
+ return false;
+}
+
bool NormalViMode::commandEnterReplaceMode()
{
m_stickyColumn = -1;
diff --git a/src/vimode/modes/normalvimode.h b/src/vimode/modes/normalvimode.h
index be4154086..e84b08ee1 100644
--- a/src/vimode/modes/normalvimode.h
+++ b/src/vimode/modes/normalvimode.h
@@ -56,6 +56,7 @@ public:
bool commandEnterVisualBlockMode();
bool commandReselectVisual();
bool commandToOtherEnd();
+ bool commandToOtherEndColumn();
bool commandEnterReplaceMode();
diff --git a/src/vimode/modes/visualvimode.cpp b/src/vimode/modes/visualvimode.cpp
index 6c601c597..6d95c45d3 100644
--- a/src/vimode/modes/visualvimode.cpp
+++ b/src/vimode/modes/visualvimode.cpp
@@ -185,10 +185,17 @@ void VisualViMode::setVisualModeType(ViMode mode)
m_mode = mode;
}
-void VisualViMode::switchStartEnd()
+void VisualViMode::switchStartEnd(bool swapOnlyColumn)
{
- KTextEditor::Cursor c = m_start;
- m_start = m_view->cursorPosition();
+ KTextEditor::Cursor c = m_view->cursorPosition();
+
+ c.setColumn(m_start.column());
+ m_start.setColumn(m_view->cursorPosition().column());
+
+ if (!swapOnlyColumn || m_mode != ViMode::VisualBlockMode) {
+ c.setLine(m_start.line());
+ m_start.setLine(m_view->cursorPosition().line());
+ }
updateCursor(c);
@@ -277,6 +284,7 @@ const std::vector<Command> &VisualViMode::commands()
ADDCMD("V", commandEnterVisualLineMode, SHOULD_NOT_RESET),
ADDCMD("<c-v>", commandEnterVisualBlockMode, SHOULD_NOT_RESET),
ADDCMD("o", commandToOtherEnd, SHOULD_NOT_RESET | CAN_LAND_INSIDE_FOLDING_RANGE),
+ ADDCMD("O", commandToOtherEndColumn, SHOULD_NOT_RESET | CAN_LAND_INSIDE_FOLDING_RANGE),
ADDCMD("=", commandAlignLines, SHOULD_NOT_RESET),
ADDCMD("~", commandChangeCase, IS_CHANGE),
ADDCMD("I", commandPrependToBlock, IS_CHANGE),
diff --git a/src/vimode/modes/visualvimode.h b/src/vimode/modes/visualvimode.h
index dc9086b3a..8613c5da9 100644
--- a/src/vimode/modes/visualvimode.h
+++ b/src/vimode/modes/visualvimode.h
@@ -34,7 +34,7 @@ public:
return m_mode == VisualBlockMode;
}
- void switchStartEnd();
+ void switchStartEnd(bool swapOnlyColumn = false);
void reset() override;
void setVisualModeType(const ViMode mode);
void saveRangeMarks();