commit 7a9c626399ca52d4bc2ca1646a6b4c9a2d386ae4
parent a99afd0ef61360028f22a13300f472e8195de68b
Author: Eric Davis <edavis@insanum.com>
Date: Thu, 2 Apr 2015 15:59:18 -0700
Merge pull request #14 from axs221/search_note
Search notes view
Diffstat:
4 files changed, 94 insertions(+), 9 deletions(-)
diff --git a/.gitignore b/.gitignore
@@ -0,0 +1,2 @@
+*.pyc
+.ropeproject
diff --git a/simplenote_cli/config.py b/simplenote_cli/config.py
@@ -59,6 +59,10 @@ def __init__(self):
'kb_select_version' : '#',
'kb_search_gstyle' : '/',
'kb_search_regex' : 'meta /',
+ 'kb_search_prev_gstyle' : '?',
+ 'kb_search_prev_regex' : 'meta ?',
+ 'kb_search_next' : 'n',
+ 'kb_search_prev' : 'N',
'kb_clear_search' : 'A',
'kb_sort_date' : 'd',
'kb_sort_alpha' : 'a',
@@ -172,8 +176,12 @@ def __init__(self):
self.keybinds['restore_version'] = [ cp.get(cfg_sec, 'kb_restore_version'), [ 'notes' ], 'Restore version of note' ]
self.keybinds['latest_version'] = [ cp.get(cfg_sec, 'kb_latest_version'), [ 'notes' ], 'View latest version' ]
self.keybinds['select_version'] = [ cp.get(cfg_sec, 'kb_select_version'), [ 'notes' ], 'Select version' ]
- self.keybinds['search_gstyle'] = [ cp.get(cfg_sec, 'kb_search_gstyle'), [ 'titles' ], 'Search using gstyle' ]
- self.keybinds['search_regex'] = [ cp.get(cfg_sec, 'kb_search_regex'), [ 'titles' ], 'Search using regex' ]
+ self.keybinds['search_gstyle'] = [ cp.get(cfg_sec, 'kb_search_gstyle'), [ 'titles', 'notes' ], 'Search using gstyle' ]
+ self.keybinds['search_prev_gstyle'] = [ cp.get(cfg_sec, 'kb_search_prev_gstyle'), [ 'notes' ], 'Search backwards using gstyle' ]
+ self.keybinds['search_regex'] = [ cp.get(cfg_sec, 'kb_search_regex'), [ 'titles', 'notes' ], 'Search using regex' ]
+ self.keybinds['search_prev_regex'] = [ cp.get(cfg_sec, 'kb_search_prev_regex'), [ 'notes' ], 'Search backwards using regex' ]
+ self.keybinds['search_next'] = [ cp.get(cfg_sec, 'kb_search_next'), [ 'notes' ], 'Go to next search result' ]
+ self.keybinds['search_prev'] = [ cp.get(cfg_sec, 'kb_search_prev'), [ 'notes' ], 'Go to previous search result' ]
self.keybinds['clear_search'] = [ cp.get(cfg_sec, 'kb_clear_search'), [ 'titles' ], 'Show all notes' ]
self.keybinds['sort_date'] = [ cp.get(cfg_sec, 'kb_sort_date'), [ 'titles' ], 'Sort notes by date' ]
self.keybinds['sort_alpha'] = [ cp.get(cfg_sec, 'kb_sort_alpha'), [ 'titles' ], 'Sort notes by alpha' ]
diff --git a/simplenote_cli/sncli.py b/simplenote_cli/sncli.py
@@ -322,7 +322,7 @@ def gui_yes_no_input(self, args, yes_no):
self.gui_body_focus()
self.master_frame.keypress = self.gui_frame_keypress
args[0](args[1],
- True if yes_no in [ 'YES', 'Yes', 'yes', 'Y', 'y' ]
+ True if yes_no in [ 'YES', 'Yes', 'yes', 'Y', 'y' ]
else False)
def gui_search_input(self, args, search_string):
@@ -330,8 +330,12 @@ def gui_search_input(self, args, search_string):
self.gui_body_focus()
self.master_frame.keypress = self.gui_frame_keypress
if search_string:
- self.view_titles.update_note_list(search_string, args[0])
- self.gui_body_set(self.view_titles)
+ if (self.gui_body_get() == self.view_note):
+ self.search_direction = args[1]
+ self.view_note.search_note_view_next(search_string=search_string, search_mode=args[0])
+ else:
+ self.view_titles.update_note_list(search_string, args[0])
+ self.gui_body_set(self.view_titles)
def gui_version_input(self, args, version):
self.gui_footer_input_clear()
@@ -780,10 +784,20 @@ def gui_frame_keypress(self, size, key):
self.master_frame.keypress = self.gui_footer_input_get().keypress
elif key == self.config.get_keybind('search_gstyle') or \
- key == self.config.get_keybind('search_regex'):
- if self.gui_body_get().__class__ != view_titles.ViewTitles:
+ key == self.config.get_keybind('search_regex') or \
+ key == self.config.get_keybind('search_prev_gstyle') or \
+ key == self.config.get_keybind('search_prev_regex'):
+ if self.gui_body_get().__class__ != view_titles.ViewTitles and \
+ self.gui_body_get().__class__ != view_note.ViewNote:
return key
+ if self.gui_body_get().__class__ == view_note.ViewNote:
+ if key == self.config.get_keybind('search_prev_gstyle') or \
+ key == self.config.get_keybind('search_prev_regex'):
+ self.view_note.search_direction = 'backward'
+ else:
+ self.view_note.search_direction = 'forward'
+
self.gui_footer_input_set(
urwid.AttrMap(
user_input.UserInput(
@@ -792,11 +806,27 @@ def gui_frame_keypress(self, size, key):
'',
self.gui_search_input,
[ 'gstyle' if key == self.config.get_keybind('search_gstyle')
- else 'regex' ]),
+ or key == self.config.get_keybind('search_prev_gstyle')
+ else 'regex',
+ 'backward' if key == self.config.get_keybind('search_prev_gstyle')
+ or key == self.config.get_keybind('search_prev_regex')
+ else 'forward' ]),
'user_input_bar'))
self.gui_footer_focus_input()
self.master_frame.keypress = self.gui_footer_input_get().keypress
+ elif key == self.config.get_keybind('search_next'):
+ if self.gui_body_get().__class__ != view_note.ViewNote:
+ return key
+
+ self.view_note.search_note_view_next()
+
+ elif key == self.config.get_keybind('search_prev'):
+ if self.gui_body_get().__class__ != view_note.ViewNote:
+ return key
+
+ self.view_note.search_note_view_prev()
+
elif key == self.config.get_keybind('clear_search'):
if self.gui_body_get().__class__ != view_titles.ViewTitles:
return key
diff --git a/simplenote_cli/view_note.py b/simplenote_cli/view_note.py
@@ -4,6 +4,7 @@
import time, urwid
import utils
+import re
class ViewNote(urwid.ListBox):
@@ -12,6 +13,9 @@ def __init__(self, config, args):
self.ndb = args['ndb']
self.key = args['key']
self.log = args['log']
+ self.search_string = ''
+ self.search_mode = 'gstyle'
+ self.search_direction = ''
self.note = self.ndb.get_note(self.key) if self.key else None
self.old_note = None
self.tabstop = int(self.config.get_config('tabstop'))
@@ -69,7 +73,48 @@ def update_note_view(self, key=None, version=None):
self.body[:] = \
urwid.SimpleFocusListWalker(self.get_note_content_as_list())
- self.focus_position = 0
+ if not self.search_string:
+ self.focus_position = 0
+
+ def lines_after_current_position(self):
+ lines_after_current_position = range(self.focus_position + 1, len(self.body.positions()) - 1)
+ return lines_after_current_position
+
+ def lines_before_current_position(self):
+ lines_before_current_position = range(0, self.focus_position)
+ lines_before_current_position.reverse()
+ return lines_before_current_position
+
+ def search_note_view_next(self, search_string=None, search_mode=None):
+ if search_string:
+ self.search_string = search_string
+ if search_mode:
+ self.search_mode = search_mode
+ note_range = self.lines_after_current_position() if self.search_direction == 'forward' else self.lines_before_current_position()
+ self.search_note_range(note_range)
+
+ def search_note_view_prev(self, search_string=None, search_mode=None):
+ if search_string:
+ self.search_string = search_string
+ if search_mode:
+ self.search_mode = search_mode
+ note_range = self.lines_after_current_position() if self.search_direction == 'backward' else self.lines_before_current_position()
+ self.search_note_range(note_range)
+
+ def search_note_range(self, note_range):
+ for line in note_range:
+ line_content = self.note['content'].split('\n')[line]
+ if (self.is_match(self.search_string, line_content)):
+ self.focus_position = line
+ break
+ self.update_note_view()
+
+ def is_match(self, term, full_text):
+ if self.search_mode == 'gstyle':
+ return term in full_text
+ else:
+ results = re.search(term, full_text)
+ return ( results is not None )
def get_status_bar(self):
if not self.key: