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