*** empty log message ***
authorhanda <handa>
Tue, 6 Oct 2009 13:10:38 +0000 (13:10 +0000)
committerhanda <handa>
Tue, 6 Oct 2009 13:10:38 +0000 (13:10 +0000)
MInputMethod.cs
XmlExpr.cs

index b0736ea..f92e302 100644 (file)
@@ -59,6 +59,14 @@ namespace M17N.Input
     private static MSymbol Mpushback = "pushback"; 
     private static MSymbol Mkeyseq = "keyseq"; 
 
+    private static MSymbol Mget_surrounding_text = "get-surrounding-text";
+    private static MSymbol Mdel_surrounding_text = "del-surrounding-text";
+
+    private static MSymbol Mat_minus_zero = "@-0";
+
+    private static Xex.Symbol Nmap = "map";
+    private static Xex.Symbol Nrule = "rule";
+    private static Xex.Symbol Nkeyseq = "keyseq";
     private static Xex.Symbol Nprogn = "progn";
     private static Xex.Symbol Ninsert = "insert";
     private static Xex.Symbol Ninsert_candidates = "insert-candidates";
@@ -127,6 +135,7 @@ namespace M17N.Input
        = new Dictionary<string, KeyModifier> ();
       private static uint keysym_base = 0x200000;
       private static uint char_mask = ~((uint) KeyModifier.All);
+      public static Key Reload;
 
       static Key ()
       {
@@ -149,6 +158,8 @@ namespace M17N.Input
        keymodifiers["altgr"] = KeyModifier.AltGr;
        keymodifiers["super"] = KeyModifier.Super;
        keymodifiers["hyper"] = KeyModifier.Hyper;
+       Reload = new Key (keysym_base);
+       keysyms["-reload"] = keysym_base++;
       }
 
       private static uint decode_keysym (MSymbol keysym)
@@ -262,6 +273,20 @@ namespace M17N.Input
        get { return ((key & (uint) KeyModifier.All) != 0); }
       }
 
+      public static bool operator== (Key k1, Key k2)
+       {
+         return k1.key == k2.key;
+       }
+
+      public static bool operator!= (Key k1, Key k2)
+       {
+         return k1.key != k2.key;
+       }
+
+      public override bool Equals (object o) { return key == ((Key) o).key; }
+
+      public override int GetHashCode () { return (int) key; }
+
       public bool Match (Key k)
       {
        if (k.key == key)
@@ -306,7 +331,7 @@ namespace M17N.Input
       }
     }
 
-    public class KeySeq : Xex.TermValue
+    internal class KeySeq : Xex.TermValue
     {
       public List<Key> keyseq = new List<Key> ();
 
@@ -387,7 +412,7 @@ namespace M17N.Input
     {
       public MSymbol name;
       public MText description;
-      public List<KeySeq> keys;
+      internal List<KeySeq> keys;
 
       public Command (MPlist p)
       {
@@ -494,20 +519,25 @@ namespace M17N.Input
     {
       private MSymbol name;
 
-      public Marker (MSymbol name)
+      private Marker (MSymbol name)
        {
          this.name = name;
        }
 
       public abstract int Position (Context ic);
-      public abstract void Mark (Context ic);
-      public abstract int CharAt (Context ic);
+      public virtual void Mark (Context ic)
+       {
+         throw new Exception ("Can't set predefined marker: " + name);
+       }
+      public virtual int CharAt (Context ic)
+       {
+         return ic.preedit[Position (ic)];
+       }
+      public override Xex.TermValue Clone () { return this; }
 
       public static Xex.TermValue parser (Xex.Domain domain, XmlNode node)
       {
-       MSymbol name = node.InnerText;
-       
-       return Get ((Context) domain.context, name);
+       return Get ((MSymbol) node.InnerText);
       }
 
       public class Named : Marker
@@ -516,20 +546,14 @@ namespace M17N.Input
 
        public override int Position (Context ic)
        {
-         int pos;
-         if (ic.markers.TryGetValue (name, out pos))
-           return pos;
-         return 0;
+         MPlist p = ic.markers.Find (name);
+         return (p != null ? p.Integer : 0);
+
        }
 
        public override void Mark (Context ic)
        {
-         ic.markers[name] = ic.cursor_pos;
-       } 
-
-       public override Xex.TermValue Clone ()
-       {
-         return new Named (name, pos);
+         ic.markers.Put (name, ic.cursor_pos);
        }
       }
      
@@ -566,23 +590,29 @@ namespace M17N.Input
            return name.Name[1] - '0';
          }
        }
-      
-       public override void Mark (Context ic)
-       {
-         throw new Exception ("Can't set predefined marker: " + name);
-       }
+      }
+
+      public class PredefinedAbsolute : Marker
+      {
+       private int pos;
 
-       public override Xex.TermValue Clone ()
+       public PredefinedAbsolute (MSymbol name) : base (name)
+         {
+           if (! int.TryParse (name.Name.Substring (1), out pos))
+             throw new Exception ("Invalid marker name: " + name);
+         }
+
+       public override int Position (Context ic)
        {
-         return new Predefined (name);
+         return (pos < ic.preedit.Length ? pos : ic.preedit.Length);
        }
       }
 
