Skip to content

Commit

Permalink
Add syntax highlighting and CodeCompletion on multiline shortcode events
Browse files Browse the repository at this point in the history
  • Loading branch information
Jowan-Spooner committed Feb 26, 2024
1 parent a647c14 commit 5e3bfc7
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 20 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ extends Node

enum Modes {TEXT_EVENT_ONLY, FULL_HIGHLIGHTING}

var syntax_highlighter :SyntaxHighlighter = load("res://addons/dialogic/Editor/TimelineEditor/TextEditor/syntax_highlighter.gd").new()
var text_syntax_highlighter :SyntaxHighlighter = load("res://addons/dialogic/Editor/TimelineEditor/TextEditor/syntax_highlighter.gd").new()
var syntax_highlighter: SyntaxHighlighter = load("res://addons/dialogic/Editor/TimelineEditor/TextEditor/syntax_highlighter.gd").new()
var text_syntax_highlighter: SyntaxHighlighter = load("res://addons/dialogic/Editor/TimelineEditor/TextEditor/syntax_highlighter.gd").new()


# These RegEx's are used to deduce information from the current line for auto-completion
Expand All @@ -29,8 +29,7 @@ func _ready():

text_syntax_highlighter.mode = text_syntax_highlighter.Modes.TEXT_EVENT_ONLY

################################################################################
## AUTO COMPLETION
#region AUTO COMPLETION
################################################################################

