Python sublime 模块,set_clipboard() 实例源码

我们从Python开源项目中,提取了以下42个代码示例,用于说明如何使用sublime.set_clipboard()

项目:sublime-text-3-packages    作者:nickjj    | 项目源码 | 文件源码
def run(self):
        info = {}

        info['platform'] = sublime.platform()
        info['version'] = sublime.version()
        info['file_icons_version'] = __version__
        info['pc_install'] = is_installed_by_package_control()
        info['current_theme'] = get_current_theme()
        info['installed_themes'] = get_installed_themes()

        msg = textwrap.dedent(
            '''\
            - File Icons: %(file_icons_version)s
            - Sublime Text: %(version)s
            - Platform: %(platform)s
            - Package Control: %(pc_install)s
            - Current Theme: %(current_theme)s
            - Installed Themes: %(installed_themes)s
            ''' % info
        )

        sublime.message_dialog(
            msg + '\nInfo has been copied to the clipboard.'
        )
        sublime.set_clipboard(msg)
项目:Verilog-Gadget    作者:poucotm    | 项目源码 | 文件源码
def run(self, edit):
        if not check_extension(self.view.file_name(), self.view.name()):
            return

        text = self.view.substr(sublime.Region(0, self.view.size()))
        text = remove_comment_line_space(text)

        mod_name, port_list, param_list, clk, rst, srst = parse_module_param_port(text, 'Instantiate Module')
        if mod_name == "":
            return
        vgs = get_prefs()
        iprefix = vgs.get("inst_prefix", "inst_")

        minst = module_inst(mod_name, port_list, param_list, iprefix)
        sublime.set_clipboard(minst)
        disp_msg("Instantiate Module : Copied to Clipboard")
项目:.sublime    作者:cxdongjack    | 项目源码 | 文件源码
def run(self, paths = []):
        items = []
        for item in SideBarSelection(paths).getSelectedImages():
            try:
                image_type, width, height = self.getImageInfo(item.path())
                items.append('<img src="'+item.pathAbsoluteFromProjectEncoded()+'" width="'+str(width)+'" height="'+str(height)+'">')
            except:
                items.append('<img src="'+item.pathAbsoluteFromProjectEncoded()+'">')
        if len(items) > 0:
            sublime.set_clipboard("\n".join(items));
            if len(items) > 1 :
                sublime.status_message("Items copied")
            else :
                sublime.status_message("Item copied")

    # http://stackoverflow.com/questions/8032642/how-to-obtain-image-size-using-standard-python-class-without-using-external-lib
项目:.sublime    作者:cxdongjack    | 项目源码 | 文件源码
def run(self, paths = []):
        items = []

        for item in SideBarSelection(paths).getSelectedItems():
            if item.isUnderCurrentProject():
                txt = item.url('url_production')
                try:
                    txt = urlunquote(txt.encode('utf8')).decode('utf8')
                except TypeError:
                    txt = urlunquote(txt)
                items.append(txt)

        if len(items) > 0:
            sublime.set_clipboard("\n".join(items));
            if len(items) > 1 :
                sublime.status_message("Items URL copied")
            else :
                sublime.status_message("Item URL copied")
项目:gissues    作者:divinites    | 项目源码 | 文件源码
def on_repo_selection(self, selection, subsequent_action, **args):
        if selection >= 0:
            if selection == 0:
                self.window.run_command('hide_panel')
                _param_on_enter_repo_info = partial(
                    self.on_enter_repo_info,
                    subsequent_action=subsequent_action,
                    **args)
                content = sublime.get_clipboard(256)
                if content.count(
                        "/") == 1:  # Add a condition to try not to jerperdize irrelevant clipboard content
                    sublime.set_clipboard(content.strip())
                self.window.show_input_panel(
                    'Enter repo in the format username/repo_name:', '',
                    _param_on_enter_repo_info, None, None)
            else:
                self.username, self.repo_name = self.entries[selection].split(
                    '/')
                acquire_repo_info = issue.AcquireRepoInfo(self.username,
                                                          self.repo_name)
                acquire_repo_info.start()
                subsequent_action(**args)