-      public class PredefinedPlusMinus : Marker
+      public class PredefinedSurround : Marker
       {
        private int distance;
 
-       public PredefinedPlusMinus (MSymbol name): base (name)
+       public PredefinedSurround (MSymbol name) : base (name)
          {
            if (! int.TryParse (name.Name.Substring (2), out distance))
              throw new Exception ("Invalid marker name: " + name);
@@ -594,6 +624,16 @@ namespace M17N.Input
        {
          return ic.cursor_pos + distance;
        }
+
+       public override int CharAt (Context ic)
+         {
+           int pos = ic.cursor_pos + distance;
+           if (pos < 0)
+             return ic.GetSurroundingChar (pos);
+           else if (pos >= ic.preedit.Length)
+             return ic.GetSurroundingChar (pos - ic.preedit.Length);
+           return ic.preedit[pos];
+         }
       }
 
       static internal Dictionary<MSymbol,Predefined> predefined_markers;
@@ -601,29 +641,26 @@ namespace M17N.Input
       static Marker ()
       {
        predefined_markers = new Dictionary<MSymbol,Predefined> ();
-       MSymbol[] symlist = new MSymbol[] {"@<", "@>", "@-", "@+", "@[", "@]",
-                                          "@0", "@1", "@2", "@3", "@4",
-                                          "@5", "@6", "@7", "@8", "@9" };
+       MSymbol[] symlist = new MSymbol[] {"@<", "@>", "@-", "@+", "@[", "@]" };
        foreach (MSymbol s in symlist)
          predefined_markers[s] = new Predefined (s);
       }
 
       public static Marker Get (MSymbol name)
       {
-       Predefined pred;
-
-       if (predefined_markers.TryGetValue (name, out pred))
-         return pred;
        if (name.Name[0] == '@')
          {
-           int pos;
-           if (name.Name.Length >= 3
-               && (name.Name[1] == '-' || name.Name[1] == '+')
-               && int.TryParse (name.Name.Substring (2), out pos)
-               && (pos > 0))
-             return (predefined_markers[name] = new Predefined (name));
-           else
+           Predefined pred;
+           if (predefined_markers.TryGetValue (name, out pred))
+             return pred;
+           if (name.Name.Length == 1)
              throw new Exception ("Invalid marker name: " + name);
+           if (Char.IsDigit (name.Name[1]))
+             return new PredefinedAbsolute (name);
+           if (name.Name.Length == 2 || name == Mat_minus_zero
+               || ! (name.Name[1] == '-' || name.Name[1] == '+'))
+             throw new Exception ("Invalid marker name: " + name);
+           return new PredefinedSurround (name);
          }
        return new Named (name);
       }
@@ -885,6 +922,30 @@ namespace M17N.Input
 
     internal class Selector : Xex.TermValue
     {
+      static new Dictionary<MSymbol, Selector> selectors;
+
+      static Selector ()
+       {
+         selectors = new Dictionary<MSymbol, Selector> ();
+         MSymbol[] symlist = new MSymbol[] { "@<", "@=", "@>", "@-", "@+",
+                                             "@[", "@]" };
+         foreach (MSymbol s in symlist)
+           selectors[s] = new Selector (s);
+         selectors["@first"] = new Selector ('<');
+         selectors["@current"] = new Selector ('=');
+         selectors["@last"] = new Selector ('>');
+         selectors["@previous"] = new Selector ('-');
+         selectors["@next"] = new Selector ('+');
+         selectors["@previous-candidate-list"] = new Selector ('[');
+         selectors["@next-candidate-list"] = new Selector (']');
+       }
+
+      private char tag;
+
+      private Selector (MSymbol sym) { tag = sym.Name[1]; }
+
+      private Selector (char tag) { this.tag = tag; }
+
       public static Xex.TermValue parser (Xex.Domain domain, XmlNode node)
       {
        return Get ((MSymbol) node.InnerText);
@@ -892,11 +953,10 @@ namespace M17N.Input
 
       public static Xex.TermValue Get (MSymbol name)
       {
-       Predefined pred;
-
-       if (! predefined_selectors.TryGetValue (name, out pred))
+       Selector selector;
+       if (! selectors.TryGetValue (name, out selector))
          throw new Exception ("Invalid selector name: " + name);
-       return pred;
+       return selector;
       }
 
       public override Xex.TermValue Clone () { return this; }
@@ -914,44 +974,71 @@ namespace M17N.Input
          default: break;
          }
       }
+    }
 