# Helper that gets the current line with a special character where the caret is
Expand Down Expand Up @@ -65,7 +64,7 @@ func request_code_completion(force:bool, text:CodeEdit, mode:=Modes.FULL_HIGHLIG

# make sure shortcode event references are loaded
if mode == Modes.FULL_HIGHLIGHTING:
var hidden_events :Array= DialogicUtil.get_editor_setting('hidden_event_buttons', [])
var hidden_events: Array = DialogicUtil.get_editor_setting('hidden_event_buttons', [])
if shortcode_events.is_empty():
for event in DialogicResourceUtil.get_event_cache():
if event.get_shortcode() != 'default_shortcode':
Expand Down Expand Up @@ -103,7 +102,7 @@ func request_code_completion(force:bool, text:CodeEdit, mode:=Modes.FULL_HIGHLIG
# The completion will check if the letter is already present and add it otherwise.

# Shortcode event suggestions
if line.begins_with('[') and !text_event.text_effects_regex.search(line.get_slice(' ', 0)) and mode == Modes.FULL_HIGHLIGHTING:
if mode == Modes.FULL_HIGHLIGHTING and syntax_highlighter.line_is_shortcode_event(text.get_caret_line()):
if symbol == '[':
# suggest shortcodes if a shortcode event has just begun
var shortcodes := shortcode_events.keys()
Expand All @@ -116,7 +115,8 @@ func request_code_completion(force:bool, text:CodeEdit, mode:=Modes.FULL_HIGHLIG
else:
text.add_code_completion_option(CodeEdit.KIND_MEMBER, shortcode, shortcode+" ", shortcode_events[shortcode].event_color.lerp(syntax_highlighter.normal_color, 0.3), shortcode_events[shortcode]._get_icon())
else:
var current_shortcode := completion_shortcode_getter_regex.search(line)
var full_event_text: String = syntax_highlighter.get_full_event(text.get_caret_line())
var current_shortcode := completion_shortcode_getter_regex.search(full_event_text)
if !current_shortcode:
text.update_code_completion_options(false)
return
Expand All @@ -128,9 +128,9 @@ func request_code_completion(force:bool, text:CodeEdit, mode:=Modes.FULL_HIGHLIG

# suggest parameters
if symbol == ' ' and line.count('"')%2 == 0:
var parameters :Array = shortcode_events[code].get_shortcode_parameters().keys()
var parameters: Array = shortcode_events[code].get_shortcode_parameters().keys()
for param in parameters:
if !param+'=' in line:
if !param+'=' in full_event_text:
text.add_code_completion_option(CodeEdit.KIND_MEMBER, param, param+'="' , shortcode_events[code].event_color.lerp(syntax_highlighter.normal_color, 0.3), text.get_theme_icon("MemberProperty", "EditorIcons"))

# suggest values
Expand All @@ -152,7 +152,7 @@ func request_code_completion(force:bool, text:CodeEdit, mode:=Modes.FULL_HIGHLIG
text.update_code_completion_options(true)
return

var suggestions : Dictionary= shortcode_events[code].get_shortcode_parameters()[current_parameter]['suggestions'].call()
var suggestions: Dictionary= shortcode_events[code].get_shortcode_parameters()[current_parameter]['suggestions'].call()
for key in suggestions.keys():
if suggestions[key].has('text_alt'):
text.add_code_completion_option(CodeEdit.KIND_MEMBER, key, suggestions[key].text_alt[0], shortcode_events[code].event_color.lerp(syntax_highlighter.normal_color, 0.3), suggestions[key].get('icon', null), '" ')
Expand Down Expand Up @@ -265,8 +265,9 @@ func confirm_code_completion(replace:bool, text:CodeEdit) -> void:
text.set_caret_column(text.get_caret_column()+1)


################################################################################
## SYMBOL CLICKING
#endregion

#region SYMBOL CLICKING
################################################################################

# Performs an action (like opening a link) when a valid symbol was clicked
Expand All @@ -290,3 +291,4 @@ func symbol_validate(symbol:String, text:CodeEdit) -> void:
if symbol in DialogicResourceUtil.get_timeline_directory():
text.set_symbol_lookup_word_as_valid(true)

#endregion
Original file line number Diff line number Diff line change
Expand Up @@ -64,15 +64,19 @@ func _get_line_syntax_highlighting(line:int) -> Dictionary:
dict = color_translation_id(dict, str_line)

if mode == Modes.FULL_HIGHLIGHTING:
if str_line.strip_edges().begins_with("[") and !text_event.text_effects_regex.search(str_line.get_slice(' ', 0)):
var result:= shortcode_regex.search(str_line)
if line_is_shortcode_event(line):
var full_event := get_full_event(line)
var result := shortcode_regex.search(full_event)
if result:
if result.get_string('id') in shortcode_events:
dict[result.get_start('id')] = {"color":shortcode_events[result.get_string('id')].event_color.lerp(normal_color, 0.4)}
dict[result.get_end('id')] = {"color":normal_color}

if result.get_string('args'):
color_shortcode_content(dict, str_line, result.get_start('args'), result.get_end('args'), shortcode_events[result.get_string('id')].event_color)
if full_event.begins_with(str_line):
dict[result.get_start('id')] = {"color":shortcode_events[result.get_string('id')].event_color.lerp(normal_color, 0.4)}
dict[result.get_end('id')] = {"color":normal_color}

if result.get_string('args'):
color_shortcode_content(dict, str_line, result.get_start('args'), result.get_end('args'), shortcode_events[result.get_string('id')].event_color)
else:
color_shortcode_content(dict, str_line, 0, 0, shortcode_events[result.get_string('id')].event_color)
return fix_dict(dict)

else:
Expand All @@ -86,6 +90,39 @@ func _get_line_syntax_highlighting(line:int) -> Dictionary:
return fix_dict(dict)


func line_is_shortcode_event(line_idx:int) -> bool:
var str_line := get_text_edit().get_line(line_idx)
if text_event.text_effects_regex.search(str_line.get_slice(' ', 0)):
return false

if str_line.strip_edges().begins_with("["):
return true

if line_idx > 0 and get_text_edit().get_line(line_idx-1).ends_with('\\'):
return line_is_shortcode_event(line_idx-1)

return false


func get_full_event(line_idx:int) -> String:
var str_line := get_text_edit().get_line(line_idx)
var offset := 1
# Add previous lines
while get_text_edit().get_line(line_idx-offset).ends_with('\\'):
str_line = get_text_edit().get_line(line_idx-offset).trim_suffix('\\')+"\n"+str_line
offset += 1

# This is commented out, as it is not needed right now.
# However without it, this isn't actually the full event.
# Might need to be included some day.
#offset = 0
## Add following lines
#while get_text_edit().get_line(line_idx+offset).ends_with('\\'):
#str_line = str_line.trim_suffix('\\')+"\n"+get_text_edit().get_line(line_idx+offset)
#offset += 1

return str_line

func fix_dict(dict:Dictionary) -> Dictionary:
var d := {}
var k := dict.keys()
Expand Down Expand Up @@ -151,7 +188,7 @@ func color_region(dict:Dictionary, color:Color, line:String, start:String, end:S
func color_shortcode_content(dict:Dictionary, line:String, from:int = 0, to:int = 0, base_color:=normal_color) -> Dictionary:
if to <= from:
to = len(line)-1
var args_result:= shortcode_param_regex.search_all(line.substr(from, to-from+2))
var args_result := shortcode_param_regex.search_all(line.substr(from, to-from+2))
for x in args_result:
dict[x.get_start()+from] = {"color":base_color.lerp(normal_color, 0.5)}
dict[x.get_start('value')+from-1] = {"color":base_color.lerp(normal_color, 0.7)}
Expand Down

0 comments on commit 5e3bfc7

Please sign in to comment.