Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
cpython
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
cpython
Commits
0bb5e75c
Commit
0bb5e75c
authored
Mar 16, 2019
by
Cheryl Sabella
Committed by
GitHub
Mar 16, 2019
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
bpo-23216: IDLE: Add docstrings to search modules (GH-12141)
parent
7c994549
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
189 additions
and
39 deletions
+189
-39
Lib/idlelib/grep.py
Lib/idlelib/grep.py
+36
-10
Lib/idlelib/replace.py
Lib/idlelib/replace.py
+87
-24
Lib/idlelib/search.py
Lib/idlelib/search.py
+65
-5
Misc/NEWS.d/next/IDLE/2019-03-02-19-39-53.bpo-23216.ZA7H8H.rst
...NEWS.d/next/IDLE/2019-03-02-19-39-53.bpo-23216.ZA7H8H.rst
+1
-0
No files found.
Lib/idlelib/grep.py
View file @
0bb5e75c
...
...
@@ -14,11 +14,16 @@ from idlelib.searchbase import SearchDialogBase
from
idlelib
import
searchengine
# Importing OutputWindow here fails due to import loop
# EditorWindow -> GrepDialo
p
-> OutputWindow -> EditorWindow
# EditorWindow -> GrepDialo
g
-> OutputWindow -> EditorWindow
def
grep
(
text
,
io
=
None
,
flist
=
None
):
"""Create or find singleton GrepDialog instance.
"""Open the Find in Files dialog.
Module-level function to access the singleton GrepDialog
instance and open the dialog. If text is selected, it is
used as the search phrase; otherwise, the previous entry
is used.
Args:
text: Text widget that contains the selected text for
...
...
@@ -26,7 +31,6 @@ def grep(text, io=None, flist=None):
io: iomenu.IOBinding instance with default path to search.
flist: filelist.FileList instance for OutputWindow parent.
"""
root
=
text
.
_root
()
engine
=
searchengine
.
get
(
root
)
if
not
hasattr
(
engine
,
"_grepdialog"
):
...
...
@@ -50,17 +54,29 @@ class GrepDialog(SearchDialogBase):
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.
flist: filelist.Filelist instance for OutputWindow parent.
globvar: String value of Entry widget for path to search.
globent: Entry widget for globvar. Created in
create_entries().
recvar: Boolean value of Checkbutton widget for
traversing through subdirectories.
"""
SearchDialogBase
.
__init__
(
self
,
root
,
engine
)
super
().
__init__
(
root
,
engine
)
self
.
flist
=
flist
self
.
globvar
=
StringVar
(
root
)
self
.
recvar
=
BooleanVar
(
root
)
def
open
(
self
,
text
,
searchphrase
,
io
=
None
):
"Make dialog visible on top of others and ready to use."
"""Make dialog visible on top of others and ready to use.
Extend the SearchDialogBase open() to set the initial value
for globvar.
Args:
text: Multicall object containing the text information.
searchphrase: String phrase to search.
io: iomenu.IOBinding instance containing file path.
"""
SearchDialogBase
.
open
(
self
,
text
,
searchphrase
)
if
io
:
path
=
io
.
filename
or
""
...
...
@@ -85,9 +101,9 @@ class GrepDialog(SearchDialogBase):
btn
.
pack
(
side
=
"top"
,
fill
=
"both"
)
def
create_command_buttons
(
self
):
"Create base command buttons and add button for
search
."
"Create base command buttons and add button for
Search Files
."
SearchDialogBase
.
create_command_buttons
(
self
)
self
.
make_button
(
"Search Files"
,
self
.
default_command
,
1
)
self
.
make_button
(
"Search Files"
,
self
.
default_command
,
isdef
=
True
)
def
default_command
(
self
,
event
=
None
):
"""Grep for search pattern in file path. The default command is bound
...
...
@@ -119,6 +135,10 @@ class GrepDialog(SearchDialogBase):
search each line for the matching pattern. If the pattern is
found, write the file and line information to stdout (which
is an OutputWindow).
Args:
prog: The compiled, cooked search pattern.
path: String containing the search path.
"""
dir
,
base
=
os
.
path
.
split
(
path
)
list
=
self
.
findfiles
(
dir
,
base
,
self
.
recvar
.
get
())
...
...
@@ -149,7 +169,13 @@ class GrepDialog(SearchDialogBase):
def
findfiles
(
self
,
dir
,
base
,
rec
):
"""Return list of files in the dir that match the base pattern.
Use the current directory if dir has no value.
If rec is True, recursively iterate through subdirectories.
Args:
dir: Directory path to search.
base: File search pattern.
rec: Boolean for recursive search through subdirectories.
"""
try
:
names
=
os
.
listdir
(
dir
or
os
.
curdir
)
...
...
Lib/idlelib/replace.py
View file @
0bb5e75c
"""Replace dialog for IDLE. Inherits SearchDialogBase for GUI.
Uses idlelib.SearchEngine for search capability.
Uses idlelib.
searchengine.
SearchEngine for search capability.
Defines various replace related functions like replace, replace all,
replace+find.
and
replace+find.
"""
import
re
...
...
@@ -10,9 +10,16 @@ from tkinter import StringVar, TclError
from
idlelib.searchbase
import
SearchDialogBase
from
idlelib
import
searchengine
def
replace
(
text
):
"""Returns a singleton ReplaceDialog instance.The single dialog
saves user entries and preferences across instances."""
"""Create or reuse a singleton ReplaceDialog instance.
The singleton dialog saves user entries and preferences
across instances.
Args:
text: Text widget containing the text to be searched.
"""
root
=
text
.
_root
()
engine
=
searchengine
.
get
(
root
)
if
not
hasattr
(
engine
,
"_replacedialog"
):
...
...
@@ -22,16 +29,36 @@ def replace(text):
class
ReplaceDialog
(
SearchDialogBase
):
"Dialog for finding and replacing a pattern in text."
title
=
"Replace Dialog"
icon
=
"Replace"
def
__init__
(
self
,
root
,
engine
):
SearchDialogBase
.
__init__
(
self
,
root
,
engine
)
"""Create search dialog for finding and replacing text.
Uses SearchDialogBase as the basis for the GUI and a
searchengine instance to prepare the search.
Attributes:
replvar: StringVar containing 'Replace with:' value.
replent: Entry widget for replvar. Created in
create_entries().
ok: Boolean used in searchengine.search_text to indicate
whether the search includes the selection.
"""
super
().
__init__
(
root
,
engine
)
self
.
replvar
=
StringVar
(
root
)
def
open
(
self
,
text
):
"""Display the replace dialog"""
"""Make dialog visible on top of others and ready to use.
Also, highlight the currently selected text and set the
search to include the current selection (self.ok).
Args:
text: Text widget being searched.
"""
SearchDialogBase
.
open
(
self
,
text
)
try
:
first
=
text
.
index
(
"sel.first"
)
...
...
@@ -44,37 +71,50 @@ class ReplaceDialog(SearchDialogBase):
first
=
first
or
text
.
index
(
"insert"
)
last
=
last
or
first
self
.
show_hit
(
first
,
last
)
self
.
ok
=
1
self
.
ok
=
True
def
create_entries
(
self
):
"
""Create label and text entry widgets""
"
"
Create base and additional label and text entry widgets.
"
SearchDialogBase
.
create_entries
(
self
)
self
.
replent
=
self
.
make_entry
(
"Replace with:"
,
self
.
replvar
)[
0
]
def
create_command_buttons
(
self
):
"""Create base and additional command buttons.
The additional buttons are for Find, Replace,
Replace+Find, and Replace All.
"""
SearchDialogBase
.
create_command_buttons
(
self
)
self
.
make_button
(
"Find"
,
self
.
find_it
)
self
.
make_button
(
"Replace"
,
self
.
replace_it
)
self
.
make_button
(
"Replace+Find"
,
self
.
default_command
,
1
)
self
.
make_button
(
"Replace+Find"
,
self
.
default_command
,
isdef
=
True
)
self
.
make_button
(
"Replace All"
,
self
.
replace_all
)
def
find_it
(
self
,
event
=
None
):
self
.
do_find
(
0
)
"Handle the Find button."
self
.
do_find
(
False
)
def
replace_it
(
self
,
event
=
None
):
"""Handle the Replace button.
If the find is successful, then perform replace.
"""
if
self
.
do_find
(
self
.
ok
):
self
.
do_replace
()
def
default_command
(
self
,
event
=
None
):
"Replace and find next."
"""Handle the Replace+Find button as the default command.
First performs a replace and then, if the replace was
successful, a find next.
"""
if
self
.
do_find
(
self
.
ok
):
if
self
.
do_replace
():
# Only find next match if replace succeeded.
# A bad re can cause it to fail.
self
.
do_find
(
0
)
self
.
do_find
(
False
)
def
_replace_expand
(
self
,
m
,
repl
):
""" Helper function for expanding a regular expression
in the replace field, if needed. """
"Expand replacement text if regular expression."
if
self
.
engine
.
isre
():
try
:
new
=
m
.
expand
(
repl
)
...
...
@@ -87,7 +127,15 @@ class ReplaceDialog(SearchDialogBase):
return
new
def
replace_all
(
self
,
event
=
None
):
"""Replace all instances of patvar with replvar in text"""
"""Handle the Replace All button.
Search text for occurrences of the Find value and replace
each of them. The 'wrap around' value controls the start
point for searching. If wrap isn't set, then the searching
starts at the first occurrence after the current selection;
if wrap is set, the replacement starts at the first line.
The replacement is always done top-to-bottom in the text.
"""
prog
=
self
.
engine
.
getprog
()
if
not
prog
:
return
...
...
@@ -104,12 +152,13 @@ class ReplaceDialog(SearchDialogBase):
if
self
.
engine
.
iswrap
():
line
=
1
col
=
0
ok
=
1
ok
=
True
first
=
last
=
None
# XXX ought to replace circular instead of top-to-bottom when wrapping
text
.
undo_block_start
()
while
1
:
res
=
self
.
engine
.
search_forward
(
text
,
prog
,
line
,
col
,
0
,
ok
)
while
True
:
res
=
self
.
engine
.
search_forward
(
text
,
prog
,
line
,
col
,
wrap
=
False
,
ok
=
ok
)
if
not
res
:
break
line
,
m
=
res
...
...
@@ -130,13 +179,17 @@ class ReplaceDialog(SearchDialogBase):
if
new
:
text
.
insert
(
first
,
new
)
col
=
i
+
len
(
new
)
ok
=
0
ok
=
False
text
.
undo_block_stop
()
if
first
and
last
:
self
.
show_hit
(
first
,
last
)
self
.
close
()
def
do_find
(
self
,
ok
=
0
):
def
do_find
(
self
,
ok
=
False
):
"""Search for and highlight next occurrence of pattern in text.
No text replacement is done with this option.
"""
if
not
self
.
engine
.
getprog
():
return
False
text
=
self
.
text
...
...
@@ -149,10 +202,11 @@ class ReplaceDialog(SearchDialogBase):
first
=
"%d.%d"
%
(
line
,
i
)
last
=
"%d.%d"
%
(
line
,
j
)
self
.
show_hit
(
first
,
last
)
self
.
ok
=
1
self
.
ok
=
True
return
True
def
do_replace
(
self
):
"Replace search pattern in text with replacement value."
prog
=
self
.
engine
.
getprog
()
if
not
prog
:
return
False
...
...
@@ -180,12 +234,20 @@ class ReplaceDialog(SearchDialogBase):
text
.
insert
(
first
,
new
)
text
.
undo_block_stop
()
self
.
show_hit
(
first
,
text
.
index
(
"insert"
))
self
.
ok
=
0
self
.
ok
=
False
return
True
def
show_hit
(
self
,
first
,
last
):
"""Highlight text from 'first' to 'last'.
'first', 'last' - Text indices"""
"""Highlight text between first and last indices.
Text is highlighted via the 'hit' tag and the marked
section is brought into view.
The colors from the 'hit' tag aren't currently shown
when the text is displayed. This is due to the 'sel'
tag being added first, so the colors in the 'sel'
config are seen instead of the colors for 'hit'.
"""
text
=
self
.
text
text
.
mark_set
(
"insert"
,
first
)
text
.
tag_remove
(
"sel"
,
"1.0"
,
"end"
)
...
...
@@ -199,6 +261,7 @@ class ReplaceDialog(SearchDialogBase):
text
.
update_idletasks
()
def
close
(
self
,
event
=
None
):
"Close the dialog and remove hit tags."
SearchDialogBase
.
close
(
self
,
event
)
self
.
text
.
tag_remove
(
"hit"
,
"1.0"
,
"end"
)
...
...
Lib/idlelib/search.py
View file @
0bb5e75c
"""Search dialog for Find, Find Again, and Find Selection
functionality.
Inherits from SearchDialogBase for GUI and uses searchengine
to prepare search pattern.
"""
from
tkinter
import
TclError
from
idlelib
import
searchengine
from
idlelib.searchbase
import
SearchDialogBase
def
_setup
(
text
):
"Create or find the singleton SearchDialog instance."
"""Return the new or existing singleton SearchDialog instance.
The singleton dialog saves user entries and preferences
across instances.
Args:
text: Text widget containing the text to be searched.
"""
root
=
text
.
_root
()
engine
=
searchengine
.
get
(
root
)
if
not
hasattr
(
engine
,
"_searchdialog"
):
...
...
@@ -12,31 +25,71 @@ def _setup(text):
return
engine
.
_searchdialog
def
find
(
text
):
"Handle the editor edit menu item and corresponding event."
"""Open the search dialog.
Module-level function to access the singleton SearchDialog
instance and open the dialog. If text is selected, it is
used as the search phrase; otherwise, the previous entry
is used. No search is done with this command.
"""
pat
=
text
.
get
(
"sel.first"
,
"sel.last"
)
return
_setup
(
text
).
open
(
text
,
pat
)
# Open is inherited from SDBase.
def
find_again
(
text
):
"Handle the editor edit menu item and corresponding event."
"""Repeat the search for the last pattern and preferences.
Module-level function to access the singleton SearchDialog
instance to search again using the user entries and preferences
from the last dialog. If there was no prior search, open the
search dialog; otherwise, perform the search without showing the
dialog.
"""
return
_setup
(
text
).
find_again
(
text
)
def
find_selection
(
text
):
"Handle the editor edit menu item and corresponding event."
"""Search for the selected pattern in the text.
Module-level function to access the singleton SearchDialog
instance to search using the selected text. With a text
selection, perform the search without displaying the dialog.
Without a selection, use the prior entry as the search phrase
and don't display the dialog. If there has been no prior
search, open the search dialog.
"""
return
_setup
(
text
).
find_selection
(
text
)
class
SearchDialog
(
SearchDialogBase
):
"Dialog for finding a pattern in text."
def
create_widgets
(
self
):
"Create the base search dialog and add a button for Find Next."
SearchDialogBase
.
create_widgets
(
self
)
self
.
make_button
(
"Find Next"
,
self
.
default_command
,
1
)
# TODO - why is this here and not in a create_command_buttons?
self
.
make_button
(
"Find Next"
,
self
.
default_command
,
isdef
=
True
)
def
default_command
(
self
,
event
=
None
):
"Handle the Find Next button as the default command."
if
not
self
.
engine
.
getprog
():
return
self
.
find_again
(
self
.
text
)
def
find_again
(
self
,
text
):
"""Repeat the last search.
If no search was previously run, open a new search dialog. In
this case, no search is done.
If a seach was previously run, the search dialog won't be
shown and the options from the previous search (including the
search pattern) will be used to find the next occurrence
of the pattern. Next is relative based on direction.
Position the window to display the located occurrence in the
text.
Return True if the search was successful and False otherwise.
"""
if
not
self
.
engine
.
getpat
():
self
.
open
(
text
)
return
False
...
...
@@ -66,6 +119,13 @@ class SearchDialog(SearchDialogBase):
return
False
def
find_selection
(
self
,
text
):
"""Search for selected text with previous dialog preferences.
Instead of using the same pattern for searching (as Find
Again does), this first resets the pattern to the currently
selected text. If the selected text isn't changed, then use
the prior search phrase.
"""
pat
=
text
.
get
(
"sel.first"
,
"sel.last"
)
if
pat
:
self
.
engine
.
setcookedpat
(
pat
)
...
...
Misc/NEWS.d/next/IDLE/2019-03-02-19-39-53.bpo-23216.ZA7H8H.rst
0 → 100644
View file @
0bb5e75c
Add docstrings to IDLE search modules.
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment