From 059dc68969b9ac8618e53919932fc345814d38aa Mon Sep 17 00:00:00 2001 From: Wulian233 <1055917385@qq.com> Date: Mon, 29 Jul 2024 20:15:31 +0800 Subject: [PATCH 1/8] Improve IDLE Find, Replace and Find in Files dialogs --- Lib/idlelib/News3.txt | 10 ++++++++++ Lib/idlelib/grep.py | 13 +++++++------ Lib/idlelib/replace.py | 16 ++++------------ Lib/idlelib/searchbase.py | 15 +++++---------- ...2024-07-29-20-11-27.gh-issue-67407.nhILB2.rst | 2 ++ 5 files changed, 28 insertions(+), 28 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2024-07-29-20-11-27.gh-issue-67407.nhILB2.rst diff --git a/Lib/idlelib/News3.txt b/Lib/idlelib/News3.txt index 68702ac8fb9157..bc65808f3faed7 100644 --- a/Lib/idlelib/News3.txt +++ b/Lib/idlelib/News3.txt @@ -1,3 +1,13 @@ +What's New in IDLE 3.14.0 +(since 3.13.0) +Released on 2025-10-xx +========================= + + +gh-67407: Improve the Find, Replace and Find in Files dialogs. Patch by +Wulian233 and AlSweigart. + + What's New in IDLE 3.13.0 (since 3.12.0) Released on 2024-10-xx diff --git a/Lib/idlelib/grep.py b/Lib/idlelib/grep.py index 42048ff2395fe1..216002c4fbd4bf 100644 --- a/Lib/idlelib/grep.py +++ b/Lib/idlelib/grep.py @@ -8,7 +8,7 @@ import sys from tkinter import StringVar, BooleanVar -from tkinter.ttk import Checkbutton # Frame imported in ...Base +from tkinter.ttk import Checkbutton, Frame from idlelib.searchbase import SearchDialogBase from idlelib import searchengine @@ -64,7 +64,7 @@ def findfiles(folder, pattern, recursive): class GrepDialog(SearchDialogBase): "Dialog for searching multiple files." - title = "Find in Files Dialog" + title = "Find in Files" icon = "Grep" needwrapbutton = 0 @@ -112,7 +112,7 @@ def open(self, text, searchphrase, io=None): def create_entries(self): "Create base entry widgets and add widget for search path." 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): "Add check button to recurse down subdirectories." @@ -122,9 +122,10 @@ def create_other_buttons(self): btn.pack(side="top", fill="both") def create_command_buttons(self): - "Create base command buttons and add button for Search Files." - SearchDialogBase.create_command_buttons(self) - self.make_button("Search Files", self.default_command, isdef=True) + """Create base command buttons and add button for Search Files.""" + f = self.buttonframe = Frame(self.frame) + f.grid(row=3, column=2, padx=4, pady=4) + self.make_button("Search", self.default_command, isdef=True) def default_command(self, event=None): """Grep for search pattern in file path. The default command is bound diff --git a/Lib/idlelib/replace.py b/Lib/idlelib/replace.py index 3716d841568d30..f61605a0ec8b7f 100644 --- a/Lib/idlelib/replace.py +++ b/Lib/idlelib/replace.py @@ -32,7 +32,7 @@ def replace(text, insert_tags=None): class ReplaceDialog(SearchDialogBase): "Dialog for finding and replacing a pattern in text." - title = "Replace Dialog" + title = "Replace" icon = "Replace" def __init__(self, root, engine): @@ -69,7 +69,7 @@ def open(self, text, searchphrase=None, *, insert_tags=None): def create_entries(self): "Create base and additional label and text entry widgets." SearchDialogBase.create_entries(self) - self.replent = self.make_entry("Replace with:", self.replvar)[0] + self.replent = self.make_entry("Replace with", self.replvar)[0] def create_command_buttons(self): """Create base and additional command buttons. @@ -78,22 +78,14 @@ def create_command_buttons(self): 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, isdef=True) + self.make_button("Find Next", self.find_it) + self.make_button("Replace", self.default_command, isdef=True) self.make_button("Replace All", self.replace_all) def find_it(self, event=None): "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): """Handle the Replace+Find button as the default command. diff --git a/Lib/idlelib/searchbase.py b/Lib/idlelib/searchbase.py index 64ed50c7364be3..08b64853e813ff 100644 --- a/Lib/idlelib/searchbase.py +++ b/Lib/idlelib/searchbase.py @@ -26,7 +26,7 @@ class SearchDialogBase: add widgets. ''' - title = "Search Dialog" # replace in subclasses + title = "Find" # replace in subclasses icon = "Search" needwrapbutton = 1 # not in Find in Files @@ -92,8 +92,6 @@ def create_widgets(self): top.grid_rowconfigure(0, weight=100) self.row = 0 - self.frame.grid_columnconfigure(0, pad=2, weight=0) - self.frame.grid_columnconfigure(1, pad=2, minsize=100, weight=100) self.create_entries() # row 0 (and maybe 1), cols 0, 1 self.create_option_buttons() # next row, cols 0, 1 @@ -109,13 +107,13 @@ def make_entry(self, label_text, var): label = Label(self.frame, text=label_text) label.grid(row=self.row, column=0, sticky="nw") entry = Entry(self.frame, textvariable=var, exportselection=0) - entry.grid(row=self.row, column=1, sticky="nwe") - self.row = self.row + 1 + entry.grid(row=self.row, column=1, columnspan=2, padx=4, pady=4, sticky="nwe") + self.row += 1 return entry, label def create_entries(self): "Create one or more entry lines with make_entry." - self.ent = self.make_entry("Find:", self.engine.patvar)[0] + self.ent = self.make_entry("Find", self.engine.patvar)[0] def make_frame(self,labeltext=None): '''Return (frame, label). @@ -179,10 +177,7 @@ def make_button(self, label, command, isdef=0): def create_command_buttons(self): "Place buttons in vertical command frame gridded on right." f = self.buttonframe = Frame(self.frame) - f.grid(row=0,column=2,padx=2,pady=2,ipadx=2,ipady=2) - - b = self.make_button("Close", self.close) - b.lower() + f.grid(row=2, column=2, padx=4, pady=4) class _searchbase(SearchDialogBase): # htest # diff --git a/Misc/NEWS.d/next/Library/2024-07-29-20-11-27.gh-issue-67407.nhILB2.rst b/Misc/NEWS.d/next/Library/2024-07-29-20-11-27.gh-issue-67407.nhILB2.rst new file mode 100644 index 00000000000000..1e6f2f96c4dead --- /dev/null +++ b/Misc/NEWS.d/next/Library/2024-07-29-20-11-27.gh-issue-67407.nhILB2.rst @@ -0,0 +1,2 @@ +Improve IDLE Find, Replace and Find in Files dialogs. Patch by Wulian233 and +AlSweigart. From f3b83633ccc27978909252a8278e72ca3ade20ec Mon Sep 17 00:00:00 2001 From: Wulian233 <1055917385@qq.com> Date: Mon, 29 Jul 2024 21:43:34 +0800 Subject: [PATCH 2/8] readd replace_it func --- Lib/idlelib/replace.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Lib/idlelib/replace.py b/Lib/idlelib/replace.py index f61605a0ec8b7f..8258cc1f78554e 100644 --- a/Lib/idlelib/replace.py +++ b/Lib/idlelib/replace.py @@ -86,6 +86,13 @@ def find_it(self, event=None): "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): """Handle the Replace+Find button as the default command. From d9ef4845090161a1124910f4349888fefda47316 Mon Sep 17 00:00:00 2001 From: Wulian233 <1055917385@qq.com> Date: Mon, 29 Jul 2024 21:44:23 +0800 Subject: [PATCH 3/8] space --- Lib/idlelib/replace.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Lib/idlelib/replace.py b/Lib/idlelib/replace.py index 8258cc1f78554e..cbc59dc06d57af 100644 --- a/Lib/idlelib/replace.py +++ b/Lib/idlelib/replace.py @@ -87,12 +87,12 @@ def find_it(self, event=None): self.do_find(False) def replace_it(self, event=None): - """Handle the Replace button. + """Handle the Replace button. - If the find is successful, then perform replace. - """ - if self.do_find(self.ok): - self.do_replace() + If the find is successful, then perform replace. + """ + if self.do_find(self.ok): + self.do_replace() def default_command(self, event=None): """Handle the Replace+Find button as the default command. From c4b39e465bdbb4d90a0a7f876d7e6b8736d62f05 Mon Sep 17 00:00:00 2001 From: Wulian233 <1055917385@qq.com> Date: Mon, 29 Jul 2024 21:48:59 +0800 Subject: [PATCH 4/8] comment --- Lib/idlelib/replace.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Lib/idlelib/replace.py b/Lib/idlelib/replace.py index cbc59dc06d57af..dca327907f2d8e 100644 --- a/Lib/idlelib/replace.py +++ b/Lib/idlelib/replace.py @@ -87,11 +87,11 @@ def find_it(self, event=None): self.do_find(False) def replace_it(self, event=None): - """Handle the Replace button. + """Only used in test case - If the find is successful, then perform replace. - """ - if self.do_find(self.ok): + If the find is successful, then perform replace. + """ + if self.do_find(self.ok): self.do_replace() def default_command(self, event=None): From eb7b0be3576943092369f627b7fe9253c20e98b7 Mon Sep 17 00:00:00 2001 From: Wulian233 <1055917385@qq.com> Date: Mon, 29 Jul 2024 21:50:08 +0800 Subject: [PATCH 5/8] fix --- Lib/idlelib/replace.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Lib/idlelib/replace.py b/Lib/idlelib/replace.py index dca327907f2d8e..0dd340e4ae01be 100644 --- a/Lib/idlelib/replace.py +++ b/Lib/idlelib/replace.py @@ -87,11 +87,11 @@ def find_it(self, event=None): self.do_find(False) def replace_it(self, event=None): - """Only used in test case + """Only used in test case - If the find is successful, then perform replace. - """ - if self.do_find(self.ok): + If the find is successful, then perform replace. + """ + if self.do_find(self.ok): self.do_replace() def default_command(self, event=None): From 51ed00955c0a37d70ad58a7c54bc4e0ff262e38a Mon Sep 17 00:00:00 2001 From: Wulian233 <1055917385@qq.com> Date: Tue, 30 Jul 2024 13:42:25 +0800 Subject: [PATCH 6/8] tests --- Lib/idlelib/idle_test/htest.py | 9 +++------ Lib/idlelib/idle_test/test_searchbase.py | 8 +------- Lib/idlelib/replace.py | 8 ++++---- 3 files changed, 8 insertions(+), 17 deletions(-) diff --git a/Lib/idlelib/idle_test/htest.py b/Lib/idlelib/idle_test/htest.py index a7293774eecaeb..c3698d331e4deb 100644 --- a/Lib/idlelib/idle_test/htest.py +++ b/Lib/idlelib/idle_test/htest.py @@ -264,8 +264,7 @@ 'file': 'replace', 'kwds': {}, 'msg': "Click the 'Replace' button.\n" - "Test various replace options in the 'Replace dialog'.\n" - "Click [Close] or [X] to close the 'Replace Dialog'." + "Test various replace options in the 'Replace dialog'." } _scrolled_list_spec = { @@ -281,15 +280,13 @@ 'file': 'search', 'kwds': {}, 'msg': "Click the 'Search' button.\n" - "Test various search options in the 'Search dialog'.\n" - "Click [Close] or [X] to close the 'Search Dialog'." + "Test various search options in the 'Search dialog'." } _searchbase_spec = { 'file': 'searchbase', 'kwds': {}, - 'msg': "Check the appearance of the base search dialog\n" - "Its only action is to close." + 'msg': "Check the appearance of the base search dialog" } show_idlehelp_spec = { diff --git a/Lib/idlelib/idle_test/test_searchbase.py b/Lib/idlelib/idle_test/test_searchbase.py index 8c9c410ebaf47c..0aaa84e2638f8f 100644 --- a/Lib/idlelib/idle_test/test_searchbase.py +++ b/Lib/idlelib/idle_test/test_searchbase.py @@ -85,7 +85,7 @@ def test_make_entry(self): equal(int(egi['row']), 0) equal(int(egi['column']), 1) equal(int(egi['rowspan']), 1) - equal(int(egi['columnspan']), 1) + equal(int(egi['columnspan']), 2) equal(self.dialog.row, 1) def test_create_entries(self): @@ -148,12 +148,6 @@ def test_make_button(self): def test_create_command_buttons(self): self.dialog.frame = Frame(self.root) self.dialog.create_command_buttons() - # Look for close button command in buttonframe - closebuttoncommand = '' - for child in self.dialog.buttonframe.winfo_children(): - if child['text'] == 'Close': - closebuttoncommand = child['command'] - self.assertIn('close', closebuttoncommand) if __name__ == '__main__': diff --git a/Lib/idlelib/replace.py b/Lib/idlelib/replace.py index 0dd340e4ae01be..9f8077d3a8bf85 100644 --- a/Lib/idlelib/replace.py +++ b/Lib/idlelib/replace.py @@ -86,11 +86,11 @@ def find_it(self, event=None): "Handle the Find button." self.do_find(False) - def replace_it(self, event=None): + def replace_it(self, event=None): """Only used in test case - - If the find is successful, then perform replace. - """ + + If the find is successful, then perform replace. + """ if self.do_find(self.ok): self.do_replace() From bf7ee82a5c7edf025ddd2d5083f8e8f1338d546e Mon Sep 17 00:00:00 2001 From: Wulian <1055917385@qq.com> Date: Sat, 31 Aug 2024 17:31:47 +0800 Subject: [PATCH 7/8] update News3.txt --- Lib/idlelib/News3.txt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Lib/idlelib/News3.txt b/Lib/idlelib/News3.txt index bc65808f3faed7..a3f5b7fb6e1410 100644 --- a/Lib/idlelib/News3.txt +++ b/Lib/idlelib/News3.txt @@ -4,8 +4,7 @@ Released on 2025-10-xx ========================= -gh-67407: Improve the Find, Replace and Find in Files dialogs. Patch by -Wulian233 and AlSweigart. +gh-67407: Improve the Find, Replace and Find in Files dialogs. What's New in IDLE 3.13.0 From 71499a80a12c2b50e4e5b7cd0071288a3b0a1f3b Mon Sep 17 00:00:00 2001 From: Wulian233 <1055917385@qq.com> Date: Mon, 15 Dec 2025 20:21:00 +0800 Subject: [PATCH 8/8] update --- Lib/idlelib/News3.txt | 9 --------- 1 file changed, 9 deletions(-) diff --git a/Lib/idlelib/News3.txt b/Lib/idlelib/News3.txt index a3f5b7fb6e1410..68702ac8fb9157 100644 --- a/Lib/idlelib/News3.txt +++ b/Lib/idlelib/News3.txt @@ -1,12 +1,3 @@ -What's New in IDLE 3.14.0 -(since 3.13.0) -Released on 2025-10-xx -========================= - - -gh-67407: Improve the Find, Replace and Find in Files dialogs. - - What's New in IDLE 3.13.0 (since 3.12.0) Released on 2024-10-xx