Beispiel #1
0
    def run(self, edit):
        pkg_name = self.pkg_for_file()

        # For unknown files, open the default topic for a default package.
        #
        # TODO: Should be user configurable?
        if pkg_name is None:
            return sublime.run_command("hyperhelp_topic",
                                       {"package": "SublimeAPI"})

        # Get the help index for the type of file currently focused.
        pkg_info = help_index_list().get(pkg_name)

        # Get an initial topic; the selected text or the word under the cursor.
        extract = self.view.sel()[0]
        if extract.empty():
            topic = _word_under_cursor(self.view)
        else:
            topic = self.view.substr(extract)

        # If the initial topic exists and is unique, open it directly.
        if topic and lookup_help_topic(pkg_info, topic):
            return sublime.run_command("hyperhelp_topic", {
                "package": pkg_info.package,
                "topic": topic
            })

        # Open the root of the help package if the topic is empty, or open the
        # index popup if it has some text. In the latter case, also use it as
        # the default filter so the user can self disambiguate.
        sublime.run_command("hyperhelp_index" if topic else "hyperhelp_topic",
                            {"package": pkg_info.package})
        if topic:
            self.view.window().run_command("insert", {"characters": topic})
    def lint(self, view, file_name):
        index_topics = {
            t["topic"]
            for t in self.pkg_info.help_topics.values()
            if t["file"] == file_name
        }

        seen = {file_name}

        file_topics = {file_name}
        for pos in view.find_by_selector("meta.anchor"):
            topic, text = parse_anchor_body(view.substr(pos))
            index_info = lookup_help_topic(self.pkg_info, topic)

            sev, msg = self.validate(seen, topic, text, index_info, file_name)
            if sev is not None:
                self.add(view, sev, file_name, pos.begin(), msg)
            elif not topic.startswith("_"):
                file_topics.add(topic)

            seen.add(topic)

        for topic in index_topics - file_topics:
            self.add_index("warning",
                           "Topic '%s' appears in the index but not in '%s'",
                           topic, file_name)
    def validate(self, pkg, topic, text, file_name, link_body):
        if topic is None:
            return ("error",
                    "Malformed link; not enough ':' characters ('{}')".format(
                        link_body))

        if "\u00a0" in topic or "\t" in topic:
            return (
                "error",
                "Link '{}' contains nonbreaking spaces or tabs".format(topic))

        link_pkg = self.pkg_info if pkg is None else help_index_list().get(pkg)

        if link_pkg is None:
            return ("error",
                    "Link references a topic in a non-existant package ('{}')".
                    format(pkg))

        index_info = lookup_help_topic(link_pkg, topic)
        if index_info is None:
            return ("warning",
                    "Link references unknown topic '{}'".format(topic))

        if is_topic_file_valid(link_pkg, index_info) is False:
            return (
                "warning",
                "Link references a non-existant package file ('{}')".format(
                    index_info["file"]))

        return (None, None)
    def validate(self, pkg, topic, file_name):
        if topic is None:
            return None

        link_pkg = self.pkg_info if pkg is None else help_index_list().get(pkg)
        if link_pkg is None or link_pkg.package != self.pkg_info.package:
            return None

        index_info = lookup_help_topic(link_pkg, topic)
        if index_info is None:
            return None

        if index_info["file"] == file_name:
            return None

        return index_info["file"]
Beispiel #5
0
def _bookmark_name(bookmark):
    """
    Given a bookmark dictionary, return back the name of that bookmark. If the
    bookmark has no defined name, one will be returned.
    """
    if bookmark is None:
        return "No bookmark"

    if "name" in bookmark:
        return bookmark["name"]

    pkg_info = help_index_list().get(bookmark.get("package"))
    topic = lookup_help_topic(pkg_info, bookmark.get("topic", ''))

    if topic is None:
        return "Bookmark specifies invalid topic"

    if topic["topic"] in pkg_info.help_files:
        return pkg_info.help_files[topic["topic"]]

    return topic.get("caption", "Caption is missing")
