OSDN Git Service

自動拾いエディタを大幅に改良。viタイプだったのを完全にやめて、ESCキーでメニューが出るVZ editorタイプにした。全てのキーワードがメニューに出るので、説明を読ま...
authormogami <mogami@0568b783-4c39-0410-ac80-bf13821ea2a2>
Tue, 16 Sep 2003 15:18:40 +0000 (15:18 +0000)
committermogami <mogami@0568b783-4c39-0410-ac80-bf13821ea2a2>
Tue, 16 Sep 2003 15:18:40 +0000 (15:18 +0000)
src/autopick.c
src/externs.h
src/util.c
src/variable.c

index 9fcf5ca..fad195a 100644 (file)
@@ -12,9 +12,8 @@
 
 #include "angband.h"
 
-#define MAX_LINELEN 1024
 
-static object_type autopick_last_destroyed_object;
+#define MAX_LINELEN 1024
 
 /*
  * Macros for Keywords
@@ -65,6 +64,9 @@ static object_type autopick_last_destroyed_object;
 #define FLG_BOOTS           47
 #define FLG_FAVORITE        48
 
+#define FLG_NOUN_BEGIN      FLG_ITEMS
+#define FLG_NOUN_END        FLG_FAVORITE
+
 #ifdef JP
 
 #define KEY_ALL "¤¹¤Ù¤Æ¤Î"
@@ -194,139 +196,6 @@ static object_type autopick_last_destroyed_object;
 
 
 /*
- * Reconstruct preference line from entry
- */
-cptr autopick_line_from_entry(autopick_type *entry)
-{
-       char buf[MAX_LINELEN];
-       char *ptr;
-       bool sepa_flag = TRUE;
-
-       *buf = '\0';
-       if (!(entry->action & DO_DISPLAY)) strcat(buf, "(");
-       if (entry->action & DO_QUERY_AUTOPICK) strcat(buf, ";");
-       if (entry->action & DO_AUTODESTROY) strcat(buf, "!");
-       if (entry->action & DONT_AUTOPICK) strcat(buf, "~");
-
-       ptr = buf;
-
-       if (IS_FLG(FLG_ALL)) ADD_KEY(KEY_ALL);
-       if (IS_FLG(FLG_COLLECTING)) ADD_KEY(KEY_COLLECTING);
-       if (IS_FLG(FLG_UNIDENTIFIED)) ADD_KEY(KEY_UNIDENTIFIED);
-       if (IS_FLG(FLG_IDENTIFIED)) ADD_KEY(KEY_IDENTIFIED);
-       if (IS_FLG(FLG_STAR_IDENTIFIED)) ADD_KEY(KEY_STAR_IDENTIFIED);
-       if (IS_FLG(FLG_UNAWARE)) ADD_KEY(KEY_UNAWARE);
-       if (IS_FLG(FLG_BOOSTED)) ADD_KEY(KEY_BOOSTED);
-
-       if (IS_FLG(FLG_MORE_THAN))
-       {
-               ADD_KEY(KEY_MORE_THAN);
-               strcat(ptr, format("%d", entry->dice));
-               ADD_KEY(KEY_DICE);
-       }
-
-       if (IS_FLG(FLG_MORE_BONUS))
-       {
-               ADD_KEY(KEY_MORE_BONUS);
-               strcat(ptr, format("%d", entry->bonus));
-               ADD_KEY(KEY_MORE_BONUS2);
-       }
-
-       if (IS_FLG(FLG_UNREADABLE)) ADD_KEY(KEY_UNREADABLE);
-       if (IS_FLG(FLG_REALM1)) ADD_KEY(KEY_REALM1);
-       if (IS_FLG(FLG_REALM2)) ADD_KEY(KEY_REALM2);
-       if (IS_FLG(FLG_FIRST)) ADD_KEY(KEY_FIRST);
-       if (IS_FLG(FLG_SECOND)) ADD_KEY(KEY_SECOND);
-       if (IS_FLG(FLG_THIRD)) ADD_KEY(KEY_THIRD);
-       if (IS_FLG(FLG_FOURTH)) ADD_KEY(KEY_FOURTH);
-       if (IS_FLG(FLG_WANTED)) ADD_KEY(KEY_WANTED);
-       if (IS_FLG(FLG_UNIQUE)) ADD_KEY(KEY_UNIQUE);
-       if (IS_FLG(FLG_HUMAN)) ADD_KEY(KEY_HUMAN);
-       if (IS_FLG(FLG_WORTHLESS)) ADD_KEY(KEY_WORTHLESS);
-       if (IS_FLG(FLG_NAMELESS)) ADD_KEY(KEY_NAMELESS);
-       if (IS_FLG(FLG_EGO)) ADD_KEY(KEY_EGO);
-
-       if (IS_FLG(FLG_ARTIFACT)) ADD_KEY(KEY_ARTIFACT);
-
-       if (IS_FLG(FLG_ITEMS)) ADD_KEY2(KEY_ITEMS);
-       else if (IS_FLG(FLG_WEAPONS)) ADD_KEY2(KEY_WEAPONS);
-       else if (IS_FLG(FLG_ARMORS)) ADD_KEY2(KEY_ARMORS);
-       else if (IS_FLG(FLG_MISSILES)) ADD_KEY2(KEY_MISSILES);
-       else if (IS_FLG(FLG_DEVICES)) ADD_KEY2(KEY_DEVICES);
-       else if (IS_FLG(FLG_LIGHTS)) ADD_KEY2(KEY_LIGHTS);
-       else if (IS_FLG(FLG_JUNKS)) ADD_KEY2(KEY_JUNKS);
-       else if (IS_FLG(FLG_SPELLBOOKS)) ADD_KEY2(KEY_SPELLBOOKS);
-       else if (IS_FLG(FLG_HAFTED)) ADD_KEY2(KEY_HAFTED);
-       else if (IS_FLG(FLG_SHIELDS)) ADD_KEY2(KEY_SHIELDS);
-       else if (IS_FLG(FLG_BOWS)) ADD_KEY2(KEY_BOWS);
-       else if (IS_FLG(FLG_RINGS)) ADD_KEY2(KEY_RINGS);
-       else if (IS_FLG(FLG_AMULETS)) ADD_KEY2(KEY_AMULETS);
-       else if (IS_FLG(FLG_SUITS)) ADD_KEY2(KEY_SUITS);
-       else if (IS_FLG(FLG_CLOAKS)) ADD_KEY2(KEY_CLOAKS);
-       else if (IS_FLG(FLG_HELMS)) ADD_KEY2(KEY_HELMS);
-       else if (IS_FLG(FLG_GLOVES)) ADD_KEY2(KEY_GLOVES);
-       else if (IS_FLG(FLG_BOOTS)) ADD_KEY2(KEY_BOOTS);
-       else if (IS_FLG(FLG_FAVORITE)) ADD_KEY2(KEY_FAVORITE);
-
-       /* You don't need sepalator after adjective */
-       /* 'artifact' is not true adjective */
-       else if (!IS_FLG(FLG_ARTIFACT))
-               sepa_flag = FALSE;
-
-       if (entry->name && entry->name[0])
-       {
-               int i, j = 0;
-
-               if (sepa_flag) strcat(buf, ":");
-
-               i = strlen(buf);
-               while (entry->name[j] && i < MAX_LINELEN - 2 - 1)
-               {
-#ifdef JP
-                       if (iskanji(entry->name[j]))
-                               buf[i++] = entry->name[j++];
-#endif
-                       buf[i++] = entry->name[j++];
-               }
-               buf[i] = '\0';
-       }
-
-       if (entry->insc)
-       {
-               int i, j = 0;
-               strcat(buf, "#");
-               i = strlen(buf);
-
-               while (entry->insc[j] && i < MAX_LINELEN - 2)
-               {
-#ifdef JP
-                       if (iskanji(entry->insc[j]))
-                               buf[i++] = entry->insc[j++];
-#endif
-                       buf[i++] = entry->insc[j++];
-               }
-               buf[i] = '\0';
-       }
-
-       return string_make(buf);
-}
-
-
-/*
- * Reconstruct preference line from entry and kill entry
- */
-static cptr autopick_line_from_entry_kill(autopick_type *entry)
-{
-       cptr ptr = autopick_line_from_entry(entry);
-
-       /* Free memory for original entry */
-       autopick_free_entry(entry);
-
-       return ptr;
-}
-
-
-/*
  * A function to create new entry
  */
 bool autopick_new_entry(autopick_type *entry, cptr str)
@@ -404,9 +273,11 @@ bool autopick_new_entry(autopick_type *entry, cptr str)
                buf[i] = c;
        }
        buf[i] = '\0';
-       
+
+#if 0  
        /* Skip empty line */
        if (*buf == 0) return FALSE;
+#endif
 
        ptr = prev_ptr = buf;
        old_ptr = NULL;
@@ -524,7 +395,13 @@ bool autopick_new_entry(autopick_type *entry, cptr str)
                ptr += 2;
 #endif
        else if (*ptr == '\0')
-               ; /* nothing to do */
+       {
+               /* There was no noun */
+               if (prev_flg == -1)
+
+               /* Add extra word "items" */
+               ADD_FLG_NOUN(FLG_ITEMS);
+       }
        else
        {
                /* Noun type? */
@@ -544,6 +421,7 @@ bool autopick_new_entry(autopick_type *entry, cptr str)
        return TRUE;
 }
 
+
 /*
  * A function to delete entry
  */
@@ -555,81 +433,277 @@ void autopick_free_entry(autopick_type *entry)
 
 
 /*
- * Favorite weapons
+ * Initialize auto-picker preference
  */