项目:SublimeKSP    作者:nojanath    | 项目源码 | 文件源码
def run(self, *args, **kwargs):
        view = sublime.active_window().active_view()

        #settings = sublime.load_settings('KSP.sublime-settings')
        #scheme_file = settings.get('color_scheme', 'Packages/SublimeKSP/KScript Light.tmTheme')
        scheme_file = 'Packages/SublimeKSP/KScript Light.tmTheme'
        plist = readPlistFromBytes(sublime.load_binary_resource(scheme_file))

        result = ['[pre]']
        start, end = view.sel()[0].a, view.sel()[0].b
        if start == end:
            start, end = 0, view.size()
        for a, b, scopes in get_ranges(view.scope_name(i) for i in range(start, end)):
            result.append(self.apply_style(scopes, plist, view.substr(sublime.Region(start+a, start+b))))
        result.append('[/pre]')
        sublime.set_clipboard(''.join(result))
项目:NeoVintageous    作者:NeoVintageous    | 项目源码 | 文件源码
def _maybe_set_sys_clipboard(self, name, value):
        # We actually need to check whether the option is set to a bool; could
        # be any JSON type.
        if (name in REG_SYS_CLIPBOARD_ALL or
           self.settings.view['vintageous_use_sys_clipboard'] is True):
                # Make sure Sublime Text does the right thing in the presence
                # of multiple selections.
                if len(value) > 1:
                    self.view.run_command('copy')
                else:
                    sublime.set_clipboard(value[0])
项目:TerminalView    作者:Wramberg    | 项目源码 | 文件源码
def run(self, edit):
        # Get selected region or use line that cursor is on if nothing is
        # selected
        selected_region = self.view.sel()[0]
        if selected_region.empty():
            selected_region = self.view.line(selected_region)

        # Clean the selected text and move it into clipboard
        selected_text = self.view.substr(selected_region)
        selected_lines = selected_text.split("\n")
        clean_contents_to_copy = ""
        for line in selected_lines:
            clean_contents_to_copy = clean_contents_to_copy + line.rstrip() + "\n"

        sublime.set_clipboard(clean_contents_to_copy[:-1])
项目:sublimeplugins    作者:ktuan89    | 项目源码 | 文件源码
def run(self, edit):
        for region in self.view.sel():
            if region.empty():
                sublime.set_clipboard(self.view.substr(self.view.word(region.begin())))

# We need to run a text command in order to force the view to update it cursor rendering
项目:FileManager    作者:math2001    | 项目源码 | 文件源码
def copy(el):
    return sublime.set_clipboard(el)
项目:SideBarTools    作者:braver    | 项目源码 | 文件源码
def copy_to_clipboard_and_inform(self, data):
        sublime.set_clipboard(data)
        lines = len(data.split('\n'))
        self.window.status_message('Copied {} to clipboard'.format(
            '{} lines'.format(lines) if lines > 1 else '"{}"'.format(data)
        ))
项目:SalesforceXyTools    作者:exiahuang    | 项目源码 | 文件源码
def run(self, edit):
        full_path = self.view.file_name()
        if full_path != None:
            str_list = full_path.split(util.get_slash())
            file_name = str(str_list[-1])
            sublime.set_clipboard(file_name)
            sublime.status_message("Copy File Name : %s " % file_name)
项目:SublimeRemoteGDB    作者:summerwinter    | 项目源码 | 文件源码
def run(self, edit):
        view = sublime.active_window().active_view()
        if not view:
            return

        filename = os.path.basename(view.file_name())
        (row, col) = view.rowcol(view.sel()[0].begin())
        bp_info = "%s:%d" % (filename, row + 1)
        sublime.set_clipboard(bp_info)
        sublime.status_message(bp_info + " copied")
项目:SublimeConfluence    作者:mlf4aiur    | 项目源码 | 文件源码
def post(self):
        region = sublime.Region(0, self.view.size())
        contents = self.view.substr(region)
        markup = Markup()
        meta, content = markup.get_meta_and_content(contents)
        syntax = self.view.settings().get("syntax")
        new_content = markup.to_html("\n".join(content), syntax)
        if not new_content:
            return
        self.confluence_api = ConfluenceApi(self.username, self.password, self.base_uri)
        response = self.confluence_api.get_content_by_title(
            meta["space_key"], meta["ancestor_title"])
        if response.ok:
            ancestor = response.json()["results"][0]
            ancestor_id = int(ancestor["id"])
            space = dict(key=meta["space_key"])
            body = dict(storage=dict(value=new_content, representation="storage"))
            data = dict(type="page", title=meta["title"], ancestors=[dict(id=ancestor_id)],
                        space=space, body=body)
            result = self.confluence_api.create_content(data)
            if result.ok:
                self.view.settings().set("confluence_content", result.json())
                # copy content url
                content_uri = self.confluence_api.get_content_uri(result.json())
                sublime.set_clipboard(content_uri)
                sublime.status_message(self.MSG_SUCCESS)
            else:
                print(result.text)
                sublime.error_message("Can not create content, reason: {}".format(result.reason))
        else:
            print(response.text)
            sublime.error_message("Can not get ancestor, reason: {}".format(response.reason))
