ACC SHELL
% A simple vi-emulation for SLrline
require ("rline/complete");
require ("rline/editfuns");
private variable Is_Command_Mode = 0;
private variable Last_Command = &rline_beep;
private define vi_enter_command_mode ()
{
Is_Command_Mode = 1;
}
private define vi_enter_insert_mode ()
{
Is_Command_Mode = 0;
}
private define self_insert_unless_command_mode ()
{
Last_Command = &rline_beep;
if (Is_Command_Mode)
return 0;
rline_call ("self_insert");
return 1;
}
private define vi_insert_mode ()
{
if (self_insert_unless_command_mode ())
return;
vi_enter_insert_mode ();
}
private define vi_append_mode ()
{
if (self_insert_unless_command_mode ())
return;
rline_call("right");
vi_enter_insert_mode ();
}
private define vi_delete_line ()
{
if (self_insert_unless_command_mode ())
return;
rline_delete_line ();
}
private define vi_left ();
private define vi_left ()
{
if (self_insert_unless_command_mode ())
return;
Last_Command = &vi_left;
rline_call ("left");
}
private define vi_right ();
private define vi_right ()
{
if (self_insert_unless_command_mode ())
return;
Last_Command = &vi_right;
rline_call ("right");
}
private define vi_up ();
private define vi_up ()
{
if (self_insert_unless_command_mode ())
return;
Last_Command = &vi_up;
rline_call ("up");
}
private define vi_down ();
private define vi_down ()
{
if (self_insert_unless_command_mode ())
return;
Last_Command = &vi_down;
rline_call ("down");
}
private define vi_bol ();
private define vi_bol ()
{
if (self_insert_unless_command_mode ())
return;
Last_Command = &vi_bol;
rline_bol ();
}
private define vi_eol ();
private define vi_eol ()
{
if (self_insert_unless_command_mode ())
return;
Last_Command = &vi_eol;
rline_eol ();
rline_left ();
}
private define vi_del ();
private define vi_del ()
{
if (self_insert_unless_command_mode ())
return;
Last_Command = &vi_del;
if (rline_eolp ())
rline_bdel ();
else
rline_del (1);
}
private define vi_replace_char ()
{
if (self_insert_unless_command_mode ())
return;
rline_del (1);
rline_ins (char (-rline_getkey ()));
}
private define vi_bskip_word ();
private define vi_bskip_word ()
{
if (self_insert_unless_command_mode ())
return;
Last_Command = &vi_bskip_word;
rline_bskip_word ();
}
private define vi_skip_word ();
private define vi_skip_word ()
{
if (self_insert_unless_command_mode ())
return;
Last_Command = &vi_skip_word;
rline_skip_word ();
}
private define vi_self_insert ()
{
if (self_insert_unless_command_mode ())
return;
rline_beep ();
}
private define vi_backspace ();
private define vi_backspace ()
{
if (Is_Command_Mode)
{
rline_beep ();
return;
}
Last_Command = &vi_backspace;
rline_bdel ();
}
private define vi_enter ()
{
vi_enter_insert_mode ();
rline_call ("enter");
}
private define vi_repeat_last_command ()
{
(@Last_Command)();
}
private variable Command_Map = Ref_Type[256];
private define vi_escape ()
{
vi_enter_command_mode ();
if (0 == rline_input_pending (1))
{
vi_left ();
return;
}
variable ch = rline_getkey ();
if ((ch == '[') || (ch == 'O'))
{
switch (rline_getkey ())
{ case 'A': vi_up (); return; }
{ case 'B': vi_down (); return; }
{ case 'C': vi_right (); return; }
{ case 'D': vi_left (); return; }
while (rline_input_pending (1))
() = rline_getkey ();
return;
}
if (Command_Map[ch] != NULL)
(@Command_Map[ch])();
}
foreach ([32:255])
{
$1 = ();
rline_setkey (&vi_self_insert, char(-$1));
}
rline_unsetkey ("\e");
rline_setkey (&vi_escape, "\e");
private define set_command_key (ch, f)
{
Command_Map[ch] = f;
rline_setkey (f, char(ch));
}
set_command_key ('\x08', &vi_backspace);
set_command_key ('\x7F', &vi_backspace);
set_command_key ('\r', &vi_enter);
set_command_key ('.', &vi_repeat_last_command);
set_command_key ('a', &vi_append_mode);
set_command_key ('i', &vi_insert_mode);
set_command_key ('d', &vi_delete_line);
set_command_key ('h', &vi_left);
set_command_key ('l', &vi_right);
set_command_key ('k', &vi_up);
set_command_key ('j', &vi_down);
set_command_key ('^', &vi_bol);
set_command_key ('$', &vi_eol);
set_command_key ('r', &vi_replace_char);
set_command_key ('x', &vi_del);
set_command_key ('b', &vi_bskip_word);
set_command_key ('w', &vi_skip_word);
ACC SHELL 2018