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