From: handa Date: Fri, 9 Oct 2009 13:04:03 +0000 (+0000) Subject: *** empty log message *** X-Git-Url: http://git.chise.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=3d9937566424ad30834dbf9090721ed8c95c47a5;p=m17n%2Fm17n-lib-cs.git *** empty log message *** --- diff --git a/MInputMethod.cs b/MInputMethod.cs index bd93150..3f80c2f 100644 --- a/MInputMethod.cs +++ b/MInputMethod.cs @@ -19,12 +19,9 @@ namespace M17N.Input public delegate bool Callback (Context ic, MPlist args); // Class members - public static Callback PreeditStart, PreeditDone, PreeditDraw; - public static Callback StatusStart, StatusDone, StatusDraw; - public static Callback CandidateStart, CandidateDone, CandidateDraw; - public static Callback SetSpot; - public static Callback Toggle; - public static Callback Reset; + public static event Callback PreeditChanged; + public static event Callback StatusChanged; + public static event Callback CandidateChanged; public static Callback GetSurroundingText; public static Callback DeleteSurroundingText; @@ -42,10 +39,6 @@ namespace M17N.Input private static MSymbol Mstate = "state"; internal static MSymbol Mcandidates = "candidates"; - - private static MSymbol Mget_surrounding_text = "get-surrounding-text"; - private static MSymbol Mdel_surrounding_text = "del-surrounding-text"; - private static Xex.Symbol Qmap = "map"; private static Xex.Symbol Qrule = "rule"; private static Xex.Symbol Qkeyseq = "keyseq"; @@ -86,7 +79,7 @@ namespace M17N.Input internal static MInputMethod im_global = null; [FlagsAttribute] - private enum LoadStatus + protected enum LoadStatus { None = 0x00, Header = 0x01, @@ -100,11 +93,13 @@ namespace M17N.Input { None = 0x00, StateTitle = 0x01, - Preedit = 0x02, + PreeditText = 0x02, CursorPos = 0x04, CandidateList = 0x08, CandidateIndex = 0x10, CandidateShow = 0x20, + Preedit = PreeditText | CursorPos, + Candidate = CandidateList | CandidateIndex | CandidateShow, } private static ChangedStatus CandidateAll = (ChangedStatus.CandidateList @@ -1217,8 +1212,8 @@ namespace M17N.Input // Instance members internal Xex.Domain domain = new Xex.Domain (im_domain, null); - private LoadStatus load_status = LoadStatus.None; - private MDatabase.Tag tag; + protected LoadStatus load_status = LoadStatus.None; + protected MDatabase.Tag tag; private MDatabase mdb; private MText description; @@ -1318,7 +1313,7 @@ namespace M17N.Input return (im_table.TryGetValue (tag, out im) ? im : null); } - public bool Open () + private bool Open () { return ((load_status == LoadStatus.Full) || load_body ()); } @@ -1382,7 +1377,7 @@ namespace M17N.Input private void add_default_state () { Xex.Symbol Qinit = "init"; - State state = new State (Qinit, im.title); + State state = new State (Qinit, title); foreach (KeyValuePairkv in maps) state.keymap.AddMap (kv.Value, null); states[Qinit] = initial_state = state; @@ -1769,6 +1764,8 @@ namespace M17N.Input { State state = new State (this, plist.Plist); states[state.name] = state; + if (initial_state == null) + initial_state = state; } } @@ -1779,6 +1776,8 @@ namespace M17N.Input { State state = new State (this, node); states[state.name] = state; + if (initial_state == null) + initial_state = state; } } @@ -2100,7 +2099,7 @@ namespace M17N.Input Context ic = (Context) domain.context; Marker m = (Marker) args[0].Objval; - return new Xex.Term (ic.char_at (m.Position (ic))); + return new Xex.Term (m.CharAt (ic)); } private static Xex.Term Fdelete (Xex.Domain domain, Xex.Variable vari, @@ -2116,8 +2115,7 @@ namespace M17N.Input Marker m = (Marker) args[0].Objval; pos = m.Position (ic); } - ic.delete (pos); - return args[0]; + return new Xex.Term (ic.delete (pos)); } private static Xex.Term Fselect (Xex.Domain domain, Xex.Variable vari, @@ -2236,11 +2234,12 @@ namespace M17N.Input Xex.Variable vari, Xex.Term[] args) { - return new Xex.Term (((Context) domain.context).SurroundingFlag); + return new Xex.Term (GetSurroundingText == null ? 0 : 1); } public override string ToString () { + this.Open (); string str = (String.Format ("({0} (title \"{1}\")", tag, title)); if (commands != null) { @@ -2278,8 +2277,6 @@ namespace M17N.Input { internal MInputMethod im; internal Xex.Domain domain; - private Dictionary callbacks - = new Dictionary (); private bool active; private MText status; @@ -2288,25 +2285,25 @@ namespace M17N.Input internal int cursor_pos; 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; + private State state, prev_state; + private MText state_preedit = new MText (); + private int state_key_head; + private object state_var_values, state_initial_var_values; + private int state_pos; + private Keymap keymap; // Sequence of input keys. internal KeySeq keys = new KeySeq (); - // Index into KEYS specifying the next key to handle. internal int key_head; - private int state_key_head; - private object state_var_values; private int commit_key_head; - private MText state_preedit; - private int state_pos; internal MText preceding_text = new MText (); internal MText following_text = new MText (); @@ -2325,25 +2322,32 @@ namespace M17N.Input status = im.initial_state.title; produced.Del (); preedit.Del (); + cursor_pos = 0; marker_positions.Clear (); candidates = null; candidate_show = false; - keys.keyseq.Clear (); + + state = im.initial_state; + prev_state = null; state_preedit.Del (); - key_head = commit_key_head = 0; - state_list.Clear (); - state_list.Add (im.initial_state); - keymap = im.initial_state.keymap; - key_head = state_key_head = 0; + state_key_head = 0; + state_var_values = state_initial_var_values; state_pos = 0; - } - static MPlist callback_arg = new MPlist (); + keymap = im.initial_state.keymap; + keys.keyseq.Clear (); + key_head = commit_key_head = 0; + + preceding_text.Del (); + following_text.Del (); + + changed = ChangedStatus.None; + } static Xex.Term[] catch_args = new Xex.Term[2]; - private bool take_action (Xex.Term[] actions) + private bool take_actions (Xex.Term[] actions) { catch_args[0] = Tcatch_tag; catch_args[1]= new Xex.Term (domain, Qprogn, actions); @@ -2352,22 +2356,17 @@ namespace M17N.Input return (! term.IsSymbol || term.Symval != Tcatch_tag.Symval); } - - private bool call_callback (MSymbol name, MPlist arg) - { - Callback callback; - if (! callbacks.TryGetValue (name, out callback)) - return false; - return callback (this, arg); - } + static MPlist callback_arg = new MPlist (); private bool get_surrounding_text (int len) { if (len < 0 ? -len <= preceding_text.Length : len <= following_text.Length) return true; + if (GetSurroundingText == null) + return false; callback_arg.Set (MSymbol.integer, len); - if (! call_callback (Mget_surrounding_text, callback_arg) + if (! GetSurroundingText (this, callback_arg) || ! callback_arg.IsMText) return false; if (len < 0) @@ -2379,11 +2378,6 @@ namespace M17N.Input 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)) @@ -2479,53 +2473,55 @@ namespace M17N.Input } } - internal int char_at (int pos) + internal int delete (int pos) { - int c; + int deleted = pos - cursor_pos; - pos += cursor_pos; - if (pos < 0) + if (pos < cursor_pos) { - if (preceding_text.Length < -pos) + if (pos < 0) { - MPlist plist = new MPlist (); - plist.Push (MSymbol.integer, pos); - if (GetSurroundingText != null - && GetSurroundingText (this, plist) - && plist.IsMText - && preceding_text.Length < plist.Text.Length) - preceding_text = plist.Text; + if (DeleteSurroundingText != null) + { + callback_arg.Set (MSymbol.integer, pos); + if (DeleteSurroundingText (this, callback_arg)) + { + if (callback_arg.IsInteger) + deleted = callback_arg.Integer - cursor_pos; + preceding_text.Del (); + } + else + deleted = - cursor_pos; + } + pos = 0; } - c = (-pos < preceding_text.Length - ? preceding_text[preceding_text.Length + pos] : -1); + if (pos < cursor_pos) + preedit_replace (pos, cursor_pos, null); } - else if (pos >= 0 && pos < preedit.Length) - c = preedit[pos]; else { - pos -= preedit.Length; - if (pos >= following_text.Length) + if (pos > preedit.Length) { - MPlist plist = new MPlist (); - plist.Push (MSymbol.integer, pos + 1); - if (GetSurroundingText != null - && GetSurroundingText (this, plist) - && plist.IsMText - && following_text.Length < plist.Text.Length) - following_text = plist.Text; + if (DeleteSurroundingText != null) + { + callback_arg.Set (MSymbol.integer, pos - preedit.Length); + if (DeleteSurroundingText (this, callback_arg)) + { + if (callback_arg.IsInteger) + deleted = callback_arg.Integer - cursor_pos; + preceding_text.Del (); + } + else + deleted = preedit.Length - cursor_pos; + } + pos = preedit.Length; } - c = (pos < following_text.Length ? following_text[pos] : -1); + if (pos > cursor_pos) + preedit_replace (cursor_pos, pos, null); } - return c; - } - - internal void delete (int pos) - { - if (pos < cursor_pos) - preedit_replace (pos, cursor_pos, null); - else - preedit_replace (cursor_pos, pos, null); - changed |= ChangedStatus.Preedit | ChangedStatus.CursorPos; + if (deleted != 0) + changed |= ChangedStatus.Preedit | ChangedStatus.CursorPos; + return deleted; } internal void show () @@ -2605,57 +2601,62 @@ namespace M17N.Input internal void shift (State state) { - bool changed; - if (state == null) { - if (state_list.Count > 1) - state_list.RemoveAt (state_list.Count - 1); - state = state_list[state_list.Count - 1]; - changed = true; + if (prev_state == null) + return; + state = prev_state; } - else - { - changed = state != state_list[state_list.Count - 1]; - if (changed) - state_list.Add (state); - } - if (state_list.Count == 1) + + if (state == im.initial_state) { commit (); - reset (); - } - else - { - state_key_head = key_head; - state_pos = cursor_pos; - state_preedit = preedit.Dup (); - state_var_values = domain.SaveValues (); - if (changed) + keys.keyseq.RemoveRange (0, key_head); + key_head = 0; + if (state != this.state) { - status = state.title; - this.changed |= ChangedStatus.StateTitle; + domain.RestoreValues (state_initial_var_values); if (state.enter_actions != null) - take_action (state.enter_actions); + take_actions (state.enter_actions); } + prev_state = null; + } + else + { + if (state != this.state && state.enter_actions != null) + take_actions (state.enter_actions); + prev_state = this.state; } + save_state (); + if (this.state.title != state.title) + this.changed |= ChangedStatus.StateTitle; + this.state = state; } public Context (MInputMethod im) { + if (im.load_status != LoadStatus.Full + && ! im.Open ()) + throw new Exception ("Openging " + im.tag + " failed"); this.im = im; domain = new Xex.Domain (im.domain, this); + state_initial_var_values = domain.SaveValues (); reset (); active = true; + if (PreeditChanged != null) + { + callback_arg.Set (MSymbol.mtext, preedit); + PreeditChanged (this, callback_arg); + } + if (StatusChanged != null) + { + callback_arg.Set (MSymbol.mtext, status); + StatusChanged (this, callback_arg); + } } public ChangedStatus Changed { get { return changed; } } - public void AddCallback (MSymbol name, Callback callback) - { - callbacks[name] = callback; - } - internal object GetCandidates (out int column) { column = 0; @@ -2669,13 +2670,27 @@ namespace M17N.Input return candidates.Current; } + private void save_state () + { + state_var_values = domain.SaveValues (); + state_preedit.Del (); + state_preedit.Ins (0, preedit); + state_key_head = key_head; + state_pos = cursor_pos; + } + private void restore_state () { + domain.RestoreValues (state_var_values); + preedit.Del (); + preedit.Ins (0, state_preedit); + key_head = state_key_head; + cursor_pos = state_pos; } private bool handle_key () { - State state = state_list[state_list.Count - 1]; + State current_state = state; Keymap sub = keymap.Lookup (keys, ref key_head); if (sub != keymap) @@ -2684,7 +2699,7 @@ namespace M17N.Input if (keymap.map_actions != null) { restore_state (); - if (! take_action (keymap.map_actions)) + if (! take_actions (keymap.map_actions)) return false; } else if (keymap.submaps != null) @@ -2697,7 +2712,7 @@ namespace M17N.Input { if (keymap.branch_actions != null) { - if (! take_action (keymap.branch_actions)) + if (! take_actions (keymap.branch_actions)) return false; } if (keymap != state.keymap) @@ -2708,10 +2723,10 @@ namespace M17N.Input { if (keymap.branch_actions != null) { - if (! take_action (keymap.branch_actions)) + if (! take_actions (keymap.branch_actions)) return false; } - if (state == state_list[state_list.Count - 1]) + if (state == current_state) { if (state == im.initial_state && key_head < keys.keyseq.Count) @@ -2745,8 +2760,9 @@ namespace M17N.Input // 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. - // The caller should use methods UnhandledKey and Produced. + // false: Some key is left unhandled or there's a text to + // commit. The caller should refer to UnhandledKey and + // Produced. public bool Filter (Key key) { @@ -2778,6 +2794,25 @@ namespace M17N.Input break; } keys.keyseq.RemoveRange (0, key_head); + + if ((changed & ChangedStatus.Preedit) != ChangedStatus.None + && PreeditChanged != null) + { + callback_arg.Set (MSymbol.mtext, preedit); + PreeditChanged (this, callback_arg); + } + if ((changed & ChangedStatus.StateTitle) != ChangedStatus.None + && StatusChanged != null) + { + callback_arg.Set (MSymbol.mtext, status); + StatusChanged (this, callback_arg); + } + if ((changed & ChangedStatus.Candidate) != ChangedStatus.None + && CandidateChanged != null) + { + CandidateChanged (this, callback_arg); + } + return (! key_unhandled && produced.Length == 0); } } diff --git a/input.cs b/input.cs index db38833..be619f6 100644 --- a/input.cs +++ b/input.cs @@ -14,35 +14,9 @@ public class Test { //M17n.debug = true; MDatabase.ApplicationDir = "/usr/local/share/m17n"; - -#if false - MDatabase.Tag tag = new MDatabase.Tag ("input-method", - "t", "nil", "vi-base"); - MDatabase mdb = MDatabase.Find (tag); - XmlNode node = mdb.Load ("map-alnum", "input-method", "map-list", "map"); - - Console.WriteLine (node.OuterXml); - -#elif true MInputMethod im = MInputMethod.Find ("vi", "telex"); + MInputMethod.Context ic = new MInputMethod.Context (im); + ic.Filter (new MInputMethod.Key ('a')); - im.Open (); - Console.WriteLine (im); -#else - MText desc, title; - Xex.Variable[] vars; - MInputMethod.Command[] cmds; - MInputMethod[] ims = MInputMethod.List (); - foreach (MInputMethod im in ims) - { - - Console.Write ("(<{0}, {1}, {2}>", im.Language, im.Name, im.SubName); - if (im.Info (out desc, out title, out vars, out cmds)) - Console.Write (" {0}, {1}, {2}, {3}", desc, title, vars, cmds); - if (! im.Open ()) - Console.Write (" open fail"); - Console.WriteLine (")"); - } -#endif } }