Example #1
0
    def on_query_completions(self, view, prefix, locations):

        match_sel = lambda s: all(view.match_selector(l, s) for l in locations)

        # import spdb ; spdb.start()
        # Check context
        if not match_sel("source.csscheme - comment - string - variable"):
            return

        if match_sel("meta.ruleset"):
            # No nested rulesets for CSS
            return self.property_completions

        if not match_sel("meta.selector, meta.property_list - meta.property"):
            return

        scope = self.get_scope(view, locations[0])

        # We can't work with different scopes
        for l in locations:
            if self.get_scope(view, l) != scope:
                return

        # Tokenize the current selector (only to the cursor)
        tokens = scope.split(".")

        if len(tokens) > 1:
            del tokens[-1]  # The last token is either incomplete or empty

            # Browse the nodes and their children
            nodes = COMPILED_HEADS
            for i, token in enumerate(tokens):
                node = nodes.find(token)
                if not node:
                    status("Warning: `%s` not found in scope naming conventions"
                           % '.'.join(tokens[:i + 1]))
                    break
                nodes = node.children
                if not nodes:
                    break

            if nodes and node:
                return (nodes.to_completion(), sublime.INHIBIT_WORD_COMPLETIONS)
            else:
                status("No nodes available in scope naming conventions after `%s`"
                       % '.'.join(tokens))
                return  # Should I inhibit here?

        # Triggered completion on whitespace:
        elif match_sel("source.csscheme.scss"):
            # For SCSS just return all the head nodes + property completions
            return self.property_completions + COMPILED_HEADS.to_completion()
        else:
            return COMPILED_HEADS.to_completion()
Example #2
0
    def on_query_completions(self, view, prefix, locations):
        # locations usually has only one entry
        loc = locations[0]

        if not view.match_selector(loc, "source.yaml-tmlanguage"):
            return []

        inhibit = lambda ret: (ret, INHIBIT_WORD_COMPLETIONS)

        # Extend numerics into `'123': {name: $0}`, as used in captures,
        # but only if they are not in a string scope
        word = view.substr(view.word(loc))
        if word.isdigit() and not view.match_selector(loc, "string"):
            return inhibit([(word, "'%s': {name: $0}" % word)])

        # Provide a selection of naming convention from TextMate + the base scope appendix
        if (view.match_selector(loc, "meta.name meta.value string") or
                view.match_selector(loc - 1, "meta.name meta.value string") or
                view.match_selector(loc - 2, "meta.name keyword.control.definition")):
            reg = extract_selector(view, "meta.name meta.value string", loc)
            if reg:
                # Tokenize the current selector
                text = view.substr(reg)
                pos = loc - reg.begin()
                scope = re.search(r"[\w\-_.]+$", text[:pos])
                tokens = scope and scope.group(0).split(".") or ""
                if len(tokens) > 1:
                    del tokens[-1]  # The last token is either incomplete or does not exist
                    # Browse the nodes and their children
                    nodes = COMPILED_HEADS
                    for i, token in enumerate(tokens):
                        node = nodes.find(token)
                        if not node:
                            print("[PackageDev] Warning: `%s` not found in scope naming conventions"
                                  % '.'.join(tokens[:i + 1]))
                            return inhibit([])
                        nodes = node.children
                        if not nodes:
                            break

                    if nodes:
                        return inhibit(nodes.to_completion())
                    else:
                        print("[PackageDev] No nodes available in scope naming conventions after `%s`"
                              % '.'.join(tokens))
                        # Search for the base scope appendix
                        regs = view.find_by_selector("meta.scope-name meta.value string")
                        if not regs:
                            print("[PackageDev] Warning: Could not find base scope")
                            return inhibit([])

                        base_scope = view.substr(regs[0]).strip("\"'")
                        tokens = base_scope.split('.')
                        return inhibit([(tokens[-1], tokens[-1])])

            # Just return all the head nodes
            return inhibit(COMPILED_HEADS.to_completion())

        # Check if triggered by a "."
        if view.substr(loc - 1) == ".":
            # Due to "." being set as a trigger this should not be computed after the block above
            return inhibit([])

        # Auto-completion for include values using the repository keys
        if view.match_selector(loc, "meta.include meta.value string, variable.other.include"):
            # Search for the whole include string which contains the current location
            reg = extract_selector(view, "meta.include meta.value string", loc)
            include_text = view.substr(reg)

            if not reg or (not include_text.startswith("'#") and not include_text.startswith('"#')):
                return []

            variables = [view.substr(r) for r in view.find_by_selector("variable.other.repository-key")]
            print("[PackageDev] Found %d local repository keys to be used in includes" % len(variables))
            return inhibit(zip(variables, variables))

        # Do not bother if the syntax def alread matched the current position, except in the main repository
        scope = view.scope_name(loc).strip()
        if (view.match_selector(loc, "meta") and not scope.endswith("meta.repository-block.yaml-tmlanguage")):
            return []

        # Otherwise, use the default completions + generated uuid
        completions = [
            ('uuid\tuuid: ...', "uuid: %s" % uuid.uuid4())
        ]

        return inhibit(self.base_completions + completions)
