def __init__(self, app, notebook): Gtk.ScrolledWindow.__init__(self) self.app = app self.notebook = notebook self.results = None self.isSearching = False newTextView = Gtk.TextView() newTextView.set_editable(False) self.createTags(newTextView.get_buffer()) self.add(newTextView) self.notebook.append_page(self) # Construct tab label and hidden spinner box = Gtk.Box(Gtk.Orientation.HORIZONTAL, spacing=6) self.label = Gtk.Label('[New tab]') self.spinner = Gtk.Spinner() self.notebook.set_tab_label(self, box) box.pack_start(self.label, True, True, 0) box.pack_start(self.spinner, True, True, 0) box.get_children()[0].show() # Always show label self.ge = GrepEngine()
class VizigrepTab(Gtk.ScrolledWindow): def __init__(self, app, notebook): Gtk.ScrolledWindow.__init__(self) self.app = app self.notebook = notebook self.results = None self.isSearching = False newTextView = Gtk.TextView() newTextView.set_editable(False) self.createTags(newTextView.get_buffer()) self.add(newTextView) self.notebook.append_page(self) # Construct tab label and hidden spinner box = Gtk.Box(Gtk.Orientation.HORIZONTAL, spacing=6) self.label = Gtk.Label('[New tab]') self.spinner = Gtk.Spinner() self.notebook.set_tab_label(self, box) box.pack_start(self.label, True, True, 0) box.pack_start(self.spinner, True, True, 0) box.get_children()[0].show() # Always show label self.ge = GrepEngine() def getIndex(self): return self.notebook.page_num(self) def getTextView(self): return self.get_child() def getTextBuffer(self): return self.get_child().get_buffer() def setTitleText(self, text): self.label.set_text(text) def setSpinner(self, active): if active: self.spinner.show() self.spinner.start() else: self.spinner.stop() self.spinner.hide() def createTags(self, txtbuf): txtbuf.create_tag("fixed", family="Monospace") txtbuf.create_tag("link", foreground="Blue") txtbuf.create_tag("red", foreground="Red") txtbuf.create_tag("green", foreground="Dark Green") txtbuf.create_tag("bg1", background="#DDDDDD") def startSearch(self, searchString, path, doneCallback): self.isSearching = True new_thread = Thread(target=self.grep_thread, args=(searchString, path, doneCallback)) new_thread.start() def grep_thread(self, searchString, path, doneCallback): self.results = None ex = None try: self.results = self.ge.grep(searchString, path) except Exception as e: ex = e GObject.idle_add(self.grep_thread_done, ex) GObject.idle_add(doneCallback, self) # Call main window's callback def grep_thread_done(self, exception): txtbuf = self.getTextBuffer() if self.ge.cancelled: txtbuf.set_text("The search was cancelled") elif self.results: try: self.set_results() except Exception as e: print type(e) print traceback.format_exc() elif exception: if isinstance(exception, GrepException): txtbuf.set_text("Grep error: %s" % exception.output) elif isinstance(exception, NoResultsException): txtbuf.set_text("No results found") elif isinstance(exception, BadRegexException): txtbuf.set_text("Search string error: %s" % str(exception)) else: txtbuf.set_text("Unexpected Error: " + str(exception)) print type(exception) print traceback.format_exc() self.setSpinner(False) self.isSearching = False def set_results(self): results = self.results txtbuf = self.getTextBuffer() tag_link = txtbuf.get_tag_table().lookup('link') tag_red = txtbuf.get_tag_table().lookup('red') tag_green = txtbuf.get_tag_table().lookup('green') tag_bg1 = txtbuf.get_tag_table().lookup('bg1') max_fnlen = results.max_fnlen() max_lnlen = results.max_lnlen() max_txtlen = results.max_txtlen() taglist = [] rstr = '' # Figure out max line length max_linelen = max_fnlen + 1 + max_txtlen if (self.app.prefs.get('show-line-numbers')): max_linelen += max_lnlen + 1 string = self.escape_regex_str(results.search_string) lineNum = 1 for r in results: lineStartIdx = len(rstr) # File name taglist.append( (len(rstr), len(r.fn), tag_link) ) rstr += r.fn # Spaces to pad out filename if max_fnlen > len(r.fn): rstr += ' ' * (max_fnlen - len(r.fn)) # : after filename rstr += ':' # Line number and : if (self.app.prefs.get('show-line-numbers')): taglist.append( (len(rstr), len(r.linenum), tag_green) ) rstr += r.linenum if max_lnlen > len(r.linenum): rstr += " " * (max_lnlen - len(r.linenum)) rstr += ':' if self.ge.case_sensitive: m = re.search(string, r.str) else: m = re.search(string, r.str, re.IGNORECASE) # Line contents if(m and len(m.group()) > 0): matched_text = m.group() (prematch, match, postmatch) = r.str.partition(matched_text) rstr += prematch taglist.append( (len(rstr), len(matched_text), tag_red) ) rstr += matched_text rstr += postmatch else: rstr += r.str # Spaces to pad out line contents if max_txtlen > len(r.str): rstr += ' ' * (max_txtlen - len(r.str)) rstr += '\n' # Add text background tag every other line lineLength = len(rstr) - lineStartIdx - 1 if (self.app.prefs.get('alternate-row-color')): if (lineNum % 2 == 1): taglist.append( (lineStartIdx, lineLength, tag_bg1) ) lineNum += 1 txtbuf.set_text(rstr) self.apply_tags(txtbuf, rstr, taglist) def escape_regex_str(self, regex): if '(' in regex: regex = regex.replace('(', '\\(') # Escape ( if ')' in regex: regex = regex.replace(')', '\\)') # Escape ) return regex def apply_tags(self, txtbuf, rstr, taglist): tag_fixed = txtbuf.get_tag_table().lookup('fixed') txtbuf.apply_tag(tag_fixed, txtbuf.get_start_iter(), txtbuf.get_end_iter()) for tagtuple in taglist: (sidx, length, tag) = tagtuple sitr = txtbuf.get_iter_at_offset(sidx) eitr = txtbuf.get_iter_at_offset(sidx + length) txtbuf.apply_tag(tag, sitr, eitr) def activate_result(self, itr): if not self.results or self.results.is_remote: return True if len(self.results) <= itr.get_line(): return True result = self.results[itr.get_line()] for tag in itr.get_tags(): # FIXME: Create a findTagByType function? if tag.get_property('name') == 'link': (itr, itr_end) = self.get_tag_pos(itr, tag) filename = self.getTextBuffer().get_text(itr, itr_end, False) filename = os.path.join(self.results.search_path, filename) filename = Path.full(filename) cmdList = [] for itm in self.app.prefs.get('editor').split(' '): if '$1' in itm: itm = itm.replace('$1', filename) if '$n' in itm: itm = itm.replace('$n', result.linenum) cmdList.append(itm) subprocess.Popen(cmdList) return True return False # Locate start/end of tag at given iterator def get_tag_pos(self, itr, tag): itr_end = itr.copy() # Find start of tag while (not itr.begins_tag(tag)): itr.backward_char() # Find end of tag while (not itr_end.ends_tag(tag)): itr_end.forward_char() return (itr, itr_end)
class testCases(unittest.TestCase): def setUp(self): self.ge = GrepEngine() self.path = 'test-data' def tearDown(self): pass ### Basic Functionality ### def testFindSimple(self): results = self.ge.grep('foo', self.path) self.assertTrue(len(results) == 1) self.checkResult(results[0], "File1", "linefoo", "2") def testNoMatches(self): with self.assertRaises(NoResultsException): self.ge.grep('idonotexistidonotexistidonotexist', self.path) def testIgnoreDirSimple(self): self.ge.exclude_dirs.append('FolderA') results = self.ge.grep('file', self.path) self.ge.exclude_dirs = [] self.assertTrue(len(results) == 2) self.checkResult(results[1], "File1", "This is a test file", "1") self.checkResult(results[0], "File2", "Another file!", "1") def testIgnoreDirWithSpaceInPath(self): self.ge.exclude_dirs.append('Space A') with self.assertRaises(NoResultsException): self.ge.grep('space_marker', self.path) self.ge.exclude_dirs = [] def testGrepGivesErrorMessage(self): with self.assertRaises(GrepException): self.ge.grep('a[]b', self.path) ### Search path ### def testPathWithSpaces(self): path = 'test-data/Space A' results = self.ge.grep('space_marker', path) self.assertTrue(len(results) == 1) self.checkResult(results[0], 'Space File', 'space_marker', '1') ### Broken Regex ### def testStartsWithStar(self): with self.assertRaises(BadRegexException): self.ge.grep('*foo', self.path) def testDoubleStar(self): with self.assertRaises(BadRegexException): self.ge.grep('foo**', self.path) def testEmptyString(self): with self.assertRaises(BadRegexException): self.ge.grep('', self.path) def testAllDots(self): with self.assertRaises(BadRegexException): self.ge.grep('...', self.path) def testDotStar(self): with self.assertRaises(BadRegexException): self.ge.grep('.*', self.path) ### Test Special Chars & Shell Escaping ### def testDoubleQuote(self): results = self.ge.grep('"stdio.h', self.path) self.assertTrue(len(results) == 1) self.checkResult(results[0], 'FolderA/File2', '#include "stdio.h"', '1') def testDoubleQuotes(self): results = self.ge.grep('"stdio.h"', self.path) self.assertTrue(len(results) == 1) self.checkResult(results[0], 'FolderA/File2', '#include "stdio.h"', '1') def testStringStartingWithHash(self): path = os.path.join(self.path, 'FolderA') results = self.ge.grep('#include', path) self.assertTrue(len(results) == 1) self.checkResult(results[0], 'File2', '#include "stdio.h"', '1') def testAngleBrackets(self): results = self.ge.grep('<stdio.h>', self.path) self.assertTrue(len(results) == 1) self.checkResult(results[0], 'FolderA/File2', '@fnclude <stdio.h>', '2') def testBackslash(self): results = self.ge.grep('fi\\\\le', self.path) self.assertTrue(len(results) == 1) self.checkResult(results[0], 'FolderA/File1', 'fi\le', '4') def testDash(self): path = os.path.join(self.path, 'FolderA') results = self.ge.grep('-d', path) self.assertTrue(len(results) == 1) self.checkResult(results[0], 'File3.py', " self.ge.exclude_dirs = self.prefs.get('exclude-dirs')", '17') def testDashDash(self): path = os.path.join(self.path, 'FolderA') results = self.ge.grep('--link', path) self.assertTrue(len(results) == 1) self.checkResult(results[0], 'File3.py', " self.lbl_options.connect('activate--link', self.options_clicked)", '32') def testCPointerDereference(self): path = os.path.join(self.path, 'c-source') results = self.ge.grep('urb->status;', path) self.assertTrue(len(results) == 2) self.checkResult(results[0], 'xpad.c', " status = urb->status;", '637') self.checkResult(results[1], 'xpad.c', " status = urb->status;", '706') def checkResult(self, result, fn, line, linenum): self.assertTrue(result.fn == fn) self.assertTrue(result.str == line) self.assertTrue(int(result.linenum) == int(linenum))
def setUp(self): self.ge = GrepEngine() self.path = 'test-data'
def setUp(self): self.ge = GrepEngine() user = getpass.getuser() host = "127.0.0.1" fullpath = os.path.abspath('./test-data') self.path = '%s@%s:%s' % (user, host, fullpath)