(minput_config_file): Comment fixed for man-page.
[m17n/m17n-lib.git] / src / input.c
index 171c4d2..cd67276 100644 (file)
 #include <dlfcn.h>
 #endif
 
-#include "m17n-gui.h"
+#include "m17n.h"
 #include "m17n-misc.h"
 #include "internal.h"
 #include "mtext.h"
 #include "database.h"
 #include "charset.h"
 
-static int mdebug_mask = MDEBUG_INPUT;
+static int mdebug_flag = MDEBUG_INPUT;
 
 static int fully_initialized;
 
@@ -489,6 +489,8 @@ marker_code (MSymbol sym, int surrounding)
 }
 
 
+/* Return a plist containing an integer value of VAR.  */
+
 static MPlist *
 resolve_variable (MInputContextInfo *ic_info, MSymbol var)
 {
@@ -585,10 +587,10 @@ get_following_char (MInputContext *ic, int pos)
   if (ic_info->following_text)
     {
       len = mtext_nchars (ic_info->following_text);
-      if (pos <= len)
-       return mtext_ref_char (ic_info->following_text, pos - 1);
+      if (pos < len)
+       return mtext_ref_char (ic_info->following_text, pos);
     }
-  mt = get_surrounding_text (ic, pos);
+  mt = get_surrounding_text (ic, pos + 1);
   if (! mt)
     return -2;
   len = mtext_nchars (mt);
@@ -604,9 +606,9 @@ get_following_char (MInputContext *ic, int pos)
     }
   else
     ic_info->following_text = mt;
-  if (pos > len)
+  if (pos >= len)
     return -1;
-  return mtext_ref_char (ic_info->following_text, pos - 1);
+  return mtext_ref_char (ic_info->following_text, pos);
 }
 
 static int
@@ -625,15 +627,13 @@ surrounding_pos (MSymbol sym)
 }
 
 static int
-integer_value (MInputContext *ic, MPlist *arg, MPlist **value, int surrounding)
+integer_value (MInputContext *ic, MPlist *arg, int surrounding)
 {
   MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
   int code, pos;
   MText *preedit = ic->preedit;
   int len = mtext_nchars (preedit);
 
-  if (value)
-    *value = NULL;
   if (MPLIST_INTEGER_P (arg))
     return MPLIST_INTEGER (arg);
 
@@ -642,8 +642,6 @@ integer_value (MInputContext *ic, MPlist *arg, MPlist **value, int surrounding)
     {
       MPlist *val = resolve_variable (ic_info, MPLIST_SYMBOL (arg));
 
-      if (value)
-       *value = val;
       return (MPLIST_INTEGER_P (val) ? MPLIST_INTEGER (val) : 0);
     }
   if (code == '@')
@@ -657,7 +655,10 @@ integer_value (MInputContext *ic, MPlist *arg, MPlist **value, int surrounding)
          pos = atoi (name + 1);
          if (pos == 0)
            return get_preceding_char (ic, 0);
-         pos = ic->cursor_pos + pos;
+         if (pos < 0)
+           pos = ic->cursor_pos + pos;
+         else
+           pos = ic->cursor_pos + pos - 1;
          if (pos < 0)
            {
              if (ic->produced && mtext_len (ic->produced) + pos >= 0)
@@ -665,8 +666,8 @@ integer_value (MInputContext *ic, MPlist *arg, MPlist **value, int surrounding)
                                       mtext_len (ic->produced) + pos);
              return get_preceding_char (ic, - pos);
            }
-         if (pos >= len)
-           return get_following_char (ic, pos - len + 1);
+         else if (pos >= len)
+           return get_following_char (ic, pos - len);
        }
       else
        pos = ic->cursor_pos + (code == '+' ? 1 : -1);
@@ -717,7 +718,7 @@ resolve_expression (MInputContext *ic, MPlist *plist)
   if (MPLIST_INTEGER_P (plist))
     return MPLIST_INTEGER (plist);
   if (MPLIST_SYMBOL_P (plist))
