## eval-mode.pkg
#
# Mode for interactive Mythryl evaluation.
#
# See also:
#
src/lib/x-kit/widget/edit/textpane.pkg#
src/lib/x-kit/widget/edit/millboss-imp.pkg#
src/lib/x-kit/widget/edit/textmill.pkg#
src/lib/x-kit/widget/edit/fundamental-mode.pkg# Compiled by:
#
src/lib/x-kit/widget/xkit-widget.sublibstipulate
include package threadkit; # threadkit is from
src/lib/src/lib/thread-kit/src/core-thread-kit/threadkit.pkg #
# package ap = client_to_atom; # client_to_atom is from
src/lib/x-kit/xclient/src/iccc/client-to-atom.pkg# package au = authentication; # authentication is from
src/lib/x-kit/xclient/src/stuff/authentication.pkg# package cpm = cs_pixmap; # cs_pixmap is from
src/lib/x-kit/xclient/src/window/cs-pixmap.pkg# package cpt = cs_pixmat; # cs_pixmat is from
src/lib/x-kit/xclient/src/window/cs-pixmat.pkg# package dy = display; # display is from
src/lib/x-kit/xclient/src/wire/display.pkg# package fti = font_index; # font_index is from
src/lib/x-kit/xclient/src/window/font-index.pkg# package r2k = xevent_router_to_keymap; # xevent_router_to_keymap is from
src/lib/x-kit/xclient/src/window/xevent-router-to-keymap.pkg# package mtx = rw_matrix; # rw_matrix is from
src/lib/std/src/rw-matrix.pkg# package rop = ro_pixmap; # ro_pixmap is from
src/lib/x-kit/xclient/src/window/ro-pixmap.pkg# package rw = root_window; # root_window is from
src/lib/x-kit/widget/lib/root-window.pkg# package rwv = rw_vector; # rw_vector is from
src/lib/std/src/rw-vector.pkg# package sep = client_to_selection; # client_to_selection is from
src/lib/x-kit/xclient/src/window/client-to-selection.pkg# package shp = shade; # shade is from
src/lib/x-kit/widget/lib/shade.pkg# package sj = socket_junk; # socket_junk is from
src/lib/internet/socket-junk.pkg# package x2s = xclient_to_sequencer; # xclient_to_sequencer is from
src/lib/x-kit/xclient/src/wire/xclient-to-sequencer.pkg# package tr = logger; # logger is from
src/lib/src/lib/thread-kit/src/lib/logger.pkg# package tsr = thread_scheduler_is_running; # thread_scheduler_is_running is from
src/lib/src/lib/thread-kit/src/core-thread-kit/thread-scheduler-is-running.pkg# package u1 = one_byte_unt; # one_byte_unt is from
src/lib/std/one-byte-unt.pkg# package v1u = vector_of_one_byte_unts; # vector_of_one_byte_unts is from
src/lib/std/src/vector-of-one-byte-unts.pkg# package v2w = value_to_wire; # value_to_wire is from
src/lib/x-kit/xclient/src/wire/value-to-wire.pkg# package wg = widget; # widget is from
src/lib/x-kit/widget/old/basic/widget.pkg# package wi = window; # window is from
src/lib/x-kit/xclient/src/window/window.pkg# package wme = window_map_event_sink; # window_map_event_sink is from
src/lib/x-kit/xclient/src/window/window-map-event-sink.pkg# package wpp = client_to_window_watcher; # client_to_window_watcher is from
src/lib/x-kit/xclient/src/window/client-to-window-watcher.pkg# package wy = widget_style; # widget_style is from
src/lib/x-kit/widget/lib/widget-style.pkg# package xc = xclient; # xclient is from
src/lib/x-kit/xclient/xclient.pkg# package xj = xsession_junk; # xsession_junk is from
src/lib/x-kit/xclient/src/window/xsession-junk.pkg# package xtr = xlogger; # xlogger is from
src/lib/x-kit/xclient/src/stuff/xlogger.pkg #
# XXX SUCKO FIXME Does this need to be __premicrothread' for any reason???
package fil = file__premicrothread; # file__premicrothread is from
src/lib/std/src/posix/file--premicrothread.pkg #
package evt = gui_event_types; # gui_event_types is from
src/lib/x-kit/widget/gui/gui-event-types.pkg package gts = gui_event_to_string; # gui_event_to_string is from
src/lib/x-kit/widget/gui/gui-event-to-string.pkg package gt = guiboss_types; # guiboss_types is from
src/lib/x-kit/widget/gui/guiboss-types.pkg package a2r = windowsystem_to_xevent_router; # windowsystem_to_xevent_router is from
src/lib/x-kit/xclient/src/window/windowsystem-to-xevent-router.pkg package gd = gui_displaylist; # gui_displaylist is from
src/lib/x-kit/widget/theme/gui-displaylist.pkg package pp = standard_prettyprinter; # standard_prettyprinter is from
src/lib/prettyprint/big/src/standard-prettyprinter.pkg package tlj = textlines_junk; # textlines_junk is from
src/lib/x-kit/widget/edit/textlines-junk.pkg # compiler is from
src/lib/core/compiler/compiler.pkg package err = compiler::error_message; # error_message is from
src/lib/compiler/front/basics/errormsg/error-message.pkg package sci = compiler::sourcecode_info; # sourcecode_info is from
src/lib/compiler/front/basics/source/sourcecode-info.pkg package ct = cutbuffer_types; # cutbuffer_types is from
src/lib/x-kit/widget/edit/cutbuffer-types.pkg# package ct = gui_to_object_theme; # gui_to_object_theme is from
src/lib/x-kit/widget/theme/object/gui-to-object-theme.pkg# package bt = gui_to_sprite_theme; # gui_to_sprite_theme is from
src/lib/x-kit/widget/theme/sprite/gui-to-sprite-theme.pkg# package wt = widget_theme; # widget_theme is from
src/lib/x-kit/widget/theme/widget/widget-theme.pkg package boi = spritespace_imp; # spritespace_imp is from
src/lib/x-kit/widget/space/sprite/spritespace-imp.pkg package cai = objectspace_imp; # objectspace_imp is from
src/lib/x-kit/widget/space/object/objectspace-imp.pkg package pai = widgetspace_imp; # widgetspace_imp is from
src/lib/x-kit/widget/space/widget/widgetspace-imp.pkg #
package gtg = guiboss_to_guishim; # guiboss_to_guishim is from
src/lib/x-kit/widget/theme/guiboss-to-guishim.pkg package b2s = spritespace_to_sprite; # spritespace_to_sprite is from
src/lib/x-kit/widget/space/sprite/spritespace-to-sprite.pkg package c2o = objectspace_to_object; # objectspace_to_object is from
src/lib/x-kit/widget/space/object/objectspace-to-object.pkg package s2b = sprite_to_spritespace; # sprite_to_spritespace is from
src/lib/x-kit/widget/space/sprite/sprite-to-spritespace.pkg package o2c = object_to_objectspace; # object_to_objectspace is from
src/lib/x-kit/widget/space/object/object-to-objectspace.pkg package g2p = gadget_to_pixmap; # gadget_to_pixmap is from
src/lib/x-kit/widget/theme/gadget-to-pixmap.pkg package m2d = mode_to_drawpane; # mode_to_drawpane is from
src/lib/x-kit/widget/edit/mode-to-drawpane.pkg package idm = id_map; # id_map is from
src/lib/src/id-map.pkg package im = int_red_black_map; # int_red_black_map is from
src/lib/src/int-red-black-map.pkg# package is = int_red_black_set; # int_red_black_set is from
src/lib/src/int-red-black-set.pkg package sm = string_map; # string_map is from
src/lib/src/string-map.pkg package r8 = rgb8; # rgb8 is from
src/lib/x-kit/xclient/src/color/rgb8.pkg package r64 = rgb; # rgb is from
src/lib/x-kit/xclient/src/color/rgb.pkg package g2d = geometry2d; # geometry2d is from
src/lib/std/2d/geometry2d.pkg package g2j = geometry2d_junk; # geometry2d_junk is from
src/lib/std/2d/geometry2d-junk.pkg package e2g = millboss_to_guiboss; # millboss_to_guiboss is from
src/lib/x-kit/widget/edit/millboss-to-guiboss.pkg package gtj = guiboss_types_junk; # guiboss_types_junk is from
src/lib/x-kit/widget/gui/guiboss-types-junk.pkg package frm = frame; # frame is from
src/lib/x-kit/widget/leaf/frame.pkg package sl = screenline; # screenline is from
src/lib/x-kit/widget/edit/screenline.pkg package p2l = textpane_to_screenline; # textpane_to_screenline is from
src/lib/x-kit/widget/edit/textpane-to-screenline.pkg package wt = widget_theme; # widget_theme is from
src/lib/x-kit/widget/theme/widget/widget-theme.pkg # compiler is from
src/lib/core/compiler/compiler.pkg package cs = compiler::compiler_state; # compiler_state is from
src/lib/compiler/toplevel/interact/compiler-state.pkg package ds = compiler::deep_syntax; # deep_syntax is from
src/lib/compiler/front/typer-stuff/deep-syntax/deep-syntax.pkg package pcs = compiler::per_compile_stuff; # per_compile_stuff is from
src/lib/compiler/front/typer-stuff/main/per-compile-stuff.pkg package raw = compiler::raw_syntax; # raw_syntax is from
src/lib/compiler/front/parser/raw-syntax/raw-syntax.pkg# package pcs = per_compile_stuff; #
package em = eval_mill; # eval_mill is from
src/lib/x-kit/widget/edit/eval-mill.pkg package mt = millboss_types; # millboss_types is from
src/lib/x-kit/widget/edit/millboss-types.pkg package fm = fundamental_mode; # fundamental_mode is from
src/lib/x-kit/widget/edit/fundamental-mode.pkg package mm = minimill_mode; # minimill_mode is from
src/lib/x-kit/widget/edit/minimill-mode.pkg# package que = queue; # queue is from
src/lib/src/queue.pkg package nl = red_black_numbered_list; # red_black_numbered_list is from
src/lib/src/red-black-numbered-list.pkg package ml = makelib; # makelib is from
src/lib/core/makelib/makelib.pkg package ci = compile_imp; # compile_imp is from
src/lib/x-kit/widget/edit/compile-imp.pkg package psx = posixlib; # posixlib is from
src/lib/std/src/psx/posixlib.pkg tracefile = "widget-unit-test.trace.log";
nb = log::note_on_stderr; # log is from
src/lib/std/src/log.pkg# Temporary test code:
stdout_redirect = psx::stdout_redirect;
stderr_redirect = psx::stderr_redirect;
Dummy1 = ci::Compile_Option; # XXX SUCKO FIXME temporary hack to ensure ci compiles during early development.
herein
package eval_mode { #
#
exception EVAL_MODE__STATE; # Our per-pane persistent state (currently none).
# Note that our eval_mill half DOES have private state -- see Eval_Mill_State in
src/lib/x-kit/widget/edit/eval-mill.pkg # Wee access that via the editfn 'mill_extension_state' field -- see below.
fun input_done (arg: mt::Editfn_In) # We bind this to RET to signal when eval-buffer code entry is complete.
: mt::Editfn_Out
=
{ arg -> { args: List( mt::Prompted_Arg ), # Args read interactively from user per our __editfn.args spec.
textlines: mt::Textlines,
point: g2d::Point, # As in Point_And_Mark.
mark: Null_Or(g2d::Point), #
lastmark: Null_Or(g2d::Point), #
screen_origin: g2d::Point, # Origin of pane-visible text relative to textmill contents: (0,0) means we're showing top of buffer at top of textpane.
visible_lines: Int, # Number of lines of text visible in pane.
readonly: Bool, # TRUE iff contents of textmill are currently marked as read-only.
keystring: String, # User keystroke that invoked this editfn.
numeric_prefix: Null_Or( Int ), # ^U "Universal numeric prefix" value for this editfn if supplied by user, else NULL.
edit_history: mt::Edit_History, # Recent visible states of textmill, to support undo functionality.
pane_tag: Int, # Tag of pane for which this editfn is being invoked. This is a small int for human/GUI use.
pane_id: Id, # Id of pane for which this editfn is being invoked.
mill_id: Id, # Id of mill for which this editfn is being invoked.
to: Replyqueue, # The name makes foo::pass_something(imp) to {. ... } syntax read well.
widget_to_guiboss: gt::Widget_To_Guiboss, #
mill_to_millboss: mt::Mill_To_Millboss,
#
mainmill_modestate: mt::Panemode_State, # Any persistent per-mode state (e.g., private state for fundamental-mode.pkg) for main mill is available via this.
minimill_modestate: mt::Panemode_State, # Any persistent per-mode state (e.g., private state for minimill-mode.pkg) for mini mill is available via this.
#
mill_extension_state: Crypt,
textpane_to_textmill: mt::Textpane_To_Textmill, # NB: We're running in textmill's microthread to guarantee atomicity, so invoking blocking textpane_to_textmill.* fns is likely to deadlock.
mode_to_drawpane: Null_Or( m2d::Mode_To_Drawpane ), # This will be non-NULL iff we specified a non-NULL draw_*_fn in our mt::PANEMODE value at bottom of file (which we do not do in this package).
valid_completions: Null_Or( String -> List(String) ) # If this is non-NULL then user is entering a commandname or filename or millname(=buffername) on the modeline, and given fn returns all valid completions of string-entered-so-far.
};
# nb {. sprintf "input_done/AAA -- eval-mode.pkg"; };
eval_mill_state
=
em::decrypt__eval_mill_state mill_extension_state;
# nb {. sprintf "input_done/BBB -- eval-mode.pkg"; };
eval_mill_state # Much of the following logic is adapted from read_eval_print_from_user() in
src/lib/compiler/toplevel/interact/read-eval-print-loop-g.pkg -> # Putting it here allows customization of the logic without having to frig with
src/lib/compiler/toplevel/interact/read-eval-print-loop-g.pkg { compiler_state_stack: Ref ((cs::Compiler_State, List(cs::Compiler_State)))
};
(pp::make_standard_prettyprinter_into_buffer [])
->
{ pp, get_buffer_contents_and_clear_buffer };
exception END_OF_FILE;
fun eval_string'' (sourcecode_info: sci::Sourcecode_Info)
=
{ parse_string_to_raw_declarations = widget_to_guiboss.g.app_to_compileimp.parse_string_to_raw_declarations;
compile_raw_declaration_to_package_closure = widget_to_guiboss.g.app_to_compileimp.compile_raw_declaration_to_package_closure;
link_and_run_package_closure = widget_to_guiboss.g.app_to_compileimp.link_and_run_package_closure;
options = [ cs::COMPILER_VERBOSITY pcs::print_expression_value ] # Print only value of expression, not its type nor any of the intermediate code representations.
: List( cs::Compile_And_Eval_String_Option );
declarations
=
parse_string_to_raw_declarations { sourcecode_info, pp };
apply do_declaration declarations
where
fun do_declaration (declaration: raw::Declaration)
=
case (compile_raw_declaration_to_package_closure
{
declaration,
sourcecode_info,
pp,
compiler_state_stack => *compiler_state_stack,
options
}
)
#
THE arg => { compiler_state_stack
:=
link_and_run_package_closure
#
{ sourcecode_info, pp }
#
arg;
# NB: There's a potential problem here in that I believe output is currently only inserted in the
# buffer once execution is complete. If execution is lengthy or indefinite, this will be a
# problem. For now I'm only intending to use this facility for quickly executing expressions
# so I'm blowing this off for now. -- 2015-09-27 CrT XXX SUCKO FIXME
};
NULL => ();
esac;
end;
};
fun eval_string' stream
=
{ error_consumer
=
{
consumer => \\ (s: String) = {
pp.lit s;
},
flush => \\ () = (),
close => \\ () = ()
};
source = sci::make_sourcecode_info
{
file_name => "*eval*", # "filename"
line_num => 1,
source_stream => stream,
error_consumer,
is_interactive => FALSE # FALSE suppresses attempts to print interactive prompts -- see
src/lib/compiler/front/parser/main/mythryl-parser-guts.pkg };
eval_string'' source
except
exception'
=
{ sci::close_source source;
#
case exception'
#
END_OF_FILE => ();
_ => raise exception exception';
esac;
};
};
fun eval_string (code: String)
=
safely::do
{
open_it => {. fil::open_string code; },
close_it => fil::close_input,
cleanup => \\ _ = ()
}
eval_string';
string_to_eval
=
case mark
#
THE mark => tlj::get_selection_as_string { mark, point, textlines };
NULL => { line = mt::findline (textlines, point.row);
#
line = if (string::is_prefix "eval: " line) string::extract (line, 6, NULL);
else line;
fi;
line;
};
esac;
# nb {. sprintf "input_done/CCC string_to_eval s='%s' -- eval-mode.pkg" string_to_eval; };
eval_string string_to_eval;
pp::flush_prettyprinter pp; # Next probably makes this redundant.
pp::close_prettyprinter pp; # Flush text from internal prettyprint datastructures into prettyprint's output stream/buffer.
output = get_buffer_contents_and_clear_buffer (); # Get contents of prettyprint's output stream/buffer.
# nb {. sprintf "input_done/EEE string::length_in_bytes(output)=%d -- eval-mode.pkg" (string::length_in_bytes output); };
# nb {. sprintf "input_done/FFF output=<<<%s>>> -- eval-mode.pkg" output; };
# nb {. sprintf "input_done/GGG string::length_in_bytes(output)=%d -- eval-mode.pkg" (string::length_in_bytes output); };
textlines = tlj::append_lines (textlines, [ output ]);
textlines = tlj::append_lines (textlines, [ "\n", "eval: \n" ]);
point = tlj::end_of_buffer_point textlines;
# nb {. sprintf "input_done/ZZZ -- eval-mode.pkg"; };
WORK [ mt::TEXTLINES textlines,
mt::POINT point
];
};
input_done__editfn
=
mt::EDITFN (
mt::PLAIN_EDITFN
{
name => "input_done",
doc => "Interactive entry of string in minimill is complete -- harvest the string and reset to display modeline instead of minimill.",
args => [],
editfn => input_done
}
); my _ =
mt::note_editfn input_done__editfn;
fun eval (arg: mt::Editfn_In) # Interactive user command to start up an eval-mode pane onto an eval-mill -- an interactive facility supporting interactive evaluation of Mythryl.
: mt::Editfn_Out
=
{ arg -> { args: List( mt::Prompted_Arg ), # Args read interactively from user per our __editfn.args spec.
textlines: mt::Textlines,
point: g2d::Point, # As in Point_And_Mark.
mark: Null_Or(g2d::Point), #
lastmark: Null_Or(g2d::Point), #
screen_origin: g2d::Point, # Origin of pane-visible text relative to textmill contents: (0,0) means we're showing top of buffer at top of textpane.
visible_lines: Int, # Number of lines of text visible in pane.
readonly: Bool, # TRUE iff contents of textmill are currently marked as read-only.
keystring: String, # User keystroke that invoked this editfn.
numeric_prefix: Null_Or( Int ), # ^U "Universal numeric prefix" value for this editfn if supplied by user, else NULL.
edit_history: mt::Edit_History, # Recent visible states of textmill, to support undo functionality.
pane_tag: Int, # Tag of pane for which this editfn is being invoked. This is a small int for human/GUI use.
pane_id: Id, # Id of pane for which this editfn is being invoked.
mill_id: Id, # Id of mill for which this editfn is being invoked.
to: Replyqueue, # The name makes foo::pass_something(imp) to {. ... } syntax read well.
widget_to_guiboss: gt::Widget_To_Guiboss, #
mill_to_millboss: mt::Mill_To_Millboss,
#
mainmill_modestate: mt::Panemode_State, # Any persistent per-mode state (e.g., private state for fundamental-mode.pkg) for main mill is available via this.
minimill_modestate: mt::Panemode_State, # Any persistent per-mode state (e.g., private state for minimill-mode.pkg) for mini mill is available via this.
#
mill_extension_state: Crypt,
textpane_to_textmill: mt::Textpane_To_Textmill, # NB: We're running in textmill's microthread to guarantee atomicity, so invoking blocking textpane_to_textmill.* fns is likely to deadlock.
mode_to_drawpane: Null_Or( m2d::Mode_To_Drawpane ), # This will be non-NULL iff we specified a non-NULL draw_*_fn in our mt::PANEMODE value at bottom of file (which we do not do in this package).
valid_completions: Null_Or( String -> List(String) ) # If this is non-NULL then user is entering a commandname or filename or millname(=buffername) on the modeline, and given fn returns all valid completions of string-entered-so-far.
};
# nb {. sprintf "eval/AAA --eval-mode.pkg"; };
# eval_mill_state # DO NOT DO THIS!
# = # 'eval' is run from an arbitrary pane in order to start up an eval mill+pane, so it is most unlikely that 'mill_extension_state' here will be an eval-mill state.
# em::decrypt__eval_mill_state mill_extension_state; # -- Voice Of Experience
# nb {. sprintf "eval/BBB --eval-mode.pkg"; };
mainmill_modestate.mode
->
mt::PANEMODE pm;
mill_to_millboss #
-> #
mt::MILL_TO_MILLBOSS m2m;
textpane_to_textmill'
=
m2m.get_or_make_textmill # It should be OK if millboss-imp finds a mill of an unexpected textmill_extension here
# # because we're going to construct the pane for it via textpane_to_textmill.app_to_mill.make_pane_guiplan().
{ name => "*eval*",
#
textmill_options => [ mt::TEXTMILL_EXTENSION em::eval_mill
]
}
: mt::Textpane_To_Textmill
;
textpane_to_textmill'
->
mt::TEXTPANE_TO_TEXTMILL t2t;
t2t.app_to_mill
->
mt::APP_TO_MILL a2m;
t2t.set_lines [ "eval: \n" ];
a2m.pass_pane_guiplan to {.
#
pane_guiplan = #guiplan;
do_while_not {. # Repeat guipith edit until it takes. This is needed because other concurrent microthreads may be
# # attempting overlapping guipith edits with us. This avoids deadlock at a (tiny) risk of livelock.
get_guipiths = widget_to_guiboss.g.get_guipiths;
install_updated_guipiths = widget_to_guiboss.g.install_updated_guipiths;
(get_guipiths ())
->
(gui_version, guipiths)
#
: (Int, idm::Map( gt::Xi_Hostwindow_Info ))
;
guipiths = gtj::guipith_map (guipiths, options)
where
fun do_widget (w: gt::Xi_Widget_Type): gt::Xi_Widget_Type
=
case w
#
gt::XI_FRAME
{ id: Id,
frame_widget: gt::Xi_Widget_Type, # Widget which will draw the frame surround.
widget: gt::Xi_Widget_Type # Widget-tree to draw surrounded by frame.
}
=>
case frame_widget
#
gt::XI_WIDGET
{
widget_id: Id,
widget_layout_hint: gt::Widget_Layout_Hint,
doc: String # Debugging support: Allow XI_WIDGETs to be distinguishable for debug-display purposes.
}
=>
if (not (same_id (widget_id, pane_id)))
#
w;
else
gt::XI_GUIPLAN pane_guiplan; # Replace current pane with new one displaying new mill.
fi; # The a2m.make_pane_guiplan here is a wrapped version of the make_pane_guiplan() in this file.
_ => w;
esac;
_ => w;
esac;
options = [ gtj::XI_WIDGET_TYPE_MAP_FN do_widget ]
#
: List( gtj::Guipith_Map_Option )
;
end;
install_updated_guipiths # If this returns FALSE we'll loop and retry.
#
(gui_version, guipiths);
};
}; # do_while_not
WORK [
];
};
eval__editfn
=
mt::EDITFN (
mt::PLAIN_EDITFN
{
name => "eval",
doc => "Open an eval-mode pane onto an eval-mill instance.",
args => [],
editfn => eval
}
); my _ =
mt::note_editfn eval__editfn;
# my _ =
# nb {. sprintf "eval__editfn registered --eval-mode.pkg"; };
eval_mode_keymap
=
keymap
where
keymap = mt::empty_keymap;
#
keymap = mt::add_editfn_to_keymap (keymap, [ "RET" ], input_done__editfn );
end;
stipulate
# # Initialize state for the eval-mode part of a textpane at startup.
fun initialize_panemode_state # Our canonical call is from textpane::startup_fn(). # textpane is from
src/lib/x-kit/widget/edit/textpane.pkg ( # To maintain system-global state for mode use the guiboss_types::Gadget_To_Guiboss fns note_global, find_global, drop_global.
panemode: mt::Panemode, # This will be eval_mode (below).
panemode_state: mt::Panemode_State, #
textmill_extension: Null_Or( mt::Textmill_Extension ), #
panemode_initialization_options: List( mt::Panemode_Initialization_Option ) #
)
: ( mt::Panemode_State,
Null_Or( mt::Textmill_Extension ),
List( mt::Panemode_Initialization_Option )
)
=
{ val = { id => issue_unique_id (), # Construct our state.
type => "eval_mode::EVAL_MODE__STATE",
info => "State for eval-mode.pkg fns",
data => EVAL_MODE__STATE
};
key = val.type; # Enter our state into given mt::Panemode_State.
# #
panemode_state #
= #
{ mode => panemode_state.mode, #
data => sm::set (panemode_state.data, key, val) #
}; #
panemode -> mt::PANEMODE mm; # Let our parent panemodes also initialize.
#
panemode_initialization_options
=
panemode_initialization_options
@
[ mt::INITIAL_POINT { row => 0, col => 6 } # Put cursor at end of "eval: " prompt.
];
case mm.parent
#
THE (parent as mt::PANEMODE p) => p.initialize_panemode_state (parent, panemode_state, textmill_extension, panemode_initialization_options);
NULL => (panemode_state, textmill_extension, panemode_initialization_options);
esac;
};
fun finalize_state
(
panemode: mt::Panemode, # This will be eval_mode (below).
panemode_state: mt::Panemode_State
)
: Void
=
{ panemode -> mt::PANEMODE mm; # Let our parent panemodes also finalize.
#
case mm.parent
#
THE (parent as mt::PANEMODE p) => p.finalize_state (parent, panemode_state);
NULL => ( );
esac;
};
herein
eval_mode
=
mt::PANEMODE
{
id => issue_unique_id (),
name => "Eval",
doc => "Interactive Mythryl evaluation.",
keymap => REF eval_mode_keymap,
parent => THE fm::fundamental_mode,
self_insert_command => fm::self_insert_command__editfn,
initialize_panemode_state,
finalize_state,
drawpane_startup_fn => NULL,
drawpane_shutdown_fn => NULL,
drawpane_initialize_gadget_fn => NULL,
drawpane_redraw_request_fn => NULL,
drawpane_mouse_click_fn => NULL,
drawpane_mouse_drag_fn => NULL,
drawpane_mouse_transit_fn => NULL
};
end;
fun make_pane_guiplan # Synthesize a pane to display textmill's state. We get invoked by above gt::XI_GUIPLAN (make_pane_guiplan ()).
{ # At the moment this is (nearly) a clone of make_textpane::make_pane_guiplan(); if it doesn't diverge we should probably just generalize that fn.
textpane_to_textmill: mt::Textpane_To_Textmill, #
filepath: Null_Or( String ), # make_pane_guiplan should select the pane mode to use based on the filename, but we do not yet do this. XXX SUCKO FIXME.
textpane_hint: Crypt
}
: gt::Gp_Widget_Type
=
{
minipanemode = mm::minimill_mode;
mainpanemode = eval_mode;
screenlines_mark = issue_unique_id ();
textpane_id = issue_unique_id ();
textmill_spec = mt::OLD_TEXTMILL_BY_PORT textpane_to_textmill;
gt::FRAME
( [ gt::FRAME_WIDGET (textpane::with { textpane_id,
screenlines_mark,
textmill_spec,
minipanemode,
mainpanemode,
options => [ ]
}
)
],
gt::COL
[
gt::MARK'
( screenlines_mark,
"Screenlines",
gt::COL
[
screenline::with
{
paneline => 0,
textpane_id,
options => [ sl::DOC "Screenline 1",
sl::PIXELS_HIGH_MIN 0,
sl::STATE { cursor_at => p2l::NO_CURSOR,
selected => NULL,
text => "I am a screenline",
prompt => "",
screencol0 => 0,
background => rgb::white
}
]
}
]
),
gt::FRAME
( [ gt::FRAME_WIDGET (frame::with [ frm::FRAME_RELIEF wt::RAISED ]) ],
#
screenline::with
{
paneline => -1,
textpane_id,
options => [ sl::DOC "Modeline (Screenline -1)",
sl::PIXELS_HIGH_MIN 16,
sl::PIXELS_HIGH_CUT 0.0,
#
sl::STATE { cursor_at => p2l::NO_CURSOR,
selected => NULL,
text => "Modeline (Screenline -1)",
prompt => "",
screencol0 => 0,
background => rgb::white
}
]
}
)
]
);
};
my _ =
em::make_pane_guiplan__hack
:=
make_pane_guiplan;
};
end;