/
LIB3/
LIB3/D/ADMIN/
LIB3/D/ADMIN/OBJ/
LIB3/D/ADMIN/ROOM/W/
LIB3/D/HOME/
LIB3/D/HOME/CITY/ARENA/
LIB3/D/HOME/CITY/ITEMS/
LIB3/D/HOME/CITY/POSTOFFI/
LIB3/DOC/
LIB3/GLOBAL/SPECIAL/
LIB3/GLOBAL/VIRTUAL/
LIB3/NET/
LIB3/NET/CONFIG/
LIB3/NET/DAEMON/CHARS/
LIB3/NET/GOPHER/
LIB3/NET/INHERIT/
LIB3/NET/OBJ/
LIB3/NET/SAVE/
LIB3/NET/VIRTUAL/
LIB3/OBJ/B_DAY/
LIB3/OBJ/HANDLERS/TERM_TYP/
LIB3/PLAYERS/B/
LIB3/PLAYERS/N/
LIB3/ROOM/
LIB3/SAVE/
LIB3/SAVE/BOARDS/
LIB3/SAVE/ENVIRON/
LIB3/SAVE/POST/
LIB3/STD/COMMANDS/SHADOWS/
LIB3/STD/CREATOR/
LIB3/STD/DOM/
LIB3/STD/EFFECTS/
LIB3/STD/EFFECTS/HEALING/
LIB3/STD/EFFECTS/OTHER/
LIB3/STD/EFFECTS/POISONS/
LIB3/STD/ENVIRON/
LIB3/STD/GUILDS/
LIB3/STD/LIQUIDS/
LIB3/STD/ROOM/
LIB3/STD/TRIGGER/SHADOW/
LIB3/W/
LIB3/W/BANNOR/
LIB3/W/NEWSTYLE/
/* This is a very quick and dirty line editor cooked up by */
/* [als] in half an hour on a not-so-stormy night of 10/12/91 */
/* It uses NO input_to's, so ALL commands are prefixed with the command word */
/* it was simply intended for those times when ed goes down the */
/* proverbial gurgler.  If you HAVE to use it, set up aliases :) */
/* commands: r file, w[file], >insert text, /search text, */
/* number goes to line number, +, -, d, N-> clears line editor */
/* Have fun, and win awards */
/* One other possible use for LE is for cute aliases */

static int line;
static string *cfile, cfile_name, last_search;

print_line()
{
   if (line > sizeof(cfile)) line = sizeof(cfile);
   if (!line) { write("No line.\n"); return; }
   write(extract("   ", 0, 3 - strlen(line + "")) + line + ":" + cfile[line-1] + "\n");
}

le(s)
{
   int j;

   if (!pointerp(cfile)) { cfile = ({ }); line = 0; }
   if (!s || s == "") { print_line(); return 1; }

   if (sscanf(s, "%d", j)) { line = j; print_line(); return 1; }
   switch (s[0]) {
   case 'd':
      if (!line) { notify_fail("Not on a line.\n"); return 0; }
      cfile = delete(cfile, line-1, 1);
      print_line();
      return 1;
   case 'N':
      cfile = ({ });
      line = 0;
      cfile_name = 0;
      write("Line editor cleared.\n");
      return 1;
   case '/':
      s = extract(s, 1);
      if (s == "") {
         s = last_search;
      }
      last_search = s;
      {
         int i, s1, s2;
         for (i = line+1; i<= sizeof(cfile); i++) {
            if (sscanf(cfile[i-1], "%s"+s+"%s", s1, s2)) { line = i; print_line(); return 1; }
         }
         write("Search failed.\n");
         return 1;
      }
   case '>':
      s = extract(s, 1);
      {
         string *tmp1, *tmp2;

         tmp1 = (line > 1) ? cfile[0..line-2] : ({ });
         tmp2 = (line <= sizeof(cfile)) ? cfile[line-1..sizeof(cfile)-1] : ({ });
         cfile = tmp1 + ({ s }) + tmp2;
      }
      line++;
      print_line();
      return 1;
   case 'r':
      {
         string sA, sB;
      
         sA = extract(s, 1);
         while (sA[0] == ' ') sA = extract(sA,1);
         sB = this_player()->get_path(sA);
         if (!sB) sB = sA;
         if (file_size(sB) < 0) { notify_fail("File doesn't exist.\n"); return 0; }
         sA = read_file(sB);
         cfile = explode(sA, "\n");
         line = 1;
      }
      write("Read file "  + sB + ": " + sizeof(cfile) + " lines.\n");
      cfile_name = sB;
      print_line();
      return 1;
   case '+':
      if (line < sizeof(cfile)) line++;
      print_line();
      return 1;
   case '-':
      if (line > 1) line --;
      print_line();
      return 1;
   case 'w':
      if (s == "w") {
         if (!cfile_name) { notify_fail("No file name.\n"); return 0; }
      } else {
         s = extract(s,1);
         while (s[0] == ' ') s = extract(s, 1);
         if (this_player()->get_path(s)) s = this_player()->get_path(s);
         cfile_name = s;
      }
      rm(cfile_name);
      write_file(cfile_name, implode(cfile, "\n"));
      write("Tried to write file " + cfile_name + ": " + sizeof(cfile) + " lines.\n");
      return 1;
   case 'z':
      {
         int q;

         q = 20;
         while (q-- && line <= sizeof(cfile)) { print_line(); line++; }
         line --;
      }
      return 1;
   }
}