mirror of
https://github.com/wassname/pyreadline.git
synced 2026-06-27 16:10:38 +08:00
Fix for reverse and forward incremental search
This commit is contained in:
@@ -22,7 +22,6 @@ class EscapeHistory(exceptions.Exception):
|
||||
|
||||
from pyreadline.logger import log
|
||||
|
||||
_ignore_leading_spaces = False
|
||||
|
||||
class LineHistory(object):
|
||||
def __init__(self):
|
||||
@@ -32,6 +31,7 @@ class LineHistory(object):
|
||||
self.history_filename = os.path.expanduser('~/.history') #Cannot expand unicode strings correctly on python2.4
|
||||
self.lastcommand = None
|
||||
self.query = u""
|
||||
self.last_search_for = u""
|
||||
|
||||
def get_current_history_length(self):
|
||||
u'''Return the number of lines currently in the history.
|
||||
@@ -140,34 +140,58 @@ class LineHistory(object):
|
||||
def reverse_search_history(self, searchfor, startpos=None):
|
||||
if startpos is None:
|
||||
startpos = self.history_cursor
|
||||
if _ignore_leading_spaces:
|
||||
res = [(idx, line.lstrip())
|
||||
for idx, line in enumerate(self.history[startpos:0:-1])
|
||||
if line.lstrip().startswith(searchfor.lstrip())]
|
||||
else:
|
||||
res = [(idx, line)
|
||||
for idx, line in enumerate(self.history[startpos:0:-1])
|
||||
if line.startswith(searchfor)]
|
||||
if res:
|
||||
self.history_cursor -= res[0][0]
|
||||
return res[0][1].get_line_text()
|
||||
return u""
|
||||
|
||||
result = lineobj.ReadLineTextBuffer("")
|
||||
|
||||
for idx, line in list(enumerate(self.history))[startpos:0:-1]:
|
||||
if searchfor in line:
|
||||
startpos = idx
|
||||
break
|
||||
|
||||
#If we get a new search without change in search term it means
|
||||
#someone pushed ctrl-r and we should find the next match
|
||||
if self.last_search_for == searchfor:
|
||||
startpos -= 1
|
||||
for idx, line in list(enumerate(self.history))[startpos:0:-1]:
|
||||
if searchfor in line:
|
||||
startpos = idx
|
||||
break
|
||||
|
||||
result = self.history[startpos]
|
||||
self.history_cursor = startpos
|
||||
self.last_search_for = searchfor
|
||||
return result.get_line_text()
|
||||
|
||||
def forward_search_history(self, searchfor, startpos=None):
|
||||
if startpos is None:
|
||||
startpos = self.history_cursor
|
||||
if _ignore_leading_spaces:
|
||||
res = [(idx, line.lstrip())
|
||||
for idx, line in enumerate(self.history[startpos:])
|
||||
if line.lstrip().startswith(searchfor.lstrip())]
|
||||
origpos = startpos
|
||||
|
||||
result = lineobj.ReadLineTextBuffer("")
|
||||
|
||||
for idx, line in list(enumerate(self.history))[startpos:]:
|
||||
if searchfor in line:
|
||||
startpos = idx
|
||||
break
|
||||
|
||||
#If we get a new search without change in search term it means
|
||||
#someone pushed ctrl-r and we should find the next match
|
||||
if self.last_search_for == searchfor:
|
||||
startpos += 1
|
||||
for idx, line in list(enumerate(self.history))[startpos:]:
|
||||
if searchfor in line:
|
||||
startpos = idx
|
||||
break
|
||||
if len(self.history) == startpos:
|
||||
if origpos == len(self.history):
|
||||
return u""
|
||||
else:
|
||||
return self.history[origpos]
|
||||
else:
|
||||
res = [(idx, line)
|
||||
for idx, line in enumerate(self.history[startpos:])
|
||||
if line.startswith(searchfor)]
|
||||
if res:
|
||||
self.history_cursor += res[0][0]
|
||||
return res[0][1].get_line_text()
|
||||
return u""
|
||||
result = self.history[startpos]
|
||||
self.history_cursor = startpos
|
||||
self.last_search_for = searchfor
|
||||
return result.get_line_text()
|
||||
|
||||
def _search(self, direction, partial):
|
||||
try:
|
||||
|
||||
@@ -133,7 +133,7 @@ class BaseMode(object):
|
||||
u"""Every bindable command should call this function for cleanup.
|
||||
Except those that want to set argument to a non-zero value.
|
||||
"""
|
||||
self.argument=0
|
||||
self.argument = 0
|
||||
|
||||
|
||||
def add_history(self, text):
|
||||
|
||||
@@ -75,8 +75,8 @@ class IncrementalSearchPromptMode(object):
|
||||
|
||||
self.subsearch_oldprompt = self.prompt
|
||||
|
||||
if (self.previous_func != self.history_search_forward and
|
||||
self.previous_func != self.history_search_backward):
|
||||
if (self.previous_func != self.reverse_search_history and
|
||||
self.previous_func != self.forward_search_history):
|
||||
self.subsearch_query = self.l_buffer[0:Point].get_line_text()
|
||||
|
||||
if self.subsearch_direction < 0:
|
||||
|
||||
@@ -18,37 +18,34 @@ from pyreadline.logger import log
|
||||
#----------------------------------------------------------------------
|
||||
RL=lineobj.ReadLineTextBuffer
|
||||
|
||||
class Test_linepos (unittest.TestCase):
|
||||
t=u"test text"
|
||||
class Test_prev_next_history(unittest.TestCase):
|
||||
t = u"test text"
|
||||
|
||||
def init_test(self):
|
||||
history._ignore_leading_spaces=False
|
||||
self.q=q=LineHistory()
|
||||
for x in [u"aaaa",u"aaba",u"aaca",u"akca",u"bbb",u"ako"]:
|
||||
def setUp(self):
|
||||
self.q = q = LineHistory()
|
||||
for x in [u"aaaa", u"aaba", u"aaca", u"akca", u"bbb", u"ako"]:
|
||||
q.add_history(RL(x))
|
||||
|
||||
def test_previous_history (self):
|
||||
self.init_test()
|
||||
hist=self.q
|
||||
assert hist.history_cursor==6
|
||||
l=RL(u"")
|
||||
hist = self.q
|
||||
assert hist.history_cursor == 6
|
||||
l = RL(u"")
|
||||
hist.previous_history(l)
|
||||
assert l.get_line_text()==u"ako"
|
||||
assert l.get_line_text() == u"ako"
|
||||
hist.previous_history(l)
|
||||
assert l.get_line_text()==u"bbb"
|
||||
assert l.get_line_text() == u"bbb"
|
||||
hist.previous_history(l)
|
||||
assert l.get_line_text()==u"akca"
|
||||
assert l.get_line_text() == u"akca"
|
||||
hist.previous_history(l)
|
||||
assert l.get_line_text()==u"aaca"
|
||||
assert l.get_line_text() == u"aaca"
|
||||
hist.previous_history(l)
|
||||
assert l.get_line_text()==u"aaba"
|
||||
assert l.get_line_text() == u"aaba"
|
||||
hist.previous_history(l)
|
||||
assert l.get_line_text()==u"aaaa"
|
||||
assert l.get_line_text() == u"aaaa"
|
||||
hist.previous_history(l)
|
||||
assert l.get_line_text()==u"aaaa"
|
||||
assert l.get_line_text() == u"aaaa"
|
||||
|
||||
def test_next_history (self):
|
||||
self.init_test()
|
||||
hist=self.q
|
||||
hist.beginning_of_history()
|
||||
assert hist.history_cursor==0
|
||||
@@ -66,14 +63,16 @@ class Test_linepos (unittest.TestCase):
|
||||
hist.next_history(l)
|
||||
assert l.get_line_text()==u"ako"
|
||||
|
||||
def init_test2(self):
|
||||
self.q=q=LineHistory()
|
||||
class Test_prev_next_history(unittest.TestCase):
|
||||
t = u"test text"
|
||||
|
||||
def setUp(self):
|
||||
self.q = q = LineHistory()
|
||||
for x in [u"aaaa",u"aaba",u"aaca",u"akca",u"bbb",u"ako"]:
|
||||
q.add_history(RL(x))
|
||||
|
||||
def test_history_search_backward (self):
|
||||
history._ignore_leading_spaces=False
|
||||
q=LineHistory()
|
||||
q = LineHistory()
|
||||
for x in [u"aaaa",u"aaba",u"aaca",u" aacax",u"akca",u"bbb",u"ako"]:
|
||||
q.add_history(RL(x))
|
||||
a=RL(u"aa",point=2)
|
||||
@@ -82,8 +81,7 @@ class Test_linepos (unittest.TestCase):
|
||||
assert res.get_line_text()==x
|
||||
|
||||
def test_history_search_forward (self):
|
||||
history._ignore_leading_spaces=False
|
||||
q=LineHistory()
|
||||
q = LineHistory()
|
||||
for x in [u"aaaa",u"aaba",u"aaca",u" aacax",u"akca",u"bbb",u"ako"]:
|
||||
q.add_history(RL(x))
|
||||
q.beginning_of_history()
|
||||
@@ -92,6 +90,40 @@ class Test_linepos (unittest.TestCase):
|
||||
res=q.history_search_forward(a)
|
||||
assert res.get_line_text()==x
|
||||
|
||||
class Test_history_search_incr_fwd_backwd(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.q = q = LineHistory()
|
||||
for x in [u"aaaa",u"aaba",u"aaca",u"akca",u"bbb",u"ako"]:
|
||||
q.add_history(RL(x))
|
||||
|
||||
def test_backward_1(self):
|
||||
q = self.q
|
||||
self.assertEqual(q.reverse_search_history(u"b"), u"bbb")
|
||||
self.assertEqual(q.reverse_search_history(u"b"), u"aaba")
|
||||
self.assertEqual(q.reverse_search_history(u"bb"), u"aaba")
|
||||
|
||||
def test_backward_2(self):
|
||||
q = self.q
|
||||
self.assertEqual(q.reverse_search_history(u"a"), u"ako")
|
||||
self.assertEqual(q.reverse_search_history(u"aa"), u"aaca")
|
||||
self.assertEqual(q.reverse_search_history(u"a"), u"aaca")
|
||||
self.assertEqual(q.reverse_search_history(u"ab"), u"aaba")
|
||||
|
||||
|
||||
def test_forward_1(self):
|
||||
q = self.q
|
||||
self.assertEqual(q.forward_search_history(u"a"), u"")
|
||||
|
||||
def test_forward_2(self):
|
||||
q = self.q
|
||||
q.history_cursor = 0
|
||||
self.assertEqual(q.forward_search_history(u"a"), u"aaaa")
|
||||
self.assertEqual(q.forward_search_history(u"a"), u"aaba")
|
||||
self.assertEqual(q.forward_search_history(u"ak"), u"akca")
|
||||
self.assertEqual(q.forward_search_history(u"akl"), u"akca")
|
||||
self.assertEqual(q.forward_search_history(u"ak"), u"akca")
|
||||
self.assertEqual(q.forward_search_history(u"ako"), u"ako")
|
||||
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
# utility functions
|
||||
|
||||
Reference in New Issue
Block a user