blob: ed5a9791b8b5882baf3451b2cac06ad9c2d7e951 [file] [log] [blame]
Guido van Rossum504b0bf1999-01-02 21:28:54 +00001import os
2import re
3import fnmatch
Guido van Rossumd53869e1999-01-04 15:52:33 +00004import sys
Guido van Rossum504b0bf1999-01-02 21:28:54 +00005from Tkinter import *
6import tkMessageBox
7import SearchEngine
8from SearchDialogBase import SearchDialogBase
9
10def grep(text, io=None, flist=None):
11 root = text._root()
12 engine = SearchEngine.get(root)
13 if not hasattr(engine, "_grepdialog"):
14 engine._grepdialog = GrepDialog(root, engine, flist)
15 dialog = engine._grepdialog
16 dialog.open(io)
17
18class GrepDialog(SearchDialogBase):
19
20 title = "Find in Files Dialog"
21 icon = "Grep"
22 needwrapbutton = 0
23
24 def __init__(self, root, engine, flist):
25 SearchDialogBase.__init__(self, root, engine)
26 self.flist = flist
27 self.globvar = StringVar(root)
28 self.recvar = BooleanVar(root)
29
30 def open(self, io=None):
31 SearchDialogBase.open(self, None)
32 if io:
33 path = io.filename or ""
34 else:
35 path = ""
36 dir, base = os.path.split(path)
37 head, tail = os.path.splitext(base)
38 if not tail:
39 tail = ".py"
40 self.globvar.set(os.path.join(dir, "*" + tail))
41
42 def create_entries(self):
43 SearchDialogBase.create_entries(self)
44 self.globent = self.make_entry("In files:", self.globvar)
45
46 def create_other_buttons(self):
47 f = self.make_frame()
48
49 btn = Checkbutton(f, anchor="w",
50 variable=self.recvar,
51 text="Recurse down subdirectories")
52 btn.pack(side="top", fill="both")
53 btn.select()
54
55 def create_command_buttons(self):
56 SearchDialogBase.create_command_buttons(self)
57 self.make_button("Search Files", self.default_command, 1)
58
59 def default_command(self, event=None):
60 prog = self.engine.getprog()
61 if not prog:
62 return
63 path = self.globvar.get()
64 if not path:
65 self.top.bell()
66 return
67 from OutputWindow import OutputWindow
68 save = sys.stdout
69 try:
70 sys.stdout = OutputWindow(self.flist)
71 self.grep_it(prog, path)
72 finally:
73 sys.stdout = save
74
75 def grep_it(self, prog, path):
76 dir, base = os.path.split(path)
77 list = self.findfiles(dir, base, self.recvar.get())
78 list.sort()
79 self.close()
80 pat = self.engine.getpat()
Guido van Rossumb10cb9a1999-06-03 14:25:49 +000081 print "Searching %s in %s ..." % (`pat`, path)
Guido van Rossum504b0bf1999-01-02 21:28:54 +000082 hits = 0
83 for fn in list:
84 try:
85 f = open(fn)
86 except IOError, msg:
87 print msg
88 continue
89 lineno = 0
90 while 1:
91 block = f.readlines(100000)
92 if not block:
93 break
94 for line in block:
95 lineno = lineno + 1
96 if line[-1:] == '\n':
97 line = line[:-1]
98 if prog.search(line):
99 sys.stdout.write("%s: %s: %s\n" % (fn, lineno, line))
100 hits = hits + 1
101 if hits:
102 if hits == 1:
103 s = ""
104 else:
105 s = "s"
106 print "Found", hits, "hit%s." % s
107 print "(Hint: right-click to open locations.)"
108 else:
109 print "No hits."
110
111 def findfiles(self, dir, base, rec):
112 try:
113 names = os.listdir(dir or os.curdir)
114 except os.error, msg:
115 print msg
116 return []
117 list = []
118 subdirs = []
119 for name in names:
120 fn = os.path.join(dir, name)
121 if os.path.isdir(fn):
122 subdirs.append(fn)
123 else:
124 if fnmatch.fnmatch(name, base):
125 list.append(fn)
126 if rec:
127 for subdir in subdirs:
128 list.extend(self.findfiles(subdir, base, rec))
129 return list
130
131 def close(self, event=None):
132 if self.top:
133 self.top.grab_release()
134 self.top.withdraw()