Example #3
0
    def on_query_completions(self, view, prefix, locations):
        # We can't work with multiple selections here
        if len(locations) > 1:
            return []

        loc = locations[0]
        # Do not bother if not in yaml-tmlanguage scope and within or at the end of a comment
        if not view.match_selector(loc, "source.yaml-tmlanguage - comment"):
            return []

        def inhibit(ret):
            return (ret, sublime.INHIBIT_WORD_COMPLETIONS)

        # Extend numerics into `'123': {name: $0}`, as used in captures,
        # but only if they are not in a string scope
        word = view.substr(view.word(loc))
        if word.isdigit() and not view.match_selector(loc, "string"):
            return inhibit([(word, "'%s': {name: $0}" % word)])

        # Provide a selection of naming convention from TextMate + the base scope appendix
        if (
            view.match_selector(loc, "meta.name meta.value string")
            or view.match_selector(loc - 1, "meta.name meta.value string")
            or view.match_selector(loc - 2, "meta.name keyword.control.definition")
        ):
            reg = extract_selector(view, "meta.name meta.value string", loc)
            if reg:
                # Tokenize the current selector (only to the cursor)
                text = view.substr(reg)
                pos = loc - reg.begin()
                scope = re.search(r"[\w\-_.]+$", text[:pos])
                tokens = scope and scope.group(0).split(".") or ""

                if len(tokens) > 1:
                    del tokens[-1]  # The last token is either incomplete or empty

                    # Browse the nodes and their children
                    nodes = COMPILED_HEADS
                    for i, token in enumerate(tokens):
                        node = nodes.find(token)
                        if not node:
                            status("Warning: `%s` not found in scope naming conventions" % ".".join(tokens[: i + 1]))
                            break
                        nodes = node.children
                        if not nodes:
                            break

                    if nodes and node:
                        return inhibit(nodes.to_completion())
                    else:
                        status("No nodes available in scope naming conventions after `%s`" % ".".join(tokens))
                        # Search for the base scope appendix/suffix
                        regs = view.find_by_selector("meta.scope-name meta.value string")
                        if not regs:
                            status("Warning: Could not find base scope")
                            return []

                        base_scope = view.substr(regs[0]).strip("\"'")
                        base_suffix = base_scope.split(".")[-1]
                        # Only useful when the base scope suffix is not already the last one
                        # In this case it is even useful to inhibit other completions completely
                        if tokens[-1] == base_suffix:
                            return inhibit([])

                        return inhibit([(base_suffix,) * 2])

            # Just return all the head nodes
            return inhibit(COMPILED_HEADS.to_completion())

        # Check if triggered by a "."
        if view.substr(loc - 1) == ".":
            # Due to "." being set as a trigger this should not be computed after the block above
            return []

        # Auto-completion for include values using the repository keys
        if view.match_selector(loc, "meta.include meta.value string, variable.other.include"):
            # Search for the whole include string which contains the current location
            reg = extract_selector(view, "meta.include meta.value string", loc)
            include_text = view.substr(reg)

            if not reg or (not include_text.startswith("'#") and not include_text.startswith('"#')):
                return []

            variables = [view.substr(r) for r in view.find_by_selector("variable.other.repository-key")]
            status("Found %d local repository keys to be used in includes" % len(variables))
            return inhibit(zip(variables, variables))

        # Do not bother if the syntax def already matched the current position,
        # except in the main repository
        scope = view.scope_name(loc).strip()
        if view.match_selector(loc, "meta") and not scope.endswith("meta.repository-block.yaml-tmlanguage"):
            return []

        # Otherwise, use the default completions + generated uuid
        completions = [("uuid\tuuid: ...", "uuid: %s" % uuid.uuid4())]

        return inhibit(self.base_completions + completions)