-    return integer_value (ic, plist, NULL, 1);
+    return integer_value (ic, plist, 1);
   if (! MPLIST_PLIST_P (plist))
     return 0;
   plist = MPLIST_PLIST (plist);
@@ -815,6 +816,11 @@ parse_action_list (MPlist *plist, MPlist *macros)
 
          pl = MPLIST_NEXT (pl);
 
+         if (action_name == M_candidates)
+           {
+             /* This is an already regularised action.  */
+             continue;
+           }
          if (action_name == Minsert)
            {
              if (MPLIST_MTEXT_P (pl))
@@ -822,6 +828,13 @@ parse_action_list (MPlist *plist, MPlist *macros)
                  if (mtext_nchars (MPLIST_MTEXT (pl)) == 0)
                    MERROR (MERROR_IM, -1);
                }
+             else if (MPLIST_INTEGER_P (pl))
+               {
+                 int c = MPLIST_INTEGER (pl);
+
+                 if (c < 0 || c > MCHAR_MAX)
+                   MERROR (MERROR_IM, -1);
+               }
              else if (MPLIST_PLIST_P (pl))
                {
                  MPLIST_DO (pl, MPLIST_PLIST (pl))
@@ -1070,34 +1083,48 @@ load_branch (MInputMethodInfo *im_info, MPlist *plist, MIMMap *map)
       if (branch_actions)
        M17N_OBJECT_REF (branch_actions);
     }
-  else if (im_info->maps
-          && (plist = (MPlist *) mplist_get (im_info->maps, map_name)))
+  else if (im_info->maps) 
     {
-      MPLIST_DO (plist, plist)
+      plist = (MPlist *) mplist_get (im_info->maps, map_name);
+      if (! plist && im_info->configured_vars)
        {
-         MPlist *keylist, *map_actions;
+         MPlist *p = mplist__assq (im_info->configured_vars, map_name);
 
-         if (! MPLIST_PLIST_P (plist))
-           MERROR (MERROR_IM, -1);
-         keylist = MPLIST_PLIST (plist);
-         map_actions = MPLIST_NEXT (keylist);
-         if (MPLIST_SYMBOL_P (keylist))
+         if (p && MPLIST_PLIST_P (p))
            {
-             MSymbol command = MPLIST_SYMBOL (keylist);
-             MPlist *pl;
+             p = MPLIST_NEXT (MPLIST_NEXT (MPLIST_NEXT (MPLIST_PLIST (p))));
+             if (MPLIST_SYMBOL_P (p))
+               plist = mplist_get (im_info->maps, MPLIST_SYMBOL (p));
+           }
+       }
+      if (plist)
+       {
+         MPLIST_DO (plist, plist)
+           {
+             MPlist *keylist, *map_actions;
 
-             if (MFAILP (command != Mat_reload))
-               continue;
-             pl = resolve_command (im_info->configured_cmds, command);
-             if (MFAILP (pl))
-               continue;
-             MPLIST_DO (pl, pl)
-               load_translation (map, pl, map_actions, branch_actions,
+             if (! MPLIST_PLIST_P (plist))
+               MERROR (MERROR_IM, -1);
+             keylist = MPLIST_PLIST (plist);
+             map_actions = MPLIST_NEXT (keylist);
+             if (MPLIST_SYMBOL_P (keylist))
+               {
+                 MSymbol command = MPLIST_SYMBOL (keylist);
+                 MPlist *pl;
+
+                 if (MFAILP (command != Mat_reload))
+                   continue;
+                 pl = resolve_command (im_info->configured_cmds, command);
+                 if (MFAILP (pl))
+                   continue;
+                 MPLIST_DO (pl, pl)
+                   load_translation (map, pl, map_actions, branch_actions,
+                                     im_info->macros);
+               }
+             else
+               load_translation (map, keylist, map_actions, branch_actions,
                                  im_info->macros);
            }
-         else
-           load_translation (map, keylist, map_actions, branch_actions,
-                             im_info->macros);
        }
     }
 
@@ -1479,6 +1506,8 @@ update_global_info (void)
     {
       MDatabase *mdb = mdatabase_find (Minput_method, Mt, Mnil, Mglobal);
 
+      if (! mdb)
+       return -1;
       global_info = new_im_info (mdb, Mt, Mnil, Mglobal, im_info_list);
     }
   if (! global_info->mdb
@@ -1548,6 +1577,8 @@ get_im_info (MSymbol language, MSymbol name, MSymbol extra, MSymbol key)
        im_info->cmds = mplist ();
       if (! im_info->vars)
        im_info->vars = mplist ();
+      if (! im_info->states)
+       im_info->states = mplist ();
     }
   if (! im_info->title
       && (key == Mnil || key == Mtitle))
@@ -1640,7 +1671,7 @@ check_description (MPlist *plist)
          {
            M17N_OBJECT_UNREF (mt);
            mt = mtext__from_data (translated, strlen (translated),
-                                  MTEXT_FORMAT_UTF_8, 0);
+                                  MTEXT_FORMAT_UTF_8, 1);
          }
       }
 #endif