项目:SublimeConfluence    作者:mlf4aiur    | 项目源码 | 文件源码
def on_done_pages(self, idx):
        if idx == -1:
            return
        content_id = self.pages[idx]["id"]
        response = self.confluence_api.get_content_by_id(content_id)
        if response.ok:
            content = response.json()
            body = content["body"]["storage"]["value"]
            if HTML_PRETTIFY:
                document_root = lxml.html.fromstring(body)
                body = (lxml.etree.tostring(document_root, encoding="unicode", pretty_print=True))

            new_view = self.view.window().new_file()
            # set syntax file
            new_view.set_syntax_file("Packages/HTML/HTML.sublime-syntax")
            new_view.settings().set("auto_indent", False)

            # insert the page
            new_view.run_command("insert", {"characters": body})
            new_view.set_name(content["title"])
            new_view.settings().set("confluence_content", content)
            new_view.settings().set("auto_indent", True)
            new_view.run_command("reindent", {"single_line": False})
            new_view.run_command("expand_tabs", {"set_translate_tabs": True})

            # copy content url
            content_uri = self.confluence_api.get_content_uri(content)
            sublime.set_clipboard(content_uri)
            sublime.status_message(self.MSG_SUCCESS)
        else:
            print(response.text)
            sublime.error_message("Can not get content, reason: {}".format(response.reason))
项目:.sublime    作者:cxdongjack    | 项目源码 | 文件源码
def run(self, paths = []):
        items = []
        for item in SideBarSelection(paths).getSelectedItems():
            items.append(item.name())

        if len(items) > 0:
            sublime.set_clipboard("\n".join(items));
            if len(items) > 1 :
                sublime.status_message("Items copied")
            else :
                sublime.status_message("Item copied")
项目:.sublime    作者:cxdongjack    | 项目源码 | 文件源码
def run(self, paths = []):
        items = []
        for item in SideBarSelection(paths).getSelectedItems():
            items.append(item.nameEncoded())

        if len(items) > 0:
            sublime.set_clipboard("\n".join(items));
            if len(items) > 1 :
                sublime.status_message("Items copied")
            else :
                sublime.status_message("Item copied")
项目:.sublime    作者:cxdongjack    | 项目源码 | 文件源码
def run(self, paths = []):
        items = []
        for item in SideBarSelection(paths).getSelectedItems():
            items.append(item.path())

        if len(items) > 0:
            sublime.set_clipboard("\n".join(items));
            if len(items) > 1 :
                sublime.status_message("Items copied")
            else :
                sublime.status_message("Item copied")
项目:.sublime    作者:cxdongjack    | 项目源码 | 文件源码
def run(self, paths = []):
        items = []
        for item in SideBarSelection(paths).getSelectedDirectoriesOrDirnames():
            items.append(item.path())

        if len(items) > 0:
            sublime.set_clipboard("\n".join(items));
            if len(items) > 1 :
                sublime.status_message("Items copied")
            else :
                sublime.status_message("Item copied")
项目:.sublime    作者:cxdongjack    | 项目源码 | 文件源码
def run(self, paths = []):
        items = []
        for item in SideBarSelection(paths).getSelectedItems():
            items.append(item.uri())

        if len(items) > 0:
            sublime.set_clipboard("\n".join(items));
            if len(items) > 1 :
                sublime.status_message("Items copied")
            else :
                sublime.status_message("Item copied")
项目:.sublime    作者:cxdongjack    | 项目源码 | 文件源码
def run(self, paths = []):
        items = []
        for item in SideBarSelection(paths).getSelectedItems():
            items.append(item.pathRelativeFromProjectEncoded())

        if len(items) > 0:
            sublime.set_clipboard("\n".join(items));
            if len(items) > 1 :
                sublime.status_message("Items copied")
            else :
                sublime.status_message("Item copied")
项目:.sublime    作者:cxdongjack    | 项目源码 | 文件源码
def run(self, paths = []):
        items = []
        for item in SideBarSelection(paths).getSelectedItems():
            items.append(item.pathRelativeFromView())

        if len(items) > 0:
            sublime.set_clipboard("\n".join(items));
            if len(items) > 1 :
                sublime.status_message("Items copied")
            else :
                sublime.status_message("Item copied")