-      static new Dictionary<MSymbol, Selector> selectors;
+    internal class Map
+    {
+      public MSymbol name;
+      public List<Entry> entries;
 
-      static Selector ()
+      public Map (MSymbol name) { this.name = name; }
+
+      public class Entry
+      {
+       public KeySeq keyseq;
+       public Xex.Term[] actions;
+
+       public Entry (Xex.Domain domain, KeySeq keyseq, Xex.Term[] actions)
        {
-         selectors = new Dictionary<MSymbol, Selector> ();
-         MSymbol[] symlist = new MSymbol[] { "@<", "@=", "@>", "@-", "@+",
-                                             "@[", "@]" };
-         foreach (MSymbol s in symlist)
-           selectors[s] = new Selector (s);
+         this.keyseq = keyseq;
+         this.actions = actions;
        }
+      }
     }
 
-    internal class Map
+    internal class Branch
     {
       public MSymbol name;
-      public Dictionary<Key, Map> submaps;
-      public Xex.Term actions;
+      public Keymap keymap;
+      public Xex.Term[] enter_actions, fallback_actions;
+    }
 
-      public void Add (KeySeq keys, int index, Xex.Term actions)
-      {
-       Map sub = null;
+    public class Keymap
+    {
+       public Dictionary<Key, Keymap> keymaps;
+       public Xex.Term[] map_actions, branch_actions;
 
-       if (submaps == null)
-         submaps = new Dictionary<Key, Map> ();
-       else
-         submaps.TryGetValue (keys.keyseq[index], out sub);
-       if (sub == null)
+       public void Add (KeySeq keys, int index, 
+                        Xex.Term[] map_actions, Xex.Term[] branch_actions)
+       {
+         Map sub = null;
+
+         if (submaps == null)
+           submaps = new Dictionary<Key, Map> ();
+         else
+           submaps.TryGetValue (keys.keyseq[index], out sub);
+         if (sub == null)
+           {
+             Key key = keys.keyseq[index];
+             submaps[key] = sub = new Map ();
+           }
+         if (index + 1 < keys.keyseq.Count)
+           sub.Add (keys, index + 1, actions);
+         else
+           this.actions = actions;
+       }
+      }
+
+      public void AddMap (Map map, Xex.Term[] actions)
+      {
+       foreach (Map.Entry entry in map.entries)
          {
-           Key key = keys.keyseq[index];
-           submaps[key] = sub = new Map ();
+           Add (entry.keyseq, 0, entry.actions, actions)
          }
-       if (index + 1 < keys.keyseq.Count)
-         sub.Add (keys, index + 1, actions);
-       else
-         this.actions = actions;
       }
 
+      public void Add (KeySeq keys, int index,
+                      Xex.Term[] map_actions, Xex.Term[] branch_actions)
       public Xex.Term Lookup (KeySeq keys, ref int index)
       {
        if (index < keys.keyseq.Count)
@@ -997,18 +1084,18 @@ namespace M17N.Input
 
     internal class State
     {
-      public MSymbol name;
+      public Xex.Symbol name;
       public MText title;
       public MPlist branches = new MPlist ();
 
-      public State (MSymbol name)
+      public State (Xex.Symbol name)
       {
        this.name = name;
       }
 
       public override string ToString ()
       {
-       MText mt = "(" + name.Name;
+       MText mt = "(" + name;
 
        if (title != null)
          mt.Cat (" \"" + title + "\"");
@@ -1031,7 +1118,8 @@ namespace M17N.Input
     internal Xex.Symbol[] var_names;
     internal Dictionary<MSymbol, Plugin> plugins;
     internal Dictionary<MSymbol, Map> maps;
-    internal MPlist states;
+    internal Dictionary<Xex.Symbol, State> states;
+    internal State initial_state;
 
     static MInputMethod ()
     {
@@ -1182,10 +1270,19 @@ namespace M17N.Input
       return true;
     }
 
+    private void add_default_state ()
+    {
+      Xex.Symbol Ninit = "init";
+      State state = new State (Ninit);
+      foreach (KeyValuePair<MSymbol, Map>kv in maps)
+       state.branches.Add (kv.Key, null);
+      states[Ninit] = initial_state = state;
+    }
+
     private void load (MPlist plist, bool full)
     {
       maps = new Dictionary<MSymbol, Map> ();
-      states = new MPlist ();
+      states = new Dictionary<Xex.Symbol, State> ();
 
       for (; ! plist.IsEmpty; plist = plist.next)
        if (plist.IsPlist)
@@ -1230,14 +1327,8 @@ namespace M17N.Input
        commands = new Command[0];
       if (! full)
        return;
-      if (states.IsEmpty)
-       {
-         State state = new State ((MSymbol) "init");
-         plist = new MPlist ();
-         foreach (KeyValuePair<MSymbol, Map>kv in maps)
-           state.branches.Add (kv.Key, null);
-         states.Add (state.name, state);
-       }
+      if (states.Count == 0)
+       add_default_state ();
     }
 
     private void load (XmlNode node, bool full)
@@ -1245,7 +1336,7 @@ namespace M17N.Input
       bool skip_header = load_status == LoadStatus.Header;
 
       maps = new Dictionary<MSymbol, Map> ();
-      states = new MPlist ();
+      states = new Dictionary<Xex.Symbol, State> ();
 
       if (node.NodeType == XmlNodeType.Document)
        node = node.FirstChild;
@@ -1286,13 +1377,8 @@ namespace M17N.Input
        commands = new Command[0];
       if (! full)
        return;
-      if (states.IsEmpty)
-       {
-         State state = new State ((MSymbol) "init");
-         foreach (KeyValuePair<MSymbol, Map>kv in maps)
-           state.branches.Add (kv.Key, null);
-         states.Add (state.name, state);
-       }
+      if (states.Count == 0)
+       add_default_state ();
     }
 
     private static void transform (MPlist plist)
@@ -1667,6 +1753,23 @@ namespace M17N.Input
 
     private void parse_maps (XmlNode node)
     {
+      for (node = node.FirstChild; node != null; node = node.NextSibling)
+       if (node.Name == Nmap)
+         {
+           MSymbol name = node.Attributes[0].Value;
+           Map map = new Map (name);
+           maps[name] = map;
+           for (XmlNode nd = node.FirstChild; nd != null; nd = nd.NextSibling)
+             if (nd.Name == Nrule)
+               {
+                 XmlNode n = nd.FirstChild;
+                 if (n.Name != Nkeyseq)
+                   continue;
+                 KeySeq keyseq = (KeySeq) KeySeq.parser (domain, n);
+                 Xex.Term[] actions = Xex.ParseTerms (domain, n.NextSibling);
+                 map.entries.Add (new Map.Entry (domain, keyseq, actions));
+               }
+         }
     }
 
     private void parse_states (XmlNode node)
@@ -1731,14 +1834,15 @@ namespace M17N.Input
        {
          if (target_name == MSymbol.nil)
            {
-             for (p = im.states; ! p.IsEmpty; p = p.next)
-               states.Add (p.key, p.val);
+             foreach (KeyValuePair<Xex.Symbol, State> kv in im.states)
+               states[kv.Key] = kv.Value;
            }
          else
            {
-             object state = im.states.Get (target_name);
-             if (state != null)
-               states.Add (target_name, state);
+             Xex.Symbol state_name = target_name.Name;
+             State state;
+             if (im.states.TryGetValue (state_name, out state))
+               states[state_name] = state;
            }
        }
     }
@@ -1883,7 +1987,6 @@ namespace M17N.Input
       return terms;
     }
 
-
     private void parse_macros (MPlist plist)
     {
       for (MPlist pl = plist; ! pl.IsEmpty; pl = pl.next)
@@ -1917,9 +2020,8 @@ namespace M17N.Input
          
            if (! pl.IsSymbol)
              continue;
-           Map map = new Map ();
-           map.name = pl.Symbol;
-           maps[map.name] = map;
+           Map map = new Map (pl.Symbol);
+           maps[pl.Symbol] = map;
            for (pl = pl.next; ! pl.IsEmpty; pl = pl.next)
              {
                if (! pl.IsPlist)
@@ -1935,8 +2037,8 @@ namespace M17N.Input
                p = p.next;
                if (p.IsEmpty)
                  continue;
-               map.Add (keys, 0,
-                        new Xex.Term (domain, Nprogn, parse_actions (p)));
+               Xex.Term[] actions = parse_actions (p);
+               map.entries.Add (new Map.Entry (domain, keys, actions));
              }
          }
     }