@@ -1742,14 +1773,13 @@ config_command (MPlist *plist, MPlist *global_cmds, MPlist *custom_cmds,
                MPlist *config_cmds)
 {
   MPlist *global = NULL, *custom = NULL, *config = NULL;
-  MSymbol name;
+  MSymbol name = MPLIST_SYMBOL (plist);
   MSymbol status;
   MPlist *description, *keyseq;
 
   if (global_cmds && (global = mplist__assq (global_cmds, name)))
     global = MPLIST_NEXT (MPLIST_PLIST (global));  
 
-  name = MPLIST_SYMBOL (plist);
   plist = MPLIST_NEXT (plist);
   if (MPLIST_MTEXT_P (plist) || MPLIST_PLIST_P (plist))
     {
@@ -1782,11 +1812,14 @@ config_command (MPlist *plist, MPlist *global_cmds, MPlist *custom_cmds,
     }
   else if (custom_cmds && (custom = mplist__assq (custom_cmds, name)))
     {
-      custom = MPLIST_NEXT (MPLIST_PLIST (custom));
-      if (! MPLIST_TAIL_P (custom))
+      MPlist *this_keyseq = MPLIST_NEXT (MPLIST_NEXT (MPLIST_PLIST (custom)));
+
+      if (MPLIST_TAIL_P (this_keyseq))
+       mplist__pop_unref (custom);
+      else
        {
          status = Mcustomized;
-         keyseq = custom;
+         keyseq = this_keyseq;
        }
     }
   
@@ -2075,10 +2108,13 @@ config_variable (MPlist *plist, MPlist *global_vars, MPlist *custom_vars,
     }
   else if (custom_vars && (custom = mplist__assq (custom_vars, name)))
     {
-      custom = MPLIST_NEXT (MPLIST_PLIST (custom));
-      if (! MPLIST_TAIL_P (custom))
+      MPlist *this_value = MPLIST_NEXT (MPLIST_NEXT (MPLIST_PLIST (custom)));
+
+      if (MPLIST_TAIL_P (this_value))
+       mplist__pop_unref (custom);
+      else
        {
-         value = custom;
+         value = this_value;
          if (MFAILP (check_variable_value (value, global ? global : plist)))
            value = NULL;
          status = Mcustomized;
@@ -2305,7 +2341,7 @@ load_im_info (MPlist *plist, MInputMethodInfo *im_info)
 \f
 
 static int take_action_list (MInputContext *ic, MPlist *action_list);
-static void preedit_commit (MInputContext *ic);
+static void preedit_commit (MInputContext *ic, int need_prefix);
 
 static void
 shift_state (MInputContext *ic, MSymbol state_name)
@@ -2333,7 +2369,15 @@ shift_state (MInputContext *ic, MSymbol state_name)
        state = (MIMState *) MPLIST_VAL (im_info->states);
     }
 
-  MDEBUG_PRINT1 ("\n  [IM] (shift %s)", MSYMBOL_NAME (state->name));
+  if (MDEBUG_FLAG ())
+    {
+      if (orig_state)
+       MDEBUG_PRINT2 ("\n  [IM] [%s] (shift %s)\n",
+                      MSYMBOL_NAME (orig_state->name),
+                      MSYMBOL_NAME (state->name));
+      else
+       MDEBUG_PRINT1 (" (shift %s)\n", MSYMBOL_NAME (state->name));
+    }
 
   /* Enter the new state.  */
   ic_info->state = state;
@@ -2342,7 +2386,7 @@ shift_state (MInputContext *ic, MSymbol state_name)
   if (state == (MIMState *) MPLIST_VAL (im_info->states)
       && orig_state)
     /* We have shifted to the initial state.  */
-    preedit_commit (ic);
+    preedit_commit (ic, 0);
   mtext_cpy (ic_info->preedit_saved, ic->preedit);
   ic_info->state_pos = ic->cursor_pos;
   if (state != orig_state)
@@ -2365,7 +2409,8 @@ shift_state (MInputContext *ic, MSymbol state_name)
       if (ic_info->map == ic_info->state->map
          && ic_info->map->map_actions)
        {
-         MDEBUG_PRINT (" init-actions:");
+         MDEBUG_PRINT1 ("  [IM] [%s] init-actions:",
+                        MSYMBOL_NAME (state->name));
          take_action_list (ic, ic_info->map->map_actions);
        }
     }
@@ -2449,9 +2494,18 @@ preedit_insert (MInputContext *ic, int pos, MText *mt, int c)
   int nchars = mt ? mtext_nchars (mt) : 1;
 
   if (mt)
-    mtext_ins (ic->preedit, pos, mt);
+    {
+      mtext_ins (ic->preedit, pos, mt);
+      MDEBUG_PRINT1 ("(\"%s\")", MTEXT_DATA (mt));
+    }
   else
-    mtext_ins_char (ic->preedit, pos, c, 1);
+    {
+      mtext_ins_char (ic->preedit, pos, c, 1);
+      if (c < 0x7F)
+       MDEBUG_PRINT1 ("('%c')", c);
+      else
+       MDEBUG_PRINT1 ("(U+%04X)", c);
+    }
   adjust_markers (ic, pos, pos, nchars);
   ic->preedit_changed = 1;
 }
@@ -2487,7 +2541,7 @@ preedit_replace (MInputContext *ic, int from, int to, MText *mt, int c)
 
 
 static void
-preedit_commit (MInputContext *ic)
+preedit_commit (MInputContext *ic, int need_prefix)
 {
   MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
   int preedit_len = mtext_nchars (ic->preedit);
@@ -2501,10 +2555,13 @@ preedit_commit (MInputContext *ic)
       mtext_put_prop_values (ic->preedit, 0, mtext_nchars (ic->preedit),
                             Mcandidate_index, NULL, 0);
       mtext_cat (ic->produced, ic->preedit);
-      if (mdebug__flag & mdebug_mask)
+      if (MDEBUG_FLAG ())
        {
          int i;
 
+         if (need_prefix)
+           MDEBUG_PRINT1 ("\n  [IM] [%s]",
+                          MSYMBOL_NAME (ic_info->state->name));
          MDEBUG_PRINT (" (commit");
          for (i = 0; i < mtext_nchars (ic->preedit); i++)
            MDEBUG_PRINT1 (" U+%04X", mtext_ref_char (ic->preedit, i));
@@ -2581,6 +2638,7 @@ update_candidate (MInputContext *ic, MTextProperty *prop, int idx)
   int ingroup_index = idx - start;
   MText *mt;
 
+  candidate_list = mplist_copy (candidate_list);
   if (MPLIST_MTEXT_P (group))
     {
       mt = MPLIST_MTEXT (group);
@@ -2599,6 +2657,7 @@ update_candidate (MInputContext *ic, MTextProperty *prop, int idx)
       to = from + mtext_nchars (mt);
     }
   mtext_put_prop (ic->preedit, from, to, Mcandidate_list, candidate_list);
+  M17N_OBJECT_UNREF (candidate_list);
   mtext_put_prop (ic->preedit, from, to, Mcandidate_index, (void *) idx);
   ic->cursor_pos = to;
 }
@@ -2926,9 +2985,11 @@ take_action_list (MInputContext *ic, MPlist *action_list)
              preedit_insert (ic, ic->cursor_pos, mt, 0);
              len = mtext_nchars (mt);
            }
+         plist = mplist_copy (plist);
          mtext_put_prop (ic->preedit,
                          ic->cursor_pos - len, ic->cursor_pos,
                          Mcandidate_list, plist);
+         M17N_OBJECT_UNREF (plist);
          mtext_put_prop (ic->preedit,
                          ic->cursor_pos - len, ic->cursor_pos,
                          Mcandidate_index, (void *) 0);
@@ -3052,8 +3113,9 @@ take_action_list (MInputContext *ic, MPlist *action_list)
                to = 0;
              else if (to > len)
                to = len;
+             pos = to - ic->cursor_pos;
            }
