-- State transitions while colorizing a single line. -- Just for comments and strings. -- Limitation: each fragment gets a uniform color so we can only change color -- at word boundaries. Next_state = { normal={ {prefix='--[[', target='block_comment'}, -- only single-line for now {prefix='--', target='comment'}, {prefix='"', target='dstring'}, {prefix="'", target='sstring'}, {prefix='[[', target='block_string'}, -- only single line for now }, dstring={ {suffix='"', target='normal'}, }, sstring={ {suffix="'", target='normal'}, }, block_string={ {suffix=']]', target='normal'}, }, block_comment={ {suffix=']]', target='normal'}, }, -- comments are a sink } Comment_color = {r=0, g=0, b=1} String_color = {r=0, g=0.5, b=0.5} Divider_color = {r=0.7, g=0.7, b=0.7} Colors = { normal=Text_color, comment=Comment_color, sstring=String_color, dstring=String_color, block_string=String_color, block_comment=Comment_color, } Current_state = 'normal' function initialize_color() --? print('new line') Current_state = 'normal' end function select_color(frag) --? print('before', '^'..frag..'$', Current_state) switch_color_based_on_prefix(frag) --? print('using color', Current_state, Colors[Current_state]) App.color(Colors[Current_state]) switch_color_based_on_suffix(frag) --? print('state after suffix', Current_state) end function switch_color_based_on_prefix(frag) if Next_state[Current_state] == nil then return end frag = rtrim(frag) for _,edge in pairs(Next_state[Current_state]) do if edge.prefix and find(frag, edge.prefix, nil, --[[plain]] true) == 1 then Current_state = edge.target break end end end function switch_color_based_on_suffix(frag) if Next_state[Current_state] == nil then return end frag = rtrim(frag) for _,edge in pairs(Next_state[Current_state]) do if edge.suffix and rfind(frag, edge.suffix, nil, --[[plain]] true) == #frag - #edge.suffix + 1 then Current_state = edge.target break end end end function trim(s) return s:gsub('^%s+', ''):gsub('%s+$', '') end function ltrim(s) return s:gsub('^%s+', '') end function rtrim(s) return s:gsub('%s+$', '') end