Kaydet (Commit) 213ce12a authored tarafından Serhiy Storchaka's avatar Serhiy Storchaka Kaydeden (comit) terryjreedy

bpo-29910: IDLE no longer deletes a character after commenting out a region (#825)

This happened because shortcut has a class binding and 'break' was not returned.
Fix other potential conflicts between IDLE and default key bindings.

* Add news item

* Update NEWS
üst 9a02ae3d
...@@ -60,6 +60,7 @@ class AutoComplete: ...@@ -60,6 +60,7 @@ class AutoComplete:
if a function call is needed. if a function call is needed.
""" """
self.open_completions(True, False, True) self.open_completions(True, False, True)
return "break"
def try_open_completions_event(self, event): def try_open_completions_event(self, event):
"""Happens when it would be nice to open a completion list, but not """Happens when it would be nice to open a completion list, but not
......
...@@ -89,24 +89,27 @@ class CallTip: ...@@ -89,24 +89,27 @@ class CallTip:
# If the event was triggered by the same event that unbinded # If the event was triggered by the same event that unbinded
# this function, the function will be called nevertheless, # this function, the function will be called nevertheless,
# so do nothing in this case. # so do nothing in this case.
return return None
curline, curcol = map(int, self.widget.index("insert").split('.')) curline, curcol = map(int, self.widget.index("insert").split('.'))
if curline < self.parenline or \ if curline < self.parenline or \
(curline == self.parenline and curcol <= self.parencol) or \ (curline == self.parenline and curcol <= self.parencol) or \
self.widget.compare("insert", ">", MARK_RIGHT): self.widget.compare("insert", ">", MARK_RIGHT):
self.hidetip() self.hidetip()
return "break"
else: else:
self.position_window() self.position_window()
if self.checkhide_after_id is not None: if self.checkhide_after_id is not None:
self.widget.after_cancel(self.checkhide_after_id) self.widget.after_cancel(self.checkhide_after_id)
self.checkhide_after_id = \ self.checkhide_after_id = \
self.widget.after(CHECKHIDE_TIME, self.checkhide_event) self.widget.after(CHECKHIDE_TIME, self.checkhide_event)
return None
def hide_event(self, event): def hide_event(self, event):
if not self.tipwindow: if not self.tipwindow:
# See the explanation in checkhide_event. # See the explanation in checkhide_event.
return return None
self.hidetip() self.hidetip()
return "break"
def hidetip(self): def hidetip(self):
if not self.tipwindow: if not self.tipwindow:
......
...@@ -47,6 +47,7 @@ class CallTips: ...@@ -47,6 +47,7 @@ class CallTips:
def force_open_calltip_event(self, event): def force_open_calltip_event(self, event):
"The user selected the menu entry or hotkey, open the tip." "The user selected the menu entry or hotkey, open the tip."
self.open_calltip(True) self.open_calltip(True)
return "break"
def try_open_calltip_event(self, event): def try_open_calltip_event(self, event):
"""Happens when it would be nice to open a CallTip, but not really """Happens when it would be nice to open a CallTip, but not really
......
...@@ -89,6 +89,7 @@ class CodeContext: ...@@ -89,6 +89,7 @@ class CodeContext:
idleConf.SetOption("extensions", "CodeContext", "visible", idleConf.SetOption("extensions", "CodeContext", "visible",
str(self.label is not None)) str(self.label is not None))
idleConf.SaveUserCfgFiles() idleConf.SaveUserCfgFiles()
return "break"
def get_line_info(self, linenum): def get_line_info(self, linenum):
"""Get the line indent value, text, and any block start keyword """Get the line indent value, text, and any block start keyword
......
import importlib
import importlib.abc import importlib.abc
import importlib.util import importlib.util
import os import os
...@@ -147,7 +146,7 @@ class EditorWindow(object): ...@@ -147,7 +146,7 @@ class EditorWindow(object):
text.bind("<<python-docs>>", self.python_docs) text.bind("<<python-docs>>", self.python_docs)
text.bind("<<about-idle>>", self.about_dialog) text.bind("<<about-idle>>", self.about_dialog)
text.bind("<<open-config-dialog>>", self.config_dialog) text.bind("<<open-config-dialog>>", self.config_dialog)
text.bind("<<open-module>>", self.open_module) text.bind("<<open-module>>", self.open_module_event)
text.bind("<<do-nothing>>", lambda event: "break") text.bind("<<do-nothing>>", lambda event: "break")
text.bind("<<select-all>>", self.select_all) text.bind("<<select-all>>", self.select_all)
text.bind("<<remove-selection>>", self.remove_selection) text.bind("<<remove-selection>>", self.remove_selection)
...@@ -294,7 +293,7 @@ class EditorWindow(object): ...@@ -294,7 +293,7 @@ class EditorWindow(object):
def home_callback(self, event): def home_callback(self, event):
if (event.state & 4) != 0 and event.keysym == "Home": if (event.state & 4) != 0 and event.keysym == "Home":
# state&4==Control. If <Control-Home>, use the Tk binding. # state&4==Control. If <Control-Home>, use the Tk binding.
return return None
if self.text.index("iomark") and \ if self.text.index("iomark") and \
self.text.compare("iomark", "<=", "insert lineend") and \ self.text.compare("iomark", "<=", "insert lineend") and \
self.text.compare("insert linestart", "<=", "iomark"): self.text.compare("insert linestart", "<=", "iomark"):
...@@ -423,6 +422,7 @@ class EditorWindow(object): ...@@ -423,6 +422,7 @@ class EditorWindow(object):
rmenu.tk_popup(event.x_root, event.y_root) rmenu.tk_popup(event.x_root, event.y_root)
if iswin: if iswin:
self.text.config(cursor="ibeam") self.text.config(cursor="ibeam")
return "break"
rmenu_specs = [ rmenu_specs = [
# ("Label", "<<virtual-event>>", "statefuncname"), ... # ("Label", "<<virtual-event>>", "statefuncname"), ...
...@@ -464,11 +464,13 @@ class EditorWindow(object): ...@@ -464,11 +464,13 @@ class EditorWindow(object):
"Handle Help 'About IDLE' event." "Handle Help 'About IDLE' event."
# Synchronize with macosx.overrideRootMenu.about_dialog. # Synchronize with macosx.overrideRootMenu.about_dialog.
help_about.AboutDialog(self.top) help_about.AboutDialog(self.top)
return "break"
def config_dialog(self, event=None): def config_dialog(self, event=None):
"Handle Options 'Configure IDLE' event." "Handle Options 'Configure IDLE' event."
# Synchronize with macosx.overrideRootMenu.config_dialog. # Synchronize with macosx.overrideRootMenu.config_dialog.
configdialog.ConfigDialog(self.top,'Settings') configdialog.ConfigDialog(self.top,'Settings')
return "break"
def help_dialog(self, event=None): def help_dialog(self, event=None):
"Handle Help 'IDLE Help' event." "Handle Help 'IDLE Help' event."
...@@ -478,6 +480,7 @@ class EditorWindow(object): ...@@ -478,6 +480,7 @@ class EditorWindow(object):
else: else:
parent = self.top parent = self.top
help.show_idlehelp(parent) help.show_idlehelp(parent)
return "break"
def python_docs(self, event=None): def python_docs(self, event=None):
if sys.platform[:3] == 'win': if sys.platform[:3] == 'win':
...@@ -497,7 +500,7 @@ class EditorWindow(object): ...@@ -497,7 +500,7 @@ class EditorWindow(object):
def copy(self,event): def copy(self,event):
if not self.text.tag_ranges("sel"): if not self.text.tag_ranges("sel"):
# There is no selection, so do nothing and maybe interrupt. # There is no selection, so do nothing and maybe interrupt.
return return None
self.text.event_generate("<<Copy>>") self.text.event_generate("<<Copy>>")
return "break" return "break"
...@@ -515,6 +518,7 @@ class EditorWindow(object): ...@@ -515,6 +518,7 @@ class EditorWindow(object):
def remove_selection(self, event=None): def remove_selection(self, event=None):
self.text.tag_remove("sel", "1.0", "end") self.text.tag_remove("sel", "1.0", "end")
self.text.see("insert") self.text.see("insert")
return "break"
def move_at_edge_if_selection(self, edge_index): def move_at_edge_if_selection(self, edge_index):
"""Cursor move begins at start or end of selection """Cursor move begins at start or end of selection
...@@ -575,8 +579,9 @@ class EditorWindow(object): ...@@ -575,8 +579,9 @@ class EditorWindow(object):
return "break" return "break"
text.mark_set("insert", "%d.0" % lineno) text.mark_set("insert", "%d.0" % lineno)
text.see("insert") text.see("insert")
return "break"
def open_module(self, event=None): def open_module(self):
"""Get module name from user and open it. """Get module name from user and open it.
Return module path or None for calls by open_class_browser Return module path or None for calls by open_class_browser
...@@ -600,21 +605,27 @@ class EditorWindow(object): ...@@ -600,21 +605,27 @@ class EditorWindow(object):
self.io.loadfile(file_path) self.io.loadfile(file_path)
return file_path return file_path
def open_module_event(self, event):
self.open_module()
return "break"
def open_class_browser(self, event=None): def open_class_browser(self, event=None):
filename = self.io.filename filename = self.io.filename
if not (self.__class__.__name__ == 'PyShellEditorWindow' if not (self.__class__.__name__ == 'PyShellEditorWindow'
and filename): and filename):
filename = self.open_module() filename = self.open_module()
if filename is None: if filename is None:
return return "break"
head, tail = os.path.split(filename) head, tail = os.path.split(filename)
base, ext = os.path.splitext(tail) base, ext = os.path.splitext(tail)
from idlelib import browser from idlelib import browser
browser.ClassBrowser(self.flist, base, [head]) browser.ClassBrowser(self.flist, base, [head])
return "break"
def open_path_browser(self, event=None): def open_path_browser(self, event=None):
from idlelib import pathbrowser from idlelib import pathbrowser
pathbrowser.PathBrowser(self.flist) pathbrowser.PathBrowser(self.flist)
return "break"
def open_turtle_demo(self, event = None): def open_turtle_demo(self, event = None):
import subprocess import subprocess
...@@ -623,6 +634,7 @@ class EditorWindow(object): ...@@ -623,6 +634,7 @@ class EditorWindow(object):
'-c', '-c',
'from turtledemo.__main__ import main; main()'] 'from turtledemo.__main__ import main; main()']
subprocess.Popen(cmd, shell=False) subprocess.Popen(cmd, shell=False)
return "break"
def gotoline(self, lineno): def gotoline(self, lineno):
if lineno is not None and lineno > 0: if lineno is not None and lineno > 0:
...@@ -879,6 +891,7 @@ class EditorWindow(object): ...@@ -879,6 +891,7 @@ class EditorWindow(object):
def center_insert_event(self, event): def center_insert_event(self, event):
self.center() self.center()
return "break"
def center(self, mark="insert"): def center(self, mark="insert"):
text = self.text text = self.text
...@@ -910,6 +923,7 @@ class EditorWindow(object): ...@@ -910,6 +923,7 @@ class EditorWindow(object):
def close_event(self, event): def close_event(self, event):
self.close() self.close()
return "break"
def maybesave(self): def maybesave(self):
if self.io: if self.io:
...@@ -1357,6 +1371,7 @@ class EditorWindow(object): ...@@ -1357,6 +1371,7 @@ class EditorWindow(object):
line = lines[pos] line = lines[pos]
lines[pos] = '##' + line lines[pos] = '##' + line
self.set_region(head, tail, chars, lines) self.set_region(head, tail, chars, lines)
return "break"
def uncomment_region_event(self, event): def uncomment_region_event(self, event):
head, tail, chars, lines = self.get_region() head, tail, chars, lines = self.get_region()
...@@ -1370,6 +1385,7 @@ class EditorWindow(object): ...@@ -1370,6 +1385,7 @@ class EditorWindow(object):
line = line[1:] line = line[1:]
lines[pos] = line lines[pos] = line
self.set_region(head, tail, chars, lines) self.set_region(head, tail, chars, lines)
return "break"
def tabify_region_event(self, event): def tabify_region_event(self, event):
head, tail, chars, lines = self.get_region() head, tail, chars, lines = self.get_region()
...@@ -1382,6 +1398,7 @@ class EditorWindow(object): ...@@ -1382,6 +1398,7 @@ class EditorWindow(object):
ntabs, nspaces = divmod(effective, tabwidth) ntabs, nspaces = divmod(effective, tabwidth)
lines[pos] = '\t' * ntabs + ' ' * nspaces + line[raw:] lines[pos] = '\t' * ntabs + ' ' * nspaces + line[raw:]
self.set_region(head, tail, chars, lines) self.set_region(head, tail, chars, lines)
return "break"
def untabify_region_event(self, event): def untabify_region_event(self, event):
head, tail, chars, lines = self.get_region() head, tail, chars, lines = self.get_region()
...@@ -1390,6 +1407,7 @@ class EditorWindow(object): ...@@ -1390,6 +1407,7 @@ class EditorWindow(object):
for pos in range(len(lines)): for pos in range(len(lines)):
lines[pos] = lines[pos].expandtabs(tabwidth) lines[pos] = lines[pos].expandtabs(tabwidth)
self.set_region(head, tail, chars, lines) self.set_region(head, tail, chars, lines)
return "break"
def toggle_tabs_event(self, event): def toggle_tabs_event(self, event):
if self.askyesno( if self.askyesno(
......
...@@ -95,14 +95,14 @@ class ParenMatchTest(unittest.TestCase): ...@@ -95,14 +95,14 @@ class ParenMatchTest(unittest.TestCase):
pm = self.get_parenmatch() pm = self.get_parenmatch()
text.insert('insert', '# this is a commen)') text.insert('insert', '# this is a commen)')
self.assertIsNone(pm.paren_closed_event('event')) pm.paren_closed_event('event')
text.insert('insert', '\ndef') text.insert('insert', '\ndef')
self.assertIsNone(pm.flash_paren_event('event')) pm.flash_paren_event('event')
self.assertIsNone(pm.paren_closed_event('event')) pm.paren_closed_event('event')
text.insert('insert', ' a, *arg)') text.insert('insert', ' a, *arg)')
self.assertIsNone(pm.paren_closed_event('event')) pm.paren_closed_event('event')
def test_handle_restore_timer(self): def test_handle_restore_timer(self):
pm = self.get_parenmatch() pm = self.get_parenmatch()
......
...@@ -94,26 +94,28 @@ class ParenMatch: ...@@ -94,26 +94,28 @@ class ParenMatch:
.get_surrounding_brackets()) .get_surrounding_brackets())
if indices is None: if indices is None:
self.bell() self.bell()
return return "break"
self.activate_restore() self.activate_restore()
self.create_tag(indices) self.create_tag(indices)
self.set_timeout_last() self.set_timeout_last()
return "break"
def paren_closed_event(self, event): def paren_closed_event(self, event):
# If it was a shortcut and not really a closing paren, quit. # If it was a shortcut and not really a closing paren, quit.
closer = self.text.get("insert-1c") closer = self.text.get("insert-1c")
if closer not in _openers: if closer not in _openers:
return return "break"
hp = HyperParser(self.editwin, "insert-1c") hp = HyperParser(self.editwin, "insert-1c")
if not hp.is_in_code(): if not hp.is_in_code():
return return "break"
indices = hp.get_surrounding_brackets(_openers[closer], True) indices = hp.get_surrounding_brackets(_openers[closer], True)
if indices is None: if indices is None:
self.bell() self.bell()
return return "break"
self.activate_restore() self.activate_restore()
self.create_tag(indices) self.create_tag(indices)
self.set_timeout() self.set_timeout()
return "break"
def restore_event(self, event=None): def restore_event(self, event=None):
self.text.tag_delete("paren") self.text.tag_delete("paren")
......
...@@ -63,6 +63,7 @@ class ScriptBinding: ...@@ -63,6 +63,7 @@ class ScriptBinding:
return 'break' return 'break'
if not self.tabnanny(filename): if not self.tabnanny(filename):
return 'break' return 'break'
return "break"
def tabnanny(self, filename): def tabnanny(self, filename):
# XXX: tabnanny should work on binary files as well # XXX: tabnanny should work on binary files as well
......
...@@ -76,6 +76,7 @@ class ScrolledList: ...@@ -76,6 +76,7 @@ class ScrolledList:
index = self.listbox.index("active") index = self.listbox.index("active")
self.select(index) self.select(index)
menu.tk_popup(event.x_root, event.y_root) menu.tk_popup(event.x_root, event.y_root)
return "break"
def make_menu(self): def make_menu(self):
menu = Menu(self.listbox, tearoff=0) menu = Menu(self.listbox, tearoff=0)
......
...@@ -20,6 +20,7 @@ class ZoomHeight: ...@@ -20,6 +20,7 @@ class ZoomHeight:
def zoom_height_event(self, event): def zoom_height_event(self, event):
top = self.editwin.top top = self.editwin.top
zoom_height(top) zoom_height(top)
return "break"
def zoom_height(top): def zoom_height(top):
......
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.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment