X-Git-Url: http://git.chise.org/gitweb/?p=m17n%2Fm17n-lib-cs.git;a=blobdiff_plain;f=MInputMethod.cs;h=d99c609d9a45077d9da778970b5479770857ed12;hp=3f80c2f3241ee319a385668fb76284f9c150e434;hb=0f44ed40ba80ef72d6a8a835f4b980d6e3db4e50;hpb=3d9937566424ad30834dbf9090721ed8c95c47a5 diff --git a/MInputMethod.cs b/MInputMethod.cs index 3f80c2f..d99c609 100644 --- a/MInputMethod.cs +++ b/MInputMethod.cs @@ -38,6 +38,7 @@ namespace M17N.Input private static MSymbol Mmap_list = "map-list"; private static MSymbol Mstate = "state"; internal static MSymbol Mcandidates = "candidates"; + private static MSymbol Mat_minus_zero = "@-0"; private static Xex.Symbol Qmap = "map"; private static Xex.Symbol Qrule = "rule"; @@ -47,7 +48,6 @@ 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"; @@ -541,14 +541,15 @@ namespace M17N.Input internal abstract class Marker : Xex.TermValue { - private Xex.Symbol name; + private MSymbol name; - private Marker (Xex.Symbol name) + private Marker (MSymbol name) { this.name = name; } public abstract int Position (Context ic); + public virtual void Mark (Context ic) { throw new Exception ("Can't set predefined marker: " + name); @@ -557,36 +558,35 @@ namespace M17N.Input { return ic.preedit[Position (ic)]; } - public override Xex.TermValue Clone () { return this; } + + public override string ToString () { return name.Name; } public static Xex.TermValue parser (Xex.Domain domain, XmlNode node) { - return Get ((Xex.Symbol) node.InnerText); + return Get ((MSymbol) node.InnerText); } public class Named : Marker { - public Named (Xex.Symbol name) : base (name) { } + public Named (MSymbol name) : base (name) { } public override int Position (Context ic) { - int pos; - - if (ic.marker_positions.TryGetValue (this, out pos)) - return pos; - return 0; + MPlist p = ic.marker_positions.Find (name); + return (p == null ? 0 : p.Integer); } public override void Mark (Context ic) { - ic.marker_positions[this] = ic.cursor_pos; + ic.marker_positions.Put (name, ic.cursor_pos); } } public class Predefined : Marker { char tag; - public Predefined (Xex.Symbol name) : base (name) + + public Predefined (MSymbol name) : base (name) { tag = ((string) name)[1]; } @@ -626,7 +626,7 @@ namespace M17N.Input { private int pos; - public PredefinedAbsolute (Xex.Symbol name) : base (name) + public PredefinedAbsolute (MSymbol name) : base (name) { if (! int.TryParse (((string) name).Substring (1), out pos)) throw new Exception ("Invalid marker name: " + name); @@ -642,7 +642,7 @@ namespace M17N.Input { private int distance; - public PredefinedSurround (Xex.Symbol name) : base (name) + public PredefinedSurround (MSymbol name) : base (name) { if (! int.TryParse (((string) name).Substring (2), out distance)) throw new Exception ("Invalid marker name: " + name); @@ -666,20 +666,19 @@ namespace M17N.Input } } - static internal Dictionary predefined_markers; + static internal Dictionary predefined_markers; static Marker () { - predefined_markers = new Dictionary (); - Xex.Symbol[] symlist - = new Xex.Symbol[] {"@<", "@>", "@-", "@+", "@[", "@]" }; - foreach (Xex.Symbol s in symlist) + predefined_markers = new Dictionary (); + MSymbol[] symlist = new MSymbol[] {"@<", "@>", "@-", "@+", "@[", "@]" }; + foreach (MSymbol s in symlist) predefined_markers[s] = new Predefined (s); } - public static Marker Get (Xex.Symbol name) + public static Marker Get (MSymbol name) { - string str = name; + string str = name.Name; if (str[0] == '@') { Predefined pred; @@ -689,7 +688,7 @@ namespace M17N.Input throw new Exception ("Invalid marker name: " + name); if (Char.IsDigit (str[1])) return new PredefinedAbsolute (name); - if (str.Length == 2 || name == Qat_minus_zero + if (str.Length == 2 || name == Mat_minus_zero || ! (str[1] == '-' || str[1] == '+')) throw new Exception ("Invalid marker name: " + name); return new PredefinedSurround (name); @@ -991,8 +990,6 @@ namespace M17N.Input return selector; } - public override Xex.TermValue Clone () { return this; } - public void Select (Candidates candidates) { switch (tag) @@ -1930,13 +1927,13 @@ namespace M17N.Input if (plist.IsInteger && func != Qmark) args[0] = new Xex.Term (plist.Integer); else if (plist.IsSymbol) - args[0] = new Xex.Term (Marker.Get ((Xex.Symbol) plist.Symbol.Name)); + args[0] = new Xex.Term (Marker.Get (plist.Symbol)); else throw new Exception ("Invalid arg to " + func + ": " + plist); return new Xex.Term (domain, func, args); } - private Xex.Term parse_char_at (Xex.Symbol name) + private Xex.Term parse_char_at (MSymbol name) { Xex.Term[] args = new Xex.Term[1]; args[0] = new Xex.Term (Marker.Get (name)); @@ -1962,7 +1959,8 @@ namespace M17N.Input return parse_insert (plist); if (! p.IsSymbol) throw new Exception ("Invalid action: " + p); - Xex.Symbol name = p.Symbol.Name; + MSymbol sym = p.Symbol; + Xex.Symbol name = sym.Name; p = p.next; if (name == Qcond) return parse_cond (p); @@ -1975,7 +1973,7 @@ namespace M17N.Input if (name == Qshift) return parse_shift (p); if (((string) name)[0] == '@') - return parse_char_at (name); + return parse_char_at (sym); if (name == Qset || name == Qadd || name == Qsub || name == Qmul || name == Qdiv) { @@ -2124,7 +2122,12 @@ namespace M17N.Input Candidates can = ((Context) domain.context).candidates; if (can != null) - ((Selector) args[0].Objval).Select (can); + { + if (args[0].IsInt) + can.Select (args[0].Intval); + else + ((Selector) args[0].Objval).Select (can); + } return args[0]; } @@ -2283,8 +2286,7 @@ namespace M17N.Input private MText produced = new MText (); internal MText preedit = new MText (); internal int cursor_pos; - internal Dictionary marker_positions - = new Dictionary (); + internal MPlist marker_positions = new MPlist (); internal Candidates candidates; private int candidate_from, candidate_to; @@ -2303,7 +2305,6 @@ namespace M17N.Input // Index into KEYS specifying the next key to handle. internal int key_head; - private int commit_key_head; internal MText preceding_text = new MText (); internal MText following_text = new MText (); @@ -2317,13 +2318,18 @@ namespace M17N.Input internal ChangedStatus changed; + private void set_cursor (string prefix, int pos) + { + cursor_pos = pos; + } + internal void reset () { status = im.initial_state.title; produced.Del (); preedit.Del (); - cursor_pos = 0; + set_cursor ("reset", 0); marker_positions.Clear (); candidates = null; candidate_show = false; @@ -2337,7 +2343,6 @@ namespace M17N.Input keymap = im.initial_state.keymap; keys.keyseq.Clear (); - key_head = commit_key_head = 0; preceding_text.Del (); following_text.Del (); @@ -2394,21 +2399,16 @@ namespace M17N.Input : ((MText) inserted).Length); int diff = ins - (to - from); - foreach (Marker m in marker_positions.Keys) + for (MPlist p = marker_positions; ! p.IsEmpty; p = p.next) { - int pos = marker_positions[m]; + int pos = p.Integer; if (pos > from) - { - if (pos >= to) - marker_positions[m] = pos + diff; - else - marker_positions[m] = from; - } + p.Set (p.Key, pos >= to ? pos + diff : from); } if (cursor_pos >= to) - cursor_pos += diff; + set_cursor ("adjust", cursor_pos + diff); else if (cursor_pos > from) - cursor_pos = from; + set_cursor ("adjust", from); } private void preedit_replace (int from, int to, int c) @@ -2452,7 +2452,7 @@ namespace M17N.Input } preedit.PushProp (candidate_from, candidate_to, Mcandidates, this); - cursor_pos = candidate_from; + set_cursor ("update-candidate", candidate_to); changed |= (ChangedStatus.Preedit | ChangedStatus.CursorPos | CandidateAll); } @@ -2544,7 +2544,7 @@ namespace M17N.Input pos = preedit.Length; if (pos != cursor_pos) { - cursor_pos = pos; + set_cursor ("move", pos); changed |= ChangedStatus.Preedit; } } @@ -2595,7 +2595,7 @@ namespace M17N.Input internal void commit () { produced.Cat (preedit); - preedit.Del (); + preedit_replace (0, preedit.Length, null); changed |= ChangedStatus.Preedit; } @@ -2631,6 +2631,7 @@ namespace M17N.Input if (this.state.title != state.title) this.changed |= ChangedStatus.StateTitle; this.state = state; + keymap = state.keymap; } public Context (MInputMethod im) @@ -2684,21 +2685,22 @@ namespace M17N.Input domain.RestoreValues (state_var_values); preedit.Del (); preedit.Ins (0, state_preedit); - key_head = state_key_head; - cursor_pos = state_pos; + set_cursor ("restore", state_pos); } private bool handle_key () { - State current_state = state; + Console.Write ("\nHandle ({0}[{1}]) in {2}", + keys, key_head, state.name); + Keymap sub = keymap.Lookup (keys, ref key_head); if (sub != keymap) { + restore_state (); keymap = sub; if (keymap.map_actions != null) { - restore_state (); if (! take_actions (keymap.map_actions)) return false; } @@ -2721,6 +2723,8 @@ namespace M17N.Input } else { + State current_state = state; + if (keymap.branch_actions != null) { if (! take_actions (keymap.branch_actions)) @@ -2752,11 +2756,8 @@ namespace M17N.Input return key_unhandled; } - public bool Produced (out MText mt) - { - mt = produced; - return (produced.Length > 0); - } + public MText Preedit { get { return preedit; } } + public MText Produced { get { return produced; } } // Return value: // true: All keys are handled and there's no text to commit. @@ -2790,10 +2791,11 @@ namespace M17N.Input key_unhandled = true; break; } - if (++count == 100) + if (++count == 10) break; } keys.keyseq.RemoveRange (0, key_head); + key_head = 0; if ((changed & ChangedStatus.Preedit) != ChangedStatus.None && PreeditChanged != null) @@ -2813,6 +2815,9 @@ namespace M17N.Input CandidateChanged (this, callback_arg); } + Console.Write ("\nPreedit(\"{0}\"/{1}), Produced({2})", + preedit, cursor_pos, produced); + return (! key_unhandled && produced.Length == 0); } }