Skip to content

Commit

Permalink
Merge pull request #51 from bgallois/search_commands
Browse files Browse the repository at this point in the history
PR: Add search commands
  • Loading branch information
ccordoba12 committed May 18, 2020
2 parents 74cb221 + ca66e58 commit c764ad4
Show file tree
Hide file tree
Showing 2 changed files with 101 additions and 6 deletions.
38 changes: 38 additions & 0 deletions spyder_vim/tests/test_vim.py
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,44 @@ def test_three_chars_with_zero_repeat():
assert groups == ("20", "D", "")


def test_forward_search_command(vim_bot):
"""Test search forward command (/)."""
main, editor_stack, editor, vim, qtbot = vim_bot
editor.stdkey_backspace()
editor.go_to_line(1)
cmd_line = vim.get_focus_widget()
qtbot.keyClicks(cmd_line, '/line\r')
index_test = []
for i in range(5):
qtbot.keyClicks(cmd_line, 'n')
line, _ = editor.get_cursor_line_column()
index_test.append(line)
for i in range(5):
qtbot.keyClicks(cmd_line, 'N')
line, _ = editor.get_cursor_line_column()
index_test.append(line)
assert index_test == [1, 2, 3, 4, 1, 4, 3, 2, 1, 4]


def test_backward_search_command(vim_bot):
"""Test search backward command (/)."""
main, editor_stack, editor, vim, qtbot = vim_bot
editor.stdkey_backspace()
editor.go_to_line(1)
cmd_line = vim.get_focus_widget()
qtbot.keyClicks(cmd_line, '?line\r')
index_test = []
for i in range(5):
qtbot.keyClicks(cmd_line, 'n')
line, _ = editor.get_cursor_line_column()
index_test.append(line)
for i in range(5):
qtbot.keyClicks(cmd_line, 'N')
line, _ = editor.get_cursor_line_column()
index_test.append(line)
assert index_test == [4, 3, 2, 1, 4, 1, 2, 3, 4, 1]


def test_a_command_open_bracket(vim_bot):
"""Test a selection"""
main, editor_stack, editor, vim, qtbot = vim_bot
Expand Down
69 changes: 63 additions & 6 deletions spyder_vim/vim_widget.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,20 +9,21 @@


import re
import bisect
from time import time

from qtpy.QtWidgets import (QWidget, QLineEdit, QHBoxLayout, QTextEdit, QLabel,
QSizePolicy, QApplication)
from qtpy.QtGui import QTextCursor
from qtpy.QtCore import Qt
from qtpy.QtGui import QTextCursor, QTextDocument
from qtpy.QtCore import Qt, QRegExp


VIM_COMMAND_PREFIX = ":!/?"
VIM_PREFIX = "acdfFgmritTyzZ@'`\"<>"
RE_VIM_PREFIX_STR = r"^(\d*)([{prefixes}].|[^{prefixes}0123456789])(.*)$"
RE_VIM_PREFIX = re.compile(RE_VIM_PREFIX_STR.format(prefixes=VIM_PREFIX))

VIM_VISUAL_OPS = "dhjklGyw$^0 \r\b"
VIM_VISUAL_OPS = "dhjklnNGyw$^0 \r\b"
VIM_VISUAL_PREFIX = "agi"
VIM_ARG_PREFIX = "fF"

Expand Down Expand Up @@ -54,6 +55,7 @@ def __init__(self, widget):
self._widget = widget
self._prev_cursor = None
self.visual_mode = False
self.search_dict = {}

def __call__(self, key, repeat):
"""Execute vim command."""
Expand Down Expand Up @@ -159,6 +161,61 @@ def exit_visual_mode(self):
self._widget.update_vim_cursor()
self.visual_mode = False

def search(self, key, reverse=False):
""""Search regular expressions key inside document"""
editor = self._widget.editor()
cursor = QTextCursor(editor.document())
cursor.movePosition(QTextCursor.Start)
# Find key in document forward
search_stack = []
cursor = editor.document().find(key)
selection = QTextEdit.ExtraSelection()
back = Qt.black
fore = Qt.blue
while not cursor.isNull():
selection = QTextEdit.ExtraSelection()
selection.format.setBackground(fore)
selection.format.setForeground(back)
selection.cursor = cursor
search_stack.append(selection)
cursor = editor.document().find(QRegExp(key), cursor,
QTextDocument.FindCaseSensitively)
editor.set_extra_selections('search', [i for i in search_stack])
editor.update_extra_selections()
search_dict = {"stack": search_stack, "reverse": reverse}
return search_dict

def n(self, repeat=1, reverse=False):
"""Move cursor to the next searched key"""
cursor = self._editor_cursor()
search_stack = self.search_dict["stack"]
if not search_stack:
return
if not self.search_dict["reverse"]^reverse:
place = bisect.bisect([i.cursor.selectionStart()
for i in search_stack], cursor.position())
if place == len(search_stack):
self._set_cursor(search_stack[0].cursor.selectionStart(),
QTextCursor.MoveAnchor)
else:
self._set_cursor(search_stack[place].cursor.selectionStart(),
QTextCursor.MoveAnchor)
else:
place = bisect.bisect_left([i.cursor.selectionStart()
for i in search_stack], cursor.position())
if place == 0:
self._set_cursor(search_stack[-1].cursor.selectionStart(),
QTextCursor.MoveAnchor)
else:
self._set_cursor(search_stack[place-1].cursor.selectionStart(),
QTextCursor.MoveAnchor)
if repeat > 1:
self.n(repeat - 1, reverse=reverse)

def N(self, repeat=1):
"""Move cursor to the previous searched key"""
self.n(repeat, reverse=True)

# %% Movement
def h(self, repeat=1):
"""Move cursor to the left."""
Expand Down Expand Up @@ -948,15 +1005,15 @@ def on_return(self):
if not text:
return
cmd_type = text[0]
print(text)
cmd = text[1::].rstrip()
if cmd_type == ":": # Vim command
self.vim_commands(text[1:])
elif cmd_type == "!": # Shell command
pass
elif cmd_type == "/": # Forward search
pass
self.vim_keys.search_dict = self.vim_keys.search(cmd)
elif cmd_type == "?": # Reverse search
pass
self.vim_keys.search_dict = self.vim_keys.search(cmd, reverse=True)
self.commandline.clear()

def on_copy(self):
Expand Down

0 comments on commit c764ad4

Please sign in to comment.