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()); .