@@ -1957,11 +2059,12 @@ namespace M17N.Input
            if (! pl.IsSymbol)
              continue;
 
-           State state = new State (pl.Symbol);
+           Xex.Symbol name = (Xex.Symbol) pl.Symbol.Name;
+           State state = new State (name);
            state.title = title;
-           if (states == null)
-             states = new MPlist ();
-           states.Add (state.name, state);
+           if (states.Count == 0)
+             initial_state = state;
+           states[name] = state;
            for (pl = pl.next; ! pl.IsEmpty; pl = pl.next)
              {
                if (! pl.IsPlist)
@@ -2107,9 +2210,9 @@ namespace M17N.Input
     }
 
     private static Xex.Term Fshiftback (Xex.Domain domain, Xex.Variable vari,
-                                        Xex.Term[] args)
+                                       Xex.Term[] args)
     {
-      ((Context) domain.context).shift_back ();
+      ((Context) domain.context).shiftback ();
       return Tnil;
     }
 
@@ -2123,7 +2226,7 @@ namespace M17N.Input
                                               Xex.Variable vari,
                                               Xex.Term[] args)
     {
-      return new Xex.Term (((Context) domain.context).surrounding_flag);
+      return new Xex.Term (((Context) domain.context).SurroundingFlag);
     }
 
     public override string ToString ()
