10a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoimport os 20a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoimport fnmatch 30a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoimport sys 40a8c90248264a8b26970b4473770bcc3df8515fJosh Gaofrom Tkinter import * 50a8c90248264a8b26970b4473770bcc3df8515fJosh Gaofrom idlelib import SearchEngine 60a8c90248264a8b26970b4473770bcc3df8515fJosh Gaofrom idlelib.SearchDialogBase import SearchDialogBase 70a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 80a8c90248264a8b26970b4473770bcc3df8515fJosh Gaodef grep(text, io=None, flist=None): 90a8c90248264a8b26970b4473770bcc3df8515fJosh Gao root = text._root() 100a8c90248264a8b26970b4473770bcc3df8515fJosh Gao engine = SearchEngine.get(root) 110a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if not hasattr(engine, "_grepdialog"): 120a8c90248264a8b26970b4473770bcc3df8515fJosh Gao engine._grepdialog = GrepDialog(root, engine, flist) 130a8c90248264a8b26970b4473770bcc3df8515fJosh Gao dialog = engine._grepdialog 140a8c90248264a8b26970b4473770bcc3df8515fJosh Gao searchphrase = text.get("sel.first", "sel.last") 150a8c90248264a8b26970b4473770bcc3df8515fJosh Gao dialog.open(text, searchphrase, io) 160a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 170a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoclass GrepDialog(SearchDialogBase): 180a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 190a8c90248264a8b26970b4473770bcc3df8515fJosh Gao title = "Find in Files Dialog" 200a8c90248264a8b26970b4473770bcc3df8515fJosh Gao icon = "Grep" 210a8c90248264a8b26970b4473770bcc3df8515fJosh Gao needwrapbutton = 0 220a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 230a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def __init__(self, root, engine, flist): 240a8c90248264a8b26970b4473770bcc3df8515fJosh Gao SearchDialogBase.__init__(self, root, engine) 250a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.flist = flist 260a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.globvar = StringVar(root) 270a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.recvar = BooleanVar(root) 280a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 290a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def open(self, text, searchphrase, io=None): 300a8c90248264a8b26970b4473770bcc3df8515fJosh Gao SearchDialogBase.open(self, text, searchphrase) 310a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if io: 320a8c90248264a8b26970b4473770bcc3df8515fJosh Gao path = io.filename or "" 330a8c90248264a8b26970b4473770bcc3df8515fJosh Gao else: 340a8c90248264a8b26970b4473770bcc3df8515fJosh Gao path = "" 350a8c90248264a8b26970b4473770bcc3df8515fJosh Gao dir, base = os.path.split(path) 360a8c90248264a8b26970b4473770bcc3df8515fJosh Gao head, tail = os.path.splitext(base) 370a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if not tail: 380a8c90248264a8b26970b4473770bcc3df8515fJosh Gao tail = ".py" 390a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.globvar.set(os.path.join(dir, "*" + tail)) 400a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 410a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def create_entries(self): 420a8c90248264a8b26970b4473770bcc3df8515fJosh Gao SearchDialogBase.create_entries(self) 430a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.globent = self.make_entry("In files:", self.globvar) 440a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 450a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def create_other_buttons(self): 460a8c90248264a8b26970b4473770bcc3df8515fJosh Gao f = self.make_frame() 470a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 480a8c90248264a8b26970b4473770bcc3df8515fJosh Gao btn = Checkbutton(f, anchor="w", 490a8c90248264a8b26970b4473770bcc3df8515fJosh Gao variable=self.recvar, 500a8c90248264a8b26970b4473770bcc3df8515fJosh Gao text="Recurse down subdirectories") 510a8c90248264a8b26970b4473770bcc3df8515fJosh Gao btn.pack(side="top", fill="both") 520a8c90248264a8b26970b4473770bcc3df8515fJosh Gao btn.select() 530a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 540a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def create_command_buttons(self): 550a8c90248264a8b26970b4473770bcc3df8515fJosh Gao SearchDialogBase.create_command_buttons(self) 560a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.make_button("Search Files", self.default_command, 1) 570a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 580a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def default_command(self, event=None): 590a8c90248264a8b26970b4473770bcc3df8515fJosh Gao prog = self.engine.getprog() 600a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if not prog: 610a8c90248264a8b26970b4473770bcc3df8515fJosh Gao return 620a8c90248264a8b26970b4473770bcc3df8515fJosh Gao path = self.globvar.get() 630a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if not path: 640a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.top.bell() 650a8c90248264a8b26970b4473770bcc3df8515fJosh Gao return 660a8c90248264a8b26970b4473770bcc3df8515fJosh Gao from idlelib.OutputWindow import OutputWindow 670a8c90248264a8b26970b4473770bcc3df8515fJosh Gao save = sys.stdout 680a8c90248264a8b26970b4473770bcc3df8515fJosh Gao try: 690a8c90248264a8b26970b4473770bcc3df8515fJosh Gao sys.stdout = OutputWindow(self.flist) 700a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.grep_it(prog, path) 710a8c90248264a8b26970b4473770bcc3df8515fJosh Gao finally: 720a8c90248264a8b26970b4473770bcc3df8515fJosh Gao sys.stdout = save 730a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 740a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def grep_it(self, prog, path): 750a8c90248264a8b26970b4473770bcc3df8515fJosh Gao dir, base = os.path.split(path) 760a8c90248264a8b26970b4473770bcc3df8515fJosh Gao list = self.findfiles(dir, base, self.recvar.get()) 770a8c90248264a8b26970b4473770bcc3df8515fJosh Gao list.sort() 780a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.close() 790a8c90248264a8b26970b4473770bcc3df8515fJosh Gao pat = self.engine.getpat() 800a8c90248264a8b26970b4473770bcc3df8515fJosh Gao print "Searching %r in %s ..." % (pat, path) 810a8c90248264a8b26970b4473770bcc3df8515fJosh Gao hits = 0 820a8c90248264a8b26970b4473770bcc3df8515fJosh Gao for fn in list: 830a8c90248264a8b26970b4473770bcc3df8515fJosh Gao try: 840a8c90248264a8b26970b4473770bcc3df8515fJosh Gao f = open(fn) 850a8c90248264a8b26970b4473770bcc3df8515fJosh Gao except IOError, msg: 860a8c90248264a8b26970b4473770bcc3df8515fJosh Gao print msg 870a8c90248264a8b26970b4473770bcc3df8515fJosh Gao continue 880a8c90248264a8b26970b4473770bcc3df8515fJosh Gao lineno = 0 890a8c90248264a8b26970b4473770bcc3df8515fJosh Gao while 1: 900a8c90248264a8b26970b4473770bcc3df8515fJosh Gao block = f.readlines(100000) 910a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if not block: 920a8c90248264a8b26970b4473770bcc3df8515fJosh Gao break 930a8c90248264a8b26970b4473770bcc3df8515fJosh Gao for line in block: 940a8c90248264a8b26970b4473770bcc3df8515fJosh Gao lineno = lineno + 1 950a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if line[-1:] == '\n': 960a8c90248264a8b26970b4473770bcc3df8515fJosh Gao line = line[:-1] 970a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if prog.search(line): 980a8c90248264a8b26970b4473770bcc3df8515fJosh Gao sys.stdout.write("%s: %s: %s\n" % (fn, lineno, line)) 990a8c90248264a8b26970b4473770bcc3df8515fJosh Gao hits = hits + 1 1000a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if hits: 1010a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if hits == 1: 1020a8c90248264a8b26970b4473770bcc3df8515fJosh Gao s = "" 1030a8c90248264a8b26970b4473770bcc3df8515fJosh Gao else: 1040a8c90248264a8b26970b4473770bcc3df8515fJosh Gao s = "s" 1050a8c90248264a8b26970b4473770bcc3df8515fJosh Gao print "Found", hits, "hit%s." % s 1060a8c90248264a8b26970b4473770bcc3df8515fJosh Gao print "(Hint: right-click to open locations.)" 1070a8c90248264a8b26970b4473770bcc3df8515fJosh Gao else: 1080a8c90248264a8b26970b4473770bcc3df8515fJosh Gao print "No hits." 1090a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 1100a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def findfiles(self, dir, base, rec): 1110a8c90248264a8b26970b4473770bcc3df8515fJosh Gao try: 1120a8c90248264a8b26970b4473770bcc3df8515fJosh Gao names = os.listdir(dir or os.curdir) 1130a8c90248264a8b26970b4473770bcc3df8515fJosh Gao except os.error, msg: 1140a8c90248264a8b26970b4473770bcc3df8515fJosh Gao print msg 1150a8c90248264a8b26970b4473770bcc3df8515fJosh Gao return [] 1160a8c90248264a8b26970b4473770bcc3df8515fJosh Gao list = [] 1170a8c90248264a8b26970b4473770bcc3df8515fJosh Gao subdirs = [] 1180a8c90248264a8b26970b4473770bcc3df8515fJosh Gao for name in names: 1190a8c90248264a8b26970b4473770bcc3df8515fJosh Gao fn = os.path.join(dir, name) 1200a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if os.path.isdir(fn): 1210a8c90248264a8b26970b4473770bcc3df8515fJosh Gao subdirs.append(fn) 1220a8c90248264a8b26970b4473770bcc3df8515fJosh Gao else: 1230a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if fnmatch.fnmatch(name, base): 1240a8c90248264a8b26970b4473770bcc3df8515fJosh Gao list.append(fn) 1250a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if rec: 1260a8c90248264a8b26970b4473770bcc3df8515fJosh Gao for subdir in subdirs: 1270a8c90248264a8b26970b4473770bcc3df8515fJosh Gao list.extend(self.findfiles(subdir, base, rec)) 1280a8c90248264a8b26970b4473770bcc3df8515fJosh Gao return list 1290a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 1300a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def close(self, event=None): 1310a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if self.top: 1320a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.top.grab_release() 1330a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.top.withdraw() 134