From 15afd301194e834e8313cdd5fab4e86593e3b75b Mon Sep 17 00:00:00 2001 From: handa Date: Thu, 8 Oct 2009 08:16:15 +0000 Subject: [PATCH] *** empty log message *** --- MInputMethod.cs | 408 +++++++++++++++++++------------------------------------ XmlExpr.cs | 45 ++++-- input.cs | 6 +- 3 files changed, 175 insertions(+), 284 deletions(-) diff --git a/MInputMethod.cs b/MInputMethod.cs index 05e0c48..9e180d6 100644 --- a/MInputMethod.cs +++ b/MInputMethod.cs @@ -41,29 +41,11 @@ namespace M17N.Input private static MSymbol Mmap_list = "map-list"; private static MSymbol Mstate = "state"; internal static MSymbol Mcandidates = "candidates"; - private static MSymbol Minsert = "insert"; - internal static MSymbol Mselect = "select"; - private static MSymbol Mdelete = "delete"; - private static MSymbol Mmove = "move"; - private static MSymbol Mmark = "mark"; - private static MSymbol Mmarker = "marker"; - private static MSymbol Mset = "set"; - private static MSymbol Madd = "add"; - private static MSymbol Msub = "sub"; - private static MSymbol Mmul = "mul"; - private static MSymbol Mdiv = "div"; - private static MSymbol Mif = "if"; - private static MSymbol Mcond = "cond"; - private static MSymbol Mchar_at = "char-at"; - private static MSymbol Msurrounding_flag = "surrounding-text-flag"; - 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 Qmap = "map"; private static Xex.Symbol Qrule = "rule"; private static Xex.Symbol Qkeyseq = "keyseq"; @@ -72,6 +54,18 @@ namespace M17N.Input private static Xex.Symbol Qinsert = "insert"; private static Xex.Symbol Qinsert_candidates = "insert-candidates"; private static Xex.Symbol Qchar_at = "char-at"; + private static Xex.Symbol Qat_minus_zero = "@-0"; + private static Xex.Symbol Qselect = "select"; + private static Xex.Symbol Qdelete = "delete"; + private static Xex.Symbol Qshift = "shift"; + private static Xex.Symbol Qmove = "move"; + private static Xex.Symbol Qmark = "mark"; + private static Xex.Symbol Qset = "set"; + private static Xex.Symbol Qadd = "add"; + private static Xex.Symbol Qsub = "sub"; + private static Xex.Symbol Qmul = "mul"; + private static Xex.Symbol Qdiv = "div"; + private static Xex.Symbol Qcond = "cond"; private static Xex.Symbol Qsname = "sname"; private static Xex.Symbol Qmname = "mname"; private static Xex.Symbol Qstate_hook = "state-hook"; @@ -79,7 +73,8 @@ namespace M17N.Input private static Xex.Symbol Qbranch = "branch"; private static Xex.Symbol Qstate = "state"; private static Xex.Symbol Qtitle = "title"; - + private static Xex.Symbol Qeq = "="; + private static Xex.Symbol Qeqeq = "=="; private static Xex.Term Tnil = new Xex.Term ((Xex.Symbol) "nil"); private static Xex.Term Tcatch_tag = new Xex.Term ((Xex.Symbol) "@mimtag"); @@ -323,7 +318,18 @@ namespace M17N.Input public override string ToString () { - MText mt = new MText (ToChar ()); + int c = ToChar (); + MText mt = null; + if (c < 0x20) + foreach (KeyValuePair kv in keysyms) + if ((uint) c == kv.Value) + { + mt = kv.Key; + break; + } + if (mt == null) + mt = new MText (c); + KeyModifier m = ((KeyModifier) key) & KeyModifier.All; if (m != KeyModifier.None) @@ -407,7 +413,7 @@ namespace M17N.Input { MText mt; foreach (Key key in keyseq) - if (key.HasModifier) + if (key.HasModifier || key.ToChar () < 0x20) { mt = "("; foreach (Key k in keyseq) @@ -421,10 +427,12 @@ namespace M17N.Input mt = "\""; foreach (Key k in keyseq) { - if (mt.Length > 1) - mt.Cat (' '); - mt.Cat (k.ToString ()); - } + int c = k.ToChar (); + + if (c == '\\' || c == '"') + mt.Cat ('\\'); + mt.Cat (c); + } return (string) mt.Cat ("\""); } } @@ -537,9 +545,9 @@ namespace M17N.Input internal abstract class Marker : Xex.TermValue { - private MSymbol name; + private Xex.Symbol name; - private Marker (MSymbol name) + private Marker (Xex.Symbol name) { this.name = name; } @@ -557,33 +565,39 @@ namespace M17N.Input public static Xex.TermValue parser (Xex.Domain domain, XmlNode node) { - return Get ((MSymbol) node.InnerText); + return Get ((Xex.Symbol) node.InnerText); } public class Named : Marker { - public Named (MSymbol name) : base (name) { } + public Named (Xex.Symbol name) : base (name) { } public override int Position (Context ic) { - MPlist p = ic.markers.Find (name); - return (p != null ? p.Integer : 0); + int pos; + if (ic.marker_positions.TryGetValue (this, out pos)) + return pos; + return 0; } public override void Mark (Context ic) { - ic.markers.Put (name, ic.cursor_pos); + ic.marker_positions[this] = ic.cursor_pos; } } public class Predefined : Marker { - public Predefined (MSymbol name) : base (name) { } + char tag; + public Predefined (Xex.Symbol name) : base (name) + { + tag = ((string) name)[1]; + } public override int Position (Context ic) { - switch (name.Name[1]) { + switch (tag) { case '<': return 0; case '>': return ic.preedit.Length; case '-': return ic.cursor_pos - 1; @@ -607,7 +621,7 @@ namespace M17N.Input } return ic.preedit.Length; default: - return name.Name[1] - '0'; + return tag - '0'; } } } @@ -616,9 +630,9 @@ namespace M17N.Input { private int pos; - public PredefinedAbsolute (MSymbol name) : base (name) + public PredefinedAbsolute (Xex.Symbol name) : base (name) { - if (! int.TryParse (name.Name.Substring (1), out pos)) + if (! int.TryParse (((string) name).Substring (1), out pos)) throw new Exception ("Invalid marker name: " + name); } @@ -632,9 +646,9 @@ namespace M17N.Input { private int distance; - public PredefinedSurround (MSymbol name) : base (name) + public PredefinedSurround (Xex.Symbol name) : base (name) { - if (! int.TryParse (name.Name.Substring (2), out distance)) + if (! int.TryParse (((string) name).Substring (2), out distance)) throw new Exception ("Invalid marker name: " + name); if (distance > 0) distance--; @@ -656,29 +670,31 @@ namespace M17N.Input } } - static internal Dictionary predefined_markers; + static internal Dictionary predefined_markers; static Marker () { - predefined_markers = new Dictionary (); - MSymbol[] symlist = new MSymbol[] {"@<", "@>", "@-", "@+", "@[", "@]" }; - foreach (MSymbol s in symlist) + predefined_markers = new Dictionary (); + Xex.Symbol[] symlist + = new Xex.Symbol[] {"@<", "@>", "@-", "@+", "@[", "@]" }; + foreach (Xex.Symbol s in symlist) predefined_markers[s] = new Predefined (s); } - public static Marker Get (MSymbol name) + public static Marker Get (Xex.Symbol name) { - if (name.Name[0] == '@') + string str = name; + if (str[0] == '@') { Predefined pred; if (predefined_markers.TryGetValue (name, out pred)) return pred; - if (name.Name.Length == 1) + if (str.Length == 1) throw new Exception ("Invalid marker name: " + name); - if (Char.IsDigit (name.Name[1])) + if (Char.IsDigit (str[1])) return new PredefinedAbsolute (name); - if (name.Name.Length == 2 || name == Mat_minus_zero - || ! (name.Name[1] == '-' || name.Name[1] == '+')) + if (str.Length == 2 || name == Qat_minus_zero + || ! (str[1] == '-' || str[1] == '+')) throw new Exception ("Invalid marker name: " + name); return new PredefinedSurround (name); } @@ -1015,7 +1031,13 @@ namespace M17N.Input } } - public override string ToString () { return (string) name; } + public override string ToString () + { + string str = "(" + name; + foreach (Entry e in entries) + str += " " + e.keyseq.ToString (); + return str + ")"; + } } internal class Keymap @@ -1163,14 +1185,14 @@ namespace M17N.Input throw new Exception ("Invalid branch: " + p); MSymbol mapname = p.Symbol; if (mapname == MSymbol.t) - enter_actions = im.parse_actions (p.next); + enter_actions = im.parse_actions (p.next, false); else if (mapname == MSymbol.nil) - fallback_actions = im.parse_actions (p.next); + fallback_actions = im.parse_actions (p.next, false); else { Map map; if (im.maps.TryGetValue (mapname, out map)) - keymap.AddMap (map, im.parse_actions (p.next)); + keymap.AddMap (map, im.parse_actions (p.next, false)); else throw new Exception ("Unknown map: " + mapname); } @@ -1183,7 +1205,7 @@ namespace M17N.Input if (title != null) mt.Cat (" \"" + title + "\""); - mt += keymap.ToString (); + mt.Cat (keymap.ToString ()); return (string) mt + ")"; } } @@ -1211,7 +1233,7 @@ namespace M17N.Input im_domain.DefTerm ("selector", Selector.parser); im_domain.DefSubr (Finsert, "insert", false, 1, 1); - im_domain.DefSubr (Finsert_candidates, "candidates", false, 1, -1); + im_domain.DefSubr (Finsert_candidates, "insert-candidates", false, 1, -1); im_domain.DefSubr (Fdelete, "delete", false, 1, 1); im_domain.DefSubr (Fselect, "select", false, 1, 1); im_domain.DefSubr (Fshow, "show", false, 0, 0); @@ -1464,129 +1486,6 @@ namespace M17N.Input add_default_state (); } - private static void transform (MPlist plist) - { - return; -#if false - for (; ! plist.IsEmpty; plist = plist.next) - { - if (plist.IsMText) - { - MPlist p = new MPlist (); - p.Add (MSymbol.symbol, Minsert); - p.Add (MSymbol.mtext, plist.Text); - plist.Set (MSymbol.plist, p); - } - else if (plist.IsInteger) - { - MPlist p = new MPlist (); - p.Add (MSymbol.symbol, Minsert); - p.Add (MSymbol.integer, plist.Integer); - plist.Set (MSymbol.plist, p); - } - else if (plist.IsPlist) - { - MPlist pl = plist.Plist; - - if (pl.IsSymbol) - { - if (pl.Symbol == Madd) - pl.Set (MSymbol.symbol, (MSymbol) "+="); - else if (pl.Symbol == Msub) - pl.Set (MSymbol.symbol, (MSymbol) "-="); - else if (pl.Symbol == Mmul) - pl.Set (MSymbol.symbol, (MSymbol) "*="); - else if (pl.Symbol == Mdiv) - pl.Set (MSymbol.symbol, (MSymbol) "/="); - else if (pl.Symbol == Minsert) - { - // (insert (CANDIDATES ...)) - // => (candidates CANDIDATES ...) - if (pl.next.IsPlist) - { - pl.Set (MSymbol.symbol, Mcandidates); - pl = pl.next; - MPlist p = pl.Plist; - pl.Set (p.key, p.val); - for (p = p.next; ! p.IsEmpty; p = p.next); - pl.Add (p.key, p.val); - } - } - else if (pl.Symbol == Mif) - { - pl = pl.next; - if (! pl.IsEmpty) - transform (pl.next); - } - else if (pl.Symbol == Mcond) - { - for (pl = pl.next; ! pl.IsEmpty; pl = pl.next) - if (pl.IsPlist) - { - MPlist p = pl.Plist; - - if (p.IsPlist) - transform (p); - else - transform (p.next); - } - } - else if (pl.Symbol == Mdelete - || pl.Symbol == Mmove - || pl.Symbol == Mmark) - { - pl = pl.next; - if (pl.IsSymbol) - { - MSymbol sym = pl.Symbol; - MPlist p = new MPlist (); - p.Add (MSymbol.symbol, Mmarker); - p.Add (MSymbol.symbol, sym); - pl.Set (MSymbol.plist, p); - } - } - else if (pl.Symbol == Mpushback) - { - pl = pl.next; - if (pl.IsPlist) - pl.Plist.Push (MSymbol.symbol, Mkeyseq); - } - } - else if (pl.IsMText) - { - // (CANDIDATES ...) => (candidates CANDIDATES ...) - pl.Push (MSymbol.symbol, Mcandidates); - } - } - else if (plist.IsSymbol) - { - MSymbol sym = plist.Symbol; - - if (sym.Name.Length >= 3 - && sym.Name[0] == '@' - && (sym.Name[1] == '-' || sym.Name[1] == '+')) - { - int pos = int.Parse (sym.Name.Substring (1)); - MPlist p = new MPlist (); - - if (pos == 0) - { - p.Add (MSymbol.symbol, Msurrounding_flag); - } - else - { - if (sym.Name[1] == '+') - pos--; - p.Add (MSymbol.symbol, Mchar_at); - p.Add (MSymbol.integer, pos); - } - plist.Set (MSymbol.plist, p); - } - } - } -#endif - } - private static MText parse_description (MPlist plist) { if (plist.IsMText) @@ -1959,10 +1858,10 @@ namespace M17N.Input if (! plist.IsPlist) throw new Exception ("Invalid cond args: " + plist); MPlist p = plist.Plist; - List arg = new List (parse_actions (p)); + List arg = new List (parse_actions (p, false)); args[i] = new Xex.Term (arg); } - return new Xex.Term (domain, (Xex.Symbol) Mcond.Name, args); + return new Xex.Term (domain, Qcond, args); } private Xex.Term parse_insert (MPlist plist) @@ -1978,6 +1877,7 @@ namespace M17N.Input else if (plist.IsPlist) { MPlist pl = plist.Plist; + args = new Xex.Term[pl.Count]; int i; for (i = 0; ! pl.IsEmpty; i++, pl = pl.next) @@ -2018,75 +1918,99 @@ namespace M17N.Input args[0] = new Xex.Term (Selector.Get (plist.Symbol)); else args[0] = new Xex.Term (domain, (Xex.Symbol) plist.Symbol.Name); - return new Xex.Term (domain, (Xex.Symbol) Mselect.Name, args); + return new Xex.Term (domain, Qselect, args); } - private Xex.Term parse_funcall_with_marker (MPlist plist, MSymbol func) + private Xex.Term parse_funcall_with_marker (MPlist plist, Xex.Symbol func) { Xex.Term[] args = new Xex.Term[1]; - if (plist.IsInteger && func != Mmark) + if (plist.IsInteger && func != Qmark) args[0] = new Xex.Term (plist.Integer); else if (plist.IsSymbol) - args[0] = new Xex.Term (Marker.Get (plist.Symbol)); + args[0] = new Xex.Term (Marker.Get ((Xex.Symbol) plist.Symbol.Name)); else throw new Exception ("Invalid arg to " + func + ": " + plist); - return new Xex.Term (domain, (Xex.Symbol) func.Name, args); + return new Xex.Term (domain, func, args); } - private Xex.Term parse_char_at (MSymbol name) + private Xex.Term parse_char_at (Xex.Symbol name) { Xex.Term[] args = new Xex.Term[1]; args[0] = new Xex.Term (Marker.Get (name)); return new Xex.Term (domain, Qchar_at, args); } - private Xex.Term parse_action (MPlist plist) + private Xex.Term parse_shift (MPlist plist) + { + Xex.Term[] args = new Xex.Term[1]; + if (! plist.IsSymbol) + throw new Exception ("Invalid arg to shift: " + plist); + args[0] = new Xex.Term ((Xex.Symbol) plist.Symbol.Name); + return new Xex.Term (domain, Qshift, args); + } + + private Xex.Term parse_action (MPlist plist, bool as_funarg) { if (plist.IsPlist) { MPlist p = plist.Plist; if (p.IsMText || p.IsPlist) - return parse_insert (p); + return parse_insert (plist); if (! p.IsSymbol) throw new Exception ("Invalid action: " + p); - MSymbol name = p.Symbol; + Xex.Symbol name = p.Symbol.Name; p = p.next; - if (name == Mcond) + if (name == Qcond) return parse_cond (p); - if (name == Minsert) + if (name == Qinsert) return parse_insert (p); - if (name == Mselect) + if (name == Qselect) return parse_select (p); - if (name == Mdelete || name == Mmove || name == Mmark) + if (name == Qdelete || name == Qmove || name == Qmark) return parse_funcall_with_marker (p, name); - if (name.Name[0] == '@') + if (name == Qshift) + return parse_shift (p); + if (((string) name)[0] == '@') return parse_char_at (name); - if (name == Mset || name == Madd || name == Msub - || name == Mmul || name == Mdiv) + if (name == Qset || name == Qadd || name == Qsub + || name == Qmul || name == Qdiv) { if (! p.IsSymbol) throw new Exception ("Invalid action: " + p); Xex.Symbol varname = p.Symbol.Name; - return new Xex.Term (domain, (Xex.Symbol) name.Name, - varname, parse_actions (p.next)); + Xex.Term[] args = new Xex.Term[1]; + args[0] = parse_action (p.next, true); + return new Xex.Term (domain, name, varname, args); } else - return new Xex.Term (domain, (Xex.Symbol) name.Name, - parse_actions (p)); + { + if (name == Qeq) + name = Qeqeq; + if (p.IsEmpty) + return new Xex.Term (domain, name, null); + else + return new Xex.Term (domain, name, parse_actions (p, true)); + } } - else if (plist.IsMText || plist.IsInteger || plist.IsSymbol) - return parse_insert (plist); + else if (plist.IsSymbol) + return new Xex.Term (domain, (Xex.Symbol) plist.Symbol.Name); + else if (plist.IsMText) + return (as_funarg ? new Xex.Term ((string) plist.Text) + : parse_insert (plist)); + else if (plist.IsInteger) + return (as_funarg ? new Xex.Term (plist.Integer) + : parse_insert (plist)); else throw new Exception ("Invalid action: " + plist); } - private Xex.Term[] parse_actions (MPlist plist) + private Xex.Term[] parse_actions (MPlist plist, bool as_funarg) { Xex.Term[] terms = new Xex.Term[plist.Count]; for (int i = 0; ! plist.IsEmpty; i++, plist = plist.next) - terms[i] = parse_action (plist); + terms[i] = parse_action (plist, as_funarg); return terms; } @@ -2108,9 +2032,8 @@ namespace M17N.Input if (! p.IsSymbol) continue; - transform (p.next); domain.Defun ((Xex.Symbol) p.Symbol.Name, false, null, - parse_actions (p.next), false); + parse_actions (p.next, false), false); } } @@ -2138,9 +2061,8 @@ namespace M17N.Input else continue; p = p.next; - if (p.IsEmpty) - continue; - Xex.Term[] actions = parse_actions (p); + Xex.Term[] actions + = p.IsEmpty ? null : parse_actions (p, false); map.entries.Add (new Map.Entry (domain, keys, actions)); } } @@ -2348,10 +2270,12 @@ namespace M17N.Input private MText status; internal MText preedit; internal int cursor_pos; - internal MPlist markers; + internal Dictionary marker_positions + = new Dictionary (); internal Candidates candidates; private int candidate_from, candidate_to; private bool candidate_show; + public bool CandidateShow { get { return candidate_show; } } private List state_list = new List (); private Keymap keymap; @@ -2444,15 +2368,15 @@ namespace M17N.Input : ((MText) inserted).Length); int diff = ins - (to - from); - for (MPlist plist = markers; ! plist.IsEmpty; plist = plist.next) + foreach (Marker m in marker_positions.Keys) { - int pos = plist.Integer; + int pos = marker_positions[m]; if (pos > from) { if (pos >= to) - plist.val = pos + diff; + marker_positions[m] = pos + diff; else - plist.val = from; + marker_positions[m] = from; } } if (cursor_pos >= to) @@ -2525,58 +2449,6 @@ namespace M17N.Input } } - internal int marker (MSymbol sym) - { - int pos = cursor_pos; - - if (sym.Name.Length == 2 && sym.Name[0] == '@') - { - switch (sym.Name[0]) - { - case '<': pos = 0; break; - case '>': pos = preedit.Length; break; - case '-': pos = cursor_pos - 1; break; - case '+': pos = cursor_pos + 1; break; - case '[': - if (pos > 0) - { - int to; - preedit.FindProp (Mcandidates, pos - 1, - out pos, out to); - } - else - pos = 0; - break; - case ']': - if (cursor_pos < preedit.Length - 1) - { - int from; - preedit.FindProp (Mcandidates, pos, - out from, out pos); - } - else - pos = preedit.Length; - break; - default: - if (sym.Name[0] >= '0' && sym.Name[0] <= '9') - pos = sym.Name[0]; - break; - } - } - else if (sym.Name.Length >= 3 && sym.Name[0] == '@') - { - pos = int.Parse (sym.Name.Substring (2)); - } - else - { - object val = markers.Get (sym); - - if (val is int) - pos = (int) val; - } - return pos; - } - internal int char_at (int pos) { int c; @@ -2746,7 +2618,7 @@ namespace M17N.Input preedit.Del (); state_preedit.Del (); produced.Del (); - markers.Clear (); + marker_positions.Clear (); cursor_pos = 0; keys.keyseq.Clear (); key_head = commit_key_head = 0; diff --git a/XmlExpr.cs b/XmlExpr.cs index 599d3e9..eff1dc6 100644 --- a/XmlExpr.cs +++ b/XmlExpr.cs @@ -1577,17 +1577,28 @@ namespace System.Xml.Expression public Funcall (Domain domain, Symbol fname, Term[] args) { func = domain.GetFunc (fname); + if (args != null) + { + int nargs = args.Length; + if (nargs < func.min_arg + || (func.max_arg >= 0 && nargs > func.max_arg)) + throw new Exception ("Invalid number of arguments to: " + + fname + " " + nargs); + } this.args = args; } public Funcall (Domain domain, Symbol fname, Symbol vname, Term[] args) { func = domain.GetFunc (fname); - int nargs = args.Length; - if (nargs < func.min_arg - || (func.max_arg >= 0 && nargs > func.max_arg)) - throw new Exception ("Invalid number of arguments to: " - + fname + " " + nargs); + if (args != null) + { + int nargs = args.Length; + if (nargs < func.min_arg + || (func.max_arg >= 0 && nargs > func.max_arg)) + throw new Exception ("Invalid number of arguments to: " + + fname + " " + nargs); + } this.args = args; if (vname != Qnull) vari = domain.GetVar (vname, true); @@ -1633,13 +1644,15 @@ namespace System.Xml.Expression public override string ToString () { - string str = ""; - str += "\">"; + return str + "/>"; + str += ">"; foreach (Term e in args) str += e; - return (str + ""); + return (str + ""); } } @@ -1648,10 +1661,15 @@ namespace System.Xml.Expression public int intval; public object objval; + // ... public Term (int i) { intval = i; objval = null; } + // ... public Term (Symbol name) { intval = 0; objval = name; } + // ... public Term (string str) { intval = 0; objval = str; } + // ... public Term (List list) { intval = 0; objval = list; } + public Term (Term term) { intval = term.intval; objval = term.objval; } public Term (TermValue obj) { intval = 0; objval = obj; } @@ -1693,18 +1711,21 @@ namespace System.Xml.Expression } } + // public Term (Domain domain, Symbol vname) { intval = 0; objval = domain.GetVar (vname, true); } + // ... public Term (Domain domain, Symbol fname, Term[] args) { intval = 0; objval = new Funcall (domain, fname, args); } + // ... public Term (Domain domain, Symbol fname, Symbol vname, Term[] args) { intval = 0; @@ -1810,12 +1831,10 @@ namespace System.Xml.Expression str += e; str += ""; } - else if (objval is Funcall) - str = ""; - else if (objval is Variable) - str = ""; else if (objval is Term) str = "" + objval + ""; + else if (objval is TermValue) + str = ((TermValue) objval).ToString (); else throw new Exception ("invalid Term object: " + objval); return str; diff --git a/input.cs b/input.cs index 172eb7c..db38833 100644 --- a/input.cs +++ b/input.cs @@ -14,9 +14,6 @@ public class Test { //M17n.debug = true; MDatabase.ApplicationDir = "/usr/local/share/m17n"; - MText desc, title; - Xex.Variable[] vars; - MInputMethod.Command[] cmds; #if false MDatabase.Tag tag = new MDatabase.Tag ("input-method", @@ -32,6 +29,9 @@ public class Test im.Open (); Console.WriteLine (im); #else + MText desc, title; + Xex.Variable[] vars; + MInputMethod.Command[] cmds; MInputMethod[] ims = MInputMethod.List (); foreach (MInputMethod im in ims) { -- 1.7.10.4