Restyle whole buffer on event to fix style breaks

TODO: Make this more precise... some day
This commit is contained in:
2025-03-31 15:36:31 +09:00
parent 9d70f98ed0
commit dea44561ee
3 changed files with 219 additions and 28 deletions
+20 -26
View File
@@ -94,7 +94,6 @@ new(Parent) ->
?wxFONTSTYLE_NORMAL,
?wxFONTWEIGHT_NORMAL,
[{face, "Monospace"}]),
SetMonospace = fun(Style) -> wxStyledTextCtrl:styleSetFont(STC, Style, Mono) end,
ok = lists:foreach(SetMonospace, styles()),
ok = wxStyledTextCtrl:styleSetFont(STC, ?wxSTC_STYLE_DEFAULT, Mono),
@@ -109,7 +108,6 @@ set_text(STC, Text) ->
%% Force Scintilla to request styling for the entire text
wxStyledTextCtrl:colourise(STC, 0, -1).
%% ======================================================================
set_colors(STC) ->
ok = wxStyledTextCtrl:styleClearAll(STC),
@@ -125,35 +123,34 @@ set_colors(STC) ->
update(_Event, STC) ->
try
StartPos = wxStyledTextCtrl:getEndStyled(STC),
EndPos = wxStyledTextCtrl:getLength(STC),
Text = wxStyledTextCtrl:getTextRange(STC, StartPos, EndPos),
Text = wxStyledTextCtrl:getText(STC),
case so_scan:scan(Text) of
{ok, Tokens} ->
wxStyledTextCtrl:startStyling(STC, StartPos),
ok = wxStyledTextCtrl:startStyling(STC, 0),
apply_styles(STC, Tokens);
{error, _Reason} ->
wxStyledTextCtrl:startStyling(STC, StartPos),
wxStyledTextCtrl:setStyling(STC, EndPos - StartPos, 0)
end
catch
error:E:T ->
dbg("CAUGHT error:~p / ~p~n", [E, T])
ok
end.
apply_styles(STC, Tokens) ->
lists:foreach(fun(Token) -> style_token(STC, Token) end, Tokens).
% FIXME: 'qid' is not properly handled. If there are multi-dot qids, they will break
style_token(STC, Token) ->
{Type, Value} = type_and_value(Token),
{StartOffset, LengthOffset} = offset(Type),
{Line, Col} = element(2, Token),
Len = byte_size(to_binary(Value)),
Length = byte_size(to_binary(Value)) + LengthOffset,
Style = classify_style(Type, Value),
% Get exact position from Line and Column
Start = wxStyledTextCtrl:positionFromLine(STC, Line - 1) + (Col - 1),
Start = wxStyledTextCtrl:positionFromLine(STC, Line - 1) + Col + StartOffset,
wxStyledTextCtrl:startStyling(STC, Start),
wxStyledTextCtrl:setStyling(STC, Len, Style).
wxStyledTextCtrl:setStyling(STC, Length, Style).
offset(string) -> { 0, 0};
offset(qid) -> {-1, 1};
offset(_) -> {-1, 0}.
to_binary(S) when is_list(S) ->
unicode:characters_to_binary(S);
@@ -162,6 +159,7 @@ to_binary(S) when is_binary(S) ->
to_binary(I) when is_integer(I) ->
integer_to_binary(I).
classify_style(Type, Value) ->
case Type of
symbol ->
@@ -180,20 +178,16 @@ classify_style(Type, Value) ->
hex -> ?NUMBER;
bytes -> ?NUMBER;
skip -> ?COMMENT;
_Other -> ?DEFAULT
_ -> ?DEFAULT
end.
type_and_value({Type,_Line,Value}) -> {Type, Value};
type_and_value({Type, _}) -> {Type, atom_to_list(Type)}.
type_and_value({Type, _Line, Value}) -> {Type, Value};
type_and_value({Type, _}) -> {Type, atom_to_list(Type)}.
keywords() ->
["contract", "include", "let", "switch", "type", "record", "datatype", "if",
"elif", "else", "function", "stateful", "payable", "true", "false", "mod",
"public", "entrypoint", "private", "indexed", "namespace", "interface",
"main", "using", "as", "for", "hiding", "band", "bor", "bxor", "bnot"].
%% dbg(Fmt) ->
%% dbg(Fmt, []).
dbg(Fmt, Args) ->
io:format("~p: " ++ Fmt, [self()|Args]).