New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
delete_word_left and delete_word_right unexpected behaviour #3186
Comments
This was bothering me quite a lot. So i had to do something. Here is an algorithm where i tried to copy the behavior of sublime text: Basic idea is that there are 3 character groups. As long as the next character is of the same group the deletion continues. One preceding white-space is skipped so that it is removed together with the word. import tkinter as tk
example_text = """
start_index = text_widget.search(r'\w*\W?', cursor_index, backwards=True, regexp=True, stopindex='1.0')
# If start_index is at the beginning of the text, move it to the beginning of the line
if start_index == '':
start_index = '1.0'
else:
start_index = text_widget.index(start_index + "+1c")
# Delete text between start of the word and cursor position
text_widget.delete(start_index, cursor_index)
# Example usage:
def on_ctrl_backspace(event):
delete_word_left(text_widget)
asdasdf
aaaaa\tasdf\t \tfsdf\t\tsdksd\t
.)(=.,)[]$&/()''""....{} asdf§sadf
"""
def char_group(c):
# group 1 = whitespaces, group 2 = symbols, group 3 = alphanum
group2_chars = '!"#$%&\'()*+,-./:;<=>?@[\\]^`{|}~'
if c.isspace(): return 1
if c in group2_chars: return 2
return 3
def delete_word_left(text_widget):
# Get current cursor position
cursor_index = text_widget.index(tk.INSERT)
line_start_index = text_widget.index(cursor_index + " linestart")
# get the current line and search from the end
line = text_widget.get(line_start_index, tk.INSERT)
cur_index = len(line)-1
# step at least one whitespace at the beginning
if line and line[cur_index].isspace():
cur_index -= 1
last_char_group = None
for cur_char in reversed(line[:cur_index+1]):
cur_char_group = char_group(cur_char)
if last_char_group and last_char_group != cur_char_group:
break
last_char_group = cur_char_group
cur_index -= 1
start_index = text_widget.index(line_start_index + f" + {cur_index+2} chars")
text_widget.delete(start_index, cursor_index)
def delete_word_right(text_widget):
# Get current cursor position
cursor_index = text_widget.index(tk.INSERT)
line_end_index = text_widget.index(cursor_index + " lineend")
# get the current line and search from the end
line = text_widget.get(tk.INSERT, line_end_index)
cur_index = 0
# step at least one whitespace at the beginning
if line and line[cur_index].isspace():
cur_index += 1
last_char_group = None
for cur_char in line[cur_index:]:
cur_char_group = char_group(cur_char)
# print(f'{cur_index=} {cur_char=} {cur_char_group=} {last_char_group=}')
if last_char_group and last_char_group != cur_char_group:
break
last_char_group = cur_char_group
cur_index += 1
end_index = text_widget.index(cursor_index + f" + {cur_index-1} chars")
text_widget.delete(cursor_index, end_index)
def on_ctrl_backspace(event):
delete_word_left(text_widget)
def on_ctrl_delete(event):
delete_word_right(text_widget)
root = tk.Tk()
text_widget = tk.Text(root)
text_widget.insert(tk.END, example_text)
text_widget.pack()
text_widget.focus()
text_widget.bind("<Control-BackSpace>", on_ctrl_backspace)
text_widget.bind("<Control-Delete>", on_ctrl_delete)
root.mainloop() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
When deleting a word with
delete_word_left
(ctrl+backspace) ordelete_word_right
(ctrl+delete) the behavior is not like in other editor and in my opinion faulty.[foo]
foo bar []()
givesfoo
even though there is a space in between.The text was updated successfully, but these errors were encountered: