extends Node class_name LanguagetToolPlugin var api: LanguageToolApiWrapper var overlay: LanguageToolCorrectionOverlay var checkDict: Dictionary[String,LanguageToolApiWrapper.LanguageToolCheckResponse] = {} func _enter_tree() -> void: api = LanguageToolApiWrapper.new() add_child(api) overlay = LanguageToolCorrectionOverlay.new() add_child(overlay) func _exit_tree() -> void: pass func check_new_inspector(): overlay.hideOverlay() var textEdits: Array[TextEdit] = _find_multiline_text_edits() for te: TextEdit in textEdits: te.text_changed.connect(func():_on_text_changed(te)) te.focus_exited.connect(func():_on_focus_lost(te)) te.caret_changed.connect(func():_on_caret_changed(te)) _check_text(te) _mark_errors_in_text(te) func _on_text_changed(textEdit: TextEdit): _mark_errors_in_text(textEdit) overlay.hideOverlay() func _on_focus_lost(textEdit: TextEdit): _check_text(textEdit) _mark_errors_in_text(textEdit) func _on_caret_changed(textEdit: TextEdit): if(!checkDict.has(textEdit.text)): return var check: LanguageToolApiWrapper.LanguageToolCheckResponse = checkDict[textEdit.text] # find match at caret var caret_offset:int = LanguageToolUtils.row_column_to_offset(textEdit.get_caret_line(), textEdit.get_caret_column(),textEdit.text) var _match:LanguageToolApiWrapper.LanguageToolCheckResponse.Match = null for m in check.matches: if m.offset <= caret_offset and m.offset + m.length >= caret_offset: _match = m break if _match != null: var edit_global_rect = textEdit.get_global_rect() overlay.showOverlay( edit_global_rect.position + Vector2(0,edit_global_rect.size.y), edit_global_rect.size.x, _match, func(newText):_apply_text_change(textEdit,newText,_match)) else: overlay.hideOverlay() pass func _check_text(textEdit: TextEdit): if textEdit.text == "": return if checkDict.has(textEdit.text): return var response = api.check(textEdit.text) checkDict[textEdit.text] = response func _mark_errors_in_text(textEdit: TextEdit): if(!checkDict.has(textEdit.text)): textEdit.syntax_highlighter=null return var check: LanguageToolApiWrapper.LanguageToolCheckResponse = checkDict[textEdit.text] textEdit.syntax_highlighter = LanguageToolErrorSyntaxHighlighter.new(check) func _apply_text_change(textEdit:TextEdit, newText: String, _match:LanguageToolApiWrapper.LanguageToolCheckResponse.Match): var oldText = textEdit.text var removedOldWord = oldText.erase(_match.offset,_match.length) var newWordInserted = removedOldWord.insert(_match.offset,newText) textEdit.text = newWordInserted textEdit.text_changed.emit() overlay.hideOverlay() _check_text(textEdit) _mark_errors_in_text(textEdit) func _find_multiline_text_edits()->Array[TextEdit]: var multilinteTexts:Array[Node] = _find_recursive( EditorInterface.get_inspector().get_child(0).get_child(2), "EditorPropertyMultilineText"); var textEditors:Array[TextEdit] textEditors.assign( multilinteTexts.map(func(c):return c.get_child(0).get_child(0) as TextEdit)) return textEditors func _find_recursive(node: Node, type: Variant) -> Array[Node]: if type is String: if node.get_class() == type: return [node] elif is_instance_of(node, type): return [node] var retval: Array[Node] = [] for child in node.get_children(): retval.append_array(_find_recursive(child, type)) return retval