def create_text_edit_from_diff(contents, new_contents): from difflib import SequenceMatcher from robocorp_ls_core.lsp import TextEdit from robocorp_ls_core.workspace import Document d = Document("", contents) s = SequenceMatcher(None, contents, new_contents) lst = [] for tag, i1, i2, j1, j2 in s.get_opcodes(): # print( # "%7s a[%d:%d] (%s) b[%d:%d] (%s)" # % (tag, i1, i2, contents[i1:i2], j1, j2, new_contents[j1:j2]) # ) if tag in ("replace", "insert"): lst.append(TextEdit(_create_range(d, i1, i2), new_contents[j1:j2])) elif tag == "delete": lst.append(TextEdit(_create_range(d, i1, i2), "")) elif tag == "equal": pass else: raise AssertionError("Unhandled: %s" % (tag, )) return lst
def _create_completion_item( label: str, new_text: str, selection: IDocumentSelection, col_start: int, col_end: int, documentation: str, ) -> dict: from robocorp_ls_core.lsp import ( CompletionItem, InsertTextFormat, Position, Range, TextEdit, ) from robocorp_ls_core.lsp import MarkupKind from robocorp_ls_core.lsp import CompletionItemKind text_edit = TextEdit( Range( start=Position(selection.line, col_start), end=Position(selection.line, col_end), ), new_text, ) return CompletionItem( label, kind=CompletionItemKind.Field, text_edit=text_edit, insertText=label, documentation=documentation, insertTextFormat=InsertTextFormat.PlainText, documentationFormat=MarkupKind.PlainText, ).to_dict()
def complete(completion_context): """ :param CompletionContext completion_context: """ from robocorp_ls_core.lsp import CompletionItemKind from robocorp_ls_core.lsp import CompletionItem from robocorp_ls_core.lsp import TextEdit from robocorp_ls_core.lsp import Range from robocorp_ls_core.lsp import Position from robotframework_ls.impl import text_utilities from robotframework_ls.impl.string_matcher import RobotStringMatcher from robotframework_ls.impl.robot_lsp_constants import ( OPTION_ROBOT_COMPLETION_SECTION_HEADERS_FORM, ) from robotframework_ls.impl.robot_lsp_constants import ( OPTION_ROBOT_COMPLETION_SECTION_HEADERS_FORM_PLURAL, ) selection = completion_context.sel #: :type selection: DocumentSelection line_start = selection.line_to_column items = [] if line_start: tu = text_utilities.TextUtilities(line_start) if tu.strip_leading_chars("*"): # i.e.: the line must start with '*' tu.strip() words = completion_context.get_accepted_section_header_words() config = completion_context.config form = config.get_setting( OPTION_ROBOT_COMPLETION_SECTION_HEADERS_FORM, str, OPTION_ROBOT_COMPLETION_SECTION_HEADERS_FORM_PLURAL, ) matcher = RobotStringMatcher(tu.text) for word in words: if form == "plural": if not word.endswith("s"): continue elif form == "singular": if word.endswith("s"): continue if matcher.accepts(word): label = "*** %s ***" % (word, ) text_edit = TextEdit( Range( # i.e.: always replace from the start of the line. start=Position(selection.line, 0), end=Position(selection.line, selection.col), ), label, ) # text_edit = None items.append( CompletionItem(label, kind=CompletionItemKind.Class, text_edit=text_edit, insertText=text_edit.newText)) return [item.to_dict() for item in items]
def _create_completion_item_from_keyword(self, keyword_found: IKeywordFound, selection, token, col_delta=0): from robocorp_ls_core.lsp import ( CompletionItem, InsertTextFormat, Position, Range, TextEdit, ) from robocorp_ls_core.lsp import MarkupKind from robotframework_ls.impl.protocols import IKeywordArg label = keyword_found.keyword_name if keyword_found.library_name: # If we found the keyword in a library, convert its format depending on # the user configuration. label = self._convert_keyword_format(label) text = label arg: IKeywordArg for i, arg in enumerate(keyword_found.keyword_args): if arg.is_keyword_arg or arg.is_star_arg or arg.default_value is not None: continue arg_name = arg.arg_name arg_name = arg_name.replace("$", "\\$").replace("{", "").replace("}", "") text += " ${%s:%s}" % (i + 1, arg_name) text_edit = TextEdit( Range( start=Position(selection.line, token.col_offset + col_delta), end=Position(selection.line, token.end_col_offset), ), text, ) # text_edit = None return CompletionItem( label, kind=keyword_found.completion_item_kind, text_edit=text_edit, insertText=text_edit.newText, documentation=keyword_found.docs, insertTextFormat=InsertTextFormat.Snippet, documentationFormat=(MarkupKind.Markdown if keyword_found.docs_format == "markdown" else MarkupKind.PlainText), ).to_dict()
def _create_completion_item_from_keyword(self, keyword_found: IKeywordFound, selection, token, col_delta=0): from robocorp_ls_core.lsp import ( CompletionItem, InsertTextFormat, Position, Range, TextEdit, ) from robocorp_ls_core.lsp import MarkupKind from robotframework_ls.impl.robot_specbuilder import KeywordArg label = keyword_found.keyword_name text = label arg: KeywordArg for i, arg in enumerate(keyword_found.keyword_args): if arg.is_keyword_arg or arg.is_star_arg or arg.default_value is not None: continue arg_name = arg.arg_name arg_name = arg_name.replace("$", "\\$").replace("{", "").replace("}", "") text += " ${%s:%s}" % (i + 1, arg_name) text_edit = TextEdit( Range( start=Position( selection.line, token.col_offset + col_delta if token is not None else selection.col), end=Position( selection.line, token.end_col_offset if token is not None else selection.col), ), text, ) # text_edit = None return CompletionItem( keyword_found.keyword_name, kind=keyword_found.completion_item_kind, text_edit=text_edit, insertText=text_edit.newText, documentation=keyword_found.docs, insertTextFormat=InsertTextFormat.Snippet, documentationFormat=(MarkupKind.Markdown if keyword_found.docs_format == "markdown" else MarkupKind.PlainText), )
def _create_completion_item_from_variable(self, variable_found, selection, token): """ :param IVariableFound variable_found: :param selection: :param token: """ from robocorp_ls_core.lsp import ( CompletionItem, InsertTextFormat, Position, Range, TextEdit, ) from robocorp_ls_core.lsp import MarkupKind from robocorp_ls_core.lsp import CompletionItemKind label = variable_found.variable_name text = label text = text.replace("$", "\\$") text_edit = TextEdit( Range( start=Position(selection.line, token.col_offset), end=Position(selection.line, token.end_col_offset), ), text, ) # text_edit = None return CompletionItem( variable_found.variable_name, kind=CompletionItemKind.Variable, text_edit=text_edit, insertText=label, documentation=variable_found.variable_value, insertTextFormat=InsertTextFormat.Snippet, documentationFormat=MarkupKind.PlainText, ).to_dict()
def _create_completion_item_from_snippet(label, snippet, selection, line_to_col): """ :param selection: DocumentSelection """ from robocorp_ls_core.lsp import ( CompletionItem, InsertTextFormat, Position, Range, TextEdit, ) from robocorp_ls_core.lsp import MarkupKind from robocorp_ls_core.lsp import CompletionItemKind current_col = selection.col text = "\n".join(snippet["body"]) text_edit = TextEdit( Range( start=Position(selection.line, current_col - len(line_to_col)), end=Position(selection.line, current_col), ), text, ) return CompletionItem( label, kind=CompletionItemKind.Snippet, text_edit=text_edit, insertText=text_edit.newText, documentation=snippet["description"] + "\n".join(["", ""] + snippet["body"]), insertTextFormat=InsertTextFormat.Snippet, documentationFormat=MarkupKind.Markdown, ).to_dict()
def _create_completion_item(library_name, selection, token, start_col_offset=None): from robocorp_ls_core.lsp import ( CompletionItem, InsertTextFormat, Position, Range, TextEdit, ) from robocorp_ls_core.lsp import MarkupKind from robocorp_ls_core.lsp import CompletionItemKind text_edit = TextEdit( Range( start=Position( selection.line, start_col_offset if start_col_offset is not None else token.col_offset, ), end=Position(selection.line, token.end_col_offset), ), library_name, ) # text_edit = None return CompletionItem( library_name, kind=CompletionItemKind.Module, text_edit=text_edit, insertText=text_edit.newText, documentation="", insertTextFormat=InsertTextFormat.Snippet, documentationFormat=MarkupKind.PlainText, ).to_dict()
def create_completion_item( self, completion_context: ICompletionContext, keyword_name, selection, token, col_delta: int, memo: Set[str], lib_import: Optional[str] = None, resource_path: Optional[str] = None, data: Optional[Any] = None, ) -> None: """ Note: the lib_import and resource_path are the strings to be added so that the given library/resource is loaded. i.e.: It's the name concatenated to the `Library {lib_import}` or `Resource {resource_path}`. """ from robocorp_ls_core.lsp import ( CompletionItem, InsertTextFormat, Position, Range, TextEdit, ) from robocorp_ls_core.lsp import MarkupKind from robotframework_ls.impl.protocols import CompletionType label = f"{keyword_name} ({lib_import or resource_path})" if label in memo: return memo.add(label) prefix = "" import_line = -1 if completion_context.type != CompletionType.shell: if lib_import is not None: import_line = self.import_location_info.get_library_import_line( ) elif resource_path is not None: import_line = self.import_location_info.get_resource_import_line( ) if import_line == -1: # There's no existing import, so, let's see if we have a *** Settings *** section. # If we don't we have to create the whole settings, otherwise, we'll add the statement # as the first thing in the existing *** Settings *** section. if completion_context.type == CompletionType.shell: import_line = 0 prefix = "*** Settings ***\n" elif self.import_location_info.setting_section_node_info is None: import_line = 0 prefix = "*** Settings ***\n" else: import_line = (self.import_location_info. setting_section_node_info.node.end_lineno - 1) text = keyword_name if keyword_name in self.imported_keyword_name_to_keyword: check = lib_import or resource_path if check: basename = os.path.basename(check) if basename.endswith((".txt", ".py", ".robot", ".resource")): basename = os.path.splitext(basename)[0] text = f"{basename}.{keyword_name}" text_edit = TextEdit( Range( start=Position(selection.line, token.col_offset + col_delta), end=Position(selection.line, token.end_col_offset), ), text, ) additional_text_edits: List[TextEdit] = [] if lib_import is not None: additional_text_edits.append( TextEdit( Range(start=Position(import_line, 0), end=Position(import_line, 0)), f"{prefix}Library {lib_import}\n", )) elif resource_path is not None: additional_text_edits.append( TextEdit( Range(start=Position(import_line, 0), end=Position(import_line, 0)), f"{prefix}Resource {resource_path}\n", )) # text_edit = None self.completion_items.append( CompletionItem( label, kind=CompletionItemKind.Reference, text_edit=text_edit, insertText=text_edit.newText, documentation="", insertTextFormat=InsertTextFormat.Snippet, documentationFormat=MarkupKind.PlainText, additionalTextEdits=additional_text_edits, data=data, ).to_dict())
def complete(completion_context): """ :param CompletionContext completion_context: """ import itertools from robocorp_ls_core.lsp import ( TextEdit, Range, Position, CompletionItem, CompletionItemKind, ) section_name = completion_context.get_current_section_name() if section_name: from robotframework_ls.impl.string_matcher import RobotStringMatcher section = completion_context.get_section(section_name) if section is not None: selection = completion_context.sel #: :type selection: DocumentSelection line_to_col = selection.line_to_column if line_to_col.endswith(" "): return [] replace_to_col = selection.col if section.names_in_brackets: for i, c in enumerate(line_to_col): if c.isspace(): continue elif c == "[": line_to_col = line_to_col[i + 1:] replace_from_col = i break else: return [] else: return [] matcher = RobotStringMatcher(line_to_col) else: # i.e.: Needs to be the first char matcher = RobotStringMatcher(line_to_col) replace_from_col = 0 ret = [] for word in sorted(itertools.chain(section.names, section.aliases)): if matcher.accepts(word): if section.names_in_brackets: label = "[%s]" % (word, ) line = selection.current_line replacement = "[%s]" % (word, ) if line[selection.col:].startswith("]"): replace_to_col += 1 else: label = word replacement = word text_edit = TextEdit( Range( start=Position(selection.line, replace_from_col), end=Position(selection.line, replace_to_col), ), replacement, ) # text_edit = None ret.append( CompletionItem(label, kind=CompletionItemKind.Keyword, text_edit=text_edit).to_dict()) return ret return []