Как сделать многострочное всплывающее окно в плагине Sublime Text 3 - PullRequest
0 голосов
/ 16 апреля 2020

Я создаю плагин для Sublime Text 3. Он связывается с моим сервером в Java и получает ответ в виде списка строк. Я хочу, чтобы при нажатии комбинации клавиш появлялось всплывающее окно, в котором вы можете просмотреть все параметры линии и скопировать нужный. Я нашел пример того, как сделать это для одной строки ( Github ), но я не понимаю, как изменить это для нескольких строк (и нескольких кнопок «копировать», конечно). Он должен выглядеть следующим образом:

  • TEXT1 - Copy

  • TEXT2 - Copy

  • TEXT3 - Копирование

  • ...

Ниже приведен код плагин, который отображает имя области во всплывающем окне:

import sublime
import sublime_plugin


def copy(view, text):
    sublime.set_clipboard(text)
    view.hide_popup()
    sublime.status_message('Scope name copied to clipboard')


class ShowScopeNameCommand(sublime_plugin.TextCommand):
    def run(self, edit):
        scope = self.view.scope_name(self.view.sel()[-1].b)

        html = """
            <body id=show-scope>
                <style>
                    p {
                        margin-top: 0;
                    }
                    a {
                        font-family: system;
                        font-size: 1.05rem;
                    }
                </style>
                <p>%s</p>
                <a href="%s">Copy</a>
            </body>
        """ % (scope.replace(' ', '<br>'), scope.rstrip())

        self.view.show_popup(html, max_width=512, on_navigate=lambda x: copy(self.view, x))

1 Ответ

2 голосов
/ 17 апреля 2020

На самом деле все довольно просто, когда вы знаете, что копируется, когда нажимаете на ссылку, которая говорит Copy. Согласно официальной ссылке api , мы имеем: -

on_navigate is a callback that should accept a string contents of the href attribute on the link the user clicked.

Так что все, что находится в атрибуте href, копируется в буфер обмена для команды show_scope_name (или для помещения в в более корректных терминах содержимое href передается в качестве аргумента обратного вызова on_navigate). Вооружившись этой информацией, вот простой плагин, который выбирает некоторые задачи из Jsonplaceholder (который является поддельным REST API для демонстрационных целей), отображает его в виде списка, каждый из которых имеет свой собственный Copy для вас выбрать, что копировать. Вместо Jsonplaceholder вам придется отправить запрос на ваш Java сервер, чтобы получить список строк и соответствующим образом изменить пример.

import json
import sublime
import urllib.parse
import urllib.request
import sublime_plugin


def get_data(num_of_todos):
    """ Fetches some todos from the Jsonplaceholder API (for the purposes of getting fake data).

    Args:
        num_of_todos (int) : The number of todos to be fetched.

    Returns:
        final_data (list) : The number of todos as a list.
    """
    try:
        url = "https://jsonplaceholder.typicode.com/todos"
        req = urllib.request.Request(url)
        req.add_header('User-agent', 'Mozilla/5.0')
        with urllib.request.urlopen(req) as response:
            fake_data = json.loads(response.read().decode("utf-8"))
            final_data = []
            for todo in fake_data:
                final_data.append(todo["title"])
            return final_data[:num_of_todos]
    except urllib.error.HTTPError as error:
        return json.loads(error.read().decode("utf-8"))


class MultilinePopUpCopyCommand(sublime_plugin.TextCommand):
    """ Command for fetching some todos & displaying a Copy link for each one of them,
         which upon being pressed copies the specified todo
    """

    def run(self, edit):
        """ This method is invoked when the command is run.

        Args:
            edit (sublime.Edit) : The edit object necessary for making buffer modifications 
            in the current view.

        Returns:
            None.
        """

        # Construct an li tree to be injected later in the ul tag.
        li_tree = ""
        final_data = get_data(5)
        for i in range(len(final_data)):
            li_tree += "<li>%s <a href='%s'>Copy</a></li>\n" %(final_data[i], final_data[i])

        # The html to be shown.
        html = """
            <body id=copy-multiline>
                <style>
                    ul {
                        margin: 0;
                    }

                    a {
                        font-family: system;
                        font-size: 1.05rem;
                    }
                </style>

                <ul>
                    %s
                </ul>
            </body>
        """ %(li_tree)
        self.view.show_popup(html, max_width=512, on_navigate=lambda todo: self.copy_todo(todo))


    def copy_todo(self, todo):
        """ Copies the todo to the clipboard.

        Args:
            todo (str) : The selected todo.

        Returns:
            None.
        """
        sublime.set_clipboard(todo)
        self.view.hide_popup()
        sublime.status_message('Todo copied to clipboard !')

Вот демонстрационная версия плагина (Здесь у меня есть привязать команду к привязке ключа): -

enter image description here

Надеюсь, что это соответствует вашим требованиям.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...