summaryrefslogtreecommitdiff
path: root/lib/debugger
diff options
context:
space:
mode:
authorDan Gudmundsson <dgud@erlang.org>2021-07-06 10:03:59 +0200
committerDan Gudmundsson <dgud@erlang.org>2021-08-23 14:09:46 +0200
commit2426440b31dd70c985e02345ec593ac980d63e05 (patch)
treeed0d48bf9cb30b73b968c7a7025f793aed26498a /lib/debugger
parent307cb5e8a99b2e3f6f337fe6e89cf6e4faea33f6 (diff)
downloaderlang-2426440b31dd70c985e02345ec593ac980d63e05.tar.gz
Print records
Format module records in bindings area and in evaluator area.
Diffstat (limited to 'lib/debugger')
-rw-r--r--lib/debugger/src/dbg_ieval.erl93
-rw-r--r--lib/debugger/src/dbg_iload.erl3
-rw-r--r--lib/debugger/src/dbg_iserver.erl8
-rw-r--r--lib/debugger/src/dbg_wx_trace.erl41
-rw-r--r--lib/debugger/src/dbg_wx_trace_win.erl117
5 files changed, 204 insertions, 58 deletions
diff --git a/lib/debugger/src/dbg_ieval.erl b/lib/debugger/src/dbg_ieval.erl
index f7e859f174..3185b1e9e3 100644
--- a/lib/debugger/src/dbg_ieval.erl
+++ b/lib/debugger/src/dbg_ieval.erl
@@ -87,12 +87,14 @@ exit_info(Int, AttPid, OrigPid, Reason, ExitInfo) ->
%% Evalute a shell expression in the real process.
%% Called (dbg_icmd) in response to a user request.
%%--------------------------------------------------------------------
-eval_expr(Expr, Bs, Ieval) ->
+eval_expr(Expr0, Bs, Ieval) ->
%% Save current exit info
ExitInfo = get(exit_info),
Stacktrace = get(stacktrace),
+ Expr = expand_records(Expr0, Ieval#ieval.module),
+
%% Emulate a surrounding catch
try debugged_cmd({eval,Expr,Bs}, Bs, Ieval)
catch
@@ -1760,3 +1762,92 @@ get_stacktrace() ->
Stk when is_list(Stk) ->
Stk
end.
+
+%%% eval record exprs
+%%% copied from stdlib/src/shell.erl
+
+expand_records(Expr, Mod) ->
+ try
+ expand_records_1(used_record_defs(Expr, Mod), Expr)
+ catch _:_Err:_ST ->
+ Expr
+ end.
+
+expand_records_1([], Expr) ->
+ Expr;
+expand_records_1(UsedRecords, Expr) ->
+ A = erl_anno:new(1),
+ RecordDefs = [{attribute, A, record,
+ {Name, [{record_field,A,{atom,A,F}} || F <- Fields]}
+ } || {Name,Fields} <- UsedRecords],
+ Forms0 = RecordDefs ++ [{function,A,foo,0,[{clause,A,[],[],[Expr]}]}],
+ Forms = erl_expand_records:module(Forms0, [strict_record_tests]),
+ {function,A,foo,0,[{clause,A,[],[],[NE]}]} = lists:last(Forms),
+ NE.
+
+used_record_defs(E, Mod) ->
+ case mod_recs(Mod) of
+ [] -> [];
+ Recs0 ->
+ Recs = [{Name, Fields} || {{_,_,Name,_}, Fields} <- Recs0],
+ L0 = used_record_defs(E, maps:from_list(Recs), [], []),
+ L1 = lists:zip(L0, lists:seq(1, length(L0))),
+ L2 = lists:keysort(2, lists:ukeysort(1, L1)),
+ [R || {R, _} <- L2]
+ end.
+
+used_record_defs(E, Recs, Skip, Used) ->
+ case used_records(E) of
+ {name,Name,E1} ->
+ case lists:member(Name, Skip) of
+ true ->
+ used_record_defs(E1, Recs, Skip, Used);
+ false ->
+ case maps:get(Name, Recs, undefined) of
+ undefined ->
+ used_record_defs(E1, Recs, [Name|Skip], Used);
+ Fields ->
+ used_record_defs(E1, Recs, [Name|Skip], [{Name, Fields}|Used])
+ end
+ end;
+ {expr,[E1 | Es]} ->
+ used_record_defs(Es, Recs, Skip, used_record_defs(E1, Recs, Skip, Used));
+ _ ->
+ Used
+ end.
+
+mod_recs(Mod) ->
+ case db_ref(Mod) of
+ not_found ->
+ [];
+ ModDb ->
+ dbg_idb:match_object(ModDb, {{record, Mod, '_', '_'}, '_'})
+ end.
+
+used_records({record_index,_,Name,F}) ->
+ {name, Name, F};
+used_records({record,_,Name,Is}) ->
+ {name, Name, Is};
+used_records({record_field,_,R,Name,F}) ->
+ {name, Name, [R | F]};
+used_records({record,_,R,Name,Ups}) ->
+ {name, Name, [R | Ups]};
+used_records({record_field,_,R,F}) -> % illegal
+ {expr, [R | F]};
+used_records({call,_,{atom,_,record},[A,{atom,_,Name}]}) ->
+ {name, Name, A};
+used_records({call,_,{atom,_,is_record},[A,{atom,_,Name}]}) ->
+ {name, Name, A};
+used_records({call,_,{remote,_,{atom,_,erlang},{atom,_,is_record}},
+ [A,{atom,_,Name}]}) ->
+ {name, Name, A};
+used_records({call,_,{atom,_,record_info},[A,{atom,_,Name}]}) ->
+ {name, Name, A};
+used_records({call,A,{tuple,_,[M,F]},As}) ->
+ used_records({call,A,{remote,A,M,F},As});
+used_records({type,_,record,[{atom,_,Name}|Fs]}) ->
+ {name, Name, Fs};
+used_records(T) when is_tuple(T) ->
+ {expr, tuple_to_list(T)};
+used_records(E) ->
+ {expr, E}.
diff --git a/lib/debugger/src/dbg_iload.erl b/lib/debugger/src/dbg_iload.erl
index 0f8164dadf..e7b74370fc 100644
--- a/lib/debugger/src/dbg_iload.erl
+++ b/lib/debugger/src/dbg_iload.erl
@@ -145,7 +145,8 @@ store_forms([{function,_,Name,Arity,Cs0}|Fs], Mod, Db, #{exp:=Exp} = St) ->
store_forms(Fs, Mod, Db, St);
store_forms([{attribute,_,record,{Name,Defs}}|Fs], Mod, Db, St) ->
NDefs = normalise_rec_fields(Defs),
- dbg_idb:insert(Db, {Mod,record,Name}, NDefs),
+ Fields = [F || {record_field, _, {atom, _, F}, _} <- NDefs],
+ dbg_idb:insert(Db, {record,Mod,Name,length(Fields)}, Fields),
Recs = maps:get(recs, St, #{}),
store_forms(Fs, Mod, Db, St#{recs => Recs#{Name => NDefs}});
store_forms([{attribute,_,_Name,_Val}|Fs], Mod, Db, St) ->
diff --git a/lib/debugger/src/dbg_iserver.erl b/lib/debugger/src/dbg_iserver.erl
index 3e959e8e30..a9d157afa9 100644
--- a/lib/debugger/src/dbg_iserver.erl
+++ b/lib/debugger/src/dbg_iserver.erl
@@ -233,6 +233,14 @@ handle_call({load, Mod, Src, Bin}, _From, State) ->
{reply, {module, Mod}, State};
%% Module database
+handle_call({get_module_db, Mod}, _From, State) ->
+ Db = State#state.db,
+ Reply = case ets:lookup(Db, {Mod, refs}) of
+ [] -> not_found;
+ [{{Mod, refs}, [ModDb|_ModDbs]}] ->
+ ModDb
+ end,
+ {reply, Reply, State};
handle_call({get_module_db, Mod, Pid}, _From, State) ->
Db = State#state.db,
Reply = case ets:lookup(Db, {Mod, refs}) of
diff --git a/lib/debugger/src/dbg_wx_trace.erl b/lib/debugger/src/dbg_wx_trace.erl
index 210987d3e6..d1334705c6 100644
--- a/lib/debugger/src/dbg_wx_trace.erl
+++ b/lib/debugger/src/dbg_wx_trace.erl
@@ -312,7 +312,7 @@ gui_cmd('Where', State) ->
{_Status, Mod, Line} = State#state.status,
Win = gui_show_module(State#state.win, Mod, Line,
State#state.cm, State#state.pid, break),
- gui_update_bindings(State#state.win, State#state.meta),
+ gui_update_bindings(State#state.win, Mod, State#state.meta),
gui_enable_updown(State#state.stack_trace, Stack),
dbg_wx_trace_win:display(State#state.win,State#state.status),
State#state{win=Win, cm=Mod, stack=Stack};
@@ -330,10 +330,7 @@ gui_cmd('Messages', State) ->
lists:foldl(
fun(Msg, N) ->
Str1 = io_lib:format(" ~w:", [N]),
- dbg_wx_trace_win:eval_output(State#state.win,Str1, bold),
- Str2 = pretty(Msg, State),
- Str3 = io_lib:format(" ~ts~n",[Str2]),
- dbg_wx_trace_win:eval_output(State#state.win,Str3, normal),
+ dbg_wx_trace_win:eval_output(State#state.win,Str1, Msg, normal),
N+1
end,
1,
@@ -363,7 +360,7 @@ gui_cmd('Up', State) ->
{New, {undefined,-1}, _Bs} -> % call from non-interpreted code
Stack = {New, Max},
Win = dbg_wx_trace_win:show_no_code(State#state.win),
- dbg_wx_trace_win:update_bindings(State#state.win,[]),
+ dbg_wx_trace_win:update_bindings(State#state.win,undefined,[]),
gui_enable_updown(State#state.stack_trace, Stack),
dbg_wx_trace_win:display(State#state.win,{New,null,null}),
State#state{win=Win, cm=null, stack=Stack};
@@ -373,7 +370,7 @@ gui_cmd('Up', State) ->
Win = gui_show_module(State#state.win, Mod, Line,
State#state.cm, State#state.pid,
where),
- dbg_wx_trace_win:update_bindings(State#state.win,Bs),
+ dbg_wx_trace_win:update_bindings(State#state.win,Mod,Bs),
gui_enable_updown(State#state.stack_trace, Stack),
dbg_wx_trace_win:display(State#state.win,{New,Mod,Line}),
State#state{win=Win, cm=Mod, stack=Stack};
@@ -387,7 +384,7 @@ gui_cmd('Down', State) ->
{New, {undefined,-1}, _Bs} -> % call from non-interpreted code
Stack = {New, Max},
Win = dbg_wx_trace_win:show_no_code(State#state.win),
- dbg_wx_trace_win:update_bindings(State#state.win, []),
+ dbg_wx_trace_win:update_bindings(State#state.win,undefined,[]),
gui_enable_updown(State#state.stack_trace, Stack),
dbg_wx_trace_win:display(State#state.win, {New,null,null}),
State#state{win=Win, cm=null, stack=Stack};
@@ -397,7 +394,7 @@ gui_cmd('Down', State) ->
Win = gui_show_module(State#state.win, Mod, Line,
State#state.cm, State#state.pid,
where),
- dbg_wx_trace_win:update_bindings(State#state.win, Bs),
+ dbg_wx_trace_win:update_bindings(State#state.win, Mod, Bs),
gui_enable_updown(State#state.stack_trace, Stack),
dbg_wx_trace_win:display(State#state.win, {New,Mod,Line}),
State#state{win=Win, cm=Mod, stack=Stack};
@@ -511,7 +508,7 @@ gui_cmd({user_command, Cmd}, State) ->
int:meta(State#state.meta, eval, Arg);
true ->
Str = "Commands not allowed",
- dbg_wx_trace_win:eval_output(State#state.win, [$<,Str,10], normal)
+ dbg_wx_trace_win:eval_output(State#state.win, [$<,Str,10], bold)
end,
State;
@@ -633,7 +630,7 @@ meta_cmd({exit_at, {Mod,Line}, Reason, Cur}, State) ->
gui_enable_functions(exit),
gui_enable_updown(State#state.stack_trace, Stack),
gui_enable_btrace(State#state.trace, State#state.stack_trace),
- gui_update_bindings(State#state.win, State#state.meta),
+ gui_update_bindings(State#state.win, Mod, State#state.meta),
dbg_wx_trace_win:display(State#state.win, {exit, {Mod,Line}, Reason}),
State#state{win=Win, cm=Mod,status={exit,{Mod,Line},Reason},
stack=Stack};
@@ -645,7 +642,7 @@ meta_cmd({break_at, Mod, Line, Cur}, State) ->
gui_enable_functions(break),
gui_enable_updown(State#state.stack_trace, Stack),
gui_enable_btrace(State#state.trace, State#state.stack_trace),
- gui_update_bindings(State#state.win, State#state.meta),
+ gui_update_bindings(State#state.win, Mod, State#state.meta),
dbg_wx_trace_win:display(State#state.win, {break, Mod, Line}),
State#state{win=Win, cm=Mod, status={break,Mod,Line}, stack=Stack};
meta_cmd({func_at, Mod, Line, Cur}, State) ->
@@ -668,7 +665,7 @@ meta_cmd({wait_at, Mod, Line, Cur}, State) ->
gui_enable_functions(wait_break),
gui_enable_updown(State#state.stack_trace, Stack),
gui_enable_btrace(State#state.trace, State#state.stack_trace),
- gui_update_bindings(State#state.win, State#state.meta),
+ gui_update_bindings(State#state.win, Mod, State#state.meta),
dbg_wx_trace_win:display(State#state.win, {wait, Mod, Line}),
State#state{win=Win, cm=Mod, status={wait_break,Mod,Line},
stack=Stack};
@@ -677,14 +674,14 @@ meta_cmd({wait_after_at, Mod, Line, Sp}, State) ->
meta_cmd(running, State) ->
Win = dbg_wx_trace_win:unmark_line(State#state.win),
gui_enable_functions(running),
- dbg_wx_trace_win:update_bindings(State#state.win, []),
+ dbg_wx_trace_win:update_bindings(State#state.win, undefined, []),
dbg_wx_trace_win:display(State#state.win, {running, State#state.cm}),
State#state{win=Win, status={running,null,null}};
meta_cmd(idle, State) ->
Win = dbg_wx_trace_win:show_no_code(State#state.win),
gui_enable_functions(idle),
- dbg_wx_trace_win:update_bindings(State#state.win, []),
+ dbg_wx_trace_win:update_bindings(State#state.win, undefined, []),
dbg_wx_trace_win:display(State#state.win, idle),
State#state{win=Win, status={idle,null,null}, cm=undefined};
@@ -713,17 +710,9 @@ meta_cmd({trace_output, StrFun}, State) ->
%% Reply on a user command
meta_cmd({eval_rsp, Res}, State) ->
- Str = pretty(Res, State),
- dbg_wx_trace_win:eval_output(State#state.win, [$<,Str,10], normal),
+ dbg_wx_trace_win:eval_output(State#state.win, [$<], Res, normal),
State.
-pretty(Term, State) ->
- Strings = case State#state.strings of
- [str_on] -> true;
- [] -> false
- end,
- io_lib_pretty:print(Term,[{encoding,unicode},{strings,Strings}]).
-
%%====================================================================
%% GUI auxiliary functions
%%====================================================================
@@ -841,9 +830,9 @@ gui_load_module(Win, Mod, _Pid) ->
dbg_wx_trace_win:show_no_code(Win)
end.
-gui_update_bindings(Win,Meta) ->
+gui_update_bindings(Win,Mod,Meta) ->
Bs = int:meta(Meta, bindings, nostack),
- dbg_wx_trace_win:update_bindings(Win,Bs).
+ dbg_wx_trace_win:update_bindings(Win,Mod,Bs).
gui_enable_functions(Status) ->
Enable = enable(Status),
diff --git a/lib/debugger/src/dbg_wx_trace_win.erl b/lib/debugger/src/dbg_wx_trace_win.erl
index f5e5fbc5bf..526e673807 100644
--- a/lib/debugger/src/dbg_wx_trace_win.erl
+++ b/lib/debugger/src/dbg_wx_trace_win.erl
@@ -23,7 +23,7 @@
%% External exports
-export([init/0, stop/1]).
--export([create_win/4,
+-export([create_win/4,
get_window/1,
configure/2,
enable/2, is_enabled/1, select/2,
@@ -31,11 +31,11 @@
clear_breaks/1, clear_breaks/2,
display/2, % Help messages
is_shown/2, % Code area
- show_code/3, show_no_code/1, remove_code/2,
+ show_code/3, show_no_code/1, remove_code/2,
mark_line/3, unmark_line/1,
select_line/2, selected_line/1,
- eval_output/3, % Evaluator area
- update_bindings/2, % Bindings area
+ eval_output/3, eval_output/4, eval_output/5, % Evaluator area
+ update_bindings/3, % Bindings area
update_strings/1,
trace_output/2, % Trace area
handle_event/2
@@ -205,7 +205,7 @@ create_win(Parent, Title, Windows, Menus) ->
put(window, Win),
put(strings, [str_on]),
Wi
- end,
+ end,
try wx:batch(Do)
catch E:R ->
@@ -558,29 +558,83 @@ selected_line(#winInfo{editor={_,Ed}}) ->
%% Str = string()
%% Face = normal | bold
%%--------------------------------------------------------------------
-eval_output(#winInfo{eval=#sub{out=Log}}, Text, _Face) ->
+eval_output(#winInfo{eval=#sub{out=Log}}, Text, bold) ->
+ Style = wxTextCtrl:getDefaultStyle(Log),
+ Font = wxTextAttr:getFont(Style),
+ wxFont:setWeight(Font, ?wxFONTWEIGHT_BOLD),
+ wxTextAttr:setFont(Style, Font),
+ wxTextCtrl:setDefaultStyle(Log, Style),
+ wxTextCtrl:appendText(Log, dbg_wx_win:to_string(Text)),
+ wxFont:setWeight(Font, ?wxFONTWEIGHT_NORMAL),
+ wxTextAttr:setFont(Style, Font),
+ wxTextCtrl:setDefaultStyle(Log, Style),
+ ok;
+eval_output(#winInfo{eval=#sub{out=Log}}, Text, _Face) ->
wxTextCtrl:appendText(Log, dbg_wx_win:to_string(Text)),
ok.
-
+
+%%--------------------------------------------------------------------
+%% eval_output(winInfo{}, Prefix, Term, [Mod,] Face)
+%% Prefix = string()
+%% Term = term to be formatted
+%% Mod = module() | undefined for record formatting
+%% Face = normal | bold
+%%--------------------------------------------------------------------
+eval_output(Wi, Prefix, Term, Face) ->
+ {Mod,_Bs} = get(bindings),
+ eval_output(Wi, Prefix, Term, Mod, Face).
+
+eval_output(#winInfo{eval=#sub{out=Log}}=Wi, Prefix, Term, Mod, Face) ->
+ {CW, _, _, _ } = wxTextCtrl:getTextExtent(Log,"w"),
+ {W, _} = wxTextCtrl:getClientSize(Log),
+ LineLength = max(40, W div CW),
+ Column = string:length(Prefix),
+ ValStr = format_term(Term, Mod, LineLength-Column, Column, -1, -1),
+ eval_output(Wi, Prefix, bold),
+ eval_output(Wi, [ValStr, "\n"], Face),
+ ok.
+
%%--------------------------------------------------------------------
%% update_bindings(Bs)
%% Bs = [{Var,Val}]
%%--------------------------------------------------------------------
-update_bindings(#winInfo{bind=#sub{out=BA}}, Bs) ->
+update_bindings(#winInfo{bind=#sub{out=BA}}, Mod, Bs) ->
wxListCtrl:deleteAllItems(BA),
wx:foldl(fun({Var,Val},Row) ->
- wxListCtrl:insertItem(BA, Row, ""),
+ wxListCtrl:insertItem(BA, Row, ""),
wxListCtrl:setItem(BA, Row, 0, dbg_wx_win:to_string(Var)),
- Format = case get(strings) of
- [] -> "~0ltP";
- [str_on] -> "~0tP"
- end,
- wxListCtrl:setItem(BA, Row, 1, dbg_wx_win:to_string(Format,[Val, 20])),
+ Str = format_term_line(Val, Mod),
+ wxListCtrl:setItem(BA, Row, 1, Str),
Row+1
end, 0, Bs),
- put(bindings,Bs),
+ put(bindings,{Mod,Bs}),
ok.
+format_term_line(Val, Mod) ->
+ format_term(Val, Mod, 0, 1, 20, 300).
+
+format_term(Val, Mod, LineLenght, Column, Depth, Limit) ->
+ RecFun = fun(Tag,NoFields) -> record_fields(Tag, NoFields, Mod) end,
+ UseStrings = case get(strings) of
+ [] -> false;
+ [str_on] -> true
+ end,
+ Opts = [{line_length,LineLenght}, {depth, Depth}, {chars_limit, Limit}, {column, Column},
+ {strings, UseStrings}, {encoding, unicode}, {record_print_fun, RecFun}],
+ io_lib_pretty:print(Val, Opts).
+
+record_fields(Tag, NoFields, Mod) ->
+ case dbg_iserver:call({get_module_db, Mod}) of
+ not_found -> no;
+ ModDb ->
+ case dbg_idb:lookup(ModDb, {record, Mod, Tag, NoFields}) of
+ {ok, Value} ->
+ Value;
+ not_found ->
+ no
+ end
+ end.
+
update_strings(Strings) ->
_ = put(strings, Strings),
ok.
@@ -856,26 +910,23 @@ handle_event(#wx{id=?EVAL_ENTRY, event=#wxCommand{type=command_text_enter}},
eval_output(Wi, "\n", normal),
ignore;
Cmd ->
- eval_output(Wi, [$>, Cmd, 10], normal),
+ eval_output(Wi, [$>, Cmd, 10], bold),
wxTextCtrl:setValue(TC,""),
{user_command, Cmd}
end;
%% Bindings area
handle_event(#wx{event=#wxList{type=command_list_item_selected, itemIndex=Row}},Wi) ->
- Bs = get(bindings),
+ {Mod,Bs} = get(bindings),
{Var,Val} = lists:nth(Row+1, Bs),
- Str = case get(strings) of
- [] -> io_lib:format("< ~s = ~ltp~n", [Var, Val]);
- [str_on] -> io_lib:format("< ~s = ~tp~n", [Var, Val])
- end,
- eval_output(Wi, Str, bold),
+ Header = io_lib:format("< ~s = ", [Var]),
+ eval_output(Wi, Header, Val, Mod, normal),
ignore;
-handle_event(#wx{event=#wxList{type=command_list_item_activated, itemIndex=Row}},_Wi) ->
- Bs = get(bindings),
+handle_event(#wx{event=#wxList{type=command_list_item_activated, itemIndex=Row}},_Wi) ->
+ {_Mod,Bs} = get(bindings),
Binding = lists:nth(Row+1, Bs),
{edit, Binding};
-
+
handle_event(_GSEvent, _WinInfo) ->
%%io:format("~p: unhandled ~p~n",[?MODULE, _GSEvent]),
ignore.
@@ -939,7 +990,7 @@ button_area(Parent) ->
search_area(Parent) ->
HSz = wxBoxSizer:new(?wxHORIZONTAL),
- _ = wxSizer:add(HSz, wxStaticText:new(Parent, ?wxID_ANY, "Find:"),
+ _ = wxSizer:add(HSz, wxStaticText:new(Parent, ?wxID_ANY, "Find: "),
[{flag,?wxALIGN_CENTER_VERTICAL}]),
TC1 = wxTextCtrl:new(Parent, ?SEARCH_ENTRY, [{style, ?wxTE_PROCESS_ENTER}]),
_ = wxSizer:add(HSz, TC1, [{proportion,3}, {flag, ?wxEXPAND}]),
@@ -951,7 +1002,7 @@ search_area(Parent) ->
Cbtn = wxCheckBox:new(Parent, ?wxID_ANY, "Match Case"),
_ = wxSizer:add(HSz,Cbtn,[{flag,?wxALIGN_CENTER_VERTICAL}]),
_ = wxSizer:add(HSz, 15,15, [{proportion,1}, {flag, ?wxEXPAND}]),
- _ = wxSizer:add(HSz, wxStaticText:new(Parent, ?wxID_ANY, "Goto Line:"),
+ _ = wxSizer:add(HSz, wxStaticText:new(Parent, ?wxID_ANY, "Goto Line: "),
[{flag,?wxALIGN_CENTER_VERTICAL}]),
TC2 = wxTextCtrl:new(Parent, ?GOTO_ENTRY, [{style, ?wxTE_PROCESS_ENTER}]),
_ = wxSizer:add(HSz, TC2, [{proportion,0}, {flag, ?wxEXPAND}]),
@@ -970,13 +1021,19 @@ eval_area(Parent) ->
VSz = wxBoxSizer:new(?wxVERTICAL),
HSz = wxBoxSizer:new(?wxHORIZONTAL),
- _ = wxSizer:add(HSz, wxStaticText:new(Parent, ?wxID_ANY, "Evaluator:"),
+ _ = wxSizer:add(HSz, wxStaticText:new(Parent, ?wxID_ANY, "Evaluator: "),
[{flag,?wxALIGN_CENTER_VERTICAL}]),
TC = wxTextCtrl:new(Parent, ?EVAL_ENTRY, [{style, ?wxTE_PROCESS_ENTER}]),
_ = wxSizer:add(HSz, TC, [{proportion,1}, {flag, ?wxEXPAND}]),
_ = wxSizer:add(VSz, HSz, [{flag, ?wxEXPAND}]),
- TL = wxTextCtrl:new(Parent, ?EVAL_LOG, [{style, ?wxTE_DONTWRAP bor
- ?wxTE_MULTILINE bor ?wxTE_READONLY}]),
+ TL = wxTextCtrl:new(Parent, ?EVAL_LOG, [{style,
+ ?wxTE_DONTWRAP
+ bor ?wxTE_MULTILINE
+ bor ?wxTE_READONLY
+ bor ?wxTE_RICH2
+ }]),
+ FixedFont = wxFont:new(10, ?wxFONTFAMILY_TELETYPE, ?wxNORMAL, ?wxNORMAL,[]),
+ wxWindow:setFont(TL, FixedFont),
_ = wxSizer:add(VSz, TL, [{proportion,5}, {flag, ?wxEXPAND}]),
wxTextCtrl:connect(TC, command_text_enter),