Beispiel #6
0
    def run(self, edit):
        v = self.view
        active = []
        broken = []

        regions = v.get_regions("_hh_links")
        for idx, region in enumerate(regions):
            link_dat = _get_link_topic(v, idx)

            pkg_info = help_index_list().get(link_dat["pkg"], None)
            topic = lookup_help_topic(pkg_info, link_dat["topic"])

            if self.link_is_active(pkg_info, topic):
                active.append(region)
            else:
                broken.append(region)

        v.add_regions("_hh_links_active", active, "storage",
            flags=sublime.DRAW_SOLID_UNDERLINE | sublime.PERSISTENT |
                  sublime.DRAW_NO_FILL | sublime.DRAW_NO_OUTLINE)

        v.add_regions("_hh_links_broken", broken, "comment",
            flags=sublime.DRAW_STIPPLED_UNDERLINE | sublime.PERSISTENT |
                  sublime.DRAW_NO_FILL | sublime.DRAW_NO_OUTLINE)
Beispiel #7
0
    def initial_text(self):
        v = self.view

        link_info = None
        if len(v.sel()) > 0 and v.match_selector(v.sel()[0].b, "meta.link"):
            link_info = _get_link_topic(v, v.extract_scope(v.sel()[0].b))

        if self.bmark_type == "topic" and link_info is not None:
            pkg_info = help_index_list().get(link_info["pkg"])
            if pkg_info is not None:
                topic = lookup_help_topic(pkg_info, link_info["topic"])
                return topic["caption"]

        file = current_help_file()
        name = "File {} in help package {}".format(file, current_help_package())
        pkg_info = help_index_list().get(current_help_package())

        if pkg_info is not None and file in pkg_info.help_files:
            name = pkg_info.help_files[file]

        if self.bmark_type == "view":
            name = name + " (view)"

        return name
Beispiel #8
0
    def on_hover(self, view, point, hover_zone):
        """
        When the mouse hovers over a link in a help view, show a popup that
        tells you where the link goes or what file/URL it opens.
        """
        if hover_zone != sublime.HOVER_TEXT:
            return

        default_pkg = view.settings().get("_hh_pkg", None)
        if default_pkg is None or not view.score_selector(point, "meta.link"):
            return

        link_info = _get_link_topic(view, view.extract_scope(point))
        if link_info is None:
            return

        pkg = link_info.get("pkg", default_pkg)
        topic = link_info.get("topic")

        # Report if we don't know the package. In this case we may know what
        # the topic is but not what file it might appear in.
        pkg_info = help_index_list().get(pkg, None)
        if pkg_info is None:
            popup = _missing_pkg.format(pkg=pkg, topic=topic)
            return _show_popup(view, point, popup)

        # If there is no topic we can't really display anything useful. This is
        # an exceptional situation that is only possible if the help is broken.
        if topic is None:
            return

        # Look up the topic details. If we can't find it in the index, react
        # like a missing package since we can't know the file.
        topic_data = lookup_help_topic(pkg_info, topic)
        if topic_data is None:
            popup = _missing_topic.format(pkg=pkg, topic=topic)
            return _show_popup(view, point, popup)

        caption = topic_data.get("caption")
        file = topic_data.get("file")
        link = file

        # For links that open files, if that file does not exist as far as
        # Sublime is concerned, use a custom popup to let the user know. Such
        # a link will be highlighted as broken, so this explains why.
        #
        # This returns None for things that are not package files, so we need
        # to compare for False directkly.
        if is_topic_file_valid(pkg_info, topic_data) is False:
            popup = _missing_file.format(file=file)
            return _show_popup(view, point, popup)

        if is_topic_url(pkg_info, topic_data):
            link_type = "Opens URL: "
        elif is_topic_file(pkg_info, topic_data):
            link_type = "Opens File: "
        else:
            link_type = "Links To: "

            link = "" if default_pkg == pkg else pkg + " / "

            current_file = view.settings().get("_hh_file", None)
            if file != current_file:
                link = link + file + " / "

            link = link + topic

        popup = _topic_body.format(title=caption or topic,
                                   link_type=link_type,
                                   link=link)

        _show_popup(view, point, popup)