Esempio n. 1
0
def on_new_tab(event: utils.EventWithData) -> None:
    tab = event.data_widget()
    if isinstance(tab, tabs.FileTab):
        # the '#' character seems to be a 'numbersign' in tk
        tab.textwidget.bind('<numbersign>',
                            functools.partial(comment_or_uncomment, tab),
                            add=True)
Esempio n. 2
0
def on_new_tab(event: utils.EventWithData) -> None:
    tab = event.data_widget()
    if isinstance(tab, tabs.FileTab):
        get_config_and_apply_to_tab(tab)
        tab.bind('<<PathChanged>>',
                 partial(get_config_and_apply_to_tab, tab),
                 add=True)
Esempio n. 3
0
    def send_change_events(self, tab: tabs.FileTab,
                           event: utils.EventWithData) -> None:
        if self._lsp_client.state != lsp.ClientState.NORMAL:
            # The langserver will receive the actual content of the file once
            # it starts.
            self.log.debug(
                "not sending change events because langserver state == %r",
                self._lsp_client.state)
            return

        assert tab.path is not None
        self._lsp_client.did_change(
            text_document=lsp.VersionedTextDocumentIdentifier(
                uri=tab.path.as_uri(),
                version=next(self._version_counter),
            ),
            content_changes=[
                lsp.TextDocumentContentChangeEvent(
                    range=lsp.Range(
                        start=_position_tk2lsp(change.start),
                        end=_position_tk2lsp(change.end),
                    ),
                    text=change.new_text,
                )
                for change in event.data_class(textwidget.Changes).change_list
            ],
        )
Esempio n. 4
0
    def request_completions(self, event: utils.EventWithData) -> None:
        if self._lsp_client.state != lsp.ClientState.NORMAL:
            self.log.warning(
                f"autocompletions requested but langserver state == {self._lsp_client.state!r}"
            )
            return

        tab = event.widget
        assert isinstance(tab, tabs.FileTab) and tab.path is not None
        request = event.data_class(autocomplete.Request)

        lsp_id = self._lsp_client.completions(
            text_document_position=lsp.TextDocumentPosition(
                textDocument=lsp.TextDocumentIdentifier(uri=tab.path.as_uri()),
                position=_position_tk2lsp(request.cursor_pos),
            ),
            context=lsp.CompletionContext(
                # FIXME: this isn't always the case, porcupine can also trigger
                #        it automagically
                triggerKind=lsp.CompletionTriggerKind.INVOKED
            ),
        )

        assert lsp_id not in self._lsp_id_to_tab_and_request
        self._lsp_id_to_tab_and_request[lsp_id] = (tab, request)
Esempio n. 5
0
def on_new_tab(event: utils.EventWithData) -> None:
    tab = event.data_widget()
    if not isinstance(tab, tabs.FileTab):
        return

    overview = Overview(tab.right_frame, tab)
    textwidget.use_pygments_theme(overview, overview.set_colors)
    overview.pack(fill='y', expand=True)
Esempio n. 6
0
def on_new_tab(event: utils.EventWithData) -> None:
    tab = event.data_widget()
    if isinstance(tab, tabs.FileTab):
        underliner = _Underliner(tab.textwidget)
        utils.bind_with_data(tab,
                             '<<SetUnderlines>>',
                             underliner.set_underlines,
                             add=True)
Esempio n. 7
0
def on_new_tab(event: utils.EventWithData) -> None:
    tab = event.data_widget()
    if isinstance(tab, tabs.FileTab):

        def bind_callback(event: 'tkinter.Event[tkinter.Misc]') -> None:
            assert isinstance(tab, tabs.FileTab)  # because mypy is awesome
            tab.textwidget.after_idle(after_enter, tab.textwidget)

        tab.textwidget.bind('<Return>', bind_callback, add=True)
Esempio n. 8
0
 def on_change(self, event: utils.EventWithData) -> None:
     change_list = event.data_class(textwidget.Changes).change_list
     if len(change_list) == 1:
         [change] = change_list
         if len(change.new_text) <= 1:
             # Optimization for typical key strokes (but not for reloading entire file):
             # only highlight the area that might have changed
             self.highlight_range(f"{change.start[0]}.0", f"{change.end[0]}.0 lineend")
             return
     self.highlight_visible()