-         MDEBUG_PRINT1 ("(%d)", to - ic->cursor_pos);
+         MDEBUG_PRINT1 ("(%d)", pos);
          if (to < ic->cursor_pos)
            preedit_delete (ic, to, ic->cursor_pos);
          else if (to > ic->cursor_pos)
@@ -3213,7 +3275,7 @@ take_action_list (MInputContext *ic, MPlist *action_list)
        {
          int intarg = (MPLIST_TAIL_P (args)
                        ? ic_info->used - 2
-                       : integer_value (ic, args, NULL, 0));
+                       : integer_value (ic, args, 0));
 
          mtext_reset (ic->preedit);
          mtext_reset (ic_info->preedit_saved);
@@ -3242,11 +3304,11 @@ take_action_list (MInputContext *ic, MPlist *action_list)
               || name == Mmul || name == Mdiv)
        {
          MSymbol sym = MPLIST_SYMBOL (args);
+         MPlist *value = resolve_variable (ic_info, sym);
          int val1, val2;
-         MPlist *value;
          char *op;
 
-         val1 = integer_value (ic, args, &value, 0);
+         val1 = MPLIST_INTEGER (value);
          args = MPLIST_NEXT (args);
          val2 = resolve_expression (ic, args);
          if (name == Mset)
@@ -3261,8 +3323,7 @@ take_action_list (MInputContext *ic, MPlist *action_list)
            val1 /= val2, op = "/=";
          MDEBUG_PRINT4 ("(%s %s 0x%X(%d))",
                         MSYMBOL_NAME (sym), op, val1, val1);
-         if (value)
-           mplist_set (value, Minteger, (void *) val1);
+         mplist_set (value, Minteger, (void *) val1);
        }
       else if (name == Mequal || name == Mless || name == Mgreater
               || name == Mless_equal || name == Mgreater_equal)