@@ -2154,8 +2257,8 @@ namespace M17N.Input
       foreach (KeyValuePair<MSymbol, Map> kv in maps)
        str += " " + kv.Value;
       str += ") (states";
-      foreach (MPlist p in states)
-       str += " " + p.val;
+      foreach (Xex.Symbol name in states.Keys)
+       str += " " + name;
       return str + "))";
     }
 
@@ -2163,13 +2266,16 @@ namespace M17N.Input
     {
       internal static Xex.Symbol Ncandidates_group_size
         = "candidates-group-size";
-      public MInputMethod im;
+      private MInputMethod im;
+      private Dictionary<MSymbol, Callback> callbacks
+       = new Dictionary<MSymbol, Callback> ();
+
       private MText produced;
       private bool active;
       private MText status;
       internal MText preedit;
       internal int cursor_pos;
-      internal Dictionary<Xex.Symbol, int> markers;
+      internal MPlist markers;
       internal Candidates candidates;
       private int candidate_from, candidate_to;
       private bool candidate_show;
@@ -2203,17 +2309,48 @@ namespace M17N.Input
 
       internal ChangedStatus changed;
 
-      public ChangedStatus Changed { get { return changed; } }
+      static MPlist callback_arg = new MPlist ();
 
-      public Context (MInputMethod im)
+      private bool call_callback (MSymbol name, MPlist arg)
       {
-       this.im = im;
-       domain = new Xex.Domain (im.domain, this);
-       state_list = new List<State> ();
-       state_list.Add ((State) im.states.val);
-       keys = new KeySeq ();
+       Callback callback;
+       if (! callbacks.TryGetValue (name, out callback))
+         return false;
+       return callback (this, arg);
       }
 
+      private bool get_surrounding_text (int len)
+      {
+       if (len < 0 ? -len <= preceding_text.Length
+           : len <= following_text.Length)
+         return true;
+       callback_arg.Set (MSymbol.integer, len);
+       if (! call_callback (Mget_surrounding_text, callback_arg)
+           || ! callback_arg.IsMText)
+         return false;
+       if (len < 0)
+         {
+           preceding_text = callback_arg.Text;
+           return (-len <= preceding_text.Length);
+         }
+       following_text = callback_arg.Text;
+       return (len <= following_text.Length);
+      }
+
+      internal int SurroundingFlag
+      {
+       get { return (callbacks.ContainsKey (Mget_surrounding_text) ? 1 : 0); }
+      }
+
+      internal int GetSurroundingChar (int pos)
+      {
+       if (! get_surrounding_text (pos < 0 ? pos : pos + 1))
+         return 0;
+       if (pos < 0)
+         return preceding_text[preceding_text.Length + pos];
+       return following_text[pos];
+      }        
+
       private void adjust_markers (int from, int to, object inserted)
       {
        int ins = (inserted == null ? 0
@@ -2428,16 +2565,6 @@ namespace M17N.Input
          }
       }
 
-      internal void mark (MSymbol sym)
-      {
-       MPlist slot = markers.Find (sym);
-
-       if (slot == null)
-         markers.Push (sym, cursor_pos);
-       else
-         slot.val = cursor_pos;
-      }
-
       internal void pushback (int n)
       {
        if (n > 0)
@@ -2488,28 +2615,9 @@ namespace M17N.Input
        changed |= ChangedStatus.Preedit;
       }
 
-      internal void shift (MSymbol sym)
+      private void new_state (bool changed)
       {
-       State state;
-
-       if (sym == MSymbol.t)
-         {
-           state = state_list.Last ();
-           if (state_list.Count > 1)
-             state_list.RemoveAt (state_list.Count - 1);
-         }
-       else
-         {
-           state = (State) im.states.Get (sym);
-           if (state == null)
-             throw new Exception ("Unknown state: " + state.name);
-         }
-       if (state == null)
-         {
-           state = state_list.Last;
-           state_list.RemoveAt (state_list.Count -1);
-         }
-       if (state == (State) im.states.val)
+       if (state_list.Count == 1)
          {
            commit ();
            reset ();
@@ -2519,14 +2627,14 @@ namespace M17N.Input
            state_key_head = key_head;
            state_pos = cursor_pos;
            state_preedit = preedit.Dup ();
-           if (state != state_list.Last ())
+           state_var_values = domain.SaveValues ();
+           if (changed)
              {
-               state_list.Add (state);
-               state_var_values = domain.SaveValues ();
+               State state = state_list[state_list.Count - 1];
                status = state.title;
                if (status == null)
                  status = im.title;
-               changed |= ChangedStatus.StateTitle;
+               this.changed |= ChangedStatus.StateTitle;
                Xex on_entry
                  = (Xex) state.branches.Get (MSymbol.t);
                if (on_entry != null)
@@ -2535,6 +2643,26 @@ namespace M17N.Input
          }
       }
 
+      internal void shift (Xex.Symbol sym)
+      {
+       State state;
+       bool changed;
+
+       if (! im.states.TryGetValue (sym, out state))
+         throw new Exception ("Unknown state: " + sym);
+       changed = state != state_list[state_list.Count - 1];
+       if (changed)
+         state_list.Add (state);
+       new_state (changed);
+      }
+
+      internal void shiftback ()
+      {
+       if (state_list.Count > 1)
+         state_list.RemoveAt (state_list.Count - 1);
+       new_state (true);
+      }
+
       internal void reset ()
       {
        preedit.Del ();
@@ -2544,11 +2672,27 @@ namespace M17N.Input
        cursor_pos = 0;
        key_head = commit_key_head = 0;
        state_list.Clear ();
-       state_list.Add ((State) im.states.Val);
+       state_list.Add (im.initial_state);
        state_key_head = 0;
        state_pos = 0;
       }
 
+      public Context (MInputMethod im)
+      {
+       this.im = im;
+       domain = new Xex.Domain (im.domain, this);
+       state_list.Clear ();
+       state_list.Add (im.initial_state);
+       keys = new KeySeq ();
+      }
+
+      public ChangedStatus Changed { get { return changed; } }
+
+      public void AddCallback (MSymbol name, Callback callback)
+      {
+       callbacks[name] = callback;
+      }
+
       internal object GetCandidates (out int column)
       {
        column = 0;
@@ -2562,8 +2706,18 @@ namespace M17N.Input
        return candidates.Current;
       }
 
-      internal void HandleKey ()
+      private bool handle_key ()
       {
+       State state = state_list[state_list.Count - 1];
+       for (MPlist *p = state.branches; ! p.IsEmpty; p = p.next)
+         {
+           int n = state_key_head;
+           Xex.Term term = ((Map) p.Val).Lookup (keys, ref n);
+
+           
+
+         }
+
       }
 
       public bool Toggle ()
@@ -2584,7 +2738,6 @@ namespace M17N.Input
        return (produced.Length > 0);
       }
 
-
       // Return value:
       //   true: All keys are handled and there's no text to commit.
       //   false: Some key is unhandled or there's a text to commit.
@@ -2592,7 +2745,7 @@ namespace M17N.Input
 
       public bool Filter (Key key)
       {
-       if (check_reload (key))
+       if (key == Key.Reload)
          return true;
        changed = ChangedStatus.None;
        produced.Del ();
@@ -2600,20 +2753,20 @@ namespace M17N.Input
        following_text.Del ();
 
        key_unhandled = false;
-       keys.Add (key);
+       keys.keyseq.Add (key);
        int count = 0;
-       while (key_head < keys.Length)
+       while (key_head < keys.keyseq.Count)
          {
            if (! handle_key ())
              {
-               unhandled_key = keys[key_head++];
+               unhandled_key = keys.keyseq[key_head++];
                key_unhandled = true;
                break;
              }
            if (++count == 100)
              break;
          }
-       keys.RemoveRange (0, key_head);
+       keys.keyseq.RemoveRange (0, key_head);
        return (! key_unhandled && produced.Length == 0);
       }
     }