项目:.sublime    作者:cxdongjack    | 项目源码 | 文件源码
def run(self, paths = []):
        items = []
        for item in SideBarSelection(paths).getSelectedItems():
            items.append(item.pathRelativeFromViewEncoded())

        if len(items) > 0:
            sublime.set_clipboard("\n".join(items));
            if len(items) > 1 :
                sublime.status_message("Items copied")
            else :
                sublime.status_message("Item copied")
项目:.sublime    作者:cxdongjack    | 项目源码 | 文件源码
def run(self, paths = []):
        items = []
        for item in SideBarSelection(paths).getSelectedItems():
            items.append(item.pathAbsoluteFromProject())

        if len(items) > 0:
            sublime.set_clipboard("\n".join(items));
            if len(items) > 1 :
                sublime.status_message("Items copied")
            else :
                sublime.status_message("Item copied")
项目:.sublime    作者:cxdongjack    | 项目源码 | 文件源码
def run(self, paths = []):
        items = []
        for item in SideBarSelection(paths).getSelectedItems():
            items.append(item.pathAbsoluteFromProjectEncoded())

        if len(items) > 0:
            sublime.set_clipboard("\n".join(items));
            if len(items) > 1 :
                sublime.status_message("Items copied")
            else :
                sublime.status_message("Item copied")
项目:.sublime    作者:cxdongjack    | 项目源码 | 文件源码
def run(self, paths = []):
        items = []
        for item in SideBarSelection(paths).getSelectedItems():
            items.append('<a href="'+item.pathAbsoluteFromProjectEncoded()+'">'+item.namePretty()+'</a>')

        if len(items) > 0:
            sublime.set_clipboard("\n".join(items));
            if len(items) > 1 :
                sublime.status_message("Items copied")
            else :
                sublime.status_message("Item copied")
项目:.sublime    作者:cxdongjack    | 项目源码 | 文件源码
def run(self, paths = []):
        items = []
        for item in SideBarSelection(paths).getSelectedFilesWithExtension('css'):
            items.append('<link rel="stylesheet" type="text/css" href="'+item.pathAbsoluteFromProjectEncoded()+'"/>')

        if len(items) > 0:
            sublime.set_clipboard("\n".join(items));
            if len(items) > 1 :
                sublime.status_message("Items copied")
            else :
                sublime.status_message("Item copied")
项目:.sublime    作者:cxdongjack    | 项目源码 | 文件源码
def run(self, paths = []):
        items = []
        for item in SideBarSelection(paths).getSelectedFilesWithExtension('js'):
            items.append('<script type="text/javascript" src="'+item.pathAbsoluteFromProjectEncoded()+'"></script>')

        if len(items) > 0:
            sublime.set_clipboard("\n".join(items));
            if len(items) > 1 :
                sublime.status_message("Items copied")
            else :
                sublime.status_message("Item copied")
项目:.sublime    作者:cxdongjack    | 项目源码 | 文件源码
def run(self, paths = []):
        items = []
        for directory in SideBarProject().getDirectories():
            items.append(directory)

        if len(items) > 0:
            sublime.set_clipboard("\n".join(items));
            if len(items) > 1 :
                sublime.status_message("Items copied")
            else :
                sublime.status_message("Item copied")
项目:.sublime    作者:cxdongjack    | 项目源码 | 文件源码
def run(self, paths = []):
        items = []
        for item in SideBarSelection(paths).getSelectedFiles():
            items.append(item.contentBase64())

        if len(items) > 0:
            sublime.set_clipboard("\n".join(items));
            if len(items) > 1 :
                sublime.status_message("Items content copied")
            else :
                sublime.status_message("Item content copied")
项目:.sublime    作者:cxdongjack    | 项目源码 | 文件源码
def run(self, paths = []):
        items = []

        for item in SideBarSelection(paths).getSelectedItems():
            if item.isUnderCurrentProject():
                items.append(item.url('url_production'))

        if len(items) > 0:
            sublime.set_clipboard("\n".join(items));
            if len(items) > 1 :
                sublime.status_message("Items URL copied")
            else :
                sublime.status_message("Item URL copied")