@@ -3323,11 +3384,11 @@ take_action_list (MInputContext *ic, MPlist *action_list)
        }
       else if (name == Mcommit)
        {
-         preedit_commit (ic);
+         preedit_commit (ic, 0);
        }
       else if (name == Munhandle)
        {
-         preedit_commit (ic);
+         preedit_commit (ic, 0);
          return -1;
        }
       else
@@ -3387,8 +3448,8 @@ handle_key (MInputContext *ic)
   MSymbol alias = Mnil;
   int i;
 
-  MDEBUG_PRINT2 ("  [IM] handle `%s' in state %s", 
-                msymbol_name (key), MSYMBOL_NAME (ic_info->state->name));
+  MDEBUG_PRINT2 ("  [IM] [%s] handle `%s'", 
+                MSYMBOL_NAME (ic_info->state->name), msymbol_name (key));
 
   if (map->submaps)
     {
@@ -3627,8 +3688,20 @@ re_init_ic (MInputContext *ic, int reload)
   fini_ic_info (ic);
   if (reload)
     reload_im_info (im_info);
+  if (! im_info->states)
+    {
+      struct MIMState *state;
+
+      M17N_OBJECT (state, free_state, MERROR_IM);
+      state->name = msymbol ("init");
+      state->title = mtext__from_data ("ERROR!", 6, MTEXT_FORMAT_US_ASCII, 0);
+      MSTRUCT_CALLOC (state->map, MERROR_IM);
+      im_info->states = mplist ();
+      mplist_add (im_info->states, state->name, state);
+    }
   init_ic_info (ic);
   shift_state (ic, Mnil);
+
   ic->status_changed = status_changed;
   ic->preedit_changed = preedit_changed;
   ic->cursor_pos_changed = cursor_pos_changed;
@@ -3647,7 +3720,7 @@ open_im (MInputMethod *im)
 {
   MInputMethodInfo *im_info = get_im_info (im->language, im->name, Mnil, Mnil);
 
-  if (! im_info)
+  if (! im_info || ! im_info->states)
     MERROR (MERROR_IM, -1);
   im->info = im_info;
 
@@ -3786,23 +3859,21 @@ filter (MInputContext *ic, MSymbol key, void *arg)
   /* If the current map is the root of the initial state, we should
      produce any preedit text in ic->produced.  */
   if (ic_info->map == ((MIMState *) MPLIST_VAL (im_info->states))->map)
-    preedit_commit (ic);
+    preedit_commit (ic, 1);
 
   if (mtext_nchars (ic->produced) > 0)
     {
-      MSymbol lang = msymbol_get (ic->im->language, Mlanguage);
-
-      if (mdebug__flag & mdebug_mask)
+      if (MDEBUG_FLAG ())
        {
-         MDEBUG_PRINT (" (produced");
+         MDEBUG_PRINT1 ("\n  [IM] [%s] (produced",
+                        MSYMBOL_NAME (ic_info->state->name));
          for (i = 0; i < mtext_nchars (ic->produced); i++)
            MDEBUG_PRINT1 (" U+%04X", mtext_ref_char (ic->produced, i));
          MDEBUG_PRINT (")");
        }
 
-      if (lang != Mnil)
-       mtext_put_prop (ic->produced, 0, mtext_nchars (ic->produced),
-                       Mlanguage, ic->im->language);
+      mtext_put_prop (ic->produced, 0, mtext_nchars (ic->produced),
+                     Mlanguage, ic->im->language);
     }
   if (ic_info->commit_key_head > 0)
     {
@@ -4721,7 +4792,8 @@ minput_get_title_icon (MSymbol language, MSymbol name)
     ´Ø¿ô minput_get_description () ¤Ï¡¢$LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄê
     ¤µ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤òÀâÌÀ¤¹¤ë M-text ¤òÊÖ¤¹¡£
 
-    @return »ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤¬ÀâÌÀ¤¹¤ë¥Æ¥­¥¹¥È¤ò»ý¤Ã¤Æ¤¤¤ì¤Ð¡¢
+    @return
+    »ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤¬ÀâÌÀ¤¹¤ë¥Æ¥­¥¹¥È¤ò»ý¤Ã¤Æ¤¤¤ì¤Ð¡¢
     #MText ¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¸Æ¤Ó½Ð¤·Â¦¤Ï¡¢¤½¤ì¤ò m17n_object_unref
     () ¤òÍѤ¤¤Æ²òÊü¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ÆþÎϥ᥽¥Ã¥É¤ËÀâÌÀ¥Æ¥­¥¹¥È¤¬Ìµ¤±
     ¤ì¤Ð@c NULL ¤òÊÖ¤¹¡£ */
@@ -4769,7 +4841,7 @@ minput_get_description (MSymbol language, MSymbol name)
 
     If $COMMAND is #Mnil, information about all commands is returned.
 
-    The return value is a @e well-formed plist (#m17nPlist) of this
+    The return value is a @e well-formed plist (@ref m17nPlist) of this
     format:
 @verbatim
   ((NAME DESCRIPTION STATUS [KEYSEQ ...]) ...)
@@ -4823,7 +4895,7 @@ minput_get_description (MSymbol language, MSymbol name)
 
     $COMMAND ¤¬ #Mnil ¤Î¾ì¹ç¤Ï¡¢¤¹¤Ù¤Æ¤Î¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£
 
-    Ìá¤êÃͤϰʲ¼¤Î·Á¼°¤Î @e well-formed plist (#m17nPlist) ¤Ç¤¢¤ë¡£
+    Ìá¤êÃͤϰʲ¼¤Î·Á¼°¤Î @e well-formed plist (@ref m17nPlist) ¤Ç¤¢¤ë¡£
 
 @verbatim
   ((NAME DESCRIPTION STATUS [KEYSEQ ...]) ...)
@@ -5167,7 +5239,7 @@ minput_config_command (MSymbol language, MSymbol name, MSymbol command,
     If $VARIABLE is #Mnil, information about all variables is
     returned.
 
-    The return value is a @e well-formed plist (#m17nPlist) of this
+    The return value is a @e well-formed plist (@ref m17nPlist) of this
     format:
 @verbatim
   ((NAME DESCRIPTION STATUS VALUE [VALID-VALUE ...]) ...)
@@ -5227,7 +5299,7 @@ minput_config_command (MSymbol language, MSymbol name, MSymbol command,
 
     $VARIABLE ¤¬ #Mnil ¤Î¾ì¹ç¤Ï¡¢¤¹¤Ù¤Æ¤Î¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£
 
-    Ìá¤êÃͤϰʲ¼¤Î·Á¼°¤Î @e well-formed plist (#m17nPlist) ¤Ç¤¢¤ë¡£
+    Ìá¤êÃͤϰʲ¼¤Î·Á¼°¤Î @e well-formed plist (@ref m17nPlist) ¤Ç¤¢¤ë¡£
 @verbatim
   ((NAME DESCRIPTION STATUS VALUE [VALID-VALUE ...]) ...)
 @endverbatim
@@ -5465,11 +5537,14 @@ minput_config_variable (MSymbol language, MSymbol name, MSymbol variable,
            }
          else
            {
-             plist = MPLIST_PLIST (plist); /* (NAME nil VALUE) */
-             plist = MPLIST_NEXT (plist);      /* ([nil VALUE]) */
-             if (! MPLIST_TAIL_P (plist))
-               return 0;
-             mplist_set (plist, Mnil ,NULL);
+             if (no_custom)
+               mplist__pop_unref (plist);
+             else
+               {
+                 plist = MPLIST_PLIST (plist); /* (NAME nil VALUE) */
+                 plist = MPLIST_NEXT (plist);  /* ([nil VALUE]) */
+                 mplist_set (plist, Mnil ,NULL);
+               }
            }
        }
       else
@@ -5503,12 +5578,12 @@ minput_config_variable (MSymbol language, MSymbol name, MSymbol variable,
     
     The minput_config_file () function returns the absolute path name
     of per-user customization file into which minput_save_config ()
-    save configurations.  It is usually @c "config.mic" under the
-    directory @c ".m17n.d" of user's home directory.  It is not assured
-    that the file of the returned name exists nor is
-    readable/writable.  If minput_save_config () fails and returns -1,
-    an application program might check the file, make it
-    writable (if possible), and try minput_save_config () again.
+    save configurations.  It is usually @c config.mic under the
+    directory <tt>${HOME}/.m17n.d</tt> (${HOME} is user's home
+    directory).  It is not assured that the file of the returned name
+    exists nor is readable/writable.  If minput_save_config () fails
+    and returns -1, an application program might check the file, make
+    it writable (if possible), and try minput_save_config () again.
 
     @return
 
@@ -5628,30 +5703,21 @@ minput_save_config (void)
            else
              custom->cmds = mplist (), p = NULL;
            elt = MPLIST_NEXT (elt);
-           if (MPLIST_TAIL_P (elt))
+           if (p)
              {
-               if (p)
-                 {
-                   /* Make customization ignored.  */
-                   p = MPLIST_NEXT (MPLIST_PLIST (p));
-                   mplist_set (p, Mnil, NULL);
-                 }
+               p = MPLIST_NEXT (MPLIST_NEXT (MPLIST_PLIST (p)));
+               mplist_set (p, Mnil, NULL);
              }
            else
              {
-               elt = MPLIST_NEXT (elt);
-               if (p)
-                 {
-                   p = MPLIST_NEXT (MPLIST_NEXT (MPLIST_PLIST (p)));
-                   mplist_set (p, Mnil, NULL);
-                   mplist__conc (p, elt);
-                 }
-               else
-                 {
-                   p = MPLIST_PLIST (pl);
-                   mplist_add (custom->cmds, Mplist, p);
-                 }
+               p = mplist ();
+               mplist_add (custom->cmds, Mplist, p);
+               M17N_OBJECT_UNREF (p);
+               mplist_add (p, Msymbol, command);
+               p = mplist_add (p, Msymbol, Mnil);
+               p = MPLIST_NEXT (p);
              }
+           mplist__conc (p, elt);
          }
       if (config->vars)
        MPLIST_DO (pl, config->vars)
@@ -5663,29 +5729,25 @@ minput_save_config (void)
            else
              custom->vars = mplist (), p = NULL;
            elt = MPLIST_NEXT (elt);
-           if (MPLIST_TAIL_P (elt))
+           if (p)
              {
-               if (p)
-                 mplist__pop_unref (p);
+               p = MPLIST_NEXT (MPLIST_NEXT (MPLIST_PLIST (p)));
+               mplist_set (p, Mnil, NULL);
              }
            else
              {
-               elt = MPLIST_NEXT (elt);
-               if (p)
-                 {
-                   p = MPLIST_NEXT (MPLIST_NEXT (MPLIST_PLIST (p)));
-                   mplist_set (p, Mnil, NULL);
-                   mplist__conc (p, elt);
-                 }
-               else
-                 {
-                   p = MPLIST_PLIST (pl);
-                   mplist_add (custom->vars, Mplist, p);
-                 }
+               p = mplist ();
+               mplist_add (custom->vars, Mplist, p);
+               M17N_OBJECT_UNREF (p);
+               mplist_add (p, Msymbol, variable);
+               p = mplist_add (p, Msymbol, Mnil);
+               p = MPLIST_NEXT (p);
              }
+           mplist__conc (p, elt);
          }
     }
-  M17N_OBJECT_UNREF (im_config_list);
+  free_im_list (im_config_list);
+  im_config_list = NULL;
 
   /* Next, reflect customization to the actual plist to be written.  */
   data = tail = mplist ();
@@ -5792,7 +5854,7 @@ minput_save_config (void)
     The minput_get_variables () function returns a plist (#MPlist) of
     variables used to control the behavior of the input method
     specified by $LANGUAGE and $NAME.  The plist is @e well-formed
-    (#m17nPlist) of the following format:
+    (@ref m17nPlist) of the following format:
 
 @verbatim
     (VARNAME (DOC-MTEXT DEFAULT-VALUE [ VALUE ... ] )
@@ -5841,7 +5903,7 @@ minput_save_config (void)
 
     ´Ø¿ô minput_get_variables () ¤Ï¡¢$LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄꤵ
     ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤Î¿¶¤ëÉñ¤¤¤òÀ©¸æ¤¹¤ëÊÑ¿ô¤Î¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È
-    (#MPlist) ¤òÊÖ¤¹¡£¤³¤Î¥ê¥¹¥È¤Ï @e well-formed ¤Ç¤¢¤ê(#m17nPlist) °Ê
+    (#MPlist) ¤òÊÖ¤¹¡£¤³¤Î¥ê¥¹¥È¤Ï @e well-formed ¤Ç¤¢¤ê(@ref m17nPlist) °Ê
     ²¼¤Î·Á¼°¤Ç¤¢¤ë¡£
 
 @verbatim
@@ -6130,7 +6192,8 @@ minput_get_commands (MSymbol language, MSymbol name)
     ¤³¤Î³ä¤êÅö¤Æ¤Ï¡¢³ä¤êÅö¤Æ°Ê¹ß¿·¤·¤¯¥ª¡¼¥×¥ó¤µ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤«¤éÍ­
     ¸ú¤Ë¤Ê¤ë¡£
 
-    @return ½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤·¡¢
+    @return 
+    ½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤·¡¢
     #merror_code ¤ò #MERROR_IM ¤ËÀßÄꤹ¤ë¡£  */
 
 int