using M17N.Core;
using M17N.Input;
+using Xex = System.Xml.Expression.Xexpression;
+
namespace M17N.Input
{
- using Xex = System.Xml.Expression.Xexpression;
- using Mim = MInputMethod;
-
public class MInputMethod
{
// Delegaes
- public delegate bool Callback (MInputContext ic, MPlist args);
+ public delegate bool Callback (Context ic, MPlist args);
// Class members
public static Callback PreeditStart, PreeditDone, PreeditDraw;
private static MSymbol Mif = "if";
private static MSymbol Mcond = "cond";
private static MSymbol Mchar_at = "char-at";
- private static MSymbol Msurrounding_text_p = "surrounding-text-p";
+ private static MSymbol Msurrounding_flag = "surrounding-text-flag";
private static MSymbol Mpushback = "pushback";
private static MSymbol Mkeyseq = "keyseq";
keyseq.Add (new Key ((uint) mt[i]));
}
- private static uint parse_integer (string str)
- {
- if (Char.IsDigit (str[0]))
- {
- if (str[0] == '0' && str.Length > 2 && str[1] == 'x')
- {
- uint i = 0;
- for (int idx = 2; idx < str.Length; idx++)
- {
- uint c = str[idx];
- if (c >= '0' && c <= '9')
- i = i * 16 + (c - '0');
- else if (c >= 'A' && c <= 'F')
- i = i * 16 + 10 + (c - 'A');
- else if (c >= 'a' && c <= 'f')
- i = i * 16 + 10 + (c - 'a');
- else
- break;
- }
- return i;
- }
- return UInt32.Parse (str);
- }
- else if (str[0] == '?')
- return str[1];
- return 0;
- }
-
public KeySeq (List<Xex.Term> list)
{
int len = list.Count;
}
}
- public class Variable
- {
- public MSymbol name;
- public MText description;
- public Type type;
- public object value;
- public object[] candidates;
-
- public Variable (MPlist p)
- {
- name = p.Symbol;
- p = p.Next;
- description = parse_description (p);
- if (description == null)
- description = new MText ("No description");
- else
- p = p.next;
- type = (p.IsMText ? typeof (MText)
- : p.IsInteger ? typeof (int)
- : p.IsSymbol ? typeof (MSymbol)
- : typeof (object));
- value = p.val;
- p = p.next;
- candidates = new object[p.Count];
- for (int i = 0; ! p.IsEmpty; i++, p = p.next)
- candidates[i] = p.val;
- }
-
- private static Type parse_value (XmlNode node, out object value)
- {
- string typename = node.Attributes["type"].Value;
- Type type;
-
- if (typename == "integer")
- {
- int i;
- if (! Int32.TryParse (node.InnerText, out i))
- i = 0;
- value = i;
- type = typeof (int);
- }
- else if (typename == "string")
- {
- MText mt = node.InnerText;
- value = mt;
- type = typeof (MText);
- }
- else if (typename == "symbol")
- {
- MSymbol sym = node.InnerText;
- value = sym;
- type = typeof (MSymbol);
- }
- else
- {
- value = null;
- type = typeof (object);
- }
- return type;
- }
-
- public Variable (XmlNode node)
- {
- name = node.Attributes["id"].Value;
- for (node = node.FirstChild; node != null; node = node.NextSibling)
- if (node.NodeType == XmlNodeType.Element)
- {
- if (node.Name == "description")
- description = parse_description (node);
- else if (node.Name == "value")
- type = parse_value (node, out value);
- else if (node.Name == "valiable-value-candidate")
- {
- XmlNodeList n_list = node.ChildNodes;
- candidates = new object[n_list.Count];
- for (int i = 0; i < n_list.Count; i++)
- {
- object val;
- parse_value (n_list[i], out val);
- candidates[i] = val;
- }
- }
- }
- }
-
- public override string ToString ()
- {
- return ("(" + name + " \"" + (string) description
- + "\" " + type + " " + value + " " + candidates + ")");
- }
- }
-
public class Command
{
public MSymbol name;
this.name = name;
}
- public abstract int Position (MInputContext ic);
- public abstract void Mark (MInputContext ic);
+ public abstract int Position (Context ic);
+ public abstract void Mark (Context ic);
public static Xex.TermValue parser (Xex.Domain domain, XmlNode node)
{
MSymbol name = node.InnerText;
- return Get ((MInputContext) domain.context, name);
+ return Get ((Context) domain.context, name);
}
public class Named : Marker
private Named (MSymbol name, int p) : base (name) { pos = p; }
- public override int Position (MInputContext ic) { return pos; }
+ public override int Position (Context ic) { return pos; }
- public override void Mark (MInputContext ic) { pos = ic.cursor_pos; }
+ public override void Mark (Context ic) { pos = ic.cursor_pos; }
public override Xex.TermValue Clone ()
{
{
public Predefined (MSymbol name) : base (name) { }
- public override int Position (MInputContext ic)
+ public override int Position (Context ic)
{
switch (name.Name[1]) {
case '<': return 0;
}
}
- public override void Mark (MInputContext ic)
+ public override void Mark (Context ic)
{
throw new Exception ("Can't set predefined marker: " + name);
}
predefined_markers[s] = new Predefined (s);
}
- public static Marker Get (MInputContext ic, MSymbol name)
+ public static Marker Get (Context ic, MSymbol name)
{
Predefined pred;
Marker m;
group = new object[column];
}
- public static void Detach (MInputContext ic)
+ public static void Detach (Context ic)
{
ic.preedit.PopProp (0, ic.preedit.Length, Mcandidates);
ic.candidates = null;
internal Predefined (MSymbol sym) { this.tag = sym.Name[1]; }
- public override void Select (Candidates can)
+ public override void Select (Candidates candidates)
{
switch (tag)
{
im_domain.DefTerm ("marker", Marker.parser);
im_domain.DefTerm ("selector", Selector.parser);
- im_domain.DefSubr (Finsert, "insert", true, 1, 1);
- im_domain.DefSubr (Finsert_candidates, "candidates", true, 1, -1);
- im_domain.DefSubr (Fdelete, "delete", true, 1, 1);
- im_domain.DefSubr (Fselect, "select", true, 1, 1);
- im_domain.DefSubr (Fshow, "show", true, 0, 0);
- im_domain.DefSubr (Fhide, "hide", true, 0, 0);
- im_domain.DefSubr (Fmove, "move", true, 1, 1);
- im_domain.DefSubr (Fmark, "mark", true, 1, 1);
- im_domain.DefSubr (Fpushback, "pushback", true, 1, 1);
- im_domain.DefSubr (Fpop, "pop", true, 0, 0);
- im_domain.DefSubr (Fundo, "undo", true, 0, 1);
- im_domain.DefSubr (Fcommit, "commit", true, 0, 0);
- im_domain.DefSubr (Funhandle, "unhandle", true, 0, 0);
- im_domain.DefSubr (Fshift, "shift", true, 1, 1);
- im_domain.DefSubr (Fmarker, "marker", true, 1, 1);
- im_domain.DefSubr (Fchar_at, "char-at", true, 1, 1);
+ im_domain.DefSubr (Finsert, "insert", false, 1, 1);
+ im_domain.DefSubr (Finsert_candidates, "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);
+ im_domain.DefSubr (Fhide, "hide", false, 0, 0);
+ im_domain.DefSubr (Fmove, "move", false, 1, 1);
+ im_domain.DefSubr (Fmark, "mark", false, 1, 1);
+ im_domain.DefSubr (Fpushback, "pushback", false, 1, 1);
+ im_domain.DefSubr (Fpop, "pop", false, 0, 0);
+ im_domain.DefSubr (Fundo, "undo", false, 0, 1);
+ im_domain.DefSubr (Fcommit, "commit", false, 0, 0);
+ im_domain.DefSubr (Funhandle, "unhandle", false, 0, 0);
+ im_domain.DefSubr (Fshift, "shift", false, 1, 1);
+ im_domain.DefSubr (Fshift_back, "shiftback", false, 0, 0);
+ im_domain.DefSubr (Fchar_at, "char-at", false, 1, 1);
+ im_domain.DefSubr (Fkey_count, "key-count", false, 1, 1);
+ im_domain.DefSubr (Fsurrounding_flag, "surrounding-text-flag",
+ false, 0, 0);
MDatabase.Tag tag = new MDatabase.Tag (Minput_method, "*", "*", "*");
List<MDatabase> list = MDatabase.List (tag);
if (pos == 0)
{
- p.Add (MSymbol.symbol, Msurrounding_text_p);
+ p.Add (MSymbol.symbol, Msurrounding_flag);
}
else
{
private static Xex.Term Finsert (Xex.Domain domain, Xex.Variable vari,
Xex.Term[] args)
{
- ((MInputContext) domain.context).insert (args[0]);
+ ((Context) domain.context).insert (args[0]);
return args[0];
}
Xex.Variable vari,
Xex.Term[] args)
{
- ((MInputContext) domain.context).insert_candidates (args[0]);
+ ((Context) domain.context).insert_candidates (args[0]);
return args[0];
}
- private static Xex.Term Fmarker (Xex.Domain domain, Xex.Variable vari,
- Xex.Term[] args)
- {
- MSymbol name = (string) args[0].Symval;
- return new Xex.Term (Marker.Get ((MInputContext) domain.context, name));
- }
-
private static Xex.Term Fchar_at (Xex.Domain domain, Xex.Variable vari,
Xex.Term[] args)
{
- int c = ((MInputContext) domain.context).char_at (args[0].Intval);
- return new Xex.Term (c);
+ Context ic = (Context) domain.context;
+ Marker m = (Marker) args[0].Objval;
+
+ return new Xex.Term (ic.char_at (m.Position (ic)));
}
private static Xex.Term Fdelete (Xex.Domain domain, Xex.Variable vari,
Xex.Term[] args)
{
- ((MInputContext) domain.context).delete ((int) args[0].Intval);
+ ((Context) domain.context).delete ((int) args[0].Intval);
return args[0];
}
private static Xex.Term Fselect (Xex.Domain domain, Xex.Variable vari,
Xex.Term[] args)
{
- Candidates can = ((MInputContext) domain.context).candidates;
+ Candidates can = ((Context) domain.context).candidates;
if (can != null)
((Selector) args[0].Objval).Select (can);
private static Xex.Term Fshow (Xex.Domain domain, Xex.Variable vari,
Xex.Term[] args)
{
- ((MInputContext) domain.context).show ();
+ ((Context) domain.context).show ();
return Tnil;
}
private static Xex.Term Fhide (Xex.Domain domain, Xex.Variable vari,
Xex.Term[] args)
{
- ((MInputContext) domain.context).hide ();
+ ((Context) domain.context).hide ();
return Tnil;
}
Xex.Term[] args)
{
if (args[0].IsInt)
- ((MInputContext) domain.context).move (args[0].Intval);
+ ((Context) domain.context).move (args[0].Intval);
else
{
Marker m = (Marker) args[0].Objval;
- MInputContext ic = (MInputContext) domain.context;
- ((MInputContext) domain.context).move (m.Position (ic));
+ Context ic = (Context) domain.context;
+ ((Context) domain.context).move (m.Position (ic));
}
return args[0];
}
Xex.Term[] args)
{
Marker m = (Marker) args[0].Objval;
- m.Mark ((MInputContext) domain.context);
+ m.Mark ((Context) domain.context);
return args[0];
}
private static Xex.Term Fpushback (Xex.Domain domain, Xex.Variable vari,
Xex.Term[] args)
{
- MInputContext ic = (MInputContext) domain.context;
+ Context ic = (Context) domain.context;
if (args[0].IsInt)
ic.pushback (args[0].Intval);
private static Xex.Term Fpop (Xex.Domain domain, Xex.Variable vari,
Xex.Term[] args)
{
- ((MInputContext) domain.context).pop ();
+ ((Context) domain.context).pop ();
return Tnil;
}
Xex.Term[] args)
{
int n = args.Length == 0 ? -2 : args[0].Intval;
- ((MInputContext) domain.context).undo (n);
+ ((Context) domain.context).undo (n);
return Tnil;
}
private static Xex.Term Fcommit (Xex.Domain domain, Xex.Variable vari,
Xex.Term[] args)
{
- ((MInputContext) domain.context).commit ();
+ ((Context) domain.context).commit ();
return Tnil;
}
private static Xex.Term Funhandle (Xex.Domain domain, Xex.Variable vari,
Xex.Term[] args)
{
- ((MInputContext) domain.context).commit ();
+ ((Context) domain.context).commit ();
args = new Xex.Term[2];
args[0] = args[1] = Tcatch_tag;
return Xex.Fthrow (domain, vari, args);
private static Xex.Term Fshift (Xex.Domain domain, Xex.Variable vari,
Xex.Term[] args)
{
- ((MInputContext) domain.context).shift (args[0].Symval);
+ ((Context) domain.context).shift (args[0].Symval);
return args[0];
}
+ private static Xex.Term Fshift_back (Xex.Domain domain, Xex.Variable vari,
+ Xex.Term[] args)
+ {
+ ((Context) domain.context).shift_back ();
+ return Tnil;
+ }
+
+ private static Xex.Term Fkey_count (Xex.Domain domain, Xex.Variable vari,
+ Xex.Term[] args)
+ {
+ return new Xex.Term (((Context) domain.context).key_head);
+ }
+
+ private static Xex.Term Fsurrounding_flag (Xex.Domain domain,
+ Xex.Variable vari,
+ Xex.Term[] args)
+ {
+ return new Xex.Term (((Context) domain.context).surrounding_flag);
+ }
+
public override string ToString ()
{
string str = (String.Format ("({0} (title \"{1}\")", tag, title));
str += " " + p.val;
return str + "))";
}
- }
- public class MInputContext
- {
- internal static Xex.Symbol Ncandidates_group_size = "candidates-group-size";
- private static MSymbol Mat_less_than = "@<";
- private static MSymbol Mat_greater_than = "@>";
- private static MSymbol Mat_minus = "@-";
- private static MSymbol Mat_plus = "@+";
- private static MSymbol Mat_open_square_bracket = "@[";
- private static MSymbol Mat_close_square_bracket = "@]";
-
- public MInputMethod im;
- private MText produced;
- private bool active;
- private MText status;
- internal MText preedit;
- internal int cursor_pos;
- internal Mim.Candidates candidates;
- private MPlist candidate_group;
- private int candidate_index;
- private int candidate_from, candidate_to;
- private bool candidate_show;
-
- private Stack<Mim.State> states;
- internal Mim.KeySeq keys;
- private 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 MPlist markers = new MPlist ();
- internal MText preceding_text = new MText ();
- internal MText following_text = new MText ();
- private bool key_unhandled;
-
- internal Xex.Domain domain;
-
- internal Mim.ChangedStatus changed;
-
- public Mim.ChangedStatus Changed { get { return changed; } }
-
- public MInputContext (MInputMethod im)
- {
- this.im = im;
- domain = new Xex.Domain (im.domain, this);
- states = new Stack<Mim.State> ();
- states.Push ((Mim.State) im.states.val);
- keys = new Mim.KeySeq ();
- }
-
- private void adjust_markers (int from, int to, object inserted)
- {
- int ins = (inserted == null ? 0
- : inserted is int ? 1
- : ((MText) inserted).Length);
- int diff = ins - (to - from);
-
- for (MPlist plist = markers; ! plist.IsEmpty; plist = plist.next)
- {
- int pos = plist.Integer;
- if (pos > from)
- {
- if (pos >= to)
- plist.val = pos + diff;
- else
- plist.val = from;
- }
- }
- if (cursor_pos >= to)
- cursor_pos += diff;
- else if (cursor_pos > from)
- cursor_pos = from;
- }
+ public class Context
+ {
+ internal static Xex.Symbol Ncandidates_group_size
+ = "candidates-group-size";
+ public MInputMethod im;
+ private MText produced;
+ private bool active;
+ private MText status;
+ internal MText preedit;
+ internal int cursor_pos;
+ internal Candidates candidates;
+ private int candidate_from, candidate_to;
+ private bool candidate_show;
+
+ private Stack<State> state_stack;
+ internal KeySeq keys;
+ 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 MPlist markers = new MPlist ();
+ internal MText preceding_text = new MText ();
+ internal MText following_text = new MText ();
+ private bool key_unhandled;
+
+ internal Xex.Domain domain;
+
+ internal ChangedStatus changed;
+
+ public ChangedStatus Changed { get { return changed; } }
+
+ public Context (MInputMethod im)
+ {
+ this.im = im;
+ domain = new Xex.Domain (im.domain, this);
+ state_stack = new Stack<State> ();
+ state_stack.Push ((State) im.states.val);
+ keys = new KeySeq ();
+ }
- private void preedit_replace (int from, int to, int c)
- {
- preedit.Del (from, to);
- preedit.Ins (from, c);
- adjust_markers (from, to, c);
- }
+ private void adjust_markers (int from, int to, object inserted)
+ {
+ int ins = (inserted == null ? 0
+ : inserted is int ? 1
+ : ((MText) inserted).Length);
+ int diff = ins - (to - from);
- private void preedit_replace (int from, int to, MText mt)
- {
- preedit[from, to] = mt;
- adjust_markers (from, to, mt);
- }
+ for (MPlist plist = markers; ! plist.IsEmpty; plist = plist.next)
+ {
+ int pos = plist.Integer;
+ if (pos > from)
+ {
+ if (pos >= to)
+ plist.val = pos + diff;
+ else
+ plist.val = from;
+ }
+ }
+ if (cursor_pos >= to)
+ cursor_pos += diff;
+ else if (cursor_pos > from)
+ cursor_pos = from;
+ }
- internal void insert (Xex.Term arg)
- {
- if (arg.IsInt)
- preedit_replace (cursor_pos, cursor_pos, arg.Intval);
- else
- preedit_replace (cursor_pos, cursor_pos, new MText (arg.Strval));
- changed |= ChangedStatus.Preedit | ChangedStatus.CursorPos;
- }
+ private void preedit_replace (int from, int to, int c)
+ {
+ preedit.Del (from, to);
+ preedit.Ins (from, c);
+ adjust_markers (from, to, c);
+ }
- private void update_candidate ()
- {
- object candidate = candidates.Current;
+ private void preedit_replace (int from, int to, MText mt)
+ {
+ preedit[from, to] = mt;
+ adjust_markers (from, to, mt);
+ }
- if (candidate is MText)
- {
- preedit_replace (candidate_from, candidate_to, (MText) candidate);
- candidate_to = candidate_from + ((MText) candidate).Length;
- }
- else
- {
- preedit_replace (candidate_from, candidate_to, (int) candidate);
- candidate_to = candidate_from + 1;
- }
- preedit.PushProp (candidate_from, candidate_to,
- Mim.Mcandidates, this);
- cursor_pos = candidate_from;
- changed |= (ChangedStatus.Preedit | ChangedStatus.CursorPos
- | CandidateAll);
- }
+ internal void insert (Xex.Term arg)
+ {
+ if (arg.IsInt)
+ preedit_replace (cursor_pos, cursor_pos, arg.Intval);
+ else
+ preedit_replace (cursor_pos, cursor_pos, new MText (arg.Strval));
+ changed |= ChangedStatus.Preedit | ChangedStatus.CursorPos;
+ }
- internal void insert_candidates (Xex.Term arg)
- {
- int column = 0;
- Xex.Variable v = domain.GetVar (Ncandidates_group_size, false);
+ private void update_candidate ()
+ {
+ object candidate = candidates.Current;
- if (v != null)
- column = v.Value.Intval;
- candidates = new Mim.Candidates (arg.Listval, column);
- candidate_from = candidate_to = cursor_pos;
- update_candidate ();
- }
+ if (candidate is MText)
+ {
+ preedit_replace (candidate_from, candidate_to, (MText) candidate);
+ candidate_to = candidate_from + ((MText) candidate).Length;
+ }
+ else
+ {
+ preedit_replace (candidate_from, candidate_to, (int) candidate);
+ candidate_to = candidate_from + 1;
+ }
+ preedit.PushProp (candidate_from, candidate_to,
+ Mcandidates, this);
+ cursor_pos = candidate_from;
+ changed |= (ChangedStatus.Preedit | ChangedStatus.CursorPos
+ | CandidateAll);
+ }
- internal void select (int n)
- {
- if (candidates != null)
- {
- candidates.Select (n);
- update_candidate ();
- }
- }
+ internal void insert_candidates (Xex.Term arg)
+ {
+ int column = 0;
+ Xex.Variable v = domain.GetVar (Ncandidates_group_size, false);
+
+ if (v != null)
+ column = v.Value.Intval;
+ candidates = new Candidates (arg.Listval, column);
+ candidate_from = candidate_to = cursor_pos;
+ update_candidate ();
+ }
- internal int marker (MSymbol sym)
- {
- int pos = cursor_pos;
+ internal void select (int n)
+ {
+ if (candidates != null)
+ {
+ candidates.Select (n);
+ update_candidate ();
+ }
+ }
- 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 (Mim.Mcandidates, pos - 1,
- out pos, out to);
- }
- else
- pos = 0;
- break;
- case ']':
- if (cursor_pos < preedit.Length - 1)
- {
- int from;
- preedit.FindProp (Mim.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);
+ internal int marker (MSymbol sym)
+ {
+ int pos = cursor_pos;
- if (val is int)
- pos = (int) val;
- }
- return 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);
- internal int char_at (int pos)
- {
- int c;
+ if (val is int)
+ pos = (int) val;
+ }
+ return pos;
+ }
- pos += cursor_pos;
- if (pos < 0)
- {
- if (preceding_text.Length < -pos)
- {
- MPlist plist = new MPlist ();
- plist.Push (MSymbol.integer, pos);
- if (Mim.GetSurroundingText != null
- && Mim.GetSurroundingText (this, plist)
- && plist.IsMText
- && preceding_text.Length < plist.Text.Length)
- preceding_text = plist.Text;
- }
- c = (-pos < preceding_text.Length
- ? preceding_text[preceding_text.Length + pos] : -1);
- }
- else if (pos >= 0 && pos < preedit.Length)
- c = preedit[pos];
- else
- {
- pos -= preedit.Length;
- if (pos >= following_text.Length)
- {
- MPlist plist = new MPlist ();
- plist.Push (MSymbol.integer, pos + 1);
- if (Mim.GetSurroundingText != null
- && Mim.GetSurroundingText (this, plist)
- && plist.IsMText
- && following_text.Length < plist.Text.Length)
- following_text = plist.Text;
- }
- c = (pos < following_text.Length ? following_text[pos] : -1);
- }
- return c;
- }
+ internal int char_at (int pos)
+ {
+ int 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;
- }
+ pos += cursor_pos;
+ if (pos < 0)
+ {
+ if (preceding_text.Length < -pos)
+ {
+ 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;
+ }
+ c = (-pos < preceding_text.Length
+ ? preceding_text[preceding_text.Length + pos] : -1);
+ }
+ else if (pos >= 0 && pos < preedit.Length)
+ c = preedit[pos];
+ else
+ {
+ pos -= preedit.Length;
+ if (pos >= following_text.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;
+ }
+ c = (pos < following_text.Length ? following_text[pos] : -1);
+ }
+ return c;
+ }
- internal void show ()
- {
- candidate_show = true;
- changed |= ChangedStatus.CandidateShow;
- }
+ 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;
+ }
- internal void hide ()
- {
- candidate_show = false;
- changed |= ChangedStatus.CandidateShow;
- }
+ internal void show ()
+ {
+ candidate_show = true;
+ changed |= ChangedStatus.CandidateShow;
+ }
- internal void move (int pos)
- {
- if (pos < 0)
- pos = 0;
- else if (pos > preedit.Length)
- pos = preedit.Length;
- if (pos != cursor_pos)
- {
- cursor_pos = pos;
- changed |= ChangedStatus.Preedit;
- }
- }
+ internal void hide ()
+ {
+ candidate_show = false;
+ changed |= ChangedStatus.CandidateShow;
+ }
- internal void mark (MSymbol sym)
- {
- MPlist slot = markers.Find (sym);
+ internal void move (int pos)
+ {
+ if (pos < 0)
+ pos = 0;
+ else if (pos > preedit.Length)
+ pos = preedit.Length;
+ if (pos != cursor_pos)
+ {
+ cursor_pos = pos;
+ changed |= ChangedStatus.Preedit;
+ }
+ }
- if (slot == null)
- markers.Push (sym, cursor_pos);
- else
- slot.val = cursor_pos;
- }
+ internal void mark (MSymbol sym)
+ {
+ MPlist slot = markers.Find (sym);
- internal void pushback (int n)
- {
- if (n > 0)
- {
- key_head -= n;
- if (key_head < 0)
- key_head = 0;
- }
- else if (n == 0)
- key_head = 0;
- else
- {
- key_head = - n;
- if (key_head > keys.keyseq.Count)
- key_head = keys.keyseq.Count;
- }
- }
+ if (slot == null)
+ markers.Push (sym, cursor_pos);
+ else
+ slot.val = cursor_pos;
+ }
- internal void pushback (Mim.KeySeq keyseq)
- {
- if (key_head > 0)
- key_head--;
- if (key_head < keys.keyseq.Count)
- keys.keyseq.RemoveRange (key_head, keys.keyseq.Count - key_head);
- for (int i = 0; i < keyseq.keyseq.Count; i++)
- keys.keyseq.Add (keyseq.keyseq[i]);
- }
+ internal void pushback (int n)
+ {
+ if (n > 0)
+ {
+ key_head -= n;
+ if (key_head < 0)
+ key_head = 0;
+ }
+ else if (n == 0)
+ key_head = 0;
+ else
+ {
+ key_head = - n;
+ if (key_head > keys.keyseq.Count)
+ key_head = keys.keyseq.Count;
+ }
+ }
- internal void pop ()
- {
- if (key_head < keys.keyseq.Count)
- keys.keyseq.RemoveRange (key_head, 1);
- }
+ internal void pushback (KeySeq keyseq)
+ {
+ if (key_head > 0)
+ key_head--;
+ if (key_head < keys.keyseq.Count)
+ keys.keyseq.RemoveRange (key_head, keys.keyseq.Count - key_head);
+ for (int i = 0; i < keyseq.keyseq.Count; i++)
+ keys.keyseq.Add (keyseq.keyseq[i]);
+ }
- internal void undo (int n)
- {
- if (n < 0)
- keys.keyseq.RemoveRange (keys.keyseq.Count + n, - n);
- else
- keys.keyseq.RemoveRange (n, keys.keyseq.Count - n);
- reset ();
- }
+ internal void pop ()
+ {
+ if (key_head < keys.keyseq.Count)
+ keys.keyseq.RemoveRange (key_head, 1);
+ }
- internal void commit ()
- {
- produced.Cat (preedit);
- preedit.Del ();
- changed |= ChangedStatus.Preedit;
- }
+ internal void undo (int n)
+ {
+ if (n < 0)
+ keys.keyseq.RemoveRange (keys.keyseq.Count + n, - n);
+ else
+ keys.keyseq.RemoveRange (n, keys.keyseq.Count - n);
+ reset ();
+ }
- internal void shift (MSymbol sym)
- {
- Mim.State state;
+ internal void commit ()
+ {
+ produced.Cat (preedit);
+ preedit.Del ();
+ changed |= ChangedStatus.Preedit;
+ }
- if (sym == MSymbol.t)
- {
- if (states.Count > 1)
- state = states.Pop ();
- else
- state = states.Peek ();
- }
- else
- {
- state = (Mim.State) im.states.Get (sym);
- if (state == null)
- throw new Exception ("Unknown state: " + state.name);
- }
- if (state == null)
- state = states.Pop ();
- if (state == (Mim.State) im.states.val)
- {
- commit ();
- reset ();
- }
- else
- {
- state_key_head = key_head;
- state_pos = cursor_pos;
- state_preedit = preedit.Dup ();
- if (state != states.Peek ())
- {
- states.Push (state);
- state_var_values = domain.SaveValues ();
- status = state.title;
- if (status == null)
- status = im.title;
- changed |= ChangedStatus.StateTitle;
- Xex on_entry
- = (Xex) state.branches.Get (MSymbol.t);
- if (on_entry != null)
- on_entry.Eval (domain);
- }
- }
- }
+ internal void shift (MSymbol sym)
+ {
+ State state;
- internal void reset ()
- {
- preedit.Del ();
- state_preedit.Del ();
- produced.Del ();
- markers.Clear ();
- cursor_pos = 0;
- key_head = commit_key_head = 0;
- states.Clear ();
- states.Push ((Mim.State) im.states.Val);
- state_key_head = 0;
- state_pos = 0;
- }
+ if (sym == MSymbol.t)
+ {
+ if (state_stack.Count > 1)
+ state = state_stack.Pop ();
+ else
+ state = state_stack.Peek ();
+ }
+ else
+ {
+ state = (State) im.states.Get (sym);
+ if (state == null)
+ throw new Exception ("Unknown state: " + state.name);
+ }
+ if (state == null)
+ state = state_stack.Pop ();
+ if (state == (State) im.states.val)
+ {
+ commit ();
+ reset ();
+ }
+ else
+ {
+ state_key_head = key_head;
+ state_pos = cursor_pos;
+ state_preedit = preedit.Dup ();
+ if (state != state_stack.Peek ())
+ {
+ state_stack.Push (state);
+ state_var_values = domain.SaveValues ();
+ status = state.title;
+ if (status == null)
+ status = im.title;
+ changed |= ChangedStatus.StateTitle;
+ Xex on_entry
+ = (Xex) state.branches.Get (MSymbol.t);
+ if (on_entry != null)
+ on_entry.Eval (domain);
+ }
+ }
+ }
- internal object GetCandidates (out int column)
- {
- column = 0;
- if (cursor_pos == 0)
- return null;
- Mim.Candidates candidates
- = (Mim.Candidates) preedit.GetProp (cursor_pos - 1, Mim.Mcandidates);
- if (candidates == null)
- return null;
- column = candidates.Column;
- return candidates.Current;
- }
+ internal void reset ()
+ {
+ preedit.Del ();
+ state_preedit.Del ();
+ produced.Del ();
+ markers.Clear ();
+ cursor_pos = 0;
+ key_head = commit_key_head = 0;
+ state_stack.Clear ();
+ state_stack.Push ((State) im.states.Val);
+ state_key_head = 0;
+ state_pos = 0;
+ }
- internal void HandleKey ()
- {
- }
+ internal object GetCandidates (out int column)
+ {
+ column = 0;
+ if (cursor_pos == 0)
+ return null;
+ Candidates candidates
+ = (Candidates) preedit.GetProp (cursor_pos - 1, Mcandidates);
+ if (candidates == null)
+ return null;
+ column = candidates.Column;
+ return candidates.Current;
+ }
- public bool Toggle ()
- {
- active = ! active;
- return active;
+ internal void HandleKey ()
+ {
+ }
+
+ public bool Toggle ()
+ {
+ active = ! active;
+ return active;
+ }
}
}
}