index 60a2008..c609e1a 100644 (file)
@@ -1880,7 +1880,7 @@ namespace System.Xml.Expression
 
     private Term[] terms;
 
-    private void parse_terms (Domain domain, XmlNode node)
+    public static Term[] ParseTerms (Domain domain, XmlNode node)
     {
       int nterms = 0;
       for (XmlNode n = node; n != null; n = n.NextSibling)
@@ -1893,8 +1893,7 @@ namespace System.Xml.Expression
            else
              nterms++;
          }
-
-      terms = new Term[nterms];
+      Term[] terms = new Term[nterms];
       int i = 0;
       for (XmlNode n = node; n != null; n = n.NextSibling)
        if (n.NodeType == XmlNodeType.Element)
@@ -1904,11 +1903,12 @@ namespace System.Xml.Expression
            else if (n.Name != Ndefvar)
              terms[i++]= new Term (domain, n);
          }
+      return terms;
     }
 
     public Xexpression (Domain domain, XmlNode node)
     {
-      parse_terms (domain, node);
+      terms = ParseTerms (domain, node);
     }
 
     public Xexpression (Domain domain, string url)
@@ -1927,7 +1927,7 @@ namespace System.Xml.Expression
            throw new Exception ("Node <expr> not found");
          node = doc.ReadNode (reader);
        }
-      parse_terms (domain, node.FirstChild);
+      terms = ParseTerms (domain, node.FirstChild);
     }
 
     public Term Eval (Domain domain)