Skip to content

Commit

Permalink
Better Autoload suggestions
Browse files Browse the repository at this point in the history
Autoloads, autoload methods and autoload properties are now suggested in the variable and call event.
  • Loading branch information
Jowan-Spooner committed Dec 7, 2024
1 parent d42b924 commit da7edd8
Show file tree
Hide file tree
Showing 6 changed files with 119 additions and 55 deletions.
54 changes: 54 additions & 0 deletions addons/dialogic/Core/DialogicUtil.gd
Original file line number Diff line number Diff line change
Expand Up @@ -682,3 +682,57 @@ static func get_portrait_position_suggestions(search_text := "") -> Dictionary:
suggestions.erase(search_text)

return suggestions


static func get_autoload_suggestions(filter:String="") -> Dictionary:
var suggestions := {}

for prop in ProjectSettings.get_property_list():
if prop.name.begins_with('autoload/'):
var autoload: String = prop.name.trim_prefix('autoload/')
suggestions[autoload] = {'value': autoload, 'tooltip':autoload, 'editor_icon': ["Node", "EditorIcons"]}
if filter.begins_with(autoload):
suggestions[filter] = {'value': filter, 'editor_icon':["GuiScrollArrowRight", "EditorIcons"]}
return suggestions


static func get_autoload_script_resource(autoload_name:String) -> Script:
var script: Script
if autoload_name and ProjectSettings.has_setting('autoload/'+autoload_name):
var loaded_autoload := load(ProjectSettings.get_setting('autoload/'+autoload_name).trim_prefix('*'))

if loaded_autoload is PackedScene:
var packed_scene: PackedScene = loaded_autoload
script = packed_scene.instantiate().get_script()

else:
script = loaded_autoload
return script


static func get_autoload_method_suggestions(filter:String, autoload_name:String) -> Dictionary:
var suggestions := {}

var script := get_autoload_script_resource(autoload_name)
if script:
for script_method in script.get_script_method_list():
if script_method.name.begins_with('@') or script_method.name.begins_with('_'):
continue
suggestions[script_method.name] = {'value': script_method.name, 'tooltip':script_method.name, 'editor_icon': ["Callable", "EditorIcons"]}

if not filter.is_empty():
suggestions[filter] = {'value': filter, 'editor_icon':["GuiScrollArrowRight", "EditorIcons"]}

return suggestions


static func get_autoload_property_suggestions(filter:String, autoload_name:String) -> Dictionary:
var suggestions := {}
var script := get_autoload_script_resource(autoload_name)
if script:
for property in script.get_script_property_list():
if property.name.ends_with('.gd') or property.name.begins_with('_'):
continue
suggestions[property.name] = {'value': property.name, 'tooltip':property.name, 'editor_icon': ["MemberProperty", "EditorIcons"]}

return suggestions
Original file line number Diff line number Diff line change
Expand Up @@ -123,11 +123,14 @@ func _on_Search_text_entered(new_text:String) -> void:
func _on_Search_text_changed(new_text:String, just_update:bool = false) -> void:
%Suggestions.clear()

if new_text == "" and !just_update:
if new_text == "" and not just_update:
change_to_empty()
else:
%Search.show()

if just_update and new_text.is_empty() and %Search.text.ends_with("."):
new_text = %Search.text

var suggestions: Dictionary = get_suggestions_func.call(new_text)

var line_length := 0
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,10 @@ var shortcode_events := {}
var custom_syntax_events := []
var text_event: DialogicTextEvent = null


