PageRenderTime 29ms CodeModel.GetById 16ms app.highlight 10ms RepoModel.GetById 1ms app.codeStats 0ms

/Lib/idlelib/GrepDialog.py

http://unladen-swallow.googlecode.com/
Python | 133 lines | 128 code | 5 blank | 0 comment | 5 complexity | 435625b7db710f775e3430b70c74545c MD5 | raw file
  1import os
  2import fnmatch
  3import sys
  4from Tkinter import *
  5import 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    searchphrase = text.get("sel.first", "sel.last")
 15    dialog.open(text, searchphrase, io)
 16
 17class 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()