Esempio n. 9
0
def on_new_tab(event: utils.EventWithData) -> None:
    tab = event.data_widget()
    if isinstance(tab, tabs.FileTab):
        tab.settings.add_option('langserver',
                                None,
                                type=Optional[LangServerConfig])

        tab.bind('<<TabSettingChanged:langserver>>',
                 partial(switch_langservers, tab, False),
                 add=True)
        tab.bind('<<PathChanged>>',
                 partial(switch_langservers, tab, True),
                 add=True)
        switch_langservers(tab, False)
Esempio n. 10
0
def on_new_tab(event: utils.EventWithData) -> None:
    tab = event.data_widget()
    if isinstance(tab, tabs.FileTab):
        tab.textwidget.bind('<<ContentChanged>>',
                            partial(update_url_underlines, tab),
                            add=True)
        update_url_underlines(tab)

        tab.textwidget.tag_bind('underline:urls',
                                '<Control-Button-1>',
                                partial(open_the_url, tab, 'current'),
                                add=True)
        tab.textwidget.bind('<Control-Return>',
                            partial(open_the_url, tab, 'insert'),
                            add=True)
Esempio n. 11
0
def on_new_tab(event: utils.EventWithData) -> None:
    tab = event.data_widget()
    if isinstance(tab, tabs.FileTab):
        # needed because pygments_lexer might change
        def get_lexer_class() -> pygments.lexer.LexerMeta:
            assert isinstance(tab, tabs.FileTab)  # f u mypy
            return tab.settings.get('pygments_lexer', pygments.lexer.LexerMeta)

        highlighter = Highlighter(tab.textwidget, get_lexer_class)
        tab.bind('<<TabSettingChanged:pygments_lexer>>',
                 highlighter.highlight_all,
                 add=True)
        tab.textwidget.bind('<<ContentChanged>>',
                            highlighter.highlight_all,
                            add=True)
        tab.bind('<Destroy>', highlighter.on_destroy, add=True)
        highlighter.highlight_all()
Esempio n. 12
0
    def set_underlines(self, event: utils.EventWithData) -> None:
        underlines = event.data_class(Underlines)
        log.debug(f"Setting underlines: {underlines}")
        self.textwidget.tag_remove(f"underline:{underlines.id}", "1.0", "end")

        old_underlines_deleted = False
        for tag in list(self._tag2underline.keys()):
            literally_underline, tag_id, number = tag.split(":")
            if tag_id == underlines.id:
                self.textwidget.tag_delete(tag)
                del self._tag2underline[tag]
                old_underlines_deleted = True

        for index, underline in enumerate(underlines.underline_list):
            tag = f"underline:{underlines.id}:{index}"
            less_specific_tag = f"underline:{underlines.id}"

            self._tag2underline[tag] = underline
            if underline.color is None:
                self.textwidget.tag_config(tag, underline=True)
            else:
                self.textwidget.tag_config(tag,
                                           underline=True,
                                           underlinefg=underline.color)

            self.textwidget.tag_add(tag, underline.start, underline.end)
            self.textwidget.tag_add(less_specific_tag, underline.start,
                                    underline.end)

        # Updating underline_common tag is kind of brute-force because overlapping non-common
        # underline tags make it difficult. But let's not run it at every key press unless something
        # actually changed.
        if old_underlines_deleted or underlines.underline_list:
            self.textwidget.tag_remove("underline_common", "1.0", "end")
            for tag in self._tag2underline.keys():
                ranges = self.textwidget.tag_ranges(tag)
                for start, end in zip(ranges[0::2], ranges[1::2]):
                    self.textwidget.tag_add("underline_common", start, end)

        # update what's showing
        if any(
                tag.startswith("underline:")
                for tag in self.textwidget.tag_names("insert")):
            self._show_tag_at_index("insert")
        else:
            self._hide_message_label()
