From 57181d46cd5112a297a468a0ea2e6be18b0964c2 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Sun, 26 Mar 2017 20:29:17 +0300 Subject: [PATCH 1/3] bpo-29910: IDLE no longer delete character after commenting out a region by key shortcut. Fixed also other potential conflicts between IDLE's and default key bindings. --- Lib/idlelib/autocomplete.py | 1 + Lib/idlelib/calltip_w.py | 7 ++++-- Lib/idlelib/calltips.py | 1 + Lib/idlelib/codecontext.py | 1 + Lib/idlelib/editor.py | 30 +++++++++++++++++++----- Lib/idlelib/idle_test/test_parenmatch.py | 8 +++---- Lib/idlelib/parenmatch.py | 10 ++++---- Lib/idlelib/runscript.py | 1 + Lib/idlelib/scrolledlist.py | 1 + Lib/idlelib/zoomheight.py | 1 + Misc/NEWS | 4 ++++ 11 files changed, 49 insertions(+), 16 deletions(-) diff --git a/Lib/idlelib/autocomplete.py b/Lib/idlelib/autocomplete.py index 1e44fa5bc66e8a..cd212ccb143a3c 100644 --- a/Lib/idlelib/autocomplete.py +++ b/Lib/idlelib/autocomplete.py @@ -60,6 +60,7 @@ def force_open_completions_event(self, event): if a function call is needed. """ self.open_completions(True, False, True) + return "break" def try_open_completions_event(self, event): """Happens when it would be nice to open a completion list, but not diff --git a/Lib/idlelib/calltip_w.py b/Lib/idlelib/calltip_w.py index c7361d18d66efd..bf967f40b6ab1c 100644 --- a/Lib/idlelib/calltip_w.py +++ b/Lib/idlelib/calltip_w.py @@ -89,24 +89,27 @@ def checkhide_event(self, event=None): # If the event was triggered by the same event that unbinded # this function, the function will be called nevertheless, # so do nothing in this case. - return + return None curline, curcol = map(int, self.widget.index("insert").split('.')) if curline < self.parenline or \ (curline == self.parenline and curcol <= self.parencol) or \ self.widget.compare("insert", ">", MARK_RIGHT): self.hidetip() + return "break" else: self.position_window() if self.checkhide_after_id is not None: self.widget.after_cancel(self.checkhide_after_id) self.checkhide_after_id = \ self.widget.after(CHECKHIDE_TIME, self.checkhide_event) + return None def hide_event(self, event): if not self.tipwindow: # See the explanation in checkhide_event. - return + return None self.hidetip() + return "break" def hidetip(self): if not self.tipwindow: diff --git a/Lib/idlelib/calltips.py b/Lib/idlelib/calltips.py index 4c5aea2acbf40b..a8a3abe6c6982a 100644 --- a/Lib/idlelib/calltips.py +++ b/Lib/idlelib/calltips.py @@ -47,6 +47,7 @@ def _remove_calltip_window(self, event=None): def force_open_calltip_event(self, event): "The user selected the menu entry or hotkey, open the tip." self.open_calltip(True) + return "break" def try_open_calltip_event(self, event): """Happens when it would be nice to open a CallTip, but not really diff --git a/Lib/idlelib/codecontext.py b/Lib/idlelib/codecontext.py index f25e1b33a086e8..09dc078d63f191 100644 --- a/Lib/idlelib/codecontext.py +++ b/Lib/idlelib/codecontext.py @@ -89,6 +89,7 @@ def toggle_code_context_event(self, event=None): idleConf.SetOption("extensions", "CodeContext", "visible", str(self.label is not None)) idleConf.SaveUserCfgFiles() + return "break" def get_line_info(self, linenum): """Get the line indent value, text, and any block start keyword diff --git a/Lib/idlelib/editor.py b/Lib/idlelib/editor.py index ae475cb9f9a6a5..335ee984305c22 100644 --- a/Lib/idlelib/editor.py +++ b/Lib/idlelib/editor.py @@ -1,4 +1,3 @@ -import importlib import importlib.abc import importlib.util import os @@ -148,7 +147,7 @@ def __init__(self, flist=None, filename=None, key=None, root=None): text.bind("<>", self.python_docs) text.bind("<>", self.about_dialog) text.bind("<>", self.config_dialog) - text.bind("<>", self.open_module) + text.bind("<>", self.open_module_event) text.bind("<>", lambda event: "break") text.bind("<>", self.select_all) text.bind("<>", self.remove_selection) @@ -295,7 +294,7 @@ def new_callback(self, event): def home_callback(self, event): if (event.state & 4) != 0 and event.keysym == "Home": # state&4==Control. If , use the Tk binding. - return + return None if self.text.index("iomark") and \ self.text.compare("iomark", "<=", "insert lineend") and \ self.text.compare("insert linestart", "<=", "iomark"): @@ -424,6 +423,7 @@ def right_menu_event(self, event): rmenu.tk_popup(event.x_root, event.y_root) if iswin: self.text.config(cursor="ibeam") + return "break" rmenu_specs = [ # ("Label", "<>", "statefuncname"), ... @@ -465,11 +465,13 @@ def about_dialog(self, event=None): "Handle Help 'About IDLE' event." # Synchronize with macosx.overrideRootMenu.about_dialog. help_about.AboutDialog(self.top,'About IDLE') + return "break" def config_dialog(self, event=None): "Handle Options 'Configure IDLE' event." # Synchronize with macosx.overrideRootMenu.config_dialog. configdialog.ConfigDialog(self.top,'Settings') + return "break" def help_dialog(self, event=None): "Handle Help 'IDLE Help' event." @@ -479,6 +481,7 @@ def help_dialog(self, event=None): else: parent = self.top help.show_idlehelp(parent) + return "break" def python_docs(self, event=None): if sys.platform[:3] == 'win': @@ -498,7 +501,7 @@ def cut(self,event): def copy(self,event): if not self.text.tag_ranges("sel"): # There is no selection, so do nothing and maybe interrupt. - return + return None self.text.event_generate("<>") return "break" @@ -516,6 +519,7 @@ def select_all(self, event=None): def remove_selection(self, event=None): self.text.tag_remove("sel", "1.0", "end") self.text.see("insert") + return "break" def move_at_edge_if_selection(self, edge_index): """Cursor move begins at start or end of selection @@ -576,8 +580,9 @@ def goto_line_event(self, event): return "break" text.mark_set("insert", "%d.0" % lineno) text.see("insert") + return "break" - def open_module(self, event=None): + def open_module(self): """Get module name from user and open it. Return module path or None for calls by open_class_browser @@ -601,21 +606,27 @@ def open_module(self, event=None): self.io.loadfile(file_path) return file_path + def open_module_event(self, event): + self.open_module() + return "break" + def open_class_browser(self, event=None): filename = self.io.filename if not (self.__class__.__name__ == 'PyShellEditorWindow' and filename): filename = self.open_module() if filename is None: - return + return "break" head, tail = os.path.split(filename) base, ext = os.path.splitext(tail) from idlelib import browser browser.ClassBrowser(self.flist, base, [head]) + return "break" def open_path_browser(self, event=None): from idlelib import pathbrowser pathbrowser.PathBrowser(self.flist) + return "break" def open_turtle_demo(self, event = None): import subprocess @@ -624,6 +635,7 @@ def open_turtle_demo(self, event = None): '-c', 'from turtledemo.__main__ import main; main()'] subprocess.Popen(cmd, shell=False) + return "break" def gotoline(self, lineno): if lineno is not None and lineno > 0: @@ -880,6 +892,7 @@ def long_title(self): def center_insert_event(self, event): self.center() + return "break" def center(self, mark="insert"): text = self.text @@ -911,6 +924,7 @@ def get_geometry(self): def close_event(self, event): self.close() + return "break" def maybesave(self): if self.io: @@ -1358,6 +1372,7 @@ def comment_region_event(self, event): line = lines[pos] lines[pos] = '##' + line self.set_region(head, tail, chars, lines) + return "break" def uncomment_region_event(self, event): head, tail, chars, lines = self.get_region() @@ -1371,6 +1386,7 @@ def uncomment_region_event(self, event): line = line[1:] lines[pos] = line self.set_region(head, tail, chars, lines) + return "break" def tabify_region_event(self, event): head, tail, chars, lines = self.get_region() @@ -1383,6 +1399,7 @@ def tabify_region_event(self, event): ntabs, nspaces = divmod(effective, tabwidth) lines[pos] = '\t' * ntabs + ' ' * nspaces + line[raw:] self.set_region(head, tail, chars, lines) + return "break" def untabify_region_event(self, event): head, tail, chars, lines = self.get_region() @@ -1391,6 +1408,7 @@ def untabify_region_event(self, event): for pos in range(len(lines)): lines[pos] = lines[pos].expandtabs(tabwidth) self.set_region(head, tail, chars, lines) + return "break" def toggle_tabs_event(self, event): if self.askyesno( diff --git a/Lib/idlelib/idle_test/test_parenmatch.py b/Lib/idlelib/idle_test/test_parenmatch.py index 051f7eac2dce06..419b712c0f38a4 100644 --- a/Lib/idlelib/idle_test/test_parenmatch.py +++ b/Lib/idlelib/idle_test/test_parenmatch.py @@ -94,14 +94,14 @@ def test_paren_corner(self): pm = self.get_parenmatch() text.insert('insert', '# this is a commen)') - self.assertIsNone(pm.paren_closed_event('event')) + pm.paren_closed_event('event') text.insert('insert', '\ndef') - self.assertIsNone(pm.flash_paren_event('event')) - self.assertIsNone(pm.paren_closed_event('event')) + pm.flash_paren_event('event') + pm.paren_closed_event('event') text.insert('insert', ' a, *arg)') - self.assertIsNone(pm.paren_closed_event('event')) + pm.paren_closed_event('event') def test_handle_restore_timer(self): pm = self.get_parenmatch() diff --git a/Lib/idlelib/parenmatch.py b/Lib/idlelib/parenmatch.py index ccec708f31f436..dcec34c18f9287 100644 --- a/Lib/idlelib/parenmatch.py +++ b/Lib/idlelib/parenmatch.py @@ -94,26 +94,28 @@ def flash_paren_event(self, event): .get_surrounding_brackets()) if indices is None: self.bell() - return + return "break" self.activate_restore() self.create_tag(indices) self.set_timeout_last() + return "break" def paren_closed_event(self, event): # If it was a shortcut and not really a closing paren, quit. closer = self.text.get("insert-1c") if closer not in _openers: - return + return "break" hp = HyperParser(self.editwin, "insert-1c") if not hp.is_in_code(): - return + return "break" indices = hp.get_surrounding_brackets(_openers[closer], True) if indices is None: self.bell() - return + return "break" self.activate_restore() self.create_tag(indices) self.set_timeout() + return "break" def restore_event(self, event=None): self.text.tag_delete("paren") diff --git a/Lib/idlelib/runscript.py b/Lib/idlelib/runscript.py index 79d86adabc85a0..3355f17d90bdb7 100644 --- a/Lib/idlelib/runscript.py +++ b/Lib/idlelib/runscript.py @@ -63,6 +63,7 @@ def check_module_event(self, event): return 'break' if not self.tabnanny(filename): return 'break' + return "break" def tabnanny(self, filename): # XXX: tabnanny should work on binary files as well diff --git a/Lib/idlelib/scrolledlist.py b/Lib/idlelib/scrolledlist.py index cc08c26e5eefaa..cdf658404ab643 100644 --- a/Lib/idlelib/scrolledlist.py +++ b/Lib/idlelib/scrolledlist.py @@ -76,6 +76,7 @@ def popup_event(self, event): index = self.listbox.index("active") self.select(index) menu.tk_popup(event.x_root, event.y_root) + return "break" def make_menu(self): menu = Menu(self.listbox, tearoff=0) diff --git a/Lib/idlelib/zoomheight.py b/Lib/idlelib/zoomheight.py index aa4a427eab737f..d01c9e964aa60f 100644 --- a/Lib/idlelib/zoomheight.py +++ b/Lib/idlelib/zoomheight.py @@ -20,6 +20,7 @@ def __init__(self, editwin): def zoom_height_event(self, event): top = self.editwin.top zoom_height(top) + return "break" def zoom_height(top): diff --git a/Misc/NEWS b/Misc/NEWS index 8360abbdb7bae3..a649f6245f392f 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -2152,6 +2152,10 @@ Library IDLE ---- +- Issue #29910: IDLE no longer delete character after commenting out a region + by key shortcut. Fixed also other potential conflicts between IDLE's and + default key bindings. + - Issue #15308: Add 'interrupt execution' (^C) to Shell menu. Patch by Roger Serwy, updated by Bayard Randel. From ee8d76909ad8a79763ad7e97b50c5dbee6ddebd1 Mon Sep 17 00:00:00 2001 From: Terry Jan Reedy Date: Mon, 26 Jun 2017 22:47:27 -0400 Subject: [PATCH 2/3] Add news item --- Misc/NEWS.d/next/IDLE/2017-06-26-22-45-27.bpo-29910.mqHh7u.rst | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 Misc/NEWS.d/next/IDLE/2017-06-26-22-45-27.bpo-29910.mqHh7u.rst diff --git a/Misc/NEWS.d/next/IDLE/2017-06-26-22-45-27.bpo-29910.mqHh7u.rst b/Misc/NEWS.d/next/IDLE/2017-06-26-22-45-27.bpo-29910.mqHh7u.rst new file mode 100644 index 00000000000000..5157f8bb923c07 --- /dev/null +++ b/Misc/NEWS.d/next/IDLE/2017-06-26-22-45-27.bpo-29910.mqHh7u.rst @@ -0,0 +1,3 @@ +IDLE no longer deletes a character after commenting out a region by a key +shortcut. Add ``return 'break'`` for this and other potential conflicts +between IDLE and default key bindings. From d9a9b8fcad8235f3cc16168f10ca8629e5682e4a Mon Sep 17 00:00:00 2001 From: terryjreedy Date: Mon, 26 Jun 2017 22:57:19 -0400 Subject: [PATCH 3/3] Update NEWS --- Misc/NEWS | 4 ---- 1 file changed, 4 deletions(-) diff --git a/Misc/NEWS b/Misc/NEWS index a649f6245f392f..8360abbdb7bae3 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -2152,10 +2152,6 @@ Library IDLE ---- -- Issue #29910: IDLE no longer delete character after commenting out a region - by key shortcut. Fixed also other potential conflicts between IDLE's and - default key bindings. - - Issue #15308: Add 'interrupt execution' (^C) to Shell menu. Patch by Roger Serwy, updated by Bayard Randel.