def insert_char(text: tk.Text, char: str, raw: str = '', go=True): try: sel = text.get(tk.SEL_FIRST, tk.SEL_LAST) except tk.TclError: pass else: insert_text = raw + sel + char text.delete(tk.SEL_FIRST, tk.SEL_LAST) text.edit_separator() text.insert(tk.INSERT, insert_text) return 'break' index = str(text.index(tk.INSERT)).split('.') if text.get(f'{index[0]}.{int(index[1])}') == char: if char == raw: text.mark_set(tk.INSERT, f'{index[0]}.{int(index[1]) + 1}') text.see(tk.INSERT) return 'break' if raw: text.insert(tk.INSERT, raw) if (char != raw) or (char == '"') or char == "'": text.insert(tk.INSERT, char) if go: text.mark_set(tk.INSERT, f'{index[0]}.{int(index[1]) + 1}') text.see(tk.INSERT) return 'break'
def change_batch(widget: tkinter.Text) -> Iterator[None]: """A context manager to optimize doing many changes to a text widget. When :func:`track_changes` has been called, every change to a text widget generates a new ``<<ContentChanged>>`` event, and lots of ``<<ContentChanged>>`` events can cause Porcupine to run slowly. To avoid that, you can use this context manager during the changes, like this:: with textwidget.change_batch(some_text_widget_with_change_tracking): for thing in big_list_of_things_to_do: textwidget.delete(...) textwidget.insert(...) This context manager also affects some other things, and so it can be useful even with text widgets that don't use :func:`track_changes`: * Undoing the whole batch is done with one Ctrl+Z press. * When the ``with`` statement ends, the cursor is moved back to where it was when the ``with`` statement started. See :source:`porcupine/plugins/indent_block.py` for a complete example. """ cursor_pos = widget.index("insert") autoseparators_value = widget["autoseparators"] try: widget.config(autoseparators=False) widget.edit_separator() try: tracker = _change_trackers[widget] except KeyError: yield else: tracker.begin_batch() try: yield finally: tracker.finish_batch() widget.edit_separator() finally: widget.config(autoseparators=autoseparators_value) widget.mark_set("insert", cursor_pos)