-static bool is_favorite(object_type *o_ptr, bool others_ok)
+void init_autopicker(void)
 {
-       /* Only weapons match */
-       switch(o_ptr->tval)
-       {
-       case TV_BOW: case TV_HAFTED: case TV_POLEARM:
-       case TV_SWORD: case TV_DIGGING:
-               break;
-       default: return FALSE;
-       }
-
-       /* Favorite weapons are varied depend on the class */
-       switch (p_ptr->pclass)
-       {
-       case CLASS_PRIEST:
-       {
-               u32b flgs[TR_FLAG_SIZE];
-               object_flags_known(o_ptr, flgs);
+       static const char easy_autopick_inscription[] = "(:=g";
+       autopick_type entry;
+       int i;
 
-               if (!have_flag(flgs, TR_BLESSED) && 
-                   !(o_ptr->tval == TV_HAFTED))
-                       return FALSE;
-               break;
-       }
+       /* Clear old entries */
+       for( i = 0; i < max_autopick; i++)
+               autopick_free_entry(&autopick_list[i]);
 
-       case CLASS_MONK:
-       case CLASS_FORCETRAINER:
-               /* Icky to wield? */
-               if (!(s_info[p_ptr->pclass].w_max[o_ptr->tval-TV_BOW][o_ptr->sval]))
-                       return FALSE;
-               break;
+       max_autopick = 0;
 
-       case CLASS_BEASTMASTER:
-       case CLASS_CAVALRY:
-       {
-               u32b flgs[TR_FLAG_SIZE];
-               object_flags_known(o_ptr, flgs);
+       /* There is always one entry "=g" */
+       autopick_new_entry(&entry, easy_autopick_inscription);
+       autopick_list[max_autopick++] = entry;
+}
 
-               /* Is it known to be suitable to using while riding? */
-               if (!(have_flag(flgs, TR_RIDING)))
-                       return FALSE;
 
-               break;
-       }
 
-       case CLASS_NINJA:
-               /* Icky to wield? */
-               if (s_info[p_ptr->pclass].w_max[o_ptr->tval-TV_BOW][o_ptr->sval] <= WEAPON_EXP_BEGINNER)
-                       return FALSE;
-               break;
+/*
+ *  Process line for auto picker/destroyer.
+ */
+errr process_pickpref_file_line(char *buf)
+{
+       autopick_type entry;
+       int i;
 
-       default:
-               /* Non-special class */
-               if (others_ok) return TRUE;
-               else return FALSE;
+       if (max_autopick == MAX_AUTOPICK)
+               return 1;
+       
+       /* Nuke illegal char */
+       for(i = 0; buf[i]; i++)
+       {
+#ifdef JP
+               if (iskanji(buf[i]))
+               {
+                       i++;
+                       continue;
+               }
+#endif
+               if (isspace(buf[i]) && buf[i] != ' ')
+                       break;
        }
+       buf[i] = 0;
+       
+       if (!autopick_new_entry(&entry, buf)) return 0;
 
-       return TRUE;
+       /* Already has the same entry? */ 
+       for(i = 0; i < max_autopick; i++)
+               if(!strcmp(entry.name, autopick_list[i].name)
+                  && entry.flag[0] == autopick_list[i].flag[0]
+                  && entry.flag[1] == autopick_list[i].flag[1]
+                  && entry.dice == autopick_list[i].dice
+                  && entry.bonus == autopick_list[i].bonus) return 0;
+
+       autopick_list[max_autopick++] = entry;
+       return 0;
 }
 
+
 /*
- * A function for Auto-picker/destroyer
- * Examine whether the object matches to the entry
+ * Reconstruct preference line from entry
  */
-static bool is_autopick_aux(object_type *o_ptr, autopick_type *entry, cptr o_name)
+cptr autopick_line_from_entry(autopick_type *entry)
 {
-       int j;
-       cptr ptr = entry->name;
+       char buf[MAX_LINELEN];
+       char *ptr;
+       bool sepa_flag = TRUE;
 
-       /*** Unidentified ***/
-       if (IS_FLG(FLG_UNIDENTIFIED)
-           && (object_known_p(o_ptr) || (o_ptr->ident & IDENT_SENSE)))
-               return FALSE;
+       *buf = '\0';
+       if (!(entry->action & DO_DISPLAY)) strcat(buf, "(");
+       if (entry->action & DO_QUERY_AUTOPICK) strcat(buf, ";");
+       if (entry->action & DO_AUTODESTROY) strcat(buf, "!");
+       if (entry->action & DONT_AUTOPICK) strcat(buf, "~");
+
+       ptr = buf;
+
+       if (IS_FLG(FLG_ALL)) ADD_KEY(KEY_ALL);
+       if (IS_FLG(FLG_COLLECTING)) ADD_KEY(KEY_COLLECTING);
+       if (IS_FLG(FLG_UNIDENTIFIED)) ADD_KEY(KEY_UNIDENTIFIED);
+       if (IS_FLG(FLG_IDENTIFIED)) ADD_KEY(KEY_IDENTIFIED);
+       if (IS_FLG(FLG_STAR_IDENTIFIED)) ADD_KEY(KEY_STAR_IDENTIFIED);
+       if (IS_FLG(FLG_UNAWARE)) ADD_KEY(KEY_UNAWARE);
+       if (IS_FLG(FLG_BOOSTED)) ADD_KEY(KEY_BOOSTED);
+
+       if (IS_FLG(FLG_MORE_THAN))
+       {
+               ADD_KEY(KEY_MORE_THAN);
+               strcat(ptr, format("%d", entry->dice));
+               ADD_KEY(KEY_DICE);
+       }
+
+       if (IS_FLG(FLG_MORE_BONUS))
+       {
+               ADD_KEY(KEY_MORE_BONUS);
+               strcat(ptr, format("%d", entry->bonus));
+               ADD_KEY(KEY_MORE_BONUS2);
+       }
+
+       if (IS_FLG(FLG_UNREADABLE)) ADD_KEY(KEY_UNREADABLE);
+       if (IS_FLG(FLG_REALM1)) ADD_KEY(KEY_REALM1);
+       if (IS_FLG(FLG_REALM2)) ADD_KEY(KEY_REALM2);
+       if (IS_FLG(FLG_FIRST)) ADD_KEY(KEY_FIRST);
+       if (IS_FLG(FLG_SECOND)) ADD_KEY(KEY_SECOND);
+       if (IS_FLG(FLG_THIRD)) ADD_KEY(KEY_THIRD);
+       if (IS_FLG(FLG_FOURTH)) ADD_KEY(KEY_FOURTH);
+       if (IS_FLG(FLG_WANTED)) ADD_KEY(KEY_WANTED);
+       if (IS_FLG(FLG_UNIQUE)) ADD_KEY(KEY_UNIQUE);
+       if (IS_FLG(FLG_HUMAN)) ADD_KEY(KEY_HUMAN);
+       if (IS_FLG(FLG_WORTHLESS)) ADD_KEY(KEY_WORTHLESS);
+       if (IS_FLG(FLG_NAMELESS)) ADD_KEY(KEY_NAMELESS);
+       if (IS_FLG(FLG_EGO)) ADD_KEY(KEY_EGO);
+
+       if (IS_FLG(FLG_ARTIFACT)) ADD_KEY(KEY_ARTIFACT);
+
+       if (IS_FLG(FLG_ITEMS)) ADD_KEY2(KEY_ITEMS);
+       else if (IS_FLG(FLG_WEAPONS)) ADD_KEY2(KEY_WEAPONS);
+       else if (IS_FLG(FLG_ARMORS)) ADD_KEY2(KEY_ARMORS);
+       else if (IS_FLG(FLG_MISSILES)) ADD_KEY2(KEY_MISSILES);
+       else if (IS_FLG(FLG_DEVICES)) ADD_KEY2(KEY_DEVICES);
+       else if (IS_FLG(FLG_LIGHTS)) ADD_KEY2(KEY_LIGHTS);
+       else if (IS_FLG(FLG_JUNKS)) ADD_KEY2(KEY_JUNKS);
+       else if (IS_FLG(FLG_SPELLBOOKS)) ADD_KEY2(KEY_SPELLBOOKS);
+       else if (IS_FLG(FLG_HAFTED)) ADD_KEY2(KEY_HAFTED);
+       else if (IS_FLG(FLG_SHIELDS)) ADD_KEY2(KEY_SHIELDS);
+       else if (IS_FLG(FLG_BOWS)) ADD_KEY2(KEY_BOWS);
+       else if (IS_FLG(FLG_RINGS)) ADD_KEY2(KEY_RINGS);
+       else if (IS_FLG(FLG_AMULETS)) ADD_KEY2(KEY_AMULETS);
+       else if (IS_FLG(FLG_SUITS)) ADD_KEY2(KEY_SUITS);
+       else if (IS_FLG(FLG_CLOAKS)) ADD_KEY2(KEY_CLOAKS);
+       else if (IS_FLG(FLG_HELMS)) ADD_KEY2(KEY_HELMS);
+       else if (IS_FLG(FLG_GLOVES)) ADD_KEY2(KEY_GLOVES);
+       else if (IS_FLG(FLG_BOOTS)) ADD_KEY2(KEY_BOOTS);
+       else if (IS_FLG(FLG_FAVORITE)) ADD_KEY2(KEY_FAVORITE);
+
+       /* You don't need sepalator after adjective */
+       /* 'artifact' is not true adjective */
+       else if (!IS_FLG(FLG_ARTIFACT))
+               sepa_flag = FALSE;
+
+       if (entry->name && entry->name[0])
+       {
+               int i, j = 0;
+
+               if (sepa_flag) strcat(buf, ":");
+
+               i = strlen(buf);
+               while (entry->name[j] && i < MAX_LINELEN - 2 - 1)
+               {
+#ifdef JP
+                       if (iskanji(entry->name[j]))
+                               buf[i++] = entry->name[j++];
+#endif
+                       buf[i++] = entry->name[j++];
+               }
+               buf[i] = '\0';
+       }
+
+       if (entry->insc)
+       {
+               int i, j = 0;
+               strcat(buf, "#");
+               i = strlen(buf);
+
+               while (entry->insc[j] && i < MAX_LINELEN - 2)
+               {
+#ifdef JP
+                       if (iskanji(entry->insc[j]))
+                               buf[i++] = entry->insc[j++];
+#endif
+                       buf[i++] = entry->insc[j++];
+               }
+               buf[i] = '\0';
+       }
+
+       return string_make(buf);
+}
+
+
+/*
+ * Reconstruct preference line from entry and kill entry
+ */
+static cptr autopick_line_from_entry_kill(autopick_type *entry)
+{
+       cptr ptr = autopick_line_from_entry(entry);
+
+       /* Free memory for original entry */
+       autopick_free_entry(entry);
+
+       return ptr;
+}
+
+
+/*
+ * Favorite weapons
+ */
+static bool is_favorite(object_type *o_ptr, bool others_ok)
+{
+       /* Only weapons match */
+       switch(o_ptr->tval)
+       {
+       case TV_BOW: case TV_HAFTED: case TV_POLEARM:
+       case TV_SWORD: case TV_DIGGING:
+               break;
+       default: return FALSE;
+       }
+
+       /* Favorite weapons are varied depend on the class */
+       switch (p_ptr->pclass)
+       {
+       case CLASS_PRIEST:
+       {
+               u32b flgs[TR_FLAG_SIZE];
+               object_flags_known(o_ptr, flgs);
+
+               if (!have_flag(flgs, TR_BLESSED) && 
+                   !(o_ptr->tval == TV_HAFTED))
+                       return FALSE;
+               break;
+       }
+
+       case CLASS_MONK:
+       case CLASS_FORCETRAINER:
+               /* Icky to wield? */
+               if (!(s_info[p_ptr->pclass].w_max[o_ptr->tval-TV_BOW][o_ptr->sval]))
+                       return FALSE;
+               break;
+
+       case CLASS_BEASTMASTER:
+       case CLASS_CAVALRY:
+       {
+               u32b flgs[TR_FLAG_SIZE];
+               object_flags_known(o_ptr, flgs);
+
+               /* Is it known to be suitable to using while riding? */
+               if (!(have_flag(flgs, TR_RIDING)))
+                       return FALSE;
+
+               break;
+       }
+
+       case CLASS_NINJA:
+               /* Icky to wield? */
+               if (s_info[p_ptr->pclass].w_max[o_ptr->tval-TV_BOW][o_ptr->sval] <= WEAPON_EXP_BEGINNER)
+                       return FALSE;
+               break;
+
+       default:
+               /* Non-special class */
+               if (others_ok) return TRUE;
+               else return FALSE;
+       }
+
+       return TRUE;
+}
+
+/*
+ * A function for Auto-picker/destroyer
+ * Examine whether the object matches to the entry
+ */
+static bool is_autopick_aux(object_type *o_ptr, autopick_type *entry, cptr o_name)
+{
+       int j;
+       cptr ptr = entry->name;
+
+       /*** Unidentified ***/
+       if (IS_FLG(FLG_UNIDENTIFIED)
+           && (object_known_p(o_ptr) || (o_ptr->ident & IDENT_SENSE)))
+               return FALSE;
 
        /*** Identified ***/
        if (IS_FLG(FLG_IDENTIFIED) && !object_known_p(o_ptr))
@@ -979,6 +1053,42 @@ int is_autopick(object_type *o_ptr)
 
 
 /*
+ *  Auto inscription
+ */
+void auto_inscribe_item(int item, int idx)
+{
+       object_type *o_ptr;
+
+       /* Get the item (in the pack) */
+       if (item >= 0) o_ptr = &inventory[item];
+
+       /* Get the item (on the floor) */
+       else o_ptr = &o_list[0 - item];
+
+       /* Auto-inscription or Re-inscribe for resistances {%} */
+       if ((idx < 0 || !autopick_list[idx].insc) && !o_ptr->inscription)
+               return;
+
+       if (!o_ptr->inscription)
+               o_ptr->inscription = quark_add(autopick_list[idx].insc);
+
+       if (item > INVEN_PACK)
+       {
+               /* Redraw inscription */
+               p_ptr->window |= (PW_EQUIP);
+
+               /* {.} and {$} effect p_ptr->warning and TRC_TELEPORT_SELF */
+               p_ptr->update |= (PU_BONUS);
+       }
+       else if (item >= 0)
+       {
+               /* Redraw inscription */
+               p_ptr->window |= (PW_INVEN);
+       }
+}
+
+
+/*
  * Automatically destroy items in this grid.
  */
 static bool is_opt_confirm_destroy(object_type *o_ptr)
@@ -1045,60 +1155,26 @@ static bool is_opt_confirm_destroy(object_type *o_ptr)
 
 
 /*
- *  Auto inscription
+ * Automatically destroy an item if it is to be destroyed
  */
-void auto_inscribe_item(int item, int idx)
+static object_type autopick_last_destroyed_object;
+
+bool auto_destroy_item(int item, int autopick_idx)
 {
+       bool destroy = FALSE;
        object_type *o_ptr;
 
+       /* Don't destroy equipped items */
+       if (item > INVEN_PACK) return FALSE;
+
        /* Get the item (in the pack) */
        if (item >= 0) o_ptr = &inventory[item];
 
        /* Get the item (on the floor) */
        else o_ptr = &o_list[0 - item];
 
-       /* Auto-inscription or Re-inscribe for resistances {%} */
-       if ((idx < 0 || !autopick_list[idx].insc) && !o_ptr->inscription)
-               return;
-
-       if (!o_ptr->inscription)
-               o_ptr->inscription = quark_add(autopick_list[idx].insc);
-
-       if (item > INVEN_PACK)
-       {
-               /* Redraw inscription */
-               p_ptr->window |= (PW_EQUIP);
-
-               /* {.} and {$} effect p_ptr->warning and TRC_TELEPORT_SELF */
-               p_ptr->update |= (PU_BONUS);
-       }
-       else if (item >= 0)
-       {
-               /* Redraw inscription */
-               p_ptr->window |= (PW_INVEN);
-       }
-}
-
-
-/*
- * Automatically destroy an item if it is to be destroyed
- */
-bool auto_destroy_item(int item, int autopick_idx)
-{
-       bool destroy = FALSE;
-       object_type *o_ptr;
-
-       /* Don't destroy equipped items */
-       if (item > INVEN_PACK) return FALSE;
-
-       /* Get the item (in the pack) */
-       if (item >= 0) o_ptr = &inventory[item];
-
-       /* Get the item (on the floor) */
-       else o_ptr = &o_list[0 - item];
-
-       /* Easy-Auto-Destroyer */
-       if (is_opt_confirm_destroy(o_ptr)) destroy = TRUE;
+       /* Easy-Auto-Destroyer */
+       if (is_opt_confirm_destroy(o_ptr)) destroy = TRUE;
 
        /* Protected by auto-picker */
        if (autopick_idx >= 0 &&
@@ -1312,6 +1388,44 @@ void auto_pickup_items(cave_type *c_ptr)
 }
 
 
+/********  Auto-picker/destroyer editor  **********/
+
+#define MAX_YANK MAX_LINELEN
+
+/* 
+ * Struct for yank buffer
+ */
+typedef struct chain_str {
+       struct chain_str *next;
+       char s[1];
+} chain_str_type;
+
+
+/*
+ * Data struct for text editor
+ */
+typedef struct {
+       int wid, hgt;
+       int cx, cy;
+       int upper, left;
+       int old_wid, old_hgt;
+       int old_cy;
+       int old_upper, old_left;
+       int mx, my;
+       bool mark;
+       object_type *search_o_ptr;
+       cptr search_str;
+       cptr last_destroyed;
+       chain_str_type *yank;
+       bool yank_eol;
+       cptr *lines_list;
+       byte dirty_flags;
+       int dirty_line;
+       int filename_mode;
+       int old_com_id;
+} text_body_type;
+
+
 /*
  * Describe which kind of object is Auto-picked/destroyed
  */
@@ -1983,6 +2097,7 @@ static cptr *read_pickpref_text_lines(int *filename_mode_p)
        return lines_list;
 }
 
+
 /*
  * Write whole lines of memory to a file.
  */
@@ -2029,22 +2144,73 @@ static void free_text_lines(cptr *lines_list)
 /*
  * Delete or insert string
  */
-static void toggle_string(cptr *lines_list, int flg, int y)
+static void toggle_keyword(text_body_type *tb, int flg)
 {
        autopick_type an_entry, *entry = &an_entry;
 
-       if (!autopick_new_entry(entry, lines_list[y]))
+       if (!autopick_new_entry(entry, tb->lines_list[tb->cy]))
                return;
 
-       string_free(lines_list[y]);
+       string_free(tb->lines_list[tb->cy]);
+
+       /* Remove all noun flag */
+       if (FLG_NOUN_BEGIN <= flg && flg <= FLG_NOUN_END)
+       {
+               int i;
+               for (i = FLG_NOUN_BEGIN; i <= FLG_NOUN_END; i++)
+                       REM_FLG(i);
+       }
+
        if (IS_FLG(flg)) 
                REM_FLG(flg);
        else
                ADD_FLG(flg);
 
-       lines_list[y] = autopick_line_from_entry_kill(entry);
+       tb->lines_list[tb->cy] = autopick_line_from_entry_kill(entry);
+
+       /* Now dirty */
+       tb->dirty_line = tb->cy;
+}
+
+
+/*
+ * Delete or insert string
+ */
+static void add_keyword(text_body_type *tb, int flg)
+{
+       autopick_type an_entry, *entry = &an_entry;
+
+       if (!autopick_new_entry(entry, tb->lines_list[tb->cy]))
+               return;
+
+       /* There is the flag already */
+       if (IS_FLG(flg))
+       {
+               /* Free memory for the entry */
+               autopick_free_entry(entry);
+
+               return;
+       }
+
+       string_free(tb->lines_list[tb->cy]);
+
+       /* Remove all noun flag */
+       if (FLG_NOUN_BEGIN <= flg && flg <= FLG_NOUN_END)
+       {
+               int i;
+               for (i = FLG_NOUN_BEGIN; i <= FLG_NOUN_END; i++)
+                       REM_FLG(i);
+       }
+
+       ADD_FLG(flg);
+
+       tb->lines_list[tb->cy] = autopick_line_from_entry_kill(entry);
+
+       /* Now dirty */
+       tb->dirty_line = tb->cy;
 }
 
+
 /*
  * Insert return code and split the line
  */
@@ -2242,12 +2408,58 @@ static bool entry_from_choosed_object(autopick_type *entry)
 
 
 /*
+ * Choose an item for search
+ */
+static byte get_object_for_search(object_type **o_handle, cptr *search_strp)
+{
+       char buf[MAX_NLEN+20];
+       object_type *o_ptr;
+       cptr q, s;
+
+       /* Get an item */
+#ifdef JP
+       q = "¤É¤Î¥¢¥¤¥Æ¥à¤ò¸¡º÷¤·¤Þ¤¹¤«? ";
+       s = "¥¢¥¤¥Æ¥à¤ò»ý¤Ã¤Æ¤¤¤Ê¤¤¡£";
+#else
+       q = "Enter which item? ";
+       s = "You have nothing to enter.";
+#endif
+       o_ptr = choose_object(q, s);
+       if (!o_ptr) return 0;
+
+       *o_handle = o_ptr;
+
+       string_free(*search_strp);
+       object_desc(buf, *o_handle, FALSE, 3);
+       *search_strp = string_make(format("<%s>", buf));
+       return 1;
+}
+
+
+/*
+ * Prepare for search by destroyed object
+ */
+static byte get_destroyed_object_for_search(object_type **o_handle, cptr *search_strp)
+{
+       char buf[MAX_NLEN+20];
+
+       if (!autopick_last_destroyed_object.k_idx) return 0;
+
+       *o_handle = &autopick_last_destroyed_object;
+
+       string_free(*search_strp);
+       object_desc(buf, *o_handle, FALSE, 3);
+       *search_strp = string_make(format("<%s>", buf));
+       return 1;
+}
+
+
+/*
  * Choose an item or string for search
  */
-static bool get_string_for_search(object_type **o_handle, cptr *search_strp)
+static byte get_string_for_search(object_type **o_handle, cptr *search_strp)
 {
        int pos = 0;
-       cptr q, s;
        char buf[MAX_NLEN+20];
 
 #ifdef JP
@@ -2271,60 +2483,48 @@ static bool get_string_for_search(object_type **o_handle, cptr *search_strp)
        /* Process input */
        while (1)
        {
-               object_type *o_ptr;
+               bool back = FALSE;
                int i;
 
                /* Place cursor */
                Term_gotoxy(col + pos, 0);
 
-               /* Do not process macros except special keys */
-               inkey_special = TRUE;
-
                /* Get a key */
                i = inkey();
 
+               /* HACK -- ignore macro defined on ASCII keys */
+               if (strlen(inkey_macro_trigger_string) == 1)
+                       i = inkey_macro_trigger_string[0];
+
+
                /* Analyze the key */
                switch (i)
                {
                case ESCAPE:
-                       pos = 0;
-                       return FALSE;
+                       return 0;
+
+               case KTRL('r'):
+                       back = TRUE;
+                       /* Fall through */
 
                case '\n':
                case '\r':
-                       if (!pos && *o_handle) return TRUE;
+               case KTRL('s'):
+                       if (!pos && *o_handle) return (back ? -1 : 1);
                        string_free(*search_strp);
                        *search_strp = string_make(buf);
                        *o_handle = NULL;
-                       return TRUE;
+                       return (back ? -1 : 1);
 
                case KTRL('i'):
                        /* Get an item */
-#ifdef JP
-                       q = "¤É¤Î¥¢¥¤¥Æ¥à¤ò¸¡º÷¤·¤Þ¤¹¤«? ";
-                       s = "¥¢¥¤¥Æ¥à¤ò»ý¤Ã¤Æ¤¤¤Ê¤¤¡£";
-#else
-                       q = "Enter which item? ";
-                       s = "You have nothing to enter.";
-#endif
-                       o_ptr = choose_object(q, s);
-                       if (!o_ptr) return FALSE;
-
-                       *o_handle = o_ptr;
-
-                       string_free(*search_strp);
-                       object_desc(buf, *o_handle, FALSE, 3);
-                       *search_strp = string_make(format("<%s>", buf));
-                       return TRUE;
+                       return get_object_for_search(o_handle, search_strp);
 
                case KTRL('l'):
-                       if (!autopick_last_destroyed_object.k_idx) break;
-                       *o_handle = &autopick_last_destroyed_object;
-
-                       string_free(*search_strp);
-                       object_desc(buf, *o_handle, FALSE, 3);
-                       *search_strp = string_make(format("<%s>", buf));
-                       return TRUE;
+                       /* Prepare string for destroyed object if there is one. */
+                       if (get_destroyed_object_for_search(o_handle, search_strp))
+                               return 1;
+                       break;
 
                case 0x7F:
                case '\010':
@@ -2466,1411 +2666,2279 @@ static bool search_for_string(cptr *lines_list, cptr search_str, int *cxp, int *
 }
 
 
+
+
 /*
- * Initialize auto-picker preference
+ * Editor commands
  */
-void init_autopicker(void)
+#define EC_QUIT                1 
+#define EC_REVERT             2 
+#define EC_HELP                3 
+#define EC_RETURN             4        
+#define EC_LEFT                       5 
+#define EC_DOWN                       6 
+#define EC_UP                 7 
+#define EC_RIGHT              8 
+#define EC_BOL                9 
+#define EC_EOL                10
+#define EC_PGUP                       11
+#define EC_PGDOWN             12
+#define EC_TOP                13
+#define EC_BOTTOM             14
+#define EC_CUT                15
+#define EC_COPY                       16
+#define EC_PASTE              17
+#define EC_BLOCK              18
+#define EC_KILL_LINE          19
+#define EC_DELETE_CHAR        20
+#define EC_BACKSPACE          21
+#define EC_SEARCH_STR         22
+#define EC_SEARCH_FORW         23
+#define EC_SEARCH_BACK         24
+#define EC_SEARCH_OBJ         25
+#define EC_SEARCH_DESTROYED    26
+#define EC_INSERT_OBJECT       27
+#define EC_INSERT_DESTROYED    28
+#define EC_INSERT_BLOCK               29
+#define EC_INSERT_MACRO               30
+#define EC_INSERT_KEYMAP       31
+#define EC_CL_AUTOPICK        32
+#define EC_CL_DESTROY         33
+#define EC_CL_LEAVE           34
+#define EC_CL_QUERY           35
+#define EC_CL_NO_DISP         36
+#define EC_IK_UNAWARE         37
+#define EC_IK_UNIDENTIFIED     38
+#define EC_IK_IDENTIFIED       39
+#define EC_IK_STAR_IDENTIFIED  40
+#define EC_KK_WEAPONS         41
+#define EC_KK_FAVORITE        42
+#define EC_KK_ARMORS          43
+#define EC_KK_MISSILES        44
+#define EC_KK_DEVICES         45
+#define EC_KK_LIGHTS          46
+#define EC_KK_JUNKS           47
+#define EC_KK_SPELLBOOKS       48
+#define EC_KK_SHIELDS         49
+#define EC_KK_BOWS            50
+#define EC_KK_RINGS           51
+#define EC_KK_AMULETS         52
+#define EC_KK_SUITS           53
+#define EC_KK_CLOAKS          54
+#define EC_KK_HELMS           55
+#define EC_KK_GLOVES          56
+#define EC_KK_BOOTS           57
+#define EC_OK_COLLECTING       58
+#define EC_OK_BOOSTED         59
+#define EC_OK_MORE_THAN               60
+#define EC_OK_MORE_BONUS       61
+#define EC_OK_WORTHLESS               62
+#define EC_OK_ARTIFACT        63
+#define EC_OK_EGO             64
+#define EC_OK_NAMELESS        65
+#define EC_OK_WANTED          66
+#define EC_OK_UNIQUE          67
+#define EC_OK_HUMAN           68
+#define EC_OK_UNREADABLE       69
+#define EC_OK_REALM1          70
+#define EC_OK_REALM2          71
+#define EC_OK_FIRST           72
+#define EC_OK_SECOND          73
+#define EC_OK_THIRD           74
+#define EC_OK_FOURTH          75
+
+
+typedef struct {
+       int level;
+       int key;
+       int com_id;
+} command_menu_type;
+
+
+command_menu_type menu_data[] =
 {
-       static const char easy_autopick_inscription[] = "(:=g";
-       autopick_type entry;
-       int i;
-
-       /* Clear old entries */
-       for( i = 0; i < max_autopick; i++)
-               autopick_free_entry(&autopick_list[i]);
-
-       max_autopick = 0;
+       {0, KTRL('q'), EC_QUIT}, 
+       {0, KTRL('z'), EC_REVERT},
+       {0, -1, EC_HELP},
+
+       {0, -1, -1},
+       {1, KTRL('b'), EC_LEFT},
+       {1, KTRL('n'), EC_DOWN},
+       {1, KTRL('p'), EC_UP},
+       {1, KTRL('f'), EC_RIGHT},
+       {1, KTRL('a'), EC_BOL},
+       {1, KTRL('e'), EC_EOL},
+       {1, KTRL('o'), EC_PGUP},
+       {1, KTRL('l'), EC_PGDOWN},
+       {1, KTRL('y'), EC_TOP},
+       {1, KTRL('u'), EC_BOTTOM},
+
+       {0, -1, -1},
+       {1, KTRL('x'), EC_CUT},
+       {1, KTRL('c'), EC_COPY},
+       {1, KTRL('v'), EC_PASTE},
+       {1, KTRL('g'), EC_BLOCK},
+       {1, KTRL('k'), EC_KILL_LINE},
+       {1, KTRL('d'), EC_DELETE_CHAR},
+       {1, KTRL('h'), EC_BACKSPACE},
+       {1, KTRL('j'), EC_RETURN},
+       {1, KTRL('m'), EC_RETURN},
+
+       {0, -1, -1},
+       {1, KTRL('s'), EC_SEARCH_STR},
+       {1, -1, EC_SEARCH_FORW},
+       {1, KTRL('r'), EC_SEARCH_BACK},
+       {1, -1, EC_SEARCH_OBJ},
+       {1, -1, EC_SEARCH_DESTROYED},
+
+       {0, -1, -1},
+       {1, KTRL('i'), EC_INSERT_OBJECT},
+       {1, -1, EC_INSERT_DESTROYED},
+       {1, -1, EC_INSERT_BLOCK},
+       {1, -1, EC_INSERT_MACRO},
+       {1, -1, EC_INSERT_KEYMAP},
+
+       {0, -1, -1},
+       {1, -1, EC_CL_AUTOPICK},
+       {1, -1, EC_CL_DESTROY},
+       {1, -1, EC_CL_LEAVE},
+       {1, -1, EC_CL_QUERY},
+       {1, -1, EC_CL_NO_DISP},
+
+       {0, -1, -1},
+       {1, -1, EC_IK_UNAWARE},
+       {1, -1, EC_IK_UNIDENTIFIED},
+       {1, -1, EC_IK_IDENTIFIED},
+       {1, -1, EC_IK_STAR_IDENTIFIED},
+
+       {0, -1, -1},
+       {1, -1, EC_KK_WEAPONS},
+       {1, -1, EC_KK_FAVORITE},
+       {1, -1, EC_KK_ARMORS},
+       {1, -1, EC_KK_MISSILES},
+       {1, -1, EC_KK_DEVICES},
+       {1, -1, EC_KK_LIGHTS},
+       {1, -1, EC_KK_JUNKS},
+       {1, -1, EC_KK_SPELLBOOKS},
+       {1, -1, EC_KK_SHIELDS},
+       {1, -1, EC_KK_BOWS},
+       {1, -1, EC_KK_RINGS},
+       {1, -1, EC_KK_AMULETS},
+       {1, -1, EC_KK_SUITS},
+       {1, -1, EC_KK_CLOAKS},
+       {1, -1, EC_KK_HELMS},
+       {1, -1, EC_KK_GLOVES},
+       {1, -1, EC_KK_BOOTS},
+
+       {0, -1, -1},
+       {1, -1, EC_OK_COLLECTING},
+       {1, -1, EC_OK_BOOSTED},
+       {1, -1, EC_OK_MORE_THAN},
+       {1, -1, EC_OK_MORE_BONUS},
+       {1, -1, EC_OK_WORTHLESS},
+       {1, -1, EC_OK_ARTIFACT},
+       {1, -1, EC_OK_EGO},
+       {1, -1, EC_OK_NAMELESS},
+       {1, -1, EC_OK_WANTED},
+       {1, -1, EC_OK_UNIQUE},
+       {1, -1, EC_OK_HUMAN},
+       {1, -1, EC_OK_UNREADABLE},
+       {1, -1, EC_OK_REALM1},
+       {1, -1, EC_OK_REALM2},
+       {1, -1, EC_OK_FIRST},
+       {1, -1, EC_OK_SECOND},
+       {1, -1, EC_OK_THIRD},
+       {1, -1, EC_OK_FOURTH},
+
+       {-1, -1, 0}
+};
 
-       /* There is always one entry "=g" */
-       autopick_new_entry(&entry, easy_autopick_inscription);
-       autopick_list[max_autopick++] = entry;
-}
 
+cptr menu_name[] =
+#ifdef JP
+{
+       "¥»¡¼¥Ö¤·¤Æ½ªÎ»", 
+       "Á´¤Æ¤ÎÊѹ¹¤òÇË´þ", 
+       "¥Ø¥ë¥×", 
+
+       "¥«¡¼¥½¥ë°ÜÆ°", 
+       "º¸", 
+       "²¼", 
+       "¾å", 
+       "±¦", 
+       "¹Ô¤ÎÀèƬ", 
+       "¹Ô¤Î½ªÃ¼", 
+       "¾å¤Î¥Ú¡¼¥¸", 
+       "²¼¤Î¥Ú¡¼¥¸", 
+       "1¹ÔÌܤذÜÆ°", 
+       "ºÇ²¼¹Ô¤Ø°ÜÆ°", 
+
+       "ÊÔ½¸", 
+       "ÁªÂòÈϰϤò¥«¥Ã¥È", 
+       "ÁªÂòÈϰϤò¥³¥Ô¡¼", 
+       "¥Ú¡¼¥¹¥È", 
+       "ÁªÂòÈϰϤλØÄê", 
+       "¹Ô¤Î»Ä¤ê¤òºï½ü", 
+       "1ʸ»úºï½ü", 
+       "¥Ð¥Ã¥¯¥¹¥Ú¡¼¥¹", 
+       "²þ¹Ô", 
+       "²þ¹Ô", 
+
+       "¸¡º÷", 
+       "ʸ»úÎó¤Ç¸¡º÷", 
+       "Á°Êý¤ØºÆ¸¡º÷", 
+       "¸åÊý¤ØºÆ¸¡º÷", 
+       "¥¢¥¤¥Æ¥à¤òÁªÂò¤·¤Æ¸¡º÷", 
+       "¼«Æ°Ç˲õ¤µ¤ì¤¿¥¢¥¤¥Æ¥à¤Ç¸¡º÷", 
+
+       "¿§¡¹ÁÞÆþ...", 
+       "ÁªÂò¤·¤¿¥¢¥¤¥Æ¥à¤Î̾Á°¤òÁÞÆþ", 
+       "¼«Æ°Ç˲õ¤µ¤ì¤¿¥¢¥¤¥Æ¥à¤Î̾Á°¤òÁÞÆþ", 
+       "¾ò·ïʬ´ô¥Ö¥í¥Ã¥¯¤ÎÎã¤òÁÞÆþ", 
+       "¥Þ¥¯¥íÄêµÁ¤òÁÞÆþ", 
+       "¥­¡¼¥Þ¥Ã¥×ÄêµÁ¤òÁÞÆþ", 
+
+       "¼«Æ°¥³¥Þ¥ó¥É»ØÄêʸ»ú", 
+       "¡Ö ¡× (¼«Æ°½¦¤¤)", 
+       "¡Ö!¡× (¼«Æ°Ç˲õ)", 
+       "¡Ö~¡× (ÊüÃÖ)", 
+       "¡Ö;¡× (³Îǧ¤·¤Æ½¦¤¦)", 
+       "¡Ö(¡× (¥Þ¥Ã¥×¥³¥Þ¥ó¥É¤Çɽ¼¨¤·¤Ê¤¤)", 
+
+       "¼±Ê̾õÂÖ¥­¡¼¥ï¡¼¥É", 
+       "̤ȽÌÀ", 
+       "̤´ÕÄê", 
+       "´ÕÄêºÑ¤ß", 
+       "*´ÕÄê*ºÑ¤ß", 
+
+       "¥­¡¼¥ï¡¼¥É (̾»ì)", 
+       "Éð´ï", 
+       "ÆÀ°ÕÉð´ï", 
+       "Ëɶñ", 
+       "Ìð", 
+       "ËâË¡¥¢¥¤¥Æ¥à", 
+       "¸÷¸»", 
+       "¤¬¤é¤¯¤¿", 
+       "ËâË¡½ñ", 
+       "½â", 
+       "µÝ", 
+       "»ØÎØ", 
+       "¥¢¥ß¥å¥ì¥Ã¥È", 
+       "³»", 
+       "¥¯¥í¡¼¥¯", 
+       "³õ", 
+       "äƼê", 
+       "·¤", 
+
+       "¥­¡¼¥ï¡¼¥É (·ÁÍÆ»ì)", 
+       "¼ý½¸Ãæ¤Î", 
+       "¥À¥¤¥¹Ìܤΰ㤦 (Éð´ï)", 
+       "¥À¥¤¥¹ÌÜ # °Ê¾å¤Î (Éð´ï)", 
+       "½¤ÀµÃÍ # °Ê¾å¤Î", 
+       "̵²ÁÃͤÎ", 
+       "¥¢¡¼¥Æ¥£¥Õ¥¡¥¯¥È", 
+       "¥¨¥´ (ÁõÈ÷)", 
+       "̵ÌäΠ(ÁõÈ÷)", 
+       "¾Þ¶â¼ó¤Î", 
+       "¥æ¥Ë¡¼¥¯¡¦¥â¥ó¥¹¥¿¡¼¤Î", 
+       "¿Í´Ö¤Î", 
+       "Æɤá¤Ê¤¤ (ËâË¡½ñ)", 
+       "Âè°ìÎΰè¤Î (ËâË¡½ñ)", 
+       "ÂèÆóÎΰè¤Î (ËâË¡½ñ)", 
+       "1ºýÌܤΠ(ËâË¡½ñ)", 
+       "2ºýÌܤΠ(ËâË¡½ñ)", 
+       "3ºýÌܤΠ(ËâË¡½ñ)", 
+       "4ºýÌܤΠ(ËâË¡½ñ)", 
+};
+#else
+{
+       "Save & Quit", 
+       "Revert all changes", 
+       "Help", 
+
+       "Move cursor", 
+       "Left", 
+       "Down", 
+       "Up", 
+       "Right", 
+       "Beggining of line", 
+       "End of line", 
+       "Page up", 
+       "Page down", 
+       "Top", 
+       "Bottom", 
+
+       "Edit", 
+       "Cut", 
+       "Copy", 
+       "Paste", 
+       "Select block", 
+       "Kill rest of line", 
+       "Delete character", 
+       "Backspace", 
+       "Return", 
+       "Return", 
+
+       "Search", 
+       "Search by string", 
+       "Search forward", 
+       "Search backward", 
+       "Search by inventory object", 
+       "Search by destroyed object", 
+
+       "Insert...", 
+       "Insert name of choosen object", 
+       "Insert name of destroyed object", 
+       "Insert conditional block", 
+       "Insert a macro definition", 
+       "Insert a keymap definition", 
+
+       "Command letter", 
+       "' ' (Auto pick)", 
+       "'!' (Auto destroy)", 
+       "'~' (Leave it on the floor)", 
+       "';' (Query to pick up)", 
+       "'(' (No display on the large map)", 
+
+       "Identify states", 
+       "unaware", 
+       "unidentified", 
+       "identified", 
+       "*identified*", 
+
+       "Keywords (noun)", 
+       "weapons", 
+       "favorite", 
+       "armors", 
+       "missiles", 
+       "devices", 
+       "lights", 
+       "junks", 
+       "spellbooks", 
+       "shields", 
+       "bows", 
+       "rings", 
+       "amulets", 
+       "suits", 
+       "cloaks", 
+       "helms", 
+       "gloves", 
+       "boots", 
+
+       "Keywords (adjective)", 
+       "collecting", 
+       "dice boosted (weapons)", 
+       "more than # dice (weapons)", 
+       "more bonus than #", 
+       "worthless", 
+       "artifact", 
+       "ego (equipments)", 
+       "nameless (equipments)", 
+       "wanted", 
+       "unique", 
+       "human", 
+       "unreadable (spellbooks)", 
+       "realm1 (spellbooks)", 
+       "realm2 (spellbooks)", 
+       "first (spellbooks)", 
+       "second (spellbooks)", 
+       "third (spellbooks)", 
+       "fourth (spellbooks)", 
+};
 
+#endif
 
 /*
- *  Process line for auto picker/destroyer.
+ * Find a command by 'key'.
  */
-errr process_pickpref_file_line(char *buf)
+static int get_com_id(char key)
 {
-       autopick_type entry;
        int i;
 
-       if (max_autopick == MAX_AUTOPICK)
-               return 1;
-       
-       /* Nuke illegal char */
-       for(i = 0; buf[i]; i++)
+       for (i = 0; menu_name[i]; i++)
        {
-#ifdef JP
-               if (iskanji(buf[i]))
+               if (menu_data[i].key == key)
                {
-                       i++;
-                       continue;
+                       return menu_data[i].com_id;
                }
-#endif
-               if (isspace(buf[i]) && buf[i] != ' ')
-                       break;
        }
-       buf[i] = 0;
-       
-       if (!autopick_new_entry(&entry, buf)) return 0;
-
-       /* Already has the same entry? */ 
-       for(i = 0; i < max_autopick; i++)
-               if(!strcmp(entry.name, autopick_list[i].name)
-                  && entry.flag[0] == autopick_list[i].flag[0]
-                  && entry.flag[1] == autopick_list[i].flag[1]
-                  && entry.dice == autopick_list[i].dice
-                  && entry.bonus == autopick_list[i].bonus) return 0;
 
-       autopick_list[max_autopick++] = entry;
        return 0;
 }
 
 
 /*
- * Get a trigger key and insert ASCII string for the trigger
+ * Display the menu, and get a command 
  */
-static bool insert_macro_line(cptr *lines_list, int cy)
+static int do_command_menu(int level, int start)
 {
-       char tmp[1024];
-       char buf[1024];
-       int i, n = 0;
+       int i;
+       int max_len = 0;
+       int max_menu_wid;
+       int col0 = 5 + level*4;
+       int row0 = 1 + level*2;
+       byte menu_key = 0;
+       int menu_id_list[26];
+       bool redraw = TRUE;
+       char linestr[MAX_LINELEN];
+
+       /* Get max length */
+       menu_key = 0;
+       for (i = start; menu_data[i].level >= level; i++)
+       {
+               int len;
 
-       /* Flush */
-       flush();
+               /* Ignore lower level sub menus */
+               if (menu_data[i].level > level) continue;
 
-       /* Do not process macros */
-       inkey_base = TRUE;
+               len = strlen(menu_name[i]);
+               if (len > max_len) max_len = len;
 
-       /* First key */
-       i = inkey();
+               menu_id_list[menu_key] = i;
+               menu_key++;
+       }
 
-       /* Read the pattern */
-       while (i)
+       while (menu_key < 26)
        {
-               /* Save the key */
-               buf[n++] = i;
-
-               /* Do not process macros */
-               inkey_base = TRUE;
+               menu_id_list[menu_key] = -1;
+               menu_key++;
+       }
 
-               /* Do not wait for keys */
-               inkey_scan = TRUE;
+       /* Extra space for displaying menu key and command key */
+       max_menu_wid = max_len + 3 + 3;
 
-               /* Attempt to read a key */
-               i = inkey();
+       /* Prepare box line */
+       linestr[0] = '\0';
+       strcat(linestr, "+");
+       for (i = 0; i < max_menu_wid + 2; i++)
+       {
+               strcat(linestr, "-");
        }
+       strcat(linestr, "+");
 
-       /* Terminate */
-       buf[n] = '\0';
-
-       /* Flush */
-       flush();
+       while (1)
+       {
+               int com_id;
+               char key;
+               int menu_id;
 
-       /* Convert the trigger */
-       ascii_to_text(tmp, buf);
+               if (redraw)
+               {
+                       int row1 = row0 + 1;
 
-       /* Null */
-       if(!tmp[0]) return FALSE;
+                       /* Draw top line */
+                       Term_putstr(col0, row0, -1, TERM_WHITE, linestr);
 
-       /* Insert preference string */
-       insert_return_code(lines_list, 0, cy);
-       string_free(lines_list[cy]);
-       lines_list[cy] = string_make(format("P:%s", tmp));
+                       /* Draw menu items */
+                       menu_key = 0;
+                       for (i = start; menu_data[i].level >= level; i++)
+                       {
+                               char com_key_str[3];
+                               cptr str;
 
-       /* Insert blank action preference line */
-       insert_return_code(lines_list, 0, cy);
-       string_free(lines_list[cy]);
-       lines_list[cy] = string_make("A:");
+                               /* Ignore lower level sub menus */
+                               if (menu_data[i].level > level) continue;
 
-       return TRUE;
-}
+                               if (menu_data[i].com_id == -1)
+                               {
+#ifdef JP
+                                       strcpy(com_key_str, "¢§");
+#else
+                                       strcpy(com_key_str, ">");
+#endif
+                               }
+                               else if (menu_data[i].key != -1)
+                               {
+                                       com_key_str[0] = '^';
+                                       com_key_str[1] = menu_data[i].key + '@';
+                                       com_key_str[2] = '\0';
+                               }
+                               else
+                               {
+                                       com_key_str[0] = '\0';
+                               }
 
+                               str = format("| %c) %-*s %2s | ", menu_key + 'a', max_len, menu_name[i], com_key_str);
 
-/*
- * Get a command key and insert ASCII string for the key
- */
-static bool insert_keymap_line(cptr *lines_list, int cy)
-{
-       char tmp[1024];
-       char buf[2];
-       int mode;
+                               Term_putstr(col0, row1++, -1, TERM_WHITE, str);
 
-       /* Roguelike */
-       if (rogue_like_commands)
-       {
-               mode = KEYMAP_MODE_ROGUE;
-       }
+                               menu_key++;
+                       }
 
-       /* Original */
-       else
-       {
-               mode = KEYMAP_MODE_ORIG;
-       }
+                       /* Draw bottom line */
+                       Term_putstr(col0, row1, -1, TERM_WHITE, linestr);
 
-       /* Flush */
-       flush();
+                       /* The menu was shown */
+                       redraw = FALSE;
+               }
+               prt(format("(a-%c) ¥³¥Þ¥ó¥É:", menu_key + 'a' - 1), 0, 0);
+               key = inkey();
 
-       /* Get a key */
-       buf[0] = inkey();
-       buf[1] = '\0';
+               if (key == ESCAPE) return 0;
 
-       /* Flush */
-       flush();
+               if ('a' <= key && key <= 'z')
+               {
+                       menu_id = menu_id_list[key - 'a'];
 
-       /* Convert the trigger */
-       ascii_to_text(tmp, buf);
+                       if (menu_id >= 0)
+                       {
+                               com_id = menu_data[menu_id].com_id;
 
-       /* Null */
-       if(!tmp[0]) return FALSE;
+                               if (com_id == -1)
+                               {
+                                       com_id = do_command_menu(level + 1, menu_id + 1);
+                                       if (com_id) return com_id;
+                                       else redraw = TRUE;
+                               }
+                               else if (com_id)
+                               {
+                                       return com_id;
+                               }
+                       }
+               }
 
-       /* Insert preference string */
-       insert_return_code(lines_list, 0, cy);
-       string_free(lines_list[cy]);
-       lines_list[cy] = string_make(format("C:%d:%s", mode, tmp));
+               else
+               {
+                       com_id = get_com_id(key);
+                       if (com_id) return com_id;
+                       else continue;
+               }
+       }
+}
 
-       /* Insert blank action preference line */
-       insert_return_code(lines_list, 0, cy);
-       string_free(lines_list[cy]);
-       lines_list[cy] = string_make("A:");
 
-       return TRUE;
+static chain_str_type *new_chain_str(cptr str)
+{
+       chain_str_type *chain;
+
+       size_t len = strlen(str);
+
+       chain = (chain_str_type *)ralloc(sizeof(chain_str_type) + len * sizeof(char));
+
+       strcpy(chain->s, str);
+       chain->next = NULL;
+
+       return chain;
 }
 
 
-/*
- * Description of control commands
- */
+static void kill_yank_chain(text_body_type *tb)
+{
+       chain_str_type *chain = tb->yank;
+       tb->yank = NULL;
+
+       while (chain)
+       {
+               chain_str_type *next = chain->next;
+               size_t len = strlen(chain->s);
+
+               rnfree(chain, sizeof(chain_str_type) + len * sizeof(char));
+
+               chain = next;
+       }
+}
 
-#define WID_DESC 31
 
-static cptr ctrl_command_desc[] =
+static void add_str_to_yank(text_body_type *tb, cptr str)
 {
-#ifdef JP
-#define LAST_DESTROYED 6
-       "^P ^N ^B ^F ¾å²¼º¸±¦¤Ë°ÜÆ°",
-       "^A ^E ¹Ô¤ÎÀèƬ¡¢½ªÃ¼",
-       "^Q ÆþÎÏ/¥³¥Þ¥ó¥É¥â¡¼¥ÉÀÚ¤êÂؤ¨",
-       "^R Êѹ¹¤òÁ´¤Æ¼è¤ê¾Ã¤·¤Æ¸µ¤ËÌ᤹",
-       "------------------------------------",
-       "^I »ý¤Áʪ/ÁõÈ÷¤«¤éÁªÂò",
-       "^L",
-       "^K ¥«¡¼¥½¥ë¤«¤é½ªÃ¼¤Þ¤Çºï½ü",
-       "^Y ºï½ü(^K)¤·¤¿¹Ô¤òÁÞÆþ",
-       "^C ¼ï²¡¢¿¦¶È¤Î¾ò·ï¼°¤òÁÞÆþ",
-       "------------------------------------",
-       "^S Êѹ¹ (!Ç˲õ/~ÊüÃÖ/½¦¤¦)",
-       "^G \"(\" Á´ÂΥޥåפÇɽ¼¨¤·¤Ê¤¤",
-       "^O \"#\" ¼«Æ°¹ï¤ß",
-       "------------------------------------",
-       "^U Ì¤´ÕÄê/̤ȽÌÀ/´ÕÄê/*´ÕÄê*",
-       "^W \"̵²ÁÃͤÎ\"",
-       "^X ÌµÌÃ/¥¨¥´/¥¢¡¼¥Æ¥£¥Õ¥¡¥¯¥È",
-       "^Z \"¼ý½¸Ãæ¤Î\"",
-       NULL
-#else
-#define LAST_DESTROYED 6
-       "^P ^N ^B ^F Move Cursor",
-       "^A ^E Beginning and End of Line",
-       "^Q Toggle Insert/Command mode",
-       "^R Revert to Original File",
-       "------------------------------------",
-       "^I Object in Inventry/Equipment",
-       "^L",
-       "^K Kill Rest of Line",
-       "^Y Insert killed(^K) text",
-       "^C Insert conditional expression",
-       "------------------------------------",
-       "^S Toggle(!Destroy/~Leave/Pick)",
-       "^G \"(\" No display in the 'M'ap",
-       "^O \"#\" Auto-Inscribe",
-       "------------------------------------",
-       "^U Toggle 'identified' state",
-       "^W \"worthless\"",
-       "^X Toggle nameless/ego/artifact",
-       "^Z \"collecting\"",
-       NULL
-#endif
-};
+       chain_str_type *chain;
 
+       tb->yank_eol = FALSE;
 
-#define MAX_YANK MAX_LINELEN
+       if (NULL == tb->yank)
+       {
+               tb->yank = new_chain_str(str);
+               return;
+       }
+
+       chain = tb->yank;
+
+       while (1)
+       {
+               if (!chain->next)
+               {
+                       chain->next = new_chain_str(str);
+                       return;
+               }
+
+               /* Go to next */
+               chain = chain->next;
+       }
+}
+
+
+/*
+ * Dirty flag for text editor
+ */
 #define DIRTY_ALL 0x01
-#define DIRTY_COMMAND 0x02
 #define DIRTY_MODE 0x04
 #define DIRTY_SCREEN 0x08
 #define DIRTY_NOT_FOUND 0x10
 #define DIRTY_NO_SEARCH 0x20
 
+
+#define DESCRIPT_HGT 3
+
 /*
- * In-game editor of Object Auto-picker/Destoryer
+ * Draw text
  */
-void do_cmd_edit_autopick(void)
+static void draw_text_editor(text_body_type *tb)
 {
-       static int cx = 0, cy = 0;
-       static int upper = 0, left = 0;
-
-       object_type *search_o_ptr = NULL;
-       cptr search_str = NULL;
-       cptr last_destroyed = NULL;
-       char last_destroyed_command[WID_DESC+3];
-       char yank_buf[MAX_YANK];
-       char classrace[80];
-       autopick_type an_entry, *entry = &an_entry;
-       char buf[MAX_LINELEN];
-       cptr *lines_list;
-       int filename_mode = PT_WITH_PNAME;
-
-       int i, j, k, len;
+       int i;
+       int by1 = -1, bx1 = -1, by2 = -1, bx2 = -1;
 
-       int old_upper = -1, old_left = -1;
-       int old_cy = -1;
-       int key = -1, old_key;
-       bool repeated_clearing = FALSE;
-       bool edit_mode = FALSE;
+       /* Get size */
+       Term_get_size(&tb->wid, &tb->hgt);
 
-       byte dirty_flags = DIRTY_ALL | DIRTY_COMMAND | DIRTY_MODE;
-       int dirty_line = -1;
+       /*
+        * Top line (-1), description line (-3), separator (-1)
+        *  == -5
+        */
+       tb->hgt -= 2 + DESCRIPT_HGT;
 
-       int wid, hgt, old_wid = -1, old_hgt = -1;
+#ifdef JP
+       /* Don't let cursor at second byte of kanji */
+       for (i = 0; tb->lines_list[tb->cy][i]; i++)
+               if (iskanji(tb->lines_list[tb->cy][i]))
+               {
+                       i++;
+                       if (i == tb->cx)
+                       {
+                               tb->cx--;
+                               break;
+                       }
+               }
+#endif
 
-       static s32b old_autosave_turn = 0L;
+       /* Scroll if necessary */
+       if (tb->cy < tb->upper || tb->upper + tb->hgt <= tb->cy)
+               tb->upper = tb->cy - (tb->hgt)/2;
+       if (tb->upper < 0)
+               tb->upper = 0;
+       if ((tb->cx < tb->left + 10 && tb->left > 0) || tb->left + tb->wid - 5 <= tb->cx)
+               tb->left = tb->cx - (tb->wid)*2/3;
+       if (tb->left < 0)
+               tb->left = 0;
 
-       /* Autosave */
-       if (turn > old_autosave_turn + 100L)
-       {
-               do_cmd_save_game(TRUE);
-               old_autosave_turn = turn;
-       }
+       /* Redraw whole window after resize */
+       if (tb->old_wid != tb->wid || tb->old_hgt != tb->hgt)
+               tb->dirty_flags |= DIRTY_SCREEN;
 
-       /* HACK -- Reset start_time to stop counting playtime while edit */
-       update_playtime();
+       /* Redraw all text after scroll */
+       else if (tb->old_upper != tb->upper || tb->old_left != tb->left)
+               tb->dirty_flags |= DIRTY_ALL;
 
-       /* Free old entries */
-       init_autopicker();
 
-       /* Command Description of the 'Last Destroyed Item' */
-       if (autopick_last_destroyed_object.k_idx)
+       if (tb->dirty_flags & DIRTY_SCREEN)
        {
-               autopick_entry_from_object(entry, &autopick_last_destroyed_object);
-               last_destroyed = autopick_line_from_entry_kill(entry);
+               tb->dirty_flags |= (DIRTY_ALL | DIRTY_MODE);
 
-               my_strcpy(last_destroyed_command, format("^L \"%s\"", last_destroyed), sizeof(last_destroyed_command));
+               /* Clear screen */
+               Term_clear();
        }
-       else
+
+       /* Redraw mode line */
+       if (tb->dirty_flags & DIRTY_MODE)
        {
-#ifdef JP
-               strcpy(last_destroyed_command, "^L ºÇ¸å¤Ë¼«Æ°Ç˲õ¤·¤¿¥¢¥¤¥Æ¥à̾");
-#else
-               strcpy(last_destroyed_command, "^L Last destroyed object");
-#endif
-       }
-       ctrl_command_desc[LAST_DESTROYED] = last_destroyed_command;
+               char buf[MAX_LINELEN];
 
-       /* Conditional Expression for Class and Race */
-       sprintf(classrace, "?:[AND [EQU $RACE %s] [EQU $CLASS %s]]", 
-#ifdef JP
-               rp_ptr->E_title, cp_ptr->E_title
-#else
-               rp_ptr->title, cp_ptr->title
-#endif
-               );
+               int sepa_length = tb->wid;
 
-       /* Clear yank buffer */
-       yank_buf[0] = '\0';
+               /* Separator */
+               for (i = 0; i < sepa_length; i++)
+                       buf[i] = '-';
+               buf[i] = '\0';
 
-       /* Read or initialize whole text */
-       lines_list = read_pickpref_text_lines(&filename_mode);
+               Term_putstr(0, tb->hgt + 1, sepa_length, TERM_WHITE, buf);
+       }
 
-       /* Reset cursor position if needed */
-       for (i = 0; i < cy; i++)
+       if (tb->mark)
        {
-               if (!lines_list[i])
+               tb->dirty_flags |= DIRTY_ALL;
+
+               if (tb->my < tb->cy ||
+                   (tb->my == tb->cy && tb->mx < tb->cx))
                {
-                       cy = cx = 0;
-                       break;
+                       by1 = tb->my;
+                       bx1 = tb->mx;
+                       by2 = tb->cy;
+                       bx2 = tb->cx;
+               }
+               else
+               {
+                       by2 = tb->my;
+                       bx2 = tb->mx;
+                       by1 = tb->cy;
+                       bx1 = tb->cx;
                }
        }
 
-       /* Save the screen */
-       screen_save();
-
-       /* Process requests until done */
-       while (1)
+       /* Dump up to tb->hgt lines of messages */
+       for (i = 0; i < tb->hgt; i++)
        {
-               /* Get size */
-               Term_get_size(&wid, &hgt);
+               int j;
+               int leftcol = 0;
+               cptr msg;
+               int y = tb->upper+i;
 
+               /* clean or dirty? */
+               if (!(tb->dirty_flags & DIRTY_ALL) && (tb->dirty_line != y))
+                       continue;
+
+               msg = tb->lines_list[y];
+               if (!msg) break;
+
+               /* Apply horizontal scroll */
+               for (j = 0; *msg; msg++, j++)
+               {
+                       if (j == tb->left) break;
 #ifdef JP
-               /* Don't let cursor at second byte of kanji */
-               for (i = 0; lines_list[cy][i]; i++)
-                       if (iskanji(lines_list[cy][i]))
+                       if (j > tb->left)
                        {
-                               i++;
-                               if (i == cx)
-                               {
-                                       cx--;
-                                       break;
-                               }
+                               leftcol = 1;
+                               break;
+                       }
+                       if (iskanji(*msg))
+                       {
+                               msg++;
+                               j++;
                        }
 #endif
-
-               /* Scroll if necessary */
-               if (cy < upper || upper + hgt - 4 <= cy)
-                       upper = cy - (hgt-4)/2;
-               if (upper < 0)
-                       upper = 0;
-               if ((cx < left + 10 && left > 0) || left + wid - WID_DESC - 5 <= cx)
-                       left = cx - (wid - WID_DESC)*2/3;
-               if (left < 0)
-                       left = 0;
-
-               /* Redraw whole window after resize */
-               if (old_wid != wid || old_hgt != hgt)
-                       dirty_flags |= DIRTY_SCREEN;
-
-               /* Redraw all text after scroll */
-               else if (old_upper != upper || old_left != left)
-                       dirty_flags |= DIRTY_ALL;
-
-
-               if (dirty_flags & DIRTY_SCREEN)
-               {
-                       dirty_flags |= (DIRTY_ALL | DIRTY_COMMAND | DIRTY_MODE);
-
-                       /* Clear screen */
-                       Term_clear();
                }
 
-               if (dirty_flags & DIRTY_COMMAND)
+               /* Erase line */
+               Term_erase(0, i + 1, tb->wid);
+
+               if (!tb->mark)
                {
-                       /* Display control command */
-                       for (i = 0; ctrl_command_desc[i]; i++)
-                               Term_putstr(wid - WID_DESC, i + 1, WID_DESC, TERM_WHITE, ctrl_command_desc[i]);
+                       /* Dump the messages, bottom to top */
+                       Term_putstr(leftcol, i + 1, tb->wid - 1, TERM_WHITE, msg);
                }
 
-               /* Redraw mode line */
-               if (dirty_flags & DIRTY_MODE)
+               else
                {
-                       int sepa_length = wid - WID_DESC;
+                       int x0 = leftcol + tb->left;
 
-                       /* Separator */
-                       for (i = 0; i < sepa_length; i++)
-                               buf[i] = '-';
-                       buf[i] = '\0';
+                       int sx0 = 0;
+                       int sx1 = 0;
 
-                       /* Mode line */
-                       if (edit_mode)
-                               strncpy(buf + sepa_length - 21, " (INSERT MODE)  ", 16);
-                       else
-                               strncpy(buf + sepa_length - 21, " (COMMAND MODE) ", 16);
+                       if (by1 <= y && y < by2) sx1 = strlen(msg);
+                       if (y == by1) sx0 = bx1;
+                       if (y == by2) sx1 = bx2;
 
-                       Term_putstr(0, hgt - 3, sepa_length, (byte) (edit_mode ? TERM_YELLOW : TERM_WHITE), buf);
+                       Term_gotoxy(leftcol, i + 1);
+                       if (x0 < sx0) Term_addstr(sx0 - x0, TERM_WHITE, msg);
+                       if (x0 < sx1) Term_addstr(sx1 - sx0, TERM_YELLOW, msg + (sx0 - x0));
+                       Term_addstr(-1, TERM_WHITE, msg + (sx1 - x0));
                }
-               
-               /* Dump up to 20, or hgt-4, lines of messages */
-               for (i = 0; i < hgt - 4; i++)
-               {
-                       int leftcol = 0;
-                       cptr msg;
-
-                       /* clean or dirty? */
-                       if (!(dirty_flags & DIRTY_ALL) && (dirty_line != upper+i))
-                               continue;
-
-                       msg = lines_list[upper+i];
-                       if (!msg) break;
-
-                       /* Apply horizontal scroll */
-                       for (j = 0; *msg; msg++, j++)
-                       {
-                               if (j == left) break;
-#ifdef JP
-                               if (j > left)
-                               {
-                                       leftcol = 1;
-                                       break;
-                               }
-                               if (iskanji(*msg))
-                               {
-                                       msg++;
-                                       j++;
-                               }
-#endif
-                       }
+       }
 
-                       /* Erase line */
-                       Term_erase(0, i + 1, wid - WID_DESC);
+       for (; i < tb->hgt; i++)
+       {
+               /* Erase line */
+               Term_erase(0, i + 1, tb->wid);
+       }
 
-                       /* Dump the messages, bottom to top */
-                       Term_putstr(leftcol, i + 1, wid - WID_DESC - 1, TERM_WHITE, msg);
-               }
+       /* Display information when updated */
+       if (tb->old_cy != tb->cy || (tb->dirty_flags & (DIRTY_ALL | DIRTY_NOT_FOUND | DIRTY_NO_SEARCH)) || tb->dirty_line == tb->cy)
+       {
+               autopick_type an_entry, *entry = &an_entry;
 
-               for (; i < hgt - 4; i++)
+               /* Clear information line */
+               for (i = 0; i < DESCRIPT_HGT; i++)
                {
                        /* Erase line */
-                       Term_erase(0, i + 1, wid - WID_DESC);
+                       Term_erase(0, tb->hgt + 2 + i, tb->wid);
                }
 
-               /* Display header line */
-#ifdef JP
-               if (edit_mode)
-                       prt("^Q ESC ¤Ç¥³¥Þ¥ó¥É¥â¡¼¥É¤Ø°Ü¹Ô¡¢Ä̾ï¤Îʸ»ú¤Ï¤½¤Î¤Þ¤ÞÆþÎÏ", 0, 0);
-               else
-                       prt("q _ ¤Ç½ªÎ»¡¢hjkl2468 ¤Ç°ÜÆ°¡¢^Q a i ¤ÇÆþÎϥ⡼¥É¡¢/ n N ¤Ç¸¡º÷", 0, 0);
-#else  
-               if (edit_mode)
-                       prt("Press ^Q ESC to command mode, any letters to insert", 0, 0);
-               else
-                       prt(format("Press q _ to quit, %s to move, ^Q a i to insert mode, /nN to find", rogue_like_commands ? "hjkl" : "2468"), 0, 0);
-#endif
-               /* Display current position */
-               prt (format("(%d,%d)", cx, cy), 0, 70);
-
-               /* Display information when updated */
-               if (old_cy != cy || (dirty_flags & (DIRTY_ALL | DIRTY_NOT_FOUND | DIRTY_NO_SEARCH)) || dirty_line == cy)
+               /* Display information */
+               if (tb->dirty_flags & DIRTY_NOT_FOUND)
                {
-                       /* Clear information line */
-                       Term_erase(0, hgt - 3 + 1, wid);
-                       Term_erase(0, hgt - 3 + 2, wid);
-
-                       /* Display information */
-                       if (dirty_flags & DIRTY_NOT_FOUND)
-                       {
 #ifdef JP
-                               prt(format("¥Ñ¥¿¡¼¥ó¤¬¸«¤Ä¤«¤ê¤Þ¤»¤ó: %s", search_str), hgt - 3 + 1, 0);
+                       prt(format("¥Ñ¥¿¡¼¥ó¤¬¸«¤Ä¤«¤ê¤Þ¤»¤ó: %s", tb->search_str), tb->hgt + 1 + 1, 0);
 #else
-                               prt(format("Pattern not found: %s", search_str), hgt - 3 + 1, 0);
+                       prt(format("Pattern not found: %s", tb->search_str), tb->hgt + 1 + 1, 0);
 #endif
-                       }
-                       else if (dirty_flags & DIRTY_NO_SEARCH)
-                       {
+               }
+               else if (tb->dirty_flags & DIRTY_NO_SEARCH)
+               {
 #ifdef JP
-                               prt("¸¡º÷Ãæ¤Î¥Ñ¥¿¡¼¥ó¤¬¤¢¤ê¤Þ¤»¤ó('/'¤Ç¸¡º÷)¡£", hgt - 3 + 1, 0);
+                       prt("¸¡º÷Ãæ¤Î¥Ñ¥¿¡¼¥ó¤¬¤¢¤ê¤Þ¤»¤ó('/'¤Ç¸¡º÷)¡£", tb->hgt + 1 + 1, 0);
 #else
-                               prt("No pattern to search. (Press '/' to search.)", hgt - 3 + 1, 0);
+                       prt("No pattern to search. (Press '/' to search.)", tb->hgt +1 + 1, 0);
 #endif
-                       }
-                       else if (lines_list[cy][0] == '#')
-                       {
+               }
+               else if (tb->lines_list[tb->cy][0] == '#')
+               {
 #ifdef JP
-                               prt("¤³¤Î¹Ô¤Ï¥³¥á¥ó¥È¤Ç¤¹¡£", hgt - 3 + 1, 0);
+                       prt("¤³¤Î¹Ô¤Ï¥³¥á¥ó¥È¤Ç¤¹¡£", tb->hgt +1 + 1, 0);
 #else
-                               prt("This line is a comment.", hgt - 3 + 1, 0);
+                       prt("This line is a comment.", tb->hgt +1 + 1, 0);
 #endif
-                       }
-                       else if (lines_list[cy][1] == ':')
+               }
+               else if (tb->lines_list[tb->cy][1] == ':')
+               {
+                       switch(tb->lines_list[tb->cy][0])
                        {
-                               switch(lines_list[cy][0])
-                               {
-                               case '?':
+                       case '?':
 #ifdef JP
-                                       prt("¤³¤Î¹Ô¤Ï¾ò·ïʬ´ô¼°¤Ç¤¹¡£", hgt - 3 + 1, 0);
+                               prt("¤³¤Î¹Ô¤Ï¾ò·ïʬ´ô¼°¤Ç¤¹¡£", tb->hgt +1 + 1, 0);
 #else
-                                       prt("This line is a Conditional Expression.", hgt - 3 + 1, 0);
+                               prt("This line is a Conditional Expression.", tb->hgt +1 + 1, 0);
 #endif
-                                       break;
-                               case 'A':
+                               break;
+                       case 'A':
 #ifdef JP
-                                       prt("¤³¤Î¹Ô¤Ï¥Þ¥¯¥í¤Î¼Â¹ÔÆâÍƤòÄêµÁ¤·¤Þ¤¹¡£", hgt - 3 + 1, 0);
+                               prt("¤³¤Î¹Ô¤Ï¥Þ¥¯¥í¤Î¼Â¹ÔÆâÍƤòÄêµÁ¤·¤Þ¤¹¡£", tb->hgt +1 + 1, 0);
 #else
-                                       prt("This line defines a Macro action.", hgt - 3 + 1, 0);
+                               prt("This line defines a Macro action.", tb->hgt +1 + 1, 0);
 #endif
-                                       break;
-                               case 'P':
+                               break;
+                       case 'P':
 #ifdef JP
-                                       prt("¤³¤Î¹Ô¤Ï¥Þ¥¯¥í¤Î¥È¥ê¥¬¡¼¡¦¥­¡¼¤òÄêµÁ¤·¤Þ¤¹¡£", hgt - 3 + 1, 0);
+                               prt("¤³¤Î¹Ô¤Ï¥Þ¥¯¥í¤Î¥È¥ê¥¬¡¼¡¦¥­¡¼¤òÄêµÁ¤·¤Þ¤¹¡£", tb->hgt +1 + 1, 0);
 #else
-                                       prt("This line defines a Macro trigger key.", hgt - 3 + 1, 0);
+                               prt("This line defines a Macro trigger key.", tb->hgt +1 + 1, 0);
 #endif
-                                       break;
-                               case 'C':
+                               break;
+                       case 'C':
 #ifdef JP
-                                       prt("¤³¤Î¹Ô¤Ï¥­¡¼ÇÛÃÖ¤òÄêµÁ¤·¤Þ¤¹¡£", hgt - 3 + 1, 0);
+                               prt("¤³¤Î¹Ô¤Ï¥­¡¼ÇÛÃÖ¤òÄêµÁ¤·¤Þ¤¹¡£", tb->hgt +1 + 1, 0);
 #else
-                                       prt("This line defines a Keymap.", hgt - 3 + 1, 0);
+                               prt("This line defines a Keymap.", tb->hgt +1 + 1, 0);
 #endif
-                                       break;
-                               }
+                               break;
                        }
+               }
 
-                       /* Get description of an autopicker preference line */
-                       else if (autopick_new_entry(entry, lines_list[cy]))
-                       {
-                               char temp[1024];
-                               cptr t;
+               /* Get description of an autopicker preference line */
+               else if (autopick_new_entry(entry, tb->lines_list[tb->cy]))
+               {
+                       char buf[MAX_LINELEN];
+                       char temp[MAX_LINELEN];
+                       cptr t;
 
-                               describe_autopick(buf, entry);
+                       describe_autopick(buf, entry);
 
-                               roff_to_buf(buf, 81, temp, sizeof(temp));
-                               t = temp;
-                               for (i = 0; i< 2; i++)
+                       roff_to_buf(buf, 81, temp, sizeof(temp));
+                       t = temp;
+                       for (i = 0; i < 3; i++)
+                       {
+                               if(t[0] == 0)
+                                       break; 
+                               else
                                {
-                                       if(t[0] == 0)
-                                               break; 
-                                       else
-                                       {
-                                               prt(t, hgt - 3 + 1 + i, 0);
-                                               t += strlen(t) + 1;
-                                       }
+                                       prt(t, tb->hgt +1 + 1 + i, 0);
+                                       t += strlen(t) + 1;
                                }
-                               autopick_free_entry(entry);
                        }
+                       autopick_free_entry(entry);
                }
+       }
+}
 
-               /* Place cursor */
-               Term_gotoxy(cx - left, cy - upper + 1);
 
-               /* Now clean */
-               dirty_flags = 0;
-               dirty_line = -1;
+/*
+ * Kill segment of a line
+ */
+static void kill_line_segment(text_body_type *tb, int y, int x0, int x1)
+{
+       char buf[MAX_LINELEN];
+       cptr s = tb->lines_list[y];
+       char *d = buf;
+       int x;
 
-               /* Save old key and location */
-               old_cy = cy;
-               old_key = key;
-               old_upper = upper;
-               old_left = left;
-               old_wid = wid;
-               old_hgt = hgt;
+       /* No segment? */
+       if (x0 == x1) return;
 
-               /* Do not process macros except special keys */
-               inkey_special = TRUE;
+       /* Kill whole line? */
+       if (x0 == 0 && s[x1] == '\0')
+       {
+               int i;
 
-               /* Get a command */
-               key = inkey();
+               string_free(tb->lines_list[y]);
 
-               if (edit_mode)
-               {
-                       if (key == ESCAPE)
-                       {
-                               edit_mode = FALSE;
+               /* Shift lines up */
+               for (i = y; tb->lines_list[i+1]; i++)
+                       tb->lines_list[i] = tb->lines_list[i+1];
+               tb->lines_list[i] = NULL;
 
-                               /* Mode line is now dirty */
-                               dirty_flags |= DIRTY_MODE;
-                       }
+               return;
+       }
 
-                       /* Insert a character */
-                       else if (!iscntrl(key&0xff))
-                       {
-                               /* Save preceding string */
-                               for (i = j = 0; lines_list[cy][i] && i < cx; i++)
-                                       buf[j++] = lines_list[cy][i];
+       /* Before the segment */
+       for (x = 0; x < x0; x++)
+               *(d++) = s[x];
 
-                               /* Add a character */
-#ifdef JP
-                               if (iskanji(key))
-                               {
-                                       int next;
+       /* After the segment */
+       for (x = x1; s[x]; x++)
+               *(d++) = s[x];
 
-                                       inkey_base = TRUE;
-                                       next = inkey();
-                                       if (j+2 < MAX_LINELEN)
-                                       {
-                                               buf[j++] = key;
-                                               buf[j++] = next;
-                                               cx += 2;
-                                       }
-                                       else
-                                               bell();
-                               }
-                               else
-#endif
-                               {
-                                       if (j+1 < MAX_LINELEN)
-                                               buf[j++] = key;
-                                       cx++;
-                               }
+       *d = '\0';
 
-                               /* Add following */
-                               for (; lines_list[cy][i] && j + 1 < MAX_LINELEN; i++)
-                                       buf[j++] = lines_list[cy][i];
-                               buf[j] = '\0';
+       /* Replace */
+       string_free(tb->lines_list[y]);
+       tb->lines_list[y] = string_make(buf);
+}
 
-                               /* Replace current line with new line */
-                               string_free(lines_list[cy]);
-                               lines_list[cy] = string_make(buf);
 
-                               /* Move to correct collumn */
-                               len = strlen(lines_list[cy]);
-                               if (len < cx) cx = len;
+/*
+ * Kill text in the block selection
+ */
+static bool kill_text_in_selection(text_body_type *tb, bool force)
+{
+       int by1, bx1, by2, bx2;
+       int y;
 
-                               /* Now dirty */
-                               dirty_line = cy;
-                       }
-               }
-               else
-               {
-                       /* Exit on 'q' */
-                       if (key == 'q' || key == '_') break;
+       if (!force && tb->mark == -1)
+       {
+               /* Don't kill auto selection block (by paste) */
+               tb->mark = 0;
 
-                       switch(key)
-                       {
-                       case 'a': case 'i':
-                               edit_mode = TRUE;
+               /* Now dirty */
+               tb->dirty_flags |= DIRTY_ALL;
 
-                               /* Mode line is now dirty */
-                               dirty_flags |= DIRTY_MODE;
-                               break;
-                       case '~':
-                               if (!autopick_new_entry(entry, lines_list[cy]))
-                               {
-                                       if (old_key != key) repeated_clearing = FALSE;
+               return FALSE;
+       }
 
-                                       /* Next line */
-                                       if (lines_list[cy + 1]) cy++;
-                                       cx = 0;
-                                       break;
-                               }
-                               string_free(lines_list[cy]);
+       /* Correct cursor location */
+       if ((uint)tb->cx > strlen(tb->lines_list[tb->cy]))
+               tb->cx = (int)strlen(tb->lines_list[tb->cy]);
 
-                               if (old_key != key)
-                               {
-                                       if (entry->action & DONT_AUTOPICK)
-                                               repeated_clearing = TRUE;
-                                       else
-                                               repeated_clearing = FALSE;
-                               }
+       if (tb->my < tb->cy ||
+           (tb->my == tb->cy && tb->mx < tb->cx))
+       {
+               by1 = tb->my;
+               bx1 = tb->mx;
+               by2 = tb->cy;
+               bx2 = tb->cx;
+       }
+       else
+       {
+               by2 = tb->my;
+               bx2 = tb->mx;
+               by1 = tb->cy;
+               bx1 = tb->cx;
+       }
 
-                               entry->action &= ~DO_AUTODESTROY;
-                               entry->action &= ~DO_QUERY_AUTOPICK;
-                               if (!repeated_clearing)
-                               {
-                                       entry->action &= ~DO_AUTOPICK;
-                                       entry->action |= DONT_AUTOPICK;
-                               }
-                               else 
-                               {
-                                       entry->action &= ~DONT_AUTOPICK;
-                                       entry->action |= DO_AUTOPICK;
-                               }
+       /* Kill lines in reverse order */
+       for (y = by2; y >= by1; y--)
+       {
+               int x0 = 0;
+               int x1 = strlen(tb->lines_list[y]);
 
-                               lines_list[cy] = autopick_line_from_entry_kill(entry);
+               if (y == by1) x0 = bx1;
+               if (y == by2) x1 = bx2;
 
-                               /* Now dirty */
-                               dirty_line = cy;
+               kill_line_segment(tb, y, x0, x1);
+       }
 
-                               /* Next line */
-                               if (lines_list[cy + 1]) cy++;
-                               cx = 0;
-                               break;
-                       case '!':
-                               if (!autopick_new_entry(entry, lines_list[cy]))
-                               {
-                                       if (old_key != key) repeated_clearing = FALSE;
+       /* Correct cursor position */
+       tb->cy = by1;
+       tb->cx = bx1;
 
-                                       /* Next line */
-                                       if (lines_list[cy + 1]) cy++;
-                                       cx = 0;
-                                       break;
-                               }
-                               string_free(lines_list[cy]);
+       /* Disable selection */
+       tb->mark = 0;
 
-                               if (old_key != key)
-                               {
-                                       if (entry->action & DO_AUTODESTROY)
-                                               repeated_clearing = TRUE;
-                                       else
-                                               repeated_clearing = FALSE;
-                               }
+       /* Now dirty */
+       tb->dirty_flags |= DIRTY_ALL;
 
-                               entry->action &= ~DONT_AUTOPICK;
-                               entry->action &= ~DO_QUERY_AUTOPICK;
-                               if (!repeated_clearing)
-                               {
-                                       entry->action &= ~DO_AUTOPICK;
-                                       entry->action |= DO_AUTODESTROY;
-                               }
-                               else 
-                               {
-                                       entry->action &= ~DO_AUTODESTROY;
-                                       entry->action |= DO_AUTOPICK;
-                               }
+       return TRUE;
+}
 
-                               lines_list[cy] = autopick_line_from_entry_kill(entry);
 
-                               /* Now dirty */
-                               dirty_line = cy;
+/*
+ * Get a trigger key and insert ASCII string for the trigger
+ */
+static bool insert_macro_line(cptr *lines_list, int cy)
+{
+       char tmp[1024];
+       char buf[1024];
+       int i, n = 0;
 
-                               /* Next line */
-                               if (lines_list[cy + 1]) cy++;
-                               cx = 0;
-                               break;
-                       case ';':
-                               if (!autopick_new_entry(entry, lines_list[cy]))
-                               {
-                                       if (old_key != key) repeated_clearing = FALSE;
+       /* Flush */
+       flush();
 
-                                       /* Next line */
-                                       if (lines_list[cy + 1]) cy++;
-                                       cx = 0;
-                                       break;
-                               }
-                               string_free(lines_list[cy]);
+       /* Do not process macros */
+       inkey_base = TRUE;
 
-                               if (old_key != key)
-                               {
-                                       if (entry->action & DO_QUERY_AUTOPICK)
-                                               repeated_clearing = TRUE;
-                                       else
-                                               repeated_clearing = FALSE;
-                               }
+       /* First key */
+       i = inkey();
 
-                               entry->action &= ~DO_AUTODESTROY;
-                               entry->action &= ~DONT_AUTOPICK;
-                               if (!repeated_clearing)
-                               {
-                                       entry->action &= ~DO_AUTOPICK;
-                                       entry->action |= DO_QUERY_AUTOPICK;
-                               }
-                               else 
-                               {
-                                       entry->action &= ~DO_QUERY_AUTOPICK;
-                                       entry->action |= DO_AUTOPICK;
-                               }
+       /* Read the pattern */
+       while (i)
+       {
+               /* Save the key */
+               buf[n++] = i;
 
-                               lines_list[cy] = autopick_line_from_entry_kill(entry);
+               /* Do not process macros */
+               inkey_base = TRUE;
 
-                               /* Now dirty */
-                               dirty_line = cy;
+               /* Do not wait for keys */
+               inkey_scan = TRUE;
 
-                               /* Next line */
-                               if (lines_list[cy + 1]) cy++;
-                               cx = 0;
-                               break;
-                       case '(':
-                               /* Toggle display on the 'M'ap */
-                               if (!autopick_new_entry(entry, lines_list[cy]))
-                               {
-                                       if (old_key != key) repeated_clearing = FALSE;
+               /* Attempt to read a key */
+               i = inkey();
+       }
 
-                                       /* Next line */
-                                       if (lines_list[cy + 1]) cy++;
-                                       cx = 0;
-                                       break;
-                               }
-                               string_free(lines_list[cy]);
+       /* Terminate */
+       buf[n] = '\0';
 
-                               if (old_key != key)
-                               {
-                                       if (entry->action & DO_DISPLAY)
-                                               repeated_clearing = TRUE;
-                                       else
-                                               repeated_clearing = FALSE;
-                               }
+       /* Flush */
+       flush();
 
-                               if (!repeated_clearing)
-                                       entry->action |= DO_DISPLAY;
-                               else
-                                       entry->action &= ~DO_DISPLAY;
+       /* Convert the trigger */
+       ascii_to_text(tmp, buf);
 
-                               lines_list[cy] = autopick_line_from_entry_kill(entry);
+       /* Null */
+       if(!tmp[0]) return FALSE;
 
-                               /* Now dirty */
-                               dirty_line = cy;
+       /* Insert preference string */
+       insert_return_code(lines_list, 0, cy);
+       string_free(lines_list[cy]);
+       lines_list[cy] = string_make(format("P:%s", tmp));
 
-                               /* Next line */
-                               if (lines_list[cy + 1]) cy++;
-                               cx = 0;
-                               break;
-                       case '#':
-                       case '{':
-                               key = KTRL('o');
-                               break;
-                       case 'h': case '4':
-                               key = KTRL('b');
-                               break;
-                       case 'l': case '6':
-                               key = KTRL('f');
-                               break;
-                       case 'j': case '2':
-                               key = KTRL('n');
-                               break;
-                       case 'k': case '8':
-                               key = KTRL('p');
-                               break;
-                       case ' ':
-                               while (cy < upper + hgt-4 && lines_list[cy + 1])
-                                       cy++;
-                               upper = cy;
-                               break;
-                       case '-': case 'b':
-                               while (0 < cy && upper <= cy)
-                                       cy--;
-                               while (0 < upper && cy + 1 < upper + hgt - 4)
-                                       upper--;
-                               break;
+       /* Acquire action */
+       i = macro_find_exact(buf);
+
+       if (i == -1)
+       {
+               /* Nothing defined */
+               tmp[0] = '\0';
+       }
+       else
+       {
+               /* Analyze the current action */
+               ascii_to_text(tmp, macro__act[i]);
+       }
+
+       /* Insert blank action preference line */
+       insert_return_code(lines_list, 0, cy);
+       string_free(lines_list[cy]);
+       lines_list[cy] = string_make(format("A:%s", tmp));
+
+       return TRUE;
+}
+
+
+/*
+ * Get a command key and insert ASCII string for the key
+ */
+static bool insert_keymap_line(cptr *lines_list, int cy)
+{
+       char tmp[1024];
+       char buf[2];
+       int mode;
+       cptr act;
+
+       /* Roguelike */
+       if (rogue_like_commands)
+       {
+               mode = KEYMAP_MODE_ROGUE;
+       }
+
+       /* Original */
+       else
+       {
+               mode = KEYMAP_MODE_ORIG;
+       }
+
+       /* Flush */
+       flush();
+
+       /* Get a key */
+       buf[0] = inkey();
+       buf[1] = '\0';
+
+       /* Flush */
+       flush();
+
+       /* Convert the trigger */
+       ascii_to_text(tmp, buf);
+
+       /* Null */
+       if(!tmp[0]) return FALSE;
+
+       /* Insert preference string */
+       insert_return_code(lines_list, 0, cy);
+       string_free(lines_list[cy]);
+       lines_list[cy] = string_make(format("C:%d:%s", mode, tmp));
+
+       /* Look up the keymap */
+       act = keymap_act[mode][(byte)(buf[0])];
+
+       /* Insert blank action preference line */
+       insert_return_code(lines_list, 0, cy);
+       string_free(lines_list[cy]);
+       lines_list[cy] = string_make(format("A:%s", act));
+
+       return TRUE;
+}
 
-                       case 'g':
-                               cy = 0;
-                               break;
 
-                       case 'G':
-                               while (lines_list[cy + 1])
-                                       cy++;
+/*
+ * Execute a single editor command
+ */
+static bool do_editor_command(text_body_type *tb, int com_id)
+{
+       switch(com_id)
+       {
+       case EC_QUIT:
+               return TRUE;
+
+       case EC_REVERT:
+               /* Revert to original */
+#ifdef JP
+               if (!get_check("Á´¤Æ¤ÎÊѹ¹¤òÇË´þ¤·¤Æ¸µ¤Î¾õÂÖ¤ËÌᤷ¤Þ¤¹¡£¤è¤í¤·¤¤¤Ç¤¹¤«¡© "))
+#else
+                       if (!get_check("Discard all changes and revert to original file. Are you sure? "))
+#endif
                                break;
 
-                       case 'm':
-                               /* Erase line */
-                               Term_erase(0, cy - upper + 1, wid - WID_DESC);
+               free_text_lines(tb->lines_list);
+               tb->lines_list = read_pickpref_text_lines(&tb->filename_mode);
+               tb->dirty_flags |= DIRTY_ALL | DIRTY_MODE;
+               tb->cx = tb->cy = 0;
+               break;
 
-                               /* Prompt */
+       case EC_HELP:
+               /* Peruse the main help file */
 #ifdef JP
-                               Term_putstr(0, cy - upper + 1, wid - WID_DESC - 1, TERM_YELLOW, "P:<¥È¥ê¥¬¡¼¥­¡¼>: ");
+               (void)show_file(TRUE, "jhelp.hlp", NULL, 0, 0);
 #else
-                               Term_putstr(0, cy - upper + 1, wid - WID_DESC - 1, TERM_YELLOW, "P:<Trigger key>: ");
+               (void)show_file(TRUE, "help.hlp", NULL, 0, 0);
 #endif
-                               if (insert_macro_line(lines_list, cy))
-                               {
-                                       /* Prepare to input action */
-                                       cx = 2;
-                                       edit_mode = TRUE;
+               /* Redraw all */
+               tb->dirty_flags |= DIRTY_SCREEN;
 
-                                       /* Now dirty */
-                                       dirty_flags |= DIRTY_ALL;
-                                       dirty_flags |= DIRTY_MODE;
-                               }
+               break;
 
-                               break;
+       case EC_RETURN:
+               /* Split a line or insert end of line */
 
-                       case 'c':
-                               /* Erase line */
-                               Term_erase(0, cy - upper + 1, wid - WID_DESC);
+               /*
+                * If there is a selection, kill it, and replace it
+                * with return code.
+                */
+               if (tb->mark) kill_text_in_selection(tb, FALSE);
+
+               insert_return_code(tb->lines_list, tb->cx, tb->cy);
+               tb->cy++;
+               tb->cx = 0;
+
+               /* Now dirty */
+               tb->dirty_flags |= DIRTY_ALL;
+               break;
+
+       case EC_LEFT:
+               /* Back */
+               if (0 < tb->cx)
+               {
+                       int len;
+
+                       tb->cx--;
+                       len = strlen(tb->lines_list[tb->cy]);
+                       if (len < tb->cx) tb->cx = len;
+               }
+               else if (tb->cy > 0)
+               {
+                       tb->cy--;
+                       tb->cx = strlen(tb->lines_list[tb->cy]);
+               }
+               break;
+
+       case EC_DOWN:
+               /* Next line */
+               if (tb->lines_list[tb->cy + 1]) tb->cy++;
+               break;
+
+       case EC_UP:
+               /* Previous line */
+               if (tb->cy > 0) tb->cy--;
+               break;
+
+       case EC_RIGHT:
+       {
+               /* Forward */
 
-                               /* Prompt */
+               int len;
 #ifdef JP
-                               Term_putstr(0, cy - upper + 1, wid - WID_DESC - 1, TERM_YELLOW, format("C:%d:<¥³¥Þ¥ó¥É¥­¡¼>: ", (rogue_like_commands ? KEYMAP_MODE_ROGUE : KEYMAP_MODE_ORIG)));
-#else
-                               Term_putstr(0, cy - upper + 1, wid - WID_DESC - 1, TERM_YELLOW, format("C:%d:<Keypress>: ", (rogue_like_commands ? KEYMAP_MODE_ROGUE : KEYMAP_MODE_ORIG)));
+               if (iskanji(tb->lines_list[tb->cy][tb->cx])) tb->cx++;
 #endif
+               tb->cx++;
+               len = strlen(tb->lines_list[tb->cy]);
+               if (len < tb->cx)
+               {
+                       if (tb->lines_list[tb->cy + 1])
+                       {
+                               tb->cy++;
+                               tb->cx = 0;
+                       }
+                       else
+                               tb->cx = len;
+               }
+               break;
+       }
 
-                               if (insert_keymap_line(lines_list, cy))
-                               {
-                                       /* Prepare to input action */
-                                       cx = 2;
-                                       edit_mode = TRUE;
-
-                                       /* Now dirty */
-                                       dirty_flags |= DIRTY_ALL;
-                                       dirty_flags |= DIRTY_MODE;
-                               }                               
-                               break;
-                       case '/':
-                               /* Become dirty because of item/equip menu */
-                               dirty_flags |= DIRTY_SCREEN;
+       case EC_BOL:
+               /* Beginning of line */
+               tb->cx = 0;
+               break;
 
-                               if (!get_string_for_search(&search_o_ptr, &search_str))
-                                       break;
+       case EC_EOL:
+               /* End of line */
+               tb->cx = strlen(tb->lines_list[tb->cy]);
+               break;
 
-                               /* fall through */
-                       case 'n':
-                               if (search_o_ptr)
-                               {
-                                       if (!search_for_object(lines_list, search_o_ptr, &cx, &cy, TRUE)) dirty_flags |= DIRTY_NOT_FOUND;
-                               }
-                               else if (search_str)
-                               {
-                                       if (!search_for_string(lines_list, search_str, &cx, &cy, TRUE)) dirty_flags |= DIRTY_NOT_FOUND;
-                               }
-                               else
-                               {
-                                       dirty_flags |= DIRTY_NO_SEARCH;
-                               }
-                               break;
-                       case 'N':
-                               if (search_o_ptr)
-                               {
-                                       if (!search_for_object(lines_list, search_o_ptr, &cx, &cy, FALSE)) dirty_flags |= DIRTY_NOT_FOUND;
-                               }
-                               else if (search_str)
-                               {
-                                       if (!search_for_string(lines_list, search_str, &cx, &cy, FALSE)) dirty_flags |= DIRTY_NOT_FOUND;
-                               }
-                               else
-                               {
-                                       dirty_flags |= DIRTY_NO_SEARCH;
-                               }
+       case EC_PGUP:
+               while (0 < tb->cy && tb->upper <= tb->cy)
+                       tb->cy--;
+               while (0 < tb->upper && tb->cy + 1 < tb->upper + tb->hgt)
+                       tb->upper--;
+               break;
+
+       case EC_PGDOWN:
+               /* Page down */
+               while (tb->cy < tb->upper + tb->hgt && tb->lines_list[tb->cy + 1])
+                       tb->cy++;
+               tb->upper = tb->cy;
+               break;
+
+       case EC_TOP:
+               tb->cy = 0;
+               break;
+
+       case EC_BOTTOM:
+               while (tb->lines_list[tb->cy + 1])
+                       tb->cy++;
+               break;
+
+       case EC_CUT:
+       {       
+               /* Need block selection */
+               if (!tb->mark) break;
+
+               /* Copy the text first */
+               do_editor_command(tb, EC_COPY);
+
+               /* Kill all */
+               kill_text_in_selection(tb, TRUE);
+
+               break;
+       }
+
+       case EC_COPY:
+       {       
+               int by1, bx1, by2, bx2;
+               int y;
+
+               /* Need block selection */
+               if (!tb->mark) break;
+
+               /* Correct cursor location */
+               if ((uint)tb->cx > strlen(tb->lines_list[tb->cy]))
+                       tb->cx = (int)strlen(tb->lines_list[tb->cy]);
+
+               if (tb->my < tb->cy ||
+                   (tb->my == tb->cy && tb->mx < tb->cx))
+               {
+                       by1 = tb->my;
+                       bx1 = tb->mx;
+                       by2 = tb->cy;
+                       bx2 = tb->cx;
+               }
+               else
+               {
+                       by2 = tb->my;
+                       bx2 = tb->mx;
+                       by1 = tb->cy;
+                       bx1 = tb->cx;
+               }
+
+               /* Kill old yank buffer */
+               kill_yank_chain(tb);
+
+               /* Copy string to yank buffer */
+               for (y = by1; y <= by2; y++)
+               {
+                       int i;
+                       char buf[MAX_LINELEN];
+
+                       int x0 = 0;
+                       int x1 = strlen(tb->lines_list[y]);
+
+                       if (y == by1) x0 = bx1;
+                       if (y == by2) x1 = bx2;
+
+                       for (i = 0; i < x1 - x0; i++)
+                       {
+                               buf[i] = tb->lines_list[y][x0 + i];
+                       }
+                       buf[i] = '\0';
+
+                       add_str_to_yank(tb, buf);
+               }
+
+               /* Disable selection */
+               tb->mark = 0;
+
+               /* Now dirty */
+               tb->dirty_flags |= DIRTY_ALL;
+               break;
+       }
+
+       case EC_PASTE:
+       {
+               /* Paste killed text */
+
+               chain_str_type *chain = tb->yank;
+
+               /* Correct cursor location */
+               if ((uint)tb->cx > strlen(tb->lines_list[tb->cy]))
+                       tb->cx = (int)strlen(tb->lines_list[tb->cy]);
+
+               /*
+                * If there is a selection, kill text, and
+                * replace it with the yank text.
+                */
+               if (tb->mark) kill_text_in_selection(tb, FALSE);
+
+               /* Auto select pasted text */
+               tb->mark = -1;
+               tb->mx = tb->cx;
+               tb->my = tb->cy;
+
+               /* Paste text */
+               while (chain)
+               {
+                       cptr yank_str = chain->s;
+
+                       char buf[MAX_LINELEN];
+                       int i;
+                       char rest[MAX_LINELEN], *rest_ptr = rest;
+
+                       /* Save preceding string */
+                       for(i = 0; i < tb->cx; i++)
+                               buf[i] = tb->lines_list[tb->cy][i];
+
+                       strcpy(rest, &(tb->lines_list[tb->cy][i]));
+
+                       /* Paste yank buffer */
+                       while (*yank_str && i < MAX_LINELEN-1)
+                       {
+                               buf[i++] = *yank_str++;
+                       }
+
+                       /* Terminate */
+                       buf[i] = '\0';
+
+                       chain = chain->next;
+
+                       if (chain || tb->yank_eol)
+                       {
+                               /* There is an end of line between chain nodes */
+
+                               insert_return_code(tb->lines_list, tb->cx, tb->cy);
+
+                               /* Replace this line with new one */
+                               string_free(tb->lines_list[tb->cy]);
+                               tb->lines_list[tb->cy] = string_make(buf);
+
+                               /* Move to next line */
+                               tb->cx = 0;
+                               tb->cy++;
+
+                               continue;
+                       }
+
+                       /* Final line doesn't have end of line */
+
+                       tb->cx = strlen(buf);
+
+                       /* Rest of original line */
+                       while (*rest_ptr && i < MAX_LINELEN-1)
+                       {
+                               buf[i++] = *rest_ptr++;
+                       }
+
+                       /* Terminate */
+                       buf[i] = '\0';
+
+                       /* Replace this line with new one */
+                       string_free(tb->lines_list[tb->cy]);
+                       tb->lines_list[tb->cy] = string_make(buf);
+
+                       /* Finish */
+                       break;
+               }
+
+               /* Now dirty */
+               tb->dirty_flags |= DIRTY_ALL;
+               break;
+       }
+
+       case EC_BLOCK:
+               if (tb->mark)
+               {
+                       /* Disable the selection */
+                       tb->mark = 0;
+
+                       /* Redraw text */
+                       tb->dirty_flags |= DIRTY_ALL;
+               }
+               else
+               {
+                       tb->mark = 1;
+
+                       /* Repeating this command swaps cursor position */
+                       if (com_id == tb->old_com_id)
+                       {
+                               int tmp;
+
+                               tmp = tb->cy;
+                               tb->cy = tb->my;
+                               tb->my = tmp;
+                               tmp = tb->cx;
+                               tb->cx = tb->mx;
+                               tb->mx = tmp;
+
+                               /* Redraw text */
+                               tb->dirty_flags |= DIRTY_ALL;
+                       }
+                       else
+                       {
+                               /* Mark the point 1 */
+                               tb->my = tb->cy;
+                               tb->mx = tb->cx;
+                       }
+               }
+               break;
+
+       case EC_KILL_LINE:
+       {
+               /* Kill rest of line */
+
+               int i;
+               char buf[MAX_LINELEN];
+               cptr line;
+
+               /* If there is a selection, kill it */
+               if (tb->mark)
+               {
+                       if (kill_text_in_selection(tb, FALSE)) break;
+               }
+
+               /* Correct cursor location */
+               if ((uint)tb->cx > strlen(tb->lines_list[tb->cy]))
+                       tb->cx = (int)strlen(tb->lines_list[tb->cy]);
+
+               /* Save preceding string */
+               for (i = 0; tb->lines_list[tb->cy][i] && i < tb->cx; i++)
+               {
+#ifdef JP
+                       if (iskanji(tb->lines_list[tb->cy][i]))
+                       {
+                               buf[i] = tb->lines_list[tb->cy][i];
+                               i++;
+                       }
+#endif
+                       buf[i] = tb->lines_list[tb->cy][i];
+               }
+               buf[i] = '\0';
+               line = string_make(buf);
+
+               /* Append only if this command is repeated. */
+               if (tb->old_com_id != com_id)
+               {
+                       kill_yank_chain(tb);
+                       tb->yank = NULL;
+               }
+
+               /* Really deleted some text */
+               if (strlen(tb->lines_list[tb->cy] + i))
+               {
+                       /* Add deleted string to yank buffer */
+                       add_str_to_yank(tb, tb->lines_list[tb->cy] + i);
+
+                       /* Replace current line with 'preceding string' */
+                       string_free(tb->lines_list[tb->cy]);
+                       tb->lines_list[tb->cy] = line;
+
+                       /* Now dirty */
+                       tb->dirty_line = tb->cy;
+
+                       /* Leave end of line character */
+                       break;
+               }
+
+               /* Delete the end of line character only */
+               if (tb->yank_eol) add_str_to_yank(tb, "");
+               else tb->yank_eol = TRUE;
+
+               do_editor_command(tb, EC_DELETE_CHAR);
+               break;
+       }
+
+       case EC_DELETE_CHAR:
+               /* DELETE == go forward + BACK SPACE */
+
+               /* If there is a selection, kill it */
+               if (tb->mark)
+               {
+                       if (kill_text_in_selection(tb, FALSE)) break;
+               }
+
+#ifdef JP
+               if (iskanji(tb->lines_list[tb->cy][tb->cx])) tb->cx++;
+#endif
+               tb->cx++;
+
+               do_editor_command(tb, EC_BACKSPACE);
+               break;
+
+       case EC_BACKSPACE:
+       {
+               /* BACK SPACE */
+
+               int len, i, j, k;
+               char buf[MAX_LINELEN];
+
+               /* If there is a selection, kill it */
+               if (tb->mark)
+               {
+                       if (kill_text_in_selection(tb, FALSE)) break;
+               }
+
+               len = strlen(tb->lines_list[tb->cy]);
+               if (len < tb->cx)
+               {
+                       if (tb->lines_list[tb->cy + 1])
+                       {
+                               tb->cy++;
+                               tb->cx = 0;
+                       }
+                       else
+                       {
+                               tb->cx = len;
                                break;
                        }
                }
 
-               switch(key)
+               if (tb->cx == 0)
+               {
+                       /* delete a return code and union two lines */
+                       if (tb->cy == 0) break;
+                       tb->cx = strlen(tb->lines_list[tb->cy-1]);
+                       strcpy(buf, tb->lines_list[tb->cy-1]);
+                       strcat(buf, tb->lines_list[tb->cy]);
+                       string_free(tb->lines_list[tb->cy-1]);
+                       string_free(tb->lines_list[tb->cy]);
+                       tb->lines_list[tb->cy-1] = string_make(buf);
+                       for (i = tb->cy; tb->lines_list[i+1]; i++)
+                               tb->lines_list[i] = tb->lines_list[i+1];
+                       tb->lines_list[i] = NULL;
+                       tb->cy--;
+
+                       /* Now dirty */
+                       tb->dirty_flags |= DIRTY_ALL;
+                       break;
+               }
+
+               for (i = j = k = 0; tb->lines_list[tb->cy][i] && i < tb->cx; i++)
+               {
+                       k = j;
+#ifdef JP
+                       if (iskanji(tb->lines_list[tb->cy][i]))
+                               buf[j++] = tb->lines_list[tb->cy][i++];
+#endif
+                       buf[j++] = tb->lines_list[tb->cy][i];
+               }
+               while (j > k)
+               {
+                       tb->cx--;
+                       j--;
+               }
+               for (; tb->lines_list[tb->cy][i]; i++)
+                       buf[j++] = tb->lines_list[tb->cy][i];
+               buf[j] = '\0';
+               string_free(tb->lines_list[tb->cy]);
+               tb->lines_list[tb->cy] = string_make(buf);
+
+               /* Now dirty */
+               tb->dirty_line = tb->cy;
+               break;
+       }
+
+       case EC_SEARCH_STR:
+       {
+               byte search_dir;
+
+               /* Become dirty because of item/equip menu */
+               tb->dirty_flags |= DIRTY_SCREEN;
+
+               search_dir = get_string_for_search(&tb->search_o_ptr, &tb->search_str);
+
+               if (!search_dir) break;
+
+               if (search_dir == 1) do_editor_command(tb, EC_SEARCH_FORW);
+               else do_editor_command(tb, EC_SEARCH_BACK);
+               break;
+       }
+
+       case EC_SEARCH_FORW:
+               if (tb->search_o_ptr)
+               {
+                       if (!search_for_object(tb->lines_list, tb->search_o_ptr, &tb->cx, &tb->cy, TRUE)) tb->dirty_flags |= DIRTY_NOT_FOUND;
+               }
+               else if (tb->search_str)
+               {
+                       if (!search_for_string(tb->lines_list, tb->search_str, &tb->cx, &tb->cy, TRUE)) tb->dirty_flags |= DIRTY_NOT_FOUND;
+               }
+               else
+               {
+                       tb->dirty_flags |= DIRTY_NO_SEARCH;
+               }
+               break;
+
+       case EC_SEARCH_BACK:
+               if (tb->search_o_ptr)
+               {
+                       if (!search_for_object(tb->lines_list, tb->search_o_ptr, &tb->cx, &tb->cy, FALSE)) tb->dirty_flags |= DIRTY_NOT_FOUND;
+               }
+               else if (tb->search_str)
+               {
+                       if (!search_for_string(tb->lines_list, tb->search_str, &tb->cx, &tb->cy, FALSE)) tb->dirty_flags |= DIRTY_NOT_FOUND;
+               }
+               else
+               {
+                       tb->dirty_flags |= DIRTY_NO_SEARCH;
+               }
+               break;
+
+       case EC_SEARCH_OBJ:
+               /* Become dirty because of item/equip menu */
+               tb->dirty_flags |= DIRTY_SCREEN;
+
+               if (!get_object_for_search(&tb->search_o_ptr, &tb->search_str)) break;
+
+               do_editor_command(tb, EC_SEARCH_FORW);
+               break;
+
+       case EC_SEARCH_DESTROYED:
+               if (!get_destroyed_object_for_search(&tb->search_o_ptr, &tb->search_str)) break;
+
+               do_editor_command(tb, EC_SEARCH_FORW);
+               break;
+
+       case EC_INSERT_OBJECT:
+       {
+               /* Insert choosen item name */
+
+               autopick_type an_entry, *entry = &an_entry;
+
+               if (!entry_from_choosed_object(entry))
+               {
+                       /* Now dirty because of item/equip menu */
+                       tb->dirty_flags |= DIRTY_SCREEN;
+                       break;
+               }
+
+               insert_return_code(tb->lines_list, 0, tb->cy);
+               string_free(tb->lines_list[tb->cy]);
+               tb->lines_list[tb->cy] = autopick_line_from_entry_kill(entry);
+               tb->cx = 0;
+
+               /* Now dirty because of item/equip menu */
+               tb->dirty_flags |= DIRTY_SCREEN;
+
+               break;
+       }
+
+       case EC_INSERT_DESTROYED:
+               /* Insert a name of last destroyed item */
+               if (tb->last_destroyed)
+               {
+                       insert_return_code(tb->lines_list, 0, tb->cy);
+                       string_free(tb->lines_list[tb->cy]);
+                       tb->lines_list[tb->cy] = string_make(tb->last_destroyed);
+                       tb->cx = 0;
+
+                       /* Now dirty */
+                       tb->dirty_flags |= DIRTY_ALL;
+               }
+               break;
+
+       case EC_INSERT_BLOCK:
+       {
+               /* Insert a conditinal expression line */
+               char classrace[80];
+
+               /* Conditional Expression for Class and Race */
+               sprintf(classrace, "?:[AND [EQU $RACE %s] [EQU $CLASS %s]]", 
+#ifdef JP
+                       rp_ptr->E_title, cp_ptr->E_title
+#else
+                       rp_ptr->title, cp_ptr->title
+#endif
+                       );
+
+               insert_return_code(tb->lines_list, 0, tb->cy);
+               string_free(tb->lines_list[tb->cy]);
+               tb->lines_list[tb->cy] = string_make(classrace);
+               tb->cy++;
+               insert_return_code(tb->lines_list, 0, tb->cy);
+               string_free(tb->lines_list[tb->cy]);
+               tb->lines_list[tb->cy] = string_make("?:1");
+               tb->cx = 0;
+
+               /* Now dirty */
+               tb->dirty_flags |= DIRTY_ALL;
+               break;
+       }
+
+       case EC_INSERT_MACRO:
+               /* Draw_everythig (delete menu) */
+               draw_text_editor(tb);
+
+               /* Erase line */
+               Term_erase(0, tb->cy - tb->upper + 1, tb->wid);
+
+               /* Prompt */
+#ifdef JP
+               Term_putstr(0, tb->cy - tb->upper + 1, tb->wid - 1, TERM_YELLOW, "P:<¥È¥ê¥¬¡¼¥­¡¼>: ");
+#else
+               Term_putstr(0, tb->cy - tb->upper + 1, tb->wid - 1, TERM_YELLOW, "P:<Trigger key>: ");
+#endif
+               if (insert_macro_line(tb->lines_list, tb->cy))
+               {
+                       /* Prepare to input action */
+                       tb->cx = 2;
+
+                       /* Now dirty */
+                       tb->dirty_flags |= DIRTY_ALL;
+                       tb->dirty_flags |= DIRTY_MODE;
+               }
+
+               break;
+
+       case EC_INSERT_KEYMAP:
+               /* Draw_everythig (delete menu) */
+               draw_text_editor(tb);
+
+               /* Erase line */
+               Term_erase(0, tb->cy - tb->upper + 1, tb->wid);
+
+               /* Prompt */
+#ifdef JP
+               Term_putstr(0, tb->cy - tb->upper + 1, tb->wid - 1, TERM_YELLOW, format("C:%d:<¥³¥Þ¥ó¥É¥­¡¼>: ", (rogue_like_commands ? KEYMAP_MODE_ROGUE : KEYMAP_MODE_ORIG)));
+#else
+               Term_putstr(0, tb->cy - tb->upper + 1, tb->wid - 1, TERM_YELLOW, format("C:%d:<Keypress>: ", (rogue_like_commands ? KEYMAP_MODE_ROGUE : KEYMAP_MODE_ORIG)));
+#endif
+
+               if (insert_keymap_line(tb->lines_list, tb->cy))
+               {
+                       /* Prepare to input action */
+                       tb->cx = 2;
+
+                       /* Now dirty */
+                       tb->dirty_flags |= DIRTY_ALL;
+                       tb->dirty_flags |= DIRTY_MODE;
+               }                               
+               break;
+
+       case EC_CL_AUTOPICK:
+       {
+               autopick_type an_entry, *entry = &an_entry;
+
+               if (!autopick_new_entry(entry, tb->lines_list[tb->cy]))
+               {
+                       break;
+               }
+               string_free(tb->lines_list[tb->cy]);
+
+               if (entry->action & (DO_AUTODESTROY | DONT_AUTOPICK | DO_QUERY_AUTOPICK))
+                       if (tb->cx > 0) tb->cx--;
+
+               entry->action &= ~DO_AUTODESTROY;
+               entry->action &= ~DONT_AUTOPICK;
+               entry->action &= ~DO_QUERY_AUTOPICK;
+               entry->action |= DO_AUTOPICK;
+
+               tb->lines_list[tb->cy] = autopick_line_from_entry_kill(entry);
+
+               /* Now dirty */
+               tb->dirty_line = tb->cy;
+               break;
+       }
+
+       case EC_CL_DESTROY:
+       {
+               autopick_type an_entry, *entry = &an_entry;
+
+               if (!autopick_new_entry(entry, tb->lines_list[tb->cy]))
+               {
+                       break;
+               }
+               string_free(tb->lines_list[tb->cy]);
+
+               entry->action &= ~DONT_AUTOPICK;
+               entry->action &= ~DO_QUERY_AUTOPICK;
+               if (!(entry->action & DO_AUTODESTROY))
+               {
+                       entry->action &= ~DO_AUTOPICK;
+                       entry->action |= DO_AUTODESTROY;
+                       tb->cx++;
+               }
+               else 
+               {
+                       entry->action &= ~DO_AUTODESTROY;
+                       entry->action |= DO_AUTOPICK;
+                       if (tb->cx > 0) tb->cx--;
+               }
+
+               tb->lines_list[tb->cy] = autopick_line_from_entry_kill(entry);
+
+               /* Now dirty */
+               tb->dirty_line = tb->cy;
+
+               break;
+       }
+
+       case EC_CL_LEAVE:
+       {
+               autopick_type an_entry, *entry = &an_entry;
+
+               if (!autopick_new_entry(entry, tb->lines_list[tb->cy]))
+               {
+                       break;
+               }
+               string_free(tb->lines_list[tb->cy]);
+
+               entry->action &= ~DO_AUTODESTROY;
+               entry->action &= ~DO_QUERY_AUTOPICK;
+               if (!(entry->action & DONT_AUTOPICK))
+               {
+                       entry->action &= ~DO_AUTOPICK;
+                       entry->action |= DONT_AUTOPICK;
+                       tb->cx++;
+               }
+               else 
+               {
+                       entry->action &= ~DONT_AUTOPICK;
+                       entry->action |= DO_AUTOPICK;
+                       if (tb->cx > 0) tb->cx--;
+               }
+
+               tb->lines_list[tb->cy] = autopick_line_from_entry_kill(entry);
+
+               /* Now dirty */
+               tb->dirty_line = tb->cy;
+               break;
+       }
+
+       case EC_CL_QUERY:
+       {
+               autopick_type an_entry, *entry = &an_entry;
+
+               if (!autopick_new_entry(entry, tb->lines_list[tb->cy]))
                {
-               case KTRL('a'):
-                       /* Beginning of line */
-                       cx = 0;
-                       break;
-               case KTRL('b'):
-                       /* Back */
-                       if (0 < cx)
-                       {
-                               cx--;
-                               len = strlen(lines_list[cy]);
-                               if (len < cx) cx = len;
-                       }
-                       else if (cy > 0)
-                       {
-                               cy--;
-                               cx = strlen(lines_list[cy]);
-                       }
                        break;
-               case KTRL('c'):
-                       /* Insert a conditinal expression line */
-                       insert_return_code(lines_list, 0, cy);
-                       string_free(lines_list[cy]);
-                       lines_list[cy] = string_make(classrace);
-                       cy++;
-                       insert_return_code(lines_list, 0, cy);
-                       string_free(lines_list[cy]);
-                       lines_list[cy] = string_make("?:1");
-                       cx = 0;
+               }
+               string_free(tb->lines_list[tb->cy]);
 
-                       /* Now dirty */
-                       dirty_flags |= DIRTY_ALL;
-                       break;
-               case KTRL('e'):
-                       /* End of line */
-                       cx = strlen(lines_list[cy]);
-                       break;
-               case KTRL('f'):
-                       /* Forward */
-#ifdef JP
-                       if (iskanji(lines_list[cy][cx])) cx++;
-#endif
-                       cx++;
-                       len = strlen(lines_list[cy]);
-                       if (len < cx)
-                       {
-                               if (lines_list[cy + 1])
-                               {
-                                       cy++;
-                                       cx = 0;
-                               }
-                               else
-                                       cx = len;
-                       }
-                       break;
-               case KTRL('g'):
-                       /* Toggle display on the 'M'ap */
-                       if (!autopick_new_entry(entry, lines_list[cy]))
-                               break;
-                       string_free(lines_list[cy]);
+               entry->action &= ~DO_AUTODESTROY;
+               entry->action &= ~DONT_AUTOPICK;
+               if (!(entry->action & DO_QUERY_AUTOPICK))
+               {
+                       entry->action &= ~DO_AUTOPICK;
+                       entry->action |= DO_QUERY_AUTOPICK;
+                       tb->cx++;
+               }
+               else 
+               {
+                       entry->action &= ~DO_QUERY_AUTOPICK;
+                       entry->action |= DO_AUTOPICK;
+                       if (tb->cx > 0) tb->cx--;
+               }
 
-                       if (entry->action & DO_DISPLAY)
-                       {
-                               entry->action &= ~DO_DISPLAY;
-                               cx++;
-                       }
-                       else
-                       {
-                               entry->action |= DO_DISPLAY;
-                               if (cx > 0) cx--;
-                       }
+               tb->lines_list[tb->cy] = autopick_line_from_entry_kill(entry);
 
-                       lines_list[cy] = autopick_line_from_entry_kill(entry);
+               /* Now dirty */
+               tb->dirty_line = tb->cy;
+               break;
+       }
 
-                       /* Now dirty */
-                       dirty_line = cy;
+       case EC_CL_NO_DISP:
+       {
+               /* Toggle display on the 'M'ap */
+
+               autopick_type an_entry, *entry = &an_entry;
+
+               if (!autopick_new_entry(entry, tb->lines_list[tb->cy]))
                        break;
-               case KTRL('i'):
-                       /* Insert choosen item name */
-                       if (!entry_from_choosed_object(entry))
-                       {
-                               /* Now dirty because of item/equip menu */
-                               dirty_flags |= DIRTY_SCREEN;
-                               break;
-                       }
+               string_free(tb->lines_list[tb->cy]);
 
-                       insert_return_code(lines_list, 0, cy);
-                       string_free(lines_list[cy]);
-                       lines_list[cy] = autopick_line_from_entry_kill(entry);
-                       cx = 0;
+               if (entry->action & DO_DISPLAY)
+               {
+                       entry->action &= ~DO_DISPLAY;
+                       tb->cx++;
+               }
+               else
+               {
+                       entry->action |= DO_DISPLAY;
+                       if (tb->cx > 0) tb->cx--;
+               }
 
-                       /* Now dirty because of item/equip menu */
-                       dirty_flags |= DIRTY_SCREEN;
+               tb->lines_list[tb->cy] = autopick_line_from_entry_kill(entry);
 
-                       break;
-               case KTRL('l'):
-                       /* Insert a name of last destroyed item */
-                       if (last_destroyed)
-                       {
-                               insert_return_code(lines_list, 0, cy);
-                               string_free(lines_list[cy]);
-                               lines_list[cy] = string_make(last_destroyed);
-                               cx = 0;
+               /* Now dirty */
+               tb->dirty_line = tb->cy;
+               break;
+       }
 
-                               /* Now dirty */
-                               dirty_flags |= DIRTY_ALL;
-                       }
-                       break;
-               case '\n': case '\r':
-                       /* Split a line or insert end of line */
-                       insert_return_code(lines_list, cx, cy);
-                       cy++;
-                       cx = 0;
+       case EC_IK_UNAWARE: toggle_keyword(tb, FLG_UNAWARE); break;
+       case EC_IK_UNIDENTIFIED: toggle_keyword(tb, FLG_UNIDENTIFIED); break;
+       case EC_IK_IDENTIFIED: toggle_keyword(tb, FLG_IDENTIFIED); break;
+       case EC_IK_STAR_IDENTIFIED: toggle_keyword(tb, FLG_STAR_IDENTIFIED); break;
+       case EC_KK_WEAPONS: toggle_keyword(tb, FLG_WEAPONS); break;
+       case EC_KK_FAVORITE: toggle_keyword(tb, FLG_FAVORITE); break;
+       case EC_KK_ARMORS: toggle_keyword(tb, FLG_ARMORS); break;
+       case EC_KK_MISSILES: toggle_keyword(tb, FLG_MISSILES); break;
+       case EC_KK_DEVICES: toggle_keyword(tb, FLG_DEVICES); break;
+       case EC_KK_LIGHTS: toggle_keyword(tb, FLG_LIGHTS); break;
+       case EC_KK_JUNKS: toggle_keyword(tb, FLG_JUNKS); break;
+       case EC_KK_SPELLBOOKS: toggle_keyword(tb, FLG_SPELLBOOKS); break;
+       case EC_KK_SHIELDS: toggle_keyword(tb, FLG_SHIELDS); break;
+       case EC_KK_BOWS: toggle_keyword(tb, FLG_BOWS); break;
+       case EC_KK_RINGS: toggle_keyword(tb, FLG_RINGS); break;
+       case EC_KK_AMULETS: toggle_keyword(tb, FLG_AMULETS); break;
+       case EC_KK_SUITS: toggle_keyword(tb, FLG_SUITS); break;
+       case EC_KK_CLOAKS: toggle_keyword(tb, FLG_CLOAKS); break;
+       case EC_KK_HELMS: toggle_keyword(tb, FLG_HELMS); break;
+       case EC_KK_GLOVES: toggle_keyword(tb, FLG_GLOVES); break;
+       case EC_KK_BOOTS: toggle_keyword(tb, FLG_BOOTS); break;
+       case EC_OK_COLLECTING: toggle_keyword(tb, FLG_COLLECTING); break;
+       case EC_OK_BOOSTED: toggle_keyword(tb, FLG_BOOSTED); break;
+       case EC_OK_MORE_THAN: toggle_keyword(tb, FLG_MORE_THAN); break;
+       case EC_OK_MORE_BONUS: toggle_keyword(tb, FLG_MORE_BONUS); break;
+       case EC_OK_WORTHLESS: toggle_keyword(tb, FLG_WORTHLESS); break;
+       case EC_OK_ARTIFACT: toggle_keyword(tb, FLG_ARTIFACT); break;
+       case EC_OK_EGO: toggle_keyword(tb, FLG_EGO); break;
+       case EC_OK_NAMELESS: toggle_keyword(tb, FLG_NAMELESS); break;
+       case EC_OK_WANTED: toggle_keyword(tb, FLG_WANTED); break;
+       case EC_OK_UNIQUE: toggle_keyword(tb, FLG_UNIQUE); break;
+       case EC_OK_HUMAN: toggle_keyword(tb, FLG_HUMAN); break;
+       case EC_OK_UNREADABLE:
+               toggle_keyword(tb, FLG_UNREADABLE);
+               add_keyword(tb, FLG_SPELLBOOKS);
+               break;
+       case EC_OK_REALM1:
+               toggle_keyword(tb, FLG_REALM1);
+               add_keyword(tb, FLG_SPELLBOOKS);
+               break;
+       case EC_OK_REALM2:
+               toggle_keyword(tb, FLG_REALM2);
+               add_keyword(tb, FLG_SPELLBOOKS);
+               break;
+       case EC_OK_FIRST:
+               toggle_keyword(tb, FLG_FIRST);
+               add_keyword(tb, FLG_SPELLBOOKS);
+               break;
+       case EC_OK_SECOND:
+               toggle_keyword(tb, FLG_SECOND);
+               add_keyword(tb, FLG_SPELLBOOKS);
+               break;
+       case EC_OK_THIRD:
+               toggle_keyword(tb, FLG_THIRD);
+               add_keyword(tb, FLG_SPELLBOOKS);
+               break;
+       case EC_OK_FOURTH:
+               toggle_keyword(tb, FLG_FOURTH);
+               add_keyword(tb, FLG_SPELLBOOKS);
+               break;
+       }
 
-                       /* Now dirty */
-                       dirty_flags |= DIRTY_ALL;
-                       break;
-               case KTRL('n'):
-                       /* Next line */
-                       if (lines_list[cy + 1]) cy++;
-                       break;
-               case KTRL('o'):
-                       /* Prepare to write auto-inscription text */
-                       if (!autopick_new_entry(entry, lines_list[cy]))
-                               break;
-                       string_free(lines_list[cy]);
+       /* Save old command */
+       tb->old_com_id = com_id;
 
-                       if (!entry->insc) entry->insc = string_make("");
+       return FALSE;
+}
 
-                       lines_list[cy] = autopick_line_from_entry_kill(entry);
 
-                       /* Move to collumn for auto inscription */
-                       for (cx = 0; lines_list[cy][cx]; cx++)
-                               if (lines_list[cy][cx] == '#') break;
-                       cx++;
-                       edit_mode = TRUE;
+/*
+ * Insert single letter at cursor position.
+ */
+static void insert_single_letter(text_body_type *tb, int key)
+{
+       int i, j, len;
+       char buf[MAX_LINELEN];
 
-                       /* Now dirty */
-                       dirty_line = cy;
-                       dirty_flags |= DIRTY_MODE;
-                       break;
-               case KTRL('p'):
-                       /* Previous line */
-                       if (cy > 0) cy--;
-                       break;
-               case KTRL('q'):
-                       /* Change mode */
-                       edit_mode = !edit_mode;
-                       
-                       /* Mode line is now dirty */
-                       dirty_flags |= DIRTY_MODE;
-                       break;
-               case KTRL('r'):
-                       /* Revert to original */
+       /* Save preceding string */
+       for (i = j = 0; tb->lines_list[tb->cy][i] && i < tb->cx; i++)
+               buf[j++] = tb->lines_list[tb->cy][i];
+
+       /* Add a character */
 #ifdef JP
-                       if (!get_check("Á´¤Æ¤ÎÊѹ¹¤òÇË´þ¤·¤Æ¸µ¤Î¾õÂÖ¤ËÌᤷ¤Þ¤¹¡£¤è¤í¤·¤¤¤Ç¤¹¤«¡© "))
-#else
-                       if (!get_check("Discard all changes and revert to original file. Are you sure? "))
+       if (iskanji(key))
+       {
+               int next;
+
+               inkey_base = TRUE;
+               next = inkey();
+               if (j+2 < MAX_LINELEN)
+               {
+                       buf[j++] = key;
+                       buf[j++] = next;
+                       tb->cx += 2;
+               }
+               else
+                       bell();
+       }
+       else
 #endif
-                               break;
+       {
+               if (j+1 < MAX_LINELEN)
+                       buf[j++] = key;
+               tb->cx++;
+       }
 
-                       free_text_lines(lines_list);
-                       lines_list = read_pickpref_text_lines(&filename_mode);
-                       dirty_flags |= DIRTY_ALL | DIRTY_MODE;
-                       cx = cy = 0;
-                       edit_mode = FALSE;
-                       break;
-               case KTRL('s'):
-                       /* Rotate action; pickup/destroy/leave */
-                       if (!autopick_new_entry(entry, lines_list[cy]))
-                               break;
-                       string_free(lines_list[cy]);
+       /* Add following */
+       for (; tb->lines_list[tb->cy][i] && j + 1 < MAX_LINELEN; i++)
+               buf[j++] = tb->lines_list[tb->cy][i];
+       buf[j] = '\0';
 
-                       if (entry->action & DO_AUTOPICK)
-                       {
-                               entry->action &= ~DO_AUTOPICK;
-                               entry->action |= DO_AUTODESTROY;
-                       }
-                       else if (entry->action & DO_AUTODESTROY)
-                       {
-                               entry->action &= ~DO_AUTODESTROY;
-                               entry->action |= DONT_AUTOPICK;
-                       }
-                       else if (entry->action & DONT_AUTOPICK)
-                       {
-                               entry->action &= ~DONT_AUTOPICK;
-                               entry->action |= DO_AUTOPICK;
-                       }
+       /* Replace current line with new line */
+       string_free(tb->lines_list[tb->cy]);
+       tb->lines_list[tb->cy] = string_make(buf);
 
-                       lines_list[cy] = autopick_line_from_entry_kill(entry);
+       /* Move to correct collumn */
+       len = strlen(tb->lines_list[tb->cy]);
+       if (len < tb->cx) tb->cx = len;
 
-                       /* Now dirty */
-                       dirty_line = cy;
+       /* Now dirty */
+       tb->dirty_line = tb->cy;
+}
 
-                       break;
-               case KTRL('t'):
-                       /* Nothing */
-                       break;
-               case KTRL('u'):
-                       /* Rotate identify-state; identified/unidentified/... */
-                       if (!autopick_new_entry(entry, lines_list[cy]))
-                               break;
-                       string_free(lines_list[cy]);
+/*
+ * In-game editor of Object Auto-picker/Destoryer
+ */
+void do_cmd_edit_autopick(void)
+{
+       text_body_type text_body, *tb = &text_body;
 
-                       if (IS_FLG(FLG_UNIDENTIFIED)) 
-                       {
-                               REM_FLG(FLG_UNIDENTIFIED);
-                               ADD_FLG(FLG_UNAWARE);
-                               REM_FLG(FLG_IDENTIFIED);
-                               REM_FLG(FLG_STAR_IDENTIFIED);
-                       }
-                       else if (IS_FLG(FLG_UNAWARE)) 
-                       {
-                               REM_FLG(FLG_UNIDENTIFIED);
-                               REM_FLG(FLG_UNAWARE);
-                               ADD_FLG(FLG_IDENTIFIED);
-                               REM_FLG(FLG_STAR_IDENTIFIED);
-                       }
-                       else if (IS_FLG(FLG_STAR_IDENTIFIED)) 
-                       {
-                               REM_FLG(FLG_UNIDENTIFIED);
-                               REM_FLG(FLG_UNAWARE);
-                               REM_FLG(FLG_IDENTIFIED);
-                               REM_FLG(FLG_STAR_IDENTIFIED);
-                       }
-                       else if (IS_FLG(FLG_IDENTIFIED)) 
-                       {
-                               REM_FLG(FLG_UNIDENTIFIED);
-                               REM_FLG(FLG_UNAWARE);
-                               REM_FLG(FLG_IDENTIFIED);
-                               ADD_FLG(FLG_STAR_IDENTIFIED);
-                       }
-                       else
-                       {
-                               ADD_FLG(FLG_UNIDENTIFIED);
-                               REM_FLG(FLG_UNAWARE);
-                               REM_FLG(FLG_IDENTIFIED);
-                               REM_FLG(FLG_STAR_IDENTIFIED);
-                       }
+       autopick_type an_entry, *entry = &an_entry;
+       char buf[MAX_LINELEN];
+
+       int i;
+       int key = -1;
 
-                       lines_list[cy] = autopick_line_from_entry_kill(entry);
+       static s32b old_autosave_turn = 0L;
+       bool quit = FALSE;
+
+       tb->cx = tb->cy = tb->upper = tb->left = 0;
+       tb->mark = 0;
+       tb->mx = tb->my = 0;
+       tb->old_cy = tb->old_upper = tb->old_left = -1;
+       tb->old_wid = tb->old_hgt = -1;
+       tb->old_com_id = 0;
+
+       tb->yank = NULL;
+       tb->search_o_ptr = NULL;
+       tb->search_str = NULL;
+       tb->last_destroyed = NULL;
+       tb->dirty_flags = DIRTY_ALL | DIRTY_MODE;
+       tb->dirty_line = -1;
+       tb->filename_mode = PT_WITH_PNAME;
 
-                       /* Now dirty */
-                       dirty_line = cy;
-                       break;
-               case KTRL('v'):
-                       /* Scroll up */
-                       while (cy < upper + hgt-4 && lines_list[cy + 1])
-                               cy++;
-                       upper = cy;
-                       break;
-               case KTRL('w'):
-                       /* Toggle 'worthless' */
-                       toggle_string(lines_list, FLG_WORTHLESS, cy);
-                       /* Now dirty */
-                       dirty_line = cy;
-                       break;
-               case KTRL('x'):
-                       /* Rotate within nameless, ego, artifact */
-                       if (!autopick_new_entry(entry, lines_list[cy]))
-                               break;
-                       string_free(lines_list[cy]);
+       /* Autosave */
+       if (turn > old_autosave_turn + 100L)
+       {
+               do_cmd_save_game(TRUE);
+               old_autosave_turn = turn;
+       }
 
-                       if (IS_FLG(FLG_NAMELESS)) 
-                       {
-                               REM_FLG(FLG_NAMELESS);
-                               ADD_FLG(FLG_EGO);
-                               REM_FLG(FLG_ARTIFACT);
-                       }
-                       else if (IS_FLG(FLG_EGO)) 
-                       {
-                               REM_FLG(FLG_NAMELESS);
-                               REM_FLG(FLG_EGO);
-                               ADD_FLG(FLG_ARTIFACT);
-                       }
-                       else if (IS_FLG(FLG_ARTIFACT)) 
-                       {
-                               REM_FLG(FLG_NAMELESS);
-                               REM_FLG(FLG_EGO);
-                               REM_FLG(FLG_ARTIFACT);
-                       }
-                       else
-                       {
-                               ADD_FLG(FLG_NAMELESS);
-                               REM_FLG(FLG_EGO);
-                               REM_FLG(FLG_ARTIFACT);
-                       }
+       /* HACK -- Reset start_time to stop counting playtime while edit */
+       update_playtime();
 
-                       lines_list[cy] = autopick_line_from_entry_kill(entry);
+       /* Free old entries */
+       init_autopicker();
 
-                       /* Now dirty */
-                       dirty_line = cy;
-                       break;
+       /* Command Description of the 'Last Destroyed Item' */
+       if (autopick_last_destroyed_object.k_idx)
+       {
+               autopick_entry_from_object(entry, &autopick_last_destroyed_object);
+               tb->last_destroyed = autopick_line_from_entry_kill(entry);
+       }
 
-               case KTRL('y'):
-                       /* Paste killed text */
-                       if (strlen(yank_buf))
-                       {
-                               bool ret = FALSE;
+       /* Read or initialize whole text */
+       tb->lines_list = read_pickpref_text_lines(&tb->filename_mode);
 
-                               for (j = 0; yank_buf[j]; j += strlen(yank_buf + j) + 1)
-                               {
-                                       if (ret && '\n' == yank_buf[j])
-                                       {
-                                               ret = FALSE;
-                                               continue;
-                                       }
+       /* Reset cursor position if needed */
+       for (i = 0; i < tb->cy; i++)
+       {
+               if (!tb->lines_list[i])
+               {
+                       tb->cy = tb->cx = 0;
+                       break;
+               }
+       }
 
-                                       /* Split current line */
-                                       insert_return_code(lines_list, cx, cy);
+       /* Save the screen */
+       screen_save();
 
-                                       /* Save preceding string */
-                                       for(i = 0; lines_list[cy][i]; i++)
-                                               buf[i] = lines_list[cy][i];
+       /* Process requests until done */
+       while (!quit)
+       {
+               int com_id = 0;
 
-                                       /* Paste yank buffer */
-                                       if ('\n' != yank_buf[j])
-                                       {
-                                               int k = j;
-                                               while (yank_buf[k] && i < MAX_LINELEN-1)
-                                                       buf[i++] = yank_buf[k++];
-                                               ret = TRUE;
-                                       }
+               /* Draw_everythig */
+               draw_text_editor(tb);
 
-                                       buf[i] = '\0';
+               /* Display header line */
+#ifdef JP
+               prt("(^Q:½ªÎ», ESC:¥á¥Ë¥å¡¼, ¤½¤Î¾:ÆþÎÏ)", 0, 0);
+#else  
+               prt("(^Q:quit, ESC:menu, Other:input text)", 0, 0);
+#endif
+               if (!tb->mark)
+               {
+                       /* Display current position */
+                       prt (format("(%d, %d)", tb->cx, tb->cy), 0, 60);
+               }
+               else
+               {
+                       /* Display current position and mark position */
+                       prt (format("(%d-%d, %d-%d)", tb->mx, tb->cx, tb->my, tb->cy), 0, 60);
+               }
 
-                                       string_free(lines_list[cy]);
-                                       lines_list[cy] = string_make(buf);
+               /* Place cursor */
+               Term_gotoxy(tb->cx - tb->left, tb->cy - tb->upper + 1);
 
-                                       /* Move to the beggining of next line */
-                                       cx = 0;
-                                       cy++;
-                               }
+               /* Now clean */
+               tb->dirty_flags = 0;
+               tb->dirty_line = -1;
 
-                               /* Now dirty */
-                               dirty_flags |= DIRTY_ALL;
-                       }
-                       break;
-               case KTRL('z'):
-                       /* Toggle 'collecting' */
-                       toggle_string(lines_list, FLG_COLLECTING, cy);
-                       /* Now dirty */
-                       dirty_line = cy;
-                       break;
+               /* Save old key and location */
+               tb->old_cy = tb->cy;
+               tb->old_upper = tb->upper;
+               tb->old_left = tb->left;
+               tb->old_wid = tb->wid;
+               tb->old_hgt = tb->hgt;
 
-               case KTRL('k'):
-                       /* Kill rest of line */
-                       if ((uint)cx > strlen(lines_list[cy]))
-                               cx = (int)strlen(lines_list[cy]);
+               /* Get a command */
+               key = inkey();
 
-                       /* Save preceding string */
-                       for (i = 0; lines_list[cy][i] && i < cx; i++)
-                       {
-#ifdef JP
-                               if (iskanji(lines_list[cy][i]))
-                               {
-                                       buf[i] = lines_list[cy][i];
-                                       i++;
-                               }
-#endif
-                               buf[i] = lines_list[cy][i];
-                       }
-                       buf[i] = '\0';
+               /* Delete key */
+               if (key == 0x7F) key = KTRL('d');
+
+               /* HACK -- ignore macro defined on ASCII keys */
+               if (strlen(inkey_macro_trigger_string) == 1)
+               {
+                       /* Get original key */
+                       key = inkey_macro_trigger_string[0];
+               }
 
-                       j = 0;
-                       if (old_key == key)
-                               while (yank_buf[j])
-                                       j += strlen(yank_buf + j) + 1;
 
-                       /* Copy following to yank buffer */
-                       if (lines_list[cy][i])
-                       {
-                               while (lines_list[cy][i] && j < MAX_YANK - 2)
-                                       yank_buf[j++] = lines_list[cy][i++];
-                               i = TRUE;
-                       }
-                       else
-                       {
-                               if (j < MAX_YANK - 2)
-                                       yank_buf[j++] = '\n';
-                               i = FALSE;
-                       }
-                       yank_buf[j++] = '\0';
-                       yank_buf[j] = '\0';
+               if (key == ESCAPE)
+               {
+                       com_id = do_command_menu(0, 0);
 
-                       /* Replace current line with 'preceding string' */
-                       string_free(lines_list[cy]);
-                       lines_list[cy] = string_make(buf);
+                       /* Redraw all */
+                       tb->dirty_flags |= DIRTY_SCREEN;
+               }
 
-                       if (i)
+               /* Cursor key macroes to direction command */
+               else if (strlen(inkey_macro_trigger_string) > 1)
+               {
+                       switch (key)
                        {
-                               /* Now dirty */
-                               dirty_line = cy;
+                       case '2':
+                               com_id = EC_DOWN;
+                               break;
+                       case '4':
+                               com_id = EC_LEFT;
+                               break;
+                       case '6':
+                               com_id = EC_RIGHT;
+                               break;
+                       case '8':
+                               com_id = EC_UP;
                                break;
                        }
 
-                       /* fall through */
-               case KTRL('d'):
-               case 0x7F:
-                       /* DELETE == go forward + BACK SPACE */
-#ifdef JP
-                       if (iskanji(lines_list[cy][cx])) cx++;
-#endif
-                       cx++;
+                       /* Mega Hack!!! Start selection with shift + cursor keys */
+                       if (!com_id)
+                       {
+                               char buf[1024];
 
-                       /* fall through */
+                               /* Get ascii form */
+                               ascii_to_text(buf, inkey_macro_trigger_string);
 
-               case '\010':
-                       /* BACK SPACE */
-                       len = strlen(lines_list[cy]);
-                       if (len < cx)
-                       {
-                               if (lines_list[cy + 1])
-                               {
-                                       cy++;
-                                       cx = 0;
-                               }
-                               else
+                               if (strstr(buf, "shift-Down"))
+                                       com_id = EC_DOWN;
+                               else if (strstr(buf, "shift-Left"))
+                                       com_id = EC_LEFT;
+                               else if (strstr(buf, "shift-Right"))
+                                       com_id = EC_RIGHT;
+                               else if (strstr(buf, "shift-Up"))
+                                       com_id = EC_UP;
+
+                               if (com_id)
                                {
-                                       cx = len;
-                                       break;
+                                       /* Kill further macro expansion */
+                                       flush();
+
+                                       /* Start selection */
+                                       if (!tb->mark)
+                                       {
+                                               tb->mark = 1;
+                                               tb->my = tb->cy;
+                                               tb->mx = tb->cx;
+                                               
+                                               /* Need to redraw text */
+                                               if (com_id == EC_UP || com_id == EC_DOWN)
+                                               {
+                                                       /* Now dirty */
+                                                       tb->dirty_flags |= DIRTY_ALL;
+                                               }
+                                       }
                                }
                        }
+               }
 
-                       if (cx == 0)
-                       {
-                               /* delete a return code and union two lines */
-                               if (cy == 0) break;
-                               cx = strlen(lines_list[cy-1]);
-                               strcpy(buf, lines_list[cy-1]);
-                               strcat(buf, lines_list[cy]);
-                               string_free(lines_list[cy-1]);
-                               string_free(lines_list[cy]);
-                               lines_list[cy-1] = string_make(buf);
-                               for (i = cy; lines_list[i+1]; i++)
-                                       lines_list[i] = lines_list[i+1];
-                               lines_list[i] = NULL;
-                               cy--;
-
-                               /* Now dirty */
-                               dirty_flags |= DIRTY_ALL;
-                               break;
-                       }
+               if (com_id)
+               {
+                       /* Already done */
+               }
 
-                       for (i = j = k = 0; lines_list[cy][i] && i < cx; i++)
-                       {
-                               k = j;
-#ifdef JP
-                               if (iskanji(lines_list[cy][i]))
-                                       buf[j++] = lines_list[cy][i++];
-#endif
-                               buf[j++] = lines_list[cy][i];
-                       }
-                       while (j > k)
-                       {
-                               cx--;
-                               j--;
-                       }
-                       for (; lines_list[cy][i]; i++)
-                               buf[j++] = lines_list[cy][i];
-                       buf[j] = '\0';
-                       string_free(lines_list[cy]);
-                       lines_list[cy] = string_make(buf);
+               /* Insert a character */
+               else if (!iscntrl(key & 0xff))
+               {
+                       /*
+                        * If there is a selection, kill text, and
+                        * replace it with a single letter.
+                        */
+                       if (tb->mark) kill_text_in_selection(tb, FALSE);
 
-                       /* Now dirty */
-                       dirty_line = cy;
-                       break;
+                       insert_single_letter(tb, key);
+
+                       /* Next loop */
+                       continue;
+               }
+
+               /* Other commands */
+               else
+               {
+                       com_id = get_com_id(key);
                }
 
+               if (com_id) quit = do_editor_command(tb, com_id);
        } /* while (1) */
 
        /* Restore the screen */
        screen_load();
 
-       switch (filename_mode)
+       switch (tb->filename_mode)
        {
        case PT_DEFAULT:
 #ifdef JP
@@ -3889,10 +4957,13 @@ void do_cmd_edit_autopick(void)
                break;
        }
 
-       write_text_lines(buf, lines_list);
-       free_text_lines(lines_list);
+       write_text_lines(buf, tb->lines_list);
+       free_text_lines(tb->lines_list);
+
+       string_free(tb->last_destroyed);
 
-       string_free(last_destroyed);
+       /* Destroy string chain */
+       kill_yank_chain(tb);
 
        /* Reload autopick pref */
        process_pickpref_file(buf);
index 5b14393..d1e06e7 100644 (file)
@@ -178,7 +178,7 @@ extern bool inkey_base;
 extern bool inkey_xtra;
 extern bool inkey_scan;
 extern bool inkey_flag;
-extern bool inkey_special;
+extern char inkey_macro_trigger_string[1024];
 extern s16b coin_type;
 extern bool opening_chest;
 extern bool shimmer_monsters;
@@ -522,17 +522,17 @@ extern s16b now_message;
 extern bool use_menu;
 
 /* autopick.c */
-extern cptr autopick_line_from_entry(autopick_type *entry);
 extern bool autopick_new_entry(autopick_type *entry, cptr str);
 extern void autopick_free_entry(autopick_type *entry);
+extern void init_autopicker(void);
+extern errr process_pickpref_file_line(char *buf);
+extern cptr autopick_line_from_entry(autopick_type *entry);
 extern int is_autopick(object_type *o_ptr);
 extern void auto_inscribe_item(int item, int idx);
 extern bool auto_destroy_item(int item, int autopick_idx);
 extern void delayed_auto_destroy(void);
 extern void auto_pickup_items(cave_type *c_ptr);
 extern void autopick_entry_from_object(autopick_type *entry, object_type *o_ptr);
-extern void init_autopicker(void);
-extern errr process_pickpref_file_line(char *buf);
 extern void do_cmd_edit_autopick(void);
 
 /* birth.c */
index b602a08..c211eeb 100644 (file)
@@ -1703,7 +1703,7 @@ static char inkey_aux(void)
 
        cptr pat, act;
 
-       char buf[1024];
+       char *buf = inkey_macro_trigger_string;
 
        /* Hack : ¥­¡¼ÆþÎÏÂÔ¤Á¤Ç»ß¤Þ¤Ã¤Æ¤¤¤ë¤Î¤Ç¡¢Î®¤ì¤¿¹Ô¤Îµ­²±¤ÏÉÔÍס£ */
        num_more = 0;
@@ -1736,9 +1736,6 @@ static char inkey_aux(void)
        /* Inside "macro trigger" */
        if (parse_under) return (ch);
 
-       /* Parse special key only */
-       if (inkey_special && ch != 31) return (ch);
-
        /* Save the first key, advance */
        buf[p++] = ch;
        buf[p] = '\0';
@@ -1949,7 +1946,7 @@ char inkey(void)
                ch = *inkey_next++;
 
                /* Cancel the various "global parameters" */
-               inkey_base = inkey_xtra = inkey_flag = inkey_scan = inkey_special = FALSE;
+               inkey_base = inkey_xtra = inkey_flag = inkey_scan = FALSE;
 
                /* Accept result */
                return (ch);
@@ -1965,7 +1962,7 @@ char inkey(void)
        if (inkey_hack && ((ch = (*inkey_hack)(inkey_xtra)) != 0))
        {
                /* Cancel the various "global parameters" */
-               inkey_base = inkey_xtra = inkey_flag = inkey_scan = inkey_special = FALSE;
+               inkey_base = inkey_xtra = inkey_flag = inkey_scan = FALSE;
 
                /* Accept result */
                return (ch);
@@ -2150,7 +2147,7 @@ char inkey(void)
 
 
        /* Cancel the various "global parameters" */
-       inkey_base = inkey_xtra = inkey_flag = inkey_scan = inkey_special = FALSE;
+       inkey_base = inkey_xtra = inkey_flag = inkey_scan = FALSE;
 
        /* Return the keypress */
        return (ch);
index 0bf064f..5ab8910 100644 (file)
@@ -133,7 +133,7 @@ bool inkey_base;            /* See the "inkey()" function */
 bool inkey_xtra;               /* See the "inkey()" function */
 bool inkey_scan;               /* See the "inkey()" function */
 bool inkey_flag;               /* See the "inkey()" function */
-bool inkey_special;            /* See the "inkey()" function */
+char inkey_macro_trigger_string[1024];
 
 s16b coin_type;                        /* Hack -- force coin type */