parent $editors
object $generic_editor
var $root child_index 0
var $root owners [$generic_editor]
var $root owned [$generic_editor]
var $root fertile 0
var $has_commands commands [["@abort|abort", 'abort_cmd], ["quit|@quit", 'quit_cmd], ["list|nlist *", 'list_cmd], ["ins?ert *", 'insert_cmd], ["del?ete *", 'del_line_cmd], ["join *", 'join_cmd], ["enter", 'enter_cmd], ["help", 'help_screen]]
var $has_commands shortcuts [["\"*", 'add_line_cmd, [1]], ["s/*/*", 'sub_cmd, ["", 1, 2]], ["fill * @*", 'fill_cmd, ["", 1, 2]], ["fill *", 'fill_cmd, ["", 1, ""]]]
var $command_aliases command_aliases []
var $root inited 1
var $generic_editor pass_through 0
var $root manager $generic_editor
var $root writable [$generic_editor]
var $root readable ['parameters, 'methods, 'code]
var $root dbref 'generic_editor
var $old_command_environment verb_cache #[]
var $old_command_environment command_cache [["@abort|abort", 'abort_cmd], ["quit|@quit", 'quit_cmd], ["list|nlist *", 'list_cmd], ["ins?ert *", 'insert_cmd], ["del?ete *", 'del_line_cmd], ["join *", 'join_cmd], ["enter", 'enter_cmd], ["help", 'help_screen]]
var $old_command_environment shortcuts_cache [["\"*", 'add_line_cmd, [1]], ["s/*/*", 'sub_cmd, ["", 1, 2]], ["fill * @*", 'fill_cmd, ["", 1, 2]], ["fill *", 'fill_cmd, ["", 1, ""]]]
method start_editing
arg what;
// called by user.edit_cmd
sender().tell([("The selected editor, " + (.namef('id))) + "must define .start_editing()."]);
return 0;
.
method parse_command
arg str;
var cmd, loc, result, i, j, templates, template, word, fields, obj, verb_info, subbed_str;
// This method works like $user.parse_command
// The difference is that the permissions have changed, and after checking aliases and
// commands, and nothing was found, resorting to sender().match_command() is an option.
if (((sender().editor()) != this()) || (caller() != $user_input))
throw(~perm, "Invalid access to parse_command.");
// remove leading spaces, abort on blank line
subbed_str = str;
while (subbed_str && ((subbed_str[1]) == " "))
subbed_str = substr(subbed_str, 2);
if (!subbed_str)
return sender().editing();
// sub the string through command aliases first
subbed_str = .match_command_aliases(subbed_str);
// Check commands on this.
cmd = .match_command(subbed_str);
if (cmd)
return .(cmd[1])(sender().editing(), @cmd[2]);
// if we're passing unknowns on to user.parse_command()...
if (pass_through) {
sender().tell("(Still editing.)");
sender().run_with_users_perms(sender(), 'parse_command, str);
} else {
sender().tell("I don't understand that.");
}
return sender().editing();
.
method abort_cmd
arg editing, com;
.perms(sender(), 'parser);
if (type(editing) == 'dict) {
if (editing['changed])
(editing['user]).tell("Threw away changes and cleared editor variables.");
else
(editing['user]).tell("No changes to throw away. Cleared editor variables.");
} else {
(| $admin_2.tell(((.namef('id)) + ": editing corrupeted, == ") + ($data.unparse(editing))) |);
}
return 0;
.
method quit_cmd
arg editing, com;
.perms(sender(), 'parser);
if (editing['changed]) {
(editing['user]).tell("Changes have been made. Save first, or abort to cancel.");
return editing;
} else {
(editing['user]).tell("Quiting editor.");
return 0;
}
.
method adjust
arg text, [how];
var line;
for line in [1 .. listlen(text)] {
if ('spaces in how)
text = replace(text, line, " " + (text[line]));
if ('numbers in how)
text = replace(text, line, (($string.right(tostr(line), 3)) + " :") + (text[line]));
}
return text;
.
method list_cmd
arg editing, com, rest;
var line, text;
.perms(sender(), 'parser);
if (com == "list") {
(editing['user]).tell(editing['text]);
} else {
text = $generic_editor.adjust(editing['text], 'numbers);
for line in [1 .. listlen(text)] {
if (line == ((editing['cur_line]) - 1))
(editing['user]).tell((strsub($string.right(tostr(line), 3), " ", "_") + "_:") + ((editing['text])[line]));
else if (line == (editing['cur_line]))
(editing['user]).tell((strsub($string.right(tostr(line), 3), " ", "^") + "^:") + ((editing['text])[line]));
else
(editing['user]).tell(text[line]);
}
}
return editing;
.
method insert_cmd
arg editing, com, [args];
var line, text;
// re-position and (eventually/optionally) add text
.perms(sender(), 'parser);
line = [@args, ""][1];
text = [@args, "", ""][2];
if (!line) {
(editing['user]).tell(["Syntax: ins*ert line [text]", "! You must supply a line number."]);
return editing;
}
if (line != "$")
line = toint(line);
else
line = listlen(editing['text]) + 1;
if (!line) {
(editing['user]).tell(["Syntax: ins*ert line [text]", "! You must supply a line number greater than or equal to 1."]);
return editing;
}
if (line > (listlen(editing['text]) + 1))
line = listlen(editing['text]) + 1;
editing = editing.replace('cur_line, line);
._show_line(editing);
return editing;
.
method _show_line
arg editing;
var line;
line = (editing['cur_line]) - 1;
if (line)
(editing['user]).tell((strsub($string.right(tostr(line), 3), " ", "_") + "_:") + ((editing['text])[line]));
else
(editing['user]).tell("____");
line = line + 1;
if (line <= listlen(editing['text]))
(editing['user]).tell((strsub($string.right(tostr(line), 3), " ", "^") + "^:") + ((editing['text])[line]));
else
(editing['user]).tell("^^^^");
return editing;
.
method insert_line
arg editing, line;
// insert line at editing['cur_line]
// assumes editing['cur_line] is within 1 .. listlen(editing['text])
.perms(sender(), 'this);
editing = editing.replace('text, insert(editing['text], editing['cur_line], line));
editing = editing.replace('cur_line, (editing['cur_line]) + 1);
editing = editing.replace('changed, 1);
return editing;
.
method add_line_cmd
arg editing, line;
// "*
.perms(sender(), 'parser);
editing = .insert_line(editing, line);
// ._show_line(editing);
(editing['user]).tell(("Added line " + tostr((editing['cur_line]) - 1)) + ".");
return editing;
.
method delete_line
arg editing;
// delete line at editing['cur_line]
// assumes editing['cur_line] is within 1 .. listlen(editing['text])
.perms(sender(), 'this);
editing = editing.replace('text, delete(editing['text], editing['cur_line]));
editing = editing.replace('changed, 1);
editing = editing.replace('cur_line, $list.min(editing['cur_line], listlen(editing['text])));
return editing;
.
method del_line_cmd
arg editing, com, line;
// del?ete line_num
.perms(sender(), 'parser);
line = toint(line) || (editing['cur_line]);
if (line <= (editing['cur_line])) {
editing = editing.replace('cur_line, line);
(editing['user]).tell(((("Removed line " + tostr(editing['cur_line])) + ": \"") + ((editing['text])[line])) + "\".");
editing = .delete_line(editing);
} else {
(editing['user]).tell("Line number out of range.");
}
//._show_line(editing);
return editing;
.
method sub_cmd
arg editing, com, was, is;
// s/from/to/
editing = editing.replace('text, replace(editing['text], (editing['cur_line]) - 1, strsub((editing['text])[(editing['cur_line]) - 1], was, is)));
._show_line(editing);
return editing;
.
method fill_cmd
arg editing, com, range, [col];
var start, current, stop, new_text, idx;
col = toint([@col, "75"][1]) || 75;
if ("-" in range) {
start = toint(range);
if (!start) {
(editing['user]).tell("Must supply a valid range, such as 10, 2-3, or 1-$.");
return editing;
}
range = substr(range, strlen(tostr(start)) + 2);
if ((!range) || (range == "$"))
stop = listlen(editing['text]);
else
stop = toint(range);
} else {
if (!range)
start = editing['cur_line];
else
start = toint(range);
if (!start) {
(editing['user]).tell("Must supply a valid range, such as 10, 2-3, or 1-$.");
return editing;
}
stop = start;
}
// actual change:
new_text = editing['text];
current = start;
while (current <= stop) {
if (strlen(new_text[current]) > col) {
idx = col;
while (idx && (((new_text[current])[idx]) != " "))
idx = idx - 1;
if (!idx) {
idx = col + 1;
while ((idx < strlen(new_text[current])) && (((new_text[current])[idx]) != " "))
idx = idx + 1;
if (idx == strlen(new_text[current]))
idx = col;
}
new_text = insert(new_text, current + 1, substr(new_text[current], idx + 1));
new_text = replace(new_text, current, substr(new_text[current], 1, idx));
stop = stop + 1;
}
current = current + 1;
}
editing = editing.replace('text, new_text);
editing = editing.replace('cur_line, stop + 1);
new_text = $generic_editor.adjust(editing['text], 'numbers);
for current in [start .. stop - 1]
(editing['user]).tell(new_text[current]);
._show_line(editing);
return editing;
.
method join_cmd
arg editing, com, range;
var start, stop, current, new_text;
new_text = editing['text];
start = toint(range);
range = substr(range, strlen(tostr(start)) + 2);
stop = toint(range);
if (range == "$")
stop = listlen(new_text);
if ((!start) || (!stop)) {
(editing['user]).tell("Syntax: join <range>");
(editing['user]).tell("! You must supply a range of lines to join, such as 3-4 or 1-$");
return editing;
}
stop = $list.min(stop, listlen(new_text));
// actual change:
while (start < stop) {
new_text = replace(new_text, start, (new_text[start]) + (new_text[start + 1]));
new_text = delete(new_text, start + 1);
stop = stop - 1;
}
editing = editing.replace('text, new_text);
editing = editing.replace('cur_line, stop + 1);
._show_line(editing);
return editing;
.
method enter_cmd
arg editing, com;
(editing['user]).read('done_entering, editing);
return editing;
.
method done_entering
arg text, editing;
if (sender() != (editing['user]))
throw(~perm, "Invalid access to done_entering.");
if (listlen(text)) {
if (listlen(text) > 1)
(editing['user]).tell(((("Added lines " + tostr(editing['cur_line])) + " .. ") + tostr(((editing['cur_line]) + listlen(text)) - 1)) + ".");
else
(editing['user]).tell(("Added line " + tostr(editing['cur_line])) + ".");
while (text) {
editing = editing.replace('text, insert(editing['text], text[1], editing['cur_line]));
editing = editing.replace('cur_line, (editing['cur_line]) + 1);
text = delete(test, 1);
}
}
.
method help_msg
var msg;
msg = [];
msg = msg + [" ins?ert * set line number"];
msg = msg + [" del?ete * delete line"];
msg = msg + [" \"* insert text"];
msg = msg + [" abort cancel changes and exit editor"];
msg = msg + [" quit exit if no changes made since last save"];
msg = msg + [" list|nlist list text without|with numbers"];
msg = msg + [" s/*/* str sub: replace first with second in current line."];
msg = msg + [" fill * [@*] wrap lines (@ col, def: 75)"];
msg = msg + [" join * concatonates a range of lines"];
return msg;
.
method help_screen
arg editing, com;
// l?ook
.perms(sender(), 'this);
(editing['user]).tell(.help_msg());
.