func _ready() -> void:
# Compile RegEx's
completion_word_regex.compile("(?<s>(\\W)|^)(?<word>\\w*)\\x{FFFF}")
completion_word_regex.compile(r"(?<s>(\W)|^)(?<word>[\w]*)\x{FFFF}")
completion_shortcode_getter_regex.compile("\\[(?<code>\\w*)")
completion_shortcode_param_getter_regex.compile("(?<param>\\w*)\\W*=\\s*\"?(\\w|\\s)*"+String.chr(0xFFFF))
completion_shortcode_value_regex.compile(r'(\[|\s)[^\[\s=]*="(?<value>[^"$]*)'+String.chr(0xFFFF))
Expand Down Expand Up @@ -172,7 +173,7 @@ func request_code_completion(force:bool, text:CodeEdit, mode:=Modes.FULL_HIGHLIG
if mode == Modes.TEXT_EVENT_ONLY and !event is DialogicTextEvent:
continue

if ! ' ' in line_part:
if not ' ' in line_part:
event._get_start_code_completion(self, text)

if event.is_valid_event(line):
Expand All @@ -182,6 +183,9 @@ func request_code_completion(force:bool, text:CodeEdit, mode:=Modes.FULL_HIGHLIG
# Force update and showing of the popup
text.update_code_completion_options(true)

# USEFUL FOR DEBUGGING
#print(text.get_code_completion_options().map(func(x):return "{display_text}".format(x)))



# Helper that adds all characters as options
Expand Down Expand Up @@ -209,7 +213,7 @@ func suggest_labels(text:CodeEdit, timeline:String='', end:='', color:=Color())

# Helper that adds all portraits of a given character as options
func suggest_portraits(text:CodeEdit, character_name:String, end_check:=')') -> void:
if !character_name in DialogicResourceUtil.get_character_directory():
if not character_name in DialogicResourceUtil.get_character_directory():
return
var character_resource: DialogicCharacter = load(DialogicResourceUtil.get_character_directory()[character_name])
for portrait in character_resource.portraits:
Expand Down Expand Up @@ -242,7 +246,9 @@ func suggest_custom_suggestions(suggestions:Dictionary, text:CodeEdit, color:Col
# Purpose of the different Kinds is explained in [_request_code_completion]
func filter_code_completion_candidates(candidates:Array, text:CodeEdit) -> Array:
var valid_candidates := []

var current_word := get_code_completion_word(text)

for candidate in candidates:
if candidate.kind == text.KIND_PLAIN_TEXT:
if !current_word.is_empty() and candidate.insert_text.begins_with(current_word):
Expand Down
62 changes: 17 additions & 45 deletions addons/dialogic/Modules/Call/event_call.gd
Original file line number Diff line number Diff line change
Expand Up @@ -139,53 +139,17 @@ func get_shortcode_parameters() -> Dictionary:
func build_event_editor() -> void:
add_header_edit('autoload_name', ValueType.DYNAMIC_OPTIONS, {'left_text':'On autoload',
'empty_text':'Autoload',
'suggestions_func':get_autoload_suggestions,
'suggestions_func': DialogicUtil.get_autoload_suggestions,
'editor_icon':["Node", "EditorIcons"]})
add_header_edit('method', ValueType.DYNAMIC_OPTIONS, {'left_text':'call',
'empty_text':'Method',
'suggestions_func':get_method_suggestions,
'suggestions_func': get_method_suggestions,
'editor_icon':["Callable", "EditorIcons"]}, 'autoload_name')
add_body_edit('arguments', ValueType.ARRAY, {'left_text':'Arguments:'}, 'not autoload_name.is_empty() and not method.is_empty()')



func get_autoload_suggestions(filter:String="") -> Dictionary:
var suggestions := {}

for prop in ProjectSettings.get_property_list():
if prop.name.begins_with('autoload/'):
var autoload: String = prop.name.trim_prefix('autoload/')
suggestions[autoload] = {'value': autoload, 'tooltip':autoload, 'editor_icon': ["Node", "EditorIcons"]}
if filter.begins_with(autoload):
suggestions[filter] = {'value': filter, 'editor_icon':["GuiScrollArrowRight", "EditorIcons"]}
return suggestions


func get_method_suggestions(filter:String="", temp_autoload:String = "") -> Dictionary:
var suggestions := {}

var script: Script
if temp_autoload and ProjectSettings.has_setting('autoload/'+temp_autoload):
script = load(ProjectSettings.get_setting('autoload/'+temp_autoload).trim_prefix('*'))

elif autoload_name and ProjectSettings.has_setting('autoload/'+autoload_name):
var loaded_autoload := load(ProjectSettings.get_setting('autoload/'+autoload_name).trim_prefix('*'))

if loaded_autoload is PackedScene:
var packed_scene: PackedScene = loaded_autoload
script = packed_scene.instantiate().get_script()

else:
script = loaded_autoload

if script:
for script_method in script.get_script_method_list():
if script_method.name.begins_with('@') or script_method.name.begins_with('_'):
continue
suggestions[script_method.name] = {'value': script_method.name, 'tooltip':script_method.name, 'editor_icon': ["Callable", "EditorIcons"]}
if !filter.is_empty():
suggestions[filter] = {'value': filter, 'editor_icon':["GuiScrollArrowRight", "EditorIcons"]}
return suggestions
func get_method_suggestions(filter:="") -> Dictionary:
return DialogicUtil.get_autoload_method_suggestions(filter, autoload_name)


func update_argument_info() -> void:
Expand Down Expand Up @@ -236,13 +200,21 @@ func check_arguments_and_update_warning() -> void:
####################### CODE COMPLETION ########################################
################################################################################

func _get_code_completion(_CodeCompletionHelper:Node, TextNode:TextEdit, line:String, _word:String, symbol:String) -> void:
func _get_code_completion(CodeCompletionHelper:Node, TextNode:TextEdit, line:String, word:String, symbol:String) -> void:
var autoloads := DialogicUtil.get_autoload_suggestions()
var line_until_caret: String = CodeCompletionHelper.get_line_untill_caret(line)

if line.count(' ') == 1 and not '.' in line:
for i in get_autoload_suggestions():
for i in autoloads:
TextNode.add_code_completion_option(CodeEdit.KIND_MEMBER, i, i+'.', event_color.lerp(TextNode.syntax_highlighter.normal_color, 0.3), TextNode.get_theme_icon("Node", "EditorIcons"))
elif symbol == '.' and not '(' in line:
for i in get_method_suggestions('', line.get_slice('.', 0).trim_prefix('do ')):
TextNode.add_code_completion_option(CodeEdit.KIND_MEMBER, i, i+'(', event_color.lerp(TextNode.syntax_highlighter.normal_color, 0.3), TextNode.get_theme_icon("Callable", "EditorIcons"))

elif (line_until_caret.ends_with(".") or symbol == "."):
var autoload_name := line_until_caret.split(" ")[-1].split(".")[0]
if autoload_name in autoloads:
var methods := DialogicUtil.get_autoload_method_suggestions("", autoload_name)
for i in methods.keys():
TextNode.add_code_completion_option(CodeEdit.KIND_MEMBER, i, i+'(', event_color.lerp(TextNode.syntax_highlighter.normal_color, 0.3), TextNode.get_theme_icon("MemberMethod", "EditorIcons"))



func _get_start_code_completion(_CodeCompletionHelper:Node, TextNode:TextEdit) -> void:
Expand Down
4 changes: 2 additions & 2 deletions addons/dialogic/Modules/Character/event_character.gd
Original file line number Diff line number Diff line change
Expand Up @@ -478,7 +478,7 @@ func get_fade_suggestions(search_text:String='') -> Dictionary:

func _get_code_completion(CodeCompletionHelper:Node, TextNode:TextEdit, line:String, _word:String, symbol:String) -> void:
var line_until_caret: String = CodeCompletionHelper.get_line_untill_caret(line)
if symbol == ' ' and line_until_caret.count(' ') == 1:
if symbol == ' ' and line_until_caret.split(" ", false).size() == 1:
CodeCompletionHelper.suggest_characters(TextNode, CodeEdit.KIND_MEMBER)
if line.begins_with('leave'):
TextNode.add_code_completion_option(CodeEdit.KIND_MEMBER, 'All', '--All-- ', event_color, TextNode.get_theme_icon("GuiEllipsis", "EditorIcons"))
Expand All @@ -487,7 +487,7 @@ func _get_code_completion(CodeCompletionHelper:Node, TextNode:TextEdit, line:Str
var completion_character := regex.search(line).get_string('name')
CodeCompletionHelper.suggest_portraits(TextNode, completion_character)

elif not '[' in line_until_caret and symbol == ' ':
elif not '[' in line_until_caret and symbol == ' ' and line_until_caret.split(" ", false).size() > 1:
if not line.begins_with("leave"):
for position in get_position_suggestions():
TextNode.add_code_completion_option(CodeEdit.KIND_MEMBER, position, position+' ', TextNode.syntax_highlighter.normal_color)
Expand Down
37 changes: 33 additions & 4 deletions addons/dialogic/Modules/Variable/event_variable.gd
Original file line number Diff line number Diff line change
Expand Up @@ -303,10 +303,26 @@ func build_event_editor() -> void:

func get_var_suggestions(filter:String) -> Dictionary:
var suggestions := {}
if filter:
suggestions[filter] = {'value':filter, 'editor_icon':["GuiScrollArrowRight", "EditorIcons"]}
for var_path in DialogicUtil.list_variables(DialogicUtil.get_default_variables()):
suggestions[var_path] = {'value':var_path, 'icon':load("res://addons/dialogic/Editor/Images/Pieces/variable.svg")}

var autoloads := DialogicUtil.get_autoload_suggestions().keys()
var is_autoload := ""
for autoload in autoloads:
if autoload == filter:
is_autoload = autoload
break
suggestions[autoload] = {'value':autoload, 'editor_icon':["Node", "EditorIcons"]}

if is_autoload or filter.count(".") == 1 and filter.split(".")[0] in autoloads:
var autoload := filter.trim_suffix(".")
var properties := DialogicUtil.get_autoload_property_suggestions("", autoload)
for property in properties:
suggestions["."+property] = {'value':autoload+"."+property, 'editor_icon':["MemberProperty", "EditorIcons"]}

if not filter in suggestions:
suggestions[filter] = {'value':filter, 'editor_icon':["GuiScrollArrowRight", "EditorIcons"]}

return suggestions


Expand Down Expand Up @@ -342,9 +358,22 @@ func update_editor_warning() -> void:
################################################################################

func _get_code_completion(CodeCompletionHelper:Node, TextNode:TextEdit, line:String, _word:String, symbol:String) -> void:
if CodeCompletionHelper.get_line_untill_caret(line) == 'set ':
var autoloads := DialogicUtil.get_autoload_suggestions()
var line_until_caret: String = CodeCompletionHelper.get_line_untill_caret(line)
if line_until_caret.count(" ") == 1 and not "{" in line and not line_until_caret.ends_with("."):

TextNode.add_code_completion_option(CodeEdit.KIND_MEMBER, '{', '{', TextNode.syntax_highlighter.variable_color)
if symbol == '{':
for i in autoloads:
TextNode.add_code_completion_option(CodeEdit.KIND_MEMBER, i, i+'.', event_color.lerp(TextNode.syntax_highlighter.normal_color, 0.3), TextNode.get_theme_icon("Node", "EditorIcons"))

if (line_until_caret.ends_with(".") or symbol == "."):
var autoload_name := line_until_caret.split(" ")[-1].split(".")[0]
if autoload_name in autoloads:
var properties := DialogicUtil.get_autoload_property_suggestions("", autoload_name)
for i in properties.keys():
TextNode.add_code_completion_option(CodeEdit.KIND_MEMBER, i, i+" ", event_color.lerp(TextNode.syntax_highlighter.normal_color, 0.3), TextNode.get_theme_icon("MemberMethod", "EditorIcons"))

elif symbol == '{':
CodeCompletionHelper.suggest_variables(TextNode)


Expand Down

0 comments on commit da7edd8

Please sign in to comment.