class Inspector(object): """ Inspector for Lua code """ def __init__(self, lua): self.lua = lua self.docs = _SplashDocs() self.parser = LuaParser(lua) def parse(self, code, cursor_pos): return self.parser.parse(code, cursor_pos, allow_inside=True) def doc_repr(self, doc): if not doc.get("signature"): return doc["content"] parts = [doc["signature"]] if doc.get('short'): parts += [doc["short"]] if doc.get('params'): parts += ["Parameters:\n\n" + doc["params"]] if doc.get('returns'): parts += ["Returns: " + doc["returns"]] if doc.get('async'): parts += ["Async: " + doc["async"]] if doc.get('details'): parts += [doc["details"]] return "\n\n".join(parts) def help(self, code, cursor_pos, detail_level): # from .completer import _pp NO_RESULT = { 'status': 'ok', 'data': {}, 'metadata': {}, 'found': False, } m = self.parse(code, cursor_pos) if m is None: return NO_RESULT doc = None if isinstance(m, (SplashMethod, SplashMethodOpenBrace)): doc = self.docs.get("splash:" + m.prefix) elif isinstance(m, SplashAttribute): doc = self.docs.get("splash." + m.prefix) elif isinstance(m, Standalone) and m.value == "splash": doc = self.docs.get("splash") if doc is None: return NO_RESULT return { 'status': 'ok', 'data': {"text/plain": self.doc_repr(doc)}, 'metadata': {}, 'found': True, }
class Completer(object): def __init__(self, lua): self.lua = lua self.completer = self.lua.eval("require('completer')") self.parser = LuaParser(lua) def parse(self, code, cursor_pos): return self.parser.parse(code, cursor_pos) def complete(self, code, cursor_pos): NO_SUGGESTIONS = { 'matches': [], 'cursor_end': cursor_pos, 'cursor_start': cursor_pos, 'metadata': {}, 'status': 'ok', } prev_char = code[cursor_pos-1:cursor_pos] if prev_char in string.whitespace: return NO_SUGGESTIONS m = self.parse(code, cursor_pos) if m is None: return NO_SUGGESTIONS matches = [] if isinstance(m, Standalone): matches += self.complete_keyword(m.value) matches += self.complete_local_identifier(code, m.value) matches += self.complete_global_variable(m.value) elif isinstance(m, ConstantMethod): matches += self.complete_obj_method(m.const, m.prefix) elif isinstance(m, ObjectIndexedComplete): return NO_SUGGESTIONS elif hasattr(m, 'names_chain'): names_chain = self.lua.table_from(m.names_chain) if isinstance(m, ObjectAttribute): matches += self.complete_any_attribute(names_chain, m.prefix) if isinstance(m, ObjectAttributeIndexed): matches += [ "%s%s]" % (el, m.quote) for el in self.complete_any_attribute(names_chain, m.prefix) ] elif isinstance(m, ObjectMethod): matches += self.complete_method(names_chain, m.prefix) elif isinstance(m, SplashMethod): matches += [ el for el in self.complete_method(names_chain, m.prefix) if "private" not in el ] elif isinstance(m, SplashAttribute): matches += [ el for el in self.complete_non_method(names_chain, m.prefix) if not el.startswith("_") ] return { 'matches': list(dedupe(matches)), 'cursor_end': cursor_pos, 'cursor_start': cursor_pos - len(getattr(m, "prefix", "")), 'metadata': {}, 'status': 'ok', } def complete_any_attribute(self, names_chain, prefix=""): attrs = self.completer.attrs(names_chain, False, False) return sorted_with_prefix(prefix, attrs.values()) def complete_non_method(self, names_chain, prefix=""): attrs = self.completer.attrs(names_chain, True, False) return sorted_with_prefix(prefix, attrs.values()) def complete_method(self, names_chain, prefix=""): methods = self.completer.attrs(names_chain, False, True) return sorted_with_prefix(prefix, methods.values()) def complete_obj_method(self, value, prefix=""): methods = self.completer.obj_attrs(value, False, True) return sorted_with_prefix(prefix, methods.values()) def complete_keyword(self, prefix): return sorted_with_prefix(prefix, LUA_KEYWORDS) def complete_global_variable(self, prefix): g = self.lua.globals() return sorted_with_prefix(prefix, g.keys()) def complete_local_identifier(self, code, prefix): return sorted_with_prefix(prefix, self._local_identifiers(code)) def _local_identifiers(self, code): """ yield all Lua identifiers """ tokens = self.parser.lexer.tokenize(code, pad=1) for idx, tok in enumerate(tokens[1:], start=1): prev = tokens[idx-1] if tok.type == 'iden' and prev.type not in '.:': yield tok.value
class Completer(object): def __init__(self, lua): self.lua = lua self.completer = self.lua.eval("require('completer')") self.parser = LuaParser(lua) def parse(self, code, cursor_pos): return self.parser.parse(code, cursor_pos) def complete(self, code, cursor_pos): NO_SUGGESTIONS = { 'matches': [], 'cursor_end': cursor_pos, 'cursor_start': cursor_pos, 'metadata': {}, 'status': 'ok', } prev_char = code[cursor_pos - 1:cursor_pos] if prev_char in string.whitespace: return NO_SUGGESTIONS m = self.parse(code, cursor_pos) if m is None: return NO_SUGGESTIONS matches = [] if isinstance(m, Standalone): matches += self.complete_keyword(m.value) matches += self.complete_local_identifier(code, m.value) matches += self.complete_global_variable(m.value) elif isinstance(m, ConstantMethod): matches += self.complete_obj_method(m.const, m.prefix) elif isinstance(m, ObjectIndexedComplete): return NO_SUGGESTIONS elif hasattr(m, 'names_chain'): names_chain = self.lua.table_from(m.names_chain) if isinstance(m, ObjectAttribute): matches += self.complete_any_attribute(names_chain, m.prefix) if isinstance(m, ObjectAttributeIndexed): matches += [ "%s%s]" % (el, m.quote) for el in self.complete_any_attribute( names_chain, m.prefix) ] elif isinstance(m, ObjectMethod): matches += self.complete_method(names_chain, m.prefix) elif isinstance(m, SplashMethod): matches += [ el for el in self.complete_method(names_chain, m.prefix) if el not in DONT_SUGGEST_METHODS ] elif isinstance(m, SplashAttribute): matches += [ el for el in self.complete_non_method(names_chain, m.prefix) if not el.startswith("_") ] return { 'matches': list(dedupe(matches)), 'cursor_end': cursor_pos, 'cursor_start': cursor_pos - len(getattr(m, "prefix", "")), 'metadata': {}, 'status': 'ok', } def complete_any_attribute(self, names_chain, prefix=""): attrs = self.completer.attrs(names_chain, False, False) return sorted_with_prefix(prefix, attrs.values()) def complete_non_method(self, names_chain, prefix=""): attrs = self.completer.attrs(names_chain, True, False) return sorted_with_prefix(prefix, attrs.values()) def complete_method(self, names_chain, prefix=""): methods = self.completer.attrs(names_chain, False, True) return sorted_with_prefix(prefix, methods.values()) def complete_obj_method(self, value, prefix=""): methods = self.completer.obj_attrs(value, False, True) return sorted_with_prefix(prefix, methods.values()) def complete_keyword(self, prefix): return sorted_with_prefix(prefix, LUA_KEYWORDS) def complete_global_variable(self, prefix): g = self.lua.globals() return sorted_with_prefix(prefix, g.keys()) def complete_local_identifier(self, code, prefix): return sorted_with_prefix(prefix, self._local_identifiers(code)) def _local_identifiers(self, code): """ yield all Lua identifiers """ tokens = self.parser.lexer.tokenize(code, pad=1) for idx, tok in enumerate(tokens[1:], start=1): prev = tokens[idx - 1] if tok.type == 'iden' and prev.type not in '.:': yield tok.value