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()
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)
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)