Exemple #1
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)
Exemple #2
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
            ],
        )
Exemple #3
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()
Exemple #4
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()