/Lib/idlelib/GrepDialog.py

http://unladen-swallow.googlecode.com/ · Python · 133 lines · 120 code · 13 blank · 0 comment · 31 complexity · 435625b7db710f775e3430b70c74545c MD5 · raw file

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