Skip to content

Commit

Permalink
Add v_O go to other end
Browse files Browse the repository at this point in the history
  • Loading branch information
eugenesvk committed Jan 8, 2024
1 parent 2a0c462 commit d529353
Show file tree
Hide file tree
Showing 7 changed files with 74 additions and 14 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Expand Up @@ -52,6 +52,7 @@ All notable changes are documented in this file using the [Keep a CHANGELOG](htt

### Added

- [#976](https://github.com/NeoVintageous/NeoVintageous/issues/976): `O` in Visual mode: Go to Other end of highlighted text. This is like "o", but in Visual block mode the cursor moves to the other corner in the same line.
- [#973](https://github.com/NeoVintageous/NeoVintageous/issues/973): `tabp[revious] [N]` now navigates to the `[N]`th previous tab, defaulting to one.
- [#972](https://github.com/NeoVintageous/NeoVintageous/issues/972): `tabn[ext] [N]` now takes you to the `[N]`th next tab, defaulting to one.
- [#971](https://github.com/NeoVintageous/NeoVintageous/issues/971): `bp[revious] [N]` now directs you to the `[N]`th previous buffer in the buffer list, defaulting to one.
Expand Down
15 changes: 12 additions & 3 deletions ROADMAP.md
Expand Up @@ -53,6 +53,8 @@
- [2. Multiple repeats](#2-multiple-repeats)
- [3. Complex repeats](#3-complex-repeats)
- [Using the Visual mode (selecting a text area)](#using-the-visual-mode-selecting-a-text-area-visualtxt)
- [2. Starting and stopping Visual mode](#2-starting-and-stopping-visual-mode)
- [3. Changing the Visual area](#3-changing-the-visual-area)
- [Various remaining commands](#various-remaining-commands-varioustxt)
- [Command-line editing](#command-line-editing-cmdlinetxt)
- [1. Command-line editing](#1-command-line-editing)
Expand Down Expand Up @@ -688,6 +690,8 @@ last one.

## Using the Visual mode (selecting a text area) `|visual.txt|`

### 2. Starting and stopping Visual mode

| Status | Command | Description
| :----------------- | :---------------------------- | -----------
| :heavy_check_mark: | `v` | Start Visual mode per character
Expand All @@ -696,9 +700,14 @@ last one.
| :heavy_check_mark: | `gv` | Start visual mode with the same area as the previous area and the same mode
| :heavy_check_mark: | `gn` | Search forward for the last used search pattern, like with `n`, and start Visual mode to select the match.
| :heavy_check_mark: | `gN` | Like `gn` but searches backward, like with `N`
| :heavy_check_mark: | `o` | Go to other end of highlighted text
| | `O` | Like "o", but in Visual block mode the cursor moves to the other corner in the same line
| :heavy_check_mark: | `<Esc>`, `CTRL-C` | Stop Visual mode
| :heavy_check_mark: | `<Esc>` or `CTRL-C` | Stop Visual mode.

### 3. Changing the Visual area

| Status | Command | Description
| :----------------- | :---------------------------- | -----------
| :heavy_check_mark: | `o` | Go to Other end of highlighted text: The current cursor position becomes the start of the highlighted text and the cursor is moved to the other end of the highlighted text. The highlighted area remains the same.
| :heavy_check_mark: | `O` | Go to Other end of highlighted text. This is like "o", but in Visual block mode the cursor moves to the other corner in the same line. The highlighted area remains the same.

## Various remaining commands `|various.txt|`

Expand Down
22 changes: 13 additions & 9 deletions nv/commands.py
Expand Up @@ -1186,15 +1186,19 @@ def f(view, s):

class nv_vi_visual_o(TextCommand):

def run(self, edit, mode=None, count=1, register=None):
def f(view, s):
if mode in (VISUAL, VISUAL_LINE):
s = Region(s.b, s.a)

return s

regions_transformer(self.view, f)
self.view.show(self.view.sel()[0].b, False)
def run(self, edit, mode=None, count=1, register=None, same_line_if_visual_block: bool = False):
if mode == VISUAL_BLOCK:
visual_block = VisualBlockSelection(self.view)
visual_block.transform_to_other_end(
same_line=same_line_if_visual_block)
self.view.show(visual_block.b, False)
else:
def f(view, s):
if mode in (VISUAL, VISUAL_LINE):
s = Region(s.b, s.a)
return s
regions_transformer(self.view, f)
self.view.show(self.view.sel()[0].b, False)


class nv_vi_yy(TextCommand):
Expand Down
8 changes: 8 additions & 0 deletions nv/utils.py
Expand Up @@ -1006,6 +1006,14 @@ def transform_reverse(self):
sel.b = b
self.view.sel().add(sel)

def transform_to_other_end(self, same_line: bool = False):
if not same_line:
self._set_direction(
DIRECTION_UP
if self.is_direction_down()
else DIRECTION_DOWN)
self.transform_reverse()

def _transform(self, region: Region) -> None:
set_selection(self.view, region)

Expand Down
16 changes: 14 additions & 2 deletions nv/vi/cmd_defs.py
Expand Up @@ -53,15 +53,27 @@ def init(self):
self.command = 'nv_vi_d'


@assign(seqs.SEQ['⇧o'], ACTION_MODES)
@assign_text(['InsertLineBefore'], ACTION_MODES)
@assign(seqs.SEQ['⇧o'], (NORMAL,))
@assign_text(['InsertLineBefore'], (NORMAL,))
class ViInsertLineBefore(ViOperatorDef):
def init(self):
self.scroll_into_view = True
self.glue_until_normal_mode = True
self.command = 'nv_vi_big_o'


@assign(seqs.SEQ['⇧o'], (VISUAL, VISUAL_LINE, VISUAL_BLOCK))
@assign_text(['GoToOtherBigEnd'], (VISUAL, VISUAL_LINE, VISUAL_BLOCK))
class ViGoToOtherBigEnd(ViOperatorDef):
def init(self):
self.scroll_into_view = True
self.updates_xpos = True
self.command = 'nv_vi_visual_o'
self.command_args = {
'same_line_if_visual_block': True,
}


@assign(seqs.SEQ['o'], (NORMAL,))
@assign_text(['InsertLineAfter'], (NORMAL,))
class ViInsertLineAfter(ViOperatorDef):
Expand Down
18 changes: 18 additions & 0 deletions tests/functional/test__big_o.py
Expand Up @@ -33,6 +33,24 @@ def test_O_count(self):
def test_O_count_with_multiple_cursor(self):
self.eq('1\na|bc\n3\nx|yz\n5', '3O', 'i_1\n|\n|\n|\nabc\n3\n|\n|\n|\nxyz\n5')

def test_v(self):
self.eq('x|fizz|x', 'v_O', 'r_x|fizz|x')
self.eq('r_x|fizz|x', 'v_O', 'x|fizz|x')
self.assertStatusLineIsVisual()

def test_V(self):
self.eq('x\n|fizz\n|x', 'V_O', 'r_x\n|fizz\n|x')
self.eq('r_x\n|fizz\n|x', 'V_O', 'x\n|fizz\n|x')
self.assertStatusLineIsVisualLine()

def test_ctrl_v(self):
self.eq('x\nfi|zz bu|zz\nfi|zz bu|zz\nx', 'b_O', 'r_x\nfi|zz bu|zz\nfi|zz bu|zz\nx')
self.feed('O')
self.assertVblock('x\nfi|zz bu|zz\nfi|zz bu|zz\nx', direction=unittest.DIRECTION_DOWN)
self.feed('O')
self.assertRVblock('x\nfi|zz bu|zz\nfi|zz bu|zz\nx', direction=unittest.DIRECTION_DOWN)
self.assertStatusLineIsVisualBlock()


class Test_O_auto_indent(unittest.FunctionalTestCase):

Expand Down
8 changes: 8 additions & 0 deletions tests/functional/test_o.py
Expand Up @@ -38,6 +38,14 @@ def test_V(self):
self.eq('r_x\n|fizz\n|x', 'V_o', 'x\n|fizz\n|x')
self.assertStatusLineIsVisualLine()

def test_ctrl_v(self):
self.eq('x\nfi|zz bu|zz\nfi|zz bu|zz\nx', 'b_o', 'r_u_x\nfi|zz bu|zz\nfi|zz bu|zz\nx')
self.feed('o')
self.assertVblock('x\nfi|zz bu|zz\nfi|zz bu|zz\nx', direction=unittest.DIRECTION_DOWN)
self.feed('o')
self.assertRVblock('x\nfi|zz bu|zz\nfi|zz bu|zz\nx', direction=unittest.DIRECTION_UP)
self.assertStatusLineIsVisualBlock()

def test_issue_974_xpos_should_be_updated(self):
self.eq('fizz\nfi|zz\nfizz buzz\nfizz bu|zz', 'v_o', 'r_fizz\nfi|zz\nfizz buzz\nfizz bu|zz')
self.feed('j')
Expand Down

0 comments on commit d529353

Please sign in to comment.