Esempio n. 13
0
def on_new_tab(event: utils.EventWithData) -> None:
    tab = event.data_widget()
    if not isinstance(tab, tabs.FileTab):
        return

    tab.settings.add_option('autocomplete_chars', [], type=List[str])

    completer = AutoCompleter(tab)

    # no idea why backspace has to be bound separately
    utils.bind_with_data(tab.textwidget,
                         '<Key>',
                         completer.on_any_key,
                         add=True)
    tab.textwidget.bind('<BackSpace>', completer.on_any_key, add=True)

    utils.bind_tab_key(tab.textwidget, completer.on_tab, add=True)
    tab.textwidget.bind('<Return>', completer.on_enter, add=True)
    tab.textwidget.bind('<Escape>', completer.on_escape, add=True)
    tab.textwidget.bind('<Prior>', completer.popup.on_page_up_down, add=True)
    tab.textwidget.bind('<Next>', completer.popup.on_page_up_down, add=True)
    tab.textwidget.bind('<Up>', completer.popup.on_arrow_key_up_down, add=True)
    tab.textwidget.bind('<Down>',
                        completer.popup.on_arrow_key_up_down,
                        add=True)
    completer.popup.treeview.bind('<Button-1>',
                                  (lambda event: completer._accept()),
                                  add=True)

    # avoid weird corner cases
    tab.winfo_toplevel().bind('<FocusOut>',
                              (lambda event: completer._reject()),
                              add=True)
    tab.textwidget.bind(
        # any mouse button
        '<Button>',
        (lambda event: completer._reject()),
        add=True)

    tab.bind('<Destroy>', (lambda event: completer.popup.toplevel.destroy()),
             add=True)
Esempio n. 14
0
def on_new_tab(event: utils.EventWithData) -> None:
    tab = event.data_widget()
    if isinstance(tab, tabs.FileTab):
        tab.settings.add_option('commands', CommandsConfig())
Esempio n. 15
0
def on_new_tab(event: utils.EventWithData) -> None:
    tab = event.data_widget()
    if isinstance(tab, tabs.FileTab):
        textwidget.use_pygments_theme(
            tab, partial(on_pygments_theme_changed, tab.textwidget))
        tab.textwidget.bind('<<CursorMoved>>', on_cursor_moved, add=True)
Esempio n. 16
0
def on_new_tab(event: utils.EventWithData) -> None:
    tab = event.data_widget()
    if isinstance(tab, tabs.FileTab):
        tab.settings.add_option('insert_final_newline', True)
        tab.bind('<<Save>>', on_save, add=True)
Esempio n. 17
0
def on_new_tab(event: utils.EventWithData) -> None:
    tab = event.data_widget()
    if isinstance(tab, tabs.FileTab):
        linenumbers = LineNumbers(tab.left_frame, tab.textwidget)
        linenumbers.canvas.pack(side='left', fill='y')
Esempio n. 18
0
def on_new_tab(event: utils.EventWithData) -> None:
    tab = event.data_widget()
    if isinstance(tab, tabs.FileTab):
        on_path_changed(tab)
        tab.bind('<<PathChanged>>', partial(on_path_changed, tab), add=True)
Esempio n. 19
0
def on_new_tab(event: utils.EventWithData) -> None:
    tab = event.data_widget()
    if isinstance(tab, tabs.FileTab):
        utils.bind_tab_key(tab.textwidget, on_tab_key, add=True)
Esempio n. 20
0
def on_new_tab(event: utils.EventWithData) -> None:
    tab = event.data_widget()
    if isinstance(tab, tabs.FileTab):
        # raymond hettinger says 90-ish
        tab.settings.add_option('max_line_length', 90)
        LongLineMarker(tab).setup()
Esempio n. 21
0
def on_new_tab(event: utils.EventWithData) -> None:
    tab = event.data_widget()
    assert isinstance(tab, tabs.Tab)
    StatusBar(tab.bottom_frame, tab).pack(side='bottom', fill='x')
Esempio n. 22
0
 def on_new_tab(self, event: utils.EventWithData) -> None:
     self._frame.pack_forget()
     event.data_widget().bind('<Destroy>', self._on_tab_closed, add=True)