Exemple #1
0
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'
Exemple #2
0
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)