mirror of
https://github.com/python/cpython.git
synced 2025-10-02 05:12:23 +00:00
bpo-30674: IDLE: add docstrings to grep.py (#2213)
Patch by Cheryl Sabella
This commit is contained in:
parent
44913e584b
commit
65474b9d7a
2 changed files with 55 additions and 12 deletions
|
@ -1,3 +1,8 @@
|
||||||
|
"""Grep dialog for Find in Files functionality.
|
||||||
|
|
||||||
|
Inherits from SearchDialogBase for GUI and uses searchengine
|
||||||
|
to prepare search pattern.
|
||||||
|
"""
|
||||||
import fnmatch
|
import fnmatch
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
|
@ -11,7 +16,17 @@ from idlelib import searchengine
|
||||||
# Importing OutputWindow here fails due to import loop
|
# Importing OutputWindow here fails due to import loop
|
||||||
# EditorWindow -> GrepDialop -> OutputWindow -> EditorWindow
|
# EditorWindow -> GrepDialop -> OutputWindow -> EditorWindow
|
||||||
|
|
||||||
|
|
||||||
def grep(text, io=None, flist=None):
|
def grep(text, io=None, flist=None):
|
||||||
|
"""Create or find singleton GrepDialog instance.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
text: Text widget that contains the selected text for
|
||||||
|
default search phrase.
|
||||||
|
io: iomenu.IOBinding instance with default path to search.
|
||||||
|
flist: filelist.FileList instance for OutputWindow parent.
|
||||||
|
"""
|
||||||
|
|
||||||
root = text._root()
|
root = text._root()
|
||||||
engine = searchengine.get(root)
|
engine = searchengine.get(root)
|
||||||
if not hasattr(engine, "_grepdialog"):
|
if not hasattr(engine, "_grepdialog"):
|
||||||
|
@ -20,19 +35,32 @@ def grep(text, io=None, flist=None):
|
||||||
searchphrase = text.get("sel.first", "sel.last")
|
searchphrase = text.get("sel.first", "sel.last")
|
||||||
dialog.open(text, searchphrase, io)
|
dialog.open(text, searchphrase, io)
|
||||||
|
|
||||||
|
|
||||||
class GrepDialog(SearchDialogBase):
|
class GrepDialog(SearchDialogBase):
|
||||||
|
"Dialog for searching multiple files."
|
||||||
|
|
||||||
title = "Find in Files Dialog"
|
title = "Find in Files Dialog"
|
||||||
icon = "Grep"
|
icon = "Grep"
|
||||||
needwrapbutton = 0
|
needwrapbutton = 0
|
||||||
|
|
||||||
def __init__(self, root, engine, flist):
|
def __init__(self, root, engine, flist):
|
||||||
|
"""Create search dialog for searching for a phrase in the file system.
|
||||||
|
|
||||||
|
Uses SearchDialogBase as the basis for the GUI and a
|
||||||
|
searchengine instance to prepare the search.
|
||||||
|
|
||||||
|
Attributes:
|
||||||
|
globvar: Value of Text Entry widget for path to search.
|
||||||
|
recvar: Boolean value of Checkbutton widget
|
||||||
|
for traversing through subdirectories.
|
||||||
|
"""
|
||||||
SearchDialogBase.__init__(self, root, engine)
|
SearchDialogBase.__init__(self, root, engine)
|
||||||
self.flist = flist
|
self.flist = flist
|
||||||
self.globvar = StringVar(root)
|
self.globvar = StringVar(root)
|
||||||
self.recvar = BooleanVar(root)
|
self.recvar = BooleanVar(root)
|
||||||
|
|
||||||
def open(self, text, searchphrase, io=None):
|
def open(self, text, searchphrase, io=None):
|
||||||
|
"Make dialog visible on top of others and ready to use."
|
||||||
SearchDialogBase.open(self, text, searchphrase)
|
SearchDialogBase.open(self, text, searchphrase)
|
||||||
if io:
|
if io:
|
||||||
path = io.filename or ""
|
path = io.filename or ""
|
||||||
|
@ -45,20 +73,30 @@ class GrepDialog(SearchDialogBase):
|
||||||
self.globvar.set(os.path.join(dir, "*" + tail))
|
self.globvar.set(os.path.join(dir, "*" + tail))
|
||||||
|
|
||||||
def create_entries(self):
|
def create_entries(self):
|
||||||
|
"Create base entry widgets and add widget for search path."
|
||||||
SearchDialogBase.create_entries(self)
|
SearchDialogBase.create_entries(self)
|
||||||
self.globent = self.make_entry("In files:", self.globvar)[0]
|
self.globent = self.make_entry("In files:", self.globvar)[0]
|
||||||
|
|
||||||
def create_other_buttons(self):
|
def create_other_buttons(self):
|
||||||
|
"Add check button to recurse down subdirectories."
|
||||||
btn = Checkbutton(
|
btn = Checkbutton(
|
||||||
self.make_frame()[0], variable=self.recvar,
|
self.make_frame()[0], variable=self.recvar,
|
||||||
text="Recurse down subdirectories")
|
text="Recurse down subdirectories")
|
||||||
btn.pack(side="top", fill="both")
|
btn.pack(side="top", fill="both")
|
||||||
|
|
||||||
def create_command_buttons(self):
|
def create_command_buttons(self):
|
||||||
|
"Create base command buttons and add button for search."
|
||||||
SearchDialogBase.create_command_buttons(self)
|
SearchDialogBase.create_command_buttons(self)
|
||||||
self.make_button("Search Files", self.default_command, 1)
|
self.make_button("Search Files", self.default_command, 1)
|
||||||
|
|
||||||
def default_command(self, event=None):
|
def default_command(self, event=None):
|
||||||
|
"""Grep for search pattern in file path. The default command is bound
|
||||||
|
to <Return>.
|
||||||
|
|
||||||
|
If entry values are populated, set OutputWindow as stdout
|
||||||
|
and perform search. The search dialog is closed automatically
|
||||||
|
when the search begins.
|
||||||
|
"""
|
||||||
prog = self.engine.getprog()
|
prog = self.engine.getprog()
|
||||||
if not prog:
|
if not prog:
|
||||||
return
|
return
|
||||||
|
@ -75,12 +113,19 @@ class GrepDialog(SearchDialogBase):
|
||||||
sys.stdout = save
|
sys.stdout = save
|
||||||
|
|
||||||
def grep_it(self, prog, path):
|
def grep_it(self, prog, path):
|
||||||
|
"""Search for prog within the lines of the files in path.
|
||||||
|
|
||||||
|
For the each file in the path directory, open the file and
|
||||||
|
search each line for the matching pattern. If the pattern is
|
||||||
|
found, write the file and line information to stdout (which
|
||||||
|
is an OutputWindow).
|
||||||
|
"""
|
||||||
dir, base = os.path.split(path)
|
dir, base = os.path.split(path)
|
||||||
list = self.findfiles(dir, base, self.recvar.get())
|
list = self.findfiles(dir, base, self.recvar.get())
|
||||||
list.sort()
|
list.sort()
|
||||||
self.close()
|
self.close()
|
||||||
pat = self.engine.getpat()
|
pat = self.engine.getpat()
|
||||||
print("Searching %r in %s ..." % (pat, path))
|
print(f"Searching {pat!r} in {path} ...")
|
||||||
hits = 0
|
hits = 0
|
||||||
try:
|
try:
|
||||||
for fn in list:
|
for fn in list:
|
||||||
|
@ -90,20 +135,22 @@ class GrepDialog(SearchDialogBase):
|
||||||
if line[-1:] == '\n':
|
if line[-1:] == '\n':
|
||||||
line = line[:-1]
|
line = line[:-1]
|
||||||
if prog.search(line):
|
if prog.search(line):
|
||||||
sys.stdout.write("%s: %s: %s\n" %
|
sys.stdout.write(f"{fn}: {lineno}: {line}\n")
|
||||||
(fn, lineno, line))
|
|
||||||
hits += 1
|
hits += 1
|
||||||
except OSError as msg:
|
except OSError as msg:
|
||||||
print(msg)
|
print(msg)
|
||||||
print(("Hits found: %s\n"
|
print(f"Hits found: {hits}\n(Hint: right-click to open locations.)"
|
||||||
"(Hint: right-click to open locations.)"
|
if hits else "No hits.")
|
||||||
% hits) if hits else "No hits.")
|
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
# Tk window has been closed, OutputWindow.text = None,
|
# Tk window has been closed, OutputWindow.text = None,
|
||||||
# so in OW.write, OW.text.insert fails.
|
# so in OW.write, OW.text.insert fails.
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def findfiles(self, dir, base, rec):
|
def findfiles(self, dir, base, rec):
|
||||||
|
"""Return list of files in the dir that match the base pattern.
|
||||||
|
|
||||||
|
If rec is True, recursively iterate through subdirectories.
|
||||||
|
"""
|
||||||
try:
|
try:
|
||||||
names = os.listdir(dir or os.curdir)
|
names = os.listdir(dir or os.curdir)
|
||||||
except OSError as msg:
|
except OSError as msg:
|
||||||
|
@ -123,11 +170,6 @@ class GrepDialog(SearchDialogBase):
|
||||||
list.extend(self.findfiles(subdir, base, rec))
|
list.extend(self.findfiles(subdir, base, rec))
|
||||||
return list
|
return list
|
||||||
|
|
||||||
def close(self, event=None):
|
|
||||||
if self.top:
|
|
||||||
self.top.grab_release()
|
|
||||||
self.top.withdraw()
|
|
||||||
|
|
||||||
|
|
||||||
def _grep_dialog(parent): # htest #
|
def _grep_dialog(parent): # htest #
|
||||||
from tkinter import Toplevel, Text, SEL, END
|
from tkinter import Toplevel, Text, SEL, END
|
||||||
|
@ -136,7 +178,7 @@ def _grep_dialog(parent): # htest #
|
||||||
top = Toplevel(parent)
|
top = Toplevel(parent)
|
||||||
top.title("Test GrepDialog")
|
top.title("Test GrepDialog")
|
||||||
x, y = map(int, parent.geometry().split('+')[1:])
|
x, y = map(int, parent.geometry().split('+')[1:])
|
||||||
top.geometry("+%d+%d" % (x, y + 175))
|
top.geometry(f"+{x}+{y + 175}")
|
||||||
|
|
||||||
flist = PyShellFileList(top)
|
flist = PyShellFileList(top)
|
||||||
text = Text(top, height=5)
|
text = Text(top, height=5)
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
IDLE: add docstrings to grep module. Patch by Cheryl Sabella
|
Loading…
Add table
Add a link
Reference in a new issue