项目:ElectricImp-Sublime    作者:electricimp    | 项目源码 | 文件源码
def run(self):
        self.init_env_and_settings()

        def check_settings_callback():
            settings = self.load_settings()
            if EI_DEVICE_ID in settings:
                device_id = settings.get(EI_DEVICE_ID)
                response, code = HTTP.get(self.env.project_manager.get_build_api_key(),
                                          PL_BUILD_API_URL_V4 + "devices/" + device_id)
                agent_id = response.get("device").get("agent_id")
                agent_url = PL_AGENT_URL.format(agent_id)
                sublime.set_clipboard(agent_url)
                sublime.message_dialog(STR_AGENT_URL_COPIED.format(device_id, agent_url))

        self.check_settings(callback=check_settings_callback)
项目:sublime-single-trailing-new-line    作者:mattst    | 项目源码 | 文件源码
def run(self, edit):

        syntax_current_file = self.view.settings().get("syntax")
        sublime.set_clipboard(syntax_current_file)

        msg = "Syntax copied to the clipboard"
        sublime.status_message(msg)
项目:VintageousPlus    作者:trishume    | 项目源码 | 文件源码
def _maybe_set_sys_clipboard(self, name, value):
        # We actually need to check whether the option is set to a bool; could
        # be any JSON type.
        if (name in REG_SYS_CLIPBOARD_ALL or
           self.settings.view['vintageous_use_sys_clipboard'] is True):
                # Make sure Sublime Text does the right thing in the presence
                # of multiple selections.
                if len(value) > 1:
                    self.view.run_command('copy')
                else:
                    sublime.set_clipboard(value[0])
项目:VintageousPlus    作者:trishume    | 项目源码 | 文件源码
def setUp(self):
        super().setUp()
        sublime.set_clipboard('')
        registers._REGISTER_DATA = registers.init_register_data()
        self.view.settings().erase('vintage')
        self.view.settings().erase('vintageous_use_sys_clipboard')
        # self.regs = Registers(view=self.view,
                              # settings=SettingsManager(view=self.view))
        self.regs = State(self.view).registers
项目:VintageousPlus    作者:trishume    | 项目源码 | 文件源码
def testGetSysClipboardAlwaysIfRequested(self):
        self.regs.settings.view['vintageous_use_sys_clipboard'] = True
        sublime.set_clipboard('foo')
        self.assertEqual(self.regs.get(), ['foo'])
项目:VintageousPlus    作者:trishume    | 项目源码 | 文件源码
def setUp(self):
        super().setUp()
        sublime.set_clipboard('')
        registers._REGISTER_DATA = registers.init_register_data()
        self.view.settings().erase('vintage')
        self.view.settings().erase('vintageous_use_sys_clipboard')
        self.regs = State(self.view).registers
        self.regs.view = mock.Mock()
项目:VintageousPlus    作者:trishume    | 项目源码 | 文件源码
def setUp(self):
        super().setUp()
        sublime.set_clipboard('')
        registers._REGISTER_DATA = registers.init_register_data()
        self.view.settings().erase('vintage')
        self.view.settings().erase('vintageous_use_sys_clipboard')
        self.regs = State(self.view).registers
        self.regs.view = mock.Mock()
项目:st-user-package    作者:math2001    | 项目源码 | 文件源码
def copy(view, text):
    sublime.set_clipboard(text)
    view.hide_popup()
    sublime.status_message('Scope name copied to clipboard')
项目:SublimeConfluence    作者:mlf4aiur    | 项目源码 | 文件源码
def update_from_editor(self):
        # Example Data:
        """
        {
          "id": "3604482",
          "type": "page",
          "title": "new page",
          "space": {
            "key": "TST"
          },
          "body": {
            "storage": {
              "value": "<p>This is the updated text for the new page</p>",
              "representation": "storage"
            }
          },
          "version": {
            "number": 2
          }
        }
        """
        content_id = self.content["id"]
        title = self.content["title"]
        space_key = self.content["space"]["key"]
        version_number = self.content["version"]["number"] + 1
        region = sublime.Region(0, self.view.size())
        contents = self.view.substr(region)
        syntax = self.view.settings().get("syntax")
        if "HTML" in syntax:
            new_content = "".join(contents.split("\n"))
        else:
            markup = Markup()
            meta, content = markup.get_meta_and_content(contents)
            new_content = markup.to_html("\n".join(content), syntax)

        space = dict(key=space_key)
        version = dict(number=version_number, minorEdit=False)
        body = dict(storage=dict(value=new_content, representation="storage"))
        data = dict(id=content_id, type="page", title=title,
                    space=space, version=version, body=body)
        try:
            self.confluence_api = ConfluenceApi(self.username, self.password, self.base_uri)
            response = self.confluence_api.update_content(content_id, data)
            if response.ok:
                content_uri = self.confluence_api.get_content_uri(self.content)
                sublime.set_clipboard(content_uri)
                sublime.status_message(self.MSG_SUCCESS)
                self.view.settings().set("confluence_content", response.json())
            else:
                print(response.text)
                sublime.error_message("Can't update content, reason: {}".format(response.reason))
        except Exception:
            print(response.text)
            sublime.error_message("Can't update content, reason: {}".format(response.reason))
