From 51dbf41437366d4ae6719c43315a31eaf8d389b9 Mon Sep 17 00:00:00 2001 From: Keyan Pishdadian Date: Tue, 20 Jan 2015 20:57:58 -0500 Subject: [PATCH 1/3] Refactor and fix keybinding issue (fixes #447) This changes the logic for the function get_key_no_doublebind() and removes the mutable list which was previously used to keep track of keybindings which were already used. Although this fix passes the test cases and the specific case mentioned in #447, the behavior is such that specifying the same custom keybinding for two commands will result in only one command being bound. --- bpython/config.py | 55 +++++++++++++++++++++++++++++++++++++---------- 1 file changed, 44 insertions(+), 11 deletions(-) diff --git a/bpython/config.py b/bpython/config.py index e9bbe2d3e..3cef922f8 100644 --- a/bpython/config.py +++ b/bpython/config.py @@ -104,6 +104,39 @@ def loadini(struct, configfile): 'list_above' : False, 'right_arrow_completion' : True, }} + + default_keys_to_commands = { + '': 'exit', + 'C-n': 'down_one_line', + 'C-l': 'clear_screen', + 'C-k': 'kill_line', + 'C-o': 'search', + 'C-h': 'backspace', + 'C-f': 'right', + 'C-e': 'end_of_line', + 'C-d': 'delete', + 'C-b':'left', + 'C-a': 'beginning_of_line', + 'C-z': 'suspend', + 'C-y': 'yank_from_buffer', + 'C-x': 'edit_current_block', + 'C-w': 'clear_word', + 'C-u': 'clear_line', + 'C-t': 'transpose_chars', + 'C-s': 'save', + 'C-r': 'undo', + 'C-p': 'up_one_line', + 'F10': 'copy_clipboard', + 'F1': 'help', + 'F2': 'show_source', + 'F3': 'edit_config', + 'F5': 'toggle_file_watch', + 'F6': 'reimport', + 'F7': 'external_editor', + 'F8': 'pastebin', + 'F9': 'last_output' + } + fill_config_with_default_values(config, defaults) if not config.read(config_path): # No config file. If the user has it in the old place then complain @@ -113,17 +146,17 @@ def loadini(struct, configfile): "%s\n" % default_config_path()) sys.exit(1) - def get_key_no_doublebind(attr, already_used={}): - """Clears any other configured keybindings using this key""" - key = config.get('keyboard', attr) - if key in already_used: - default = defaults['keyboard'][already_used[key]] - if default in already_used: - setattr(struct, '%s_key' % already_used[key], '') - else: - setattr(struct, '%s_key' % already_used[key], default) - already_used[key] = attr - return key + + def get_key_no_doublebind(command): + default_commands_to_keys = defaults['keyboard'] + requested_key = config.get('keyboard', command) + default_command = default_keys_to_commands[requested_key] + + if default_commands_to_keys[default_command] == \ + config.get('keyboard', default_command): + setattr(struct, '%s_key' % default_command, '') + + return requested_key struct.config_path = config_path From 4dbd59abe1865711c9de244344d7a101bd1ea0dd Mon Sep 17 00:00:00 2001 From: Keyan Pishdadian Date: Wed, 21 Jan 2015 14:22:53 -0500 Subject: [PATCH 2/3] Make default keybinding reverse dictionary to interable --- bpython/config.py | 33 ++------------------------------- 1 file changed, 2 insertions(+), 31 deletions(-) diff --git a/bpython/config.py b/bpython/config.py index 3cef922f8..f5d22469a 100644 --- a/bpython/config.py +++ b/bpython/config.py @@ -105,37 +105,8 @@ def loadini(struct, configfile): 'right_arrow_completion' : True, }} - default_keys_to_commands = { - '': 'exit', - 'C-n': 'down_one_line', - 'C-l': 'clear_screen', - 'C-k': 'kill_line', - 'C-o': 'search', - 'C-h': 'backspace', - 'C-f': 'right', - 'C-e': 'end_of_line', - 'C-d': 'delete', - 'C-b':'left', - 'C-a': 'beginning_of_line', - 'C-z': 'suspend', - 'C-y': 'yank_from_buffer', - 'C-x': 'edit_current_block', - 'C-w': 'clear_word', - 'C-u': 'clear_line', - 'C-t': 'transpose_chars', - 'C-s': 'save', - 'C-r': 'undo', - 'C-p': 'up_one_line', - 'F10': 'copy_clipboard', - 'F1': 'help', - 'F2': 'show_source', - 'F3': 'edit_config', - 'F5': 'toggle_file_watch', - 'F6': 'reimport', - 'F7': 'external_editor', - 'F8': 'pastebin', - 'F9': 'last_output' - } + default_keys_to_commands = dict((value, key) for (key, value) + in defaults['keyboard'].iteritems()) fill_config_with_default_values(config, defaults) if not config.read(config_path): From fb46b607d0354085c96f11dc37e047ae6e817dc3 Mon Sep 17 00:00:00 2001 From: Keyan Pishdadian Date: Wed, 21 Jan 2015 18:09:39 -0500 Subject: [PATCH 3/3] Remove kill_line command which is duplicate of cut_to_buffer --- bpython/config.py | 2 -- bpython/curtsiesfrontend/manual_readline.py | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/bpython/config.py b/bpython/config.py index f5d22469a..0c96b25bd 100644 --- a/bpython/config.py +++ b/bpython/config.py @@ -74,7 +74,6 @@ def loadini(struct, configfile): 'transpose_chars': 'C-t', 'clear_line': 'C-u', 'clear_screen': 'C-l', - 'kill_line': 'C-k', 'clear_word': 'C-w', 'cut_to_buffer': 'C-k', 'delete': 'C-d', @@ -172,7 +171,6 @@ def get_key_no_doublebind(command): struct.transpose_chars_key = get_key_no_doublebind('transpose_chars') struct.clear_line_key = get_key_no_doublebind('clear_line') struct.clear_screen_key = get_key_no_doublebind('clear_screen') - struct.kill_line_key = get_key_no_doublebind('kill_line') struct.exit_key = get_key_no_doublebind('exit') struct.last_output_key = get_key_no_doublebind('last_output') struct.edit_config_key = get_key_no_doublebind('edit_config') diff --git a/bpython/curtsiesfrontend/manual_readline.py b/bpython/curtsiesfrontend/manual_readline.py index 3c608b14d..d2e34126a 100644 --- a/bpython/curtsiesfrontend/manual_readline.py +++ b/bpython/curtsiesfrontend/manual_readline.py @@ -250,7 +250,7 @@ def delete_line(cursor_offset, line): def uppercase_next_word(cursor_offset, line): return cursor_offset, line #TODO Not implemented -@edit_keys.on(config='kill_line_key') +@edit_keys.on(config='cut_to_buffer_key') @kills_ahead def delete_from_cursor_forward(cursor_offset, line): return cursor_offset, line[:cursor_offset], line[cursor_offset:]