项目:SublimeConfluence    作者:mlf4aiur    | 项目源码 | 文件源码
def update_from_source(self):
        region = sublime.Region(0, self.view.size())
        contents = self.view.substr(region)
        markup = Markup()
        meta, content = markup.get_meta_and_content(contents)
        syntax = self.view.settings().get("syntax")
        new_content = markup.to_html("\n".join(content), syntax)
        if not new_content:
            sublime.error_message(
                "Can't update: this doesn't appear to be a valid Confluence page.")
            return
        self.confluence_api = ConfluenceApi(self.username, self.password, self.base_uri)

        get_content_by_title_resp = self.confluence_api.get_content_by_title(
            meta["space_key"], meta["title"])
        if get_content_by_title_resp.ok:
            content_id = get_content_by_title_resp.json()["results"][0]["id"]

            get_content_by_id_resp = self.confluence_api.get_content_by_id(content_id)
            if get_content_by_id_resp.ok:
                content = get_content_by_id_resp.json()
                space = dict(key=meta["space_key"])
                version_number = content["version"]["number"] + 1
                version = dict(number=version_number, minorEdit=False)
                # ancestor_id = int(ancestor["id"])
                body = dict(storage=dict(value=new_content, representation="storage"))
                data = dict(id=content_id, type="page", title=meta["title"],
                            space=space, version=version, body=body)

                update_content_resp = self.confluence_api.update_content(content_id, data)
                if update_content_resp.ok:
                    self.view.settings().set("confluence_content", update_content_resp.json())
                    content_uri = self.confluence_api.get_content_uri(update_content_resp.json())
                    sublime.set_clipboard(content_uri)
                    sublime.status_message(self.MSG_SUCCESS)
                else:
                    print(update_content_resp.text)
                    sublime.error_message("Can not update content, reason: {}".format(
                        update_content_resp.reason))
            else:
                print(get_content_by_id_resp.text)
                sublime.error_message("Can not get content by id, reason: {}".format(
                    get_content_by_id_resp.reason))
        else:
            print(get_content_by_title_resp.text)
            sublime.error_message("Can not get content by title, reason: {}".format(
                get_content_by_title_resp.reason))
项目:a-file-icon    作者:ihodev    | 项目源码 | 文件源码
def run(self):
        info = {}

        info["platform"] = sublime.platform()
        info["sublime_version"] = sublime.version()

        info["current_theme"] = get_current()
        info["installed_themes"] = "".join([
            "\n  <li>{}</li>".format(k) for k in get_installed().keys()
        ])

        info["package_version"] = _get_package_version()
        info["installed_via_pc"] = _is_installed_via_pc()

        msg = """\
            <b>Platform:</b> %(platform)s<br>
            <b>A File Icon:</b> %(package_version)s<br>
            <b>Sublime Text:</b> %(sublime_version)s<br>
            <b>Package Control:</b> %(installed_via_pc)s<br>
            <b>Current Theme:</b> %(current_theme)s<br>
            <b>Installed Themes:</b><br>
            <ul>%(installed_themes)s
            </ul>
        """ % info

        html = """\
            <div id="afi-environment">
                <style>
                    #afi-environment {
                        padding: 0.5rem;
                        line-height: 1.5;
                    }
                    #afi-environment ul {
                        margin-top: 0.5rem;
                        margin-bottom: 0;
                        margin-left: 1rem;
                    }
                    #afi-environment a {
                        display: inline;
                    }
                </style>
                <a href="copy">Copy</a><br><br>
                %(msg)s
            </div>
        """ % {"msg": msg}

        window = sublime.active_window()
        view = window.active_view()
        window.focus_view(view)
        row = int(view.rowcol(view.visible_region().a)[0] + 1)

        def on_navigate(href):
            if (href.startswith("copy")):
                sublime.set_clipboard(msg.replace("    ", ""))
            view.hide_popup()

        view.show_popup(html,
                        location=view.text_point(row, 5),
                        max_width=800,
                        max_height=800,
                        on_navigate=on_navigate)