= new Dictionary<string, KeyModifier> ();
private static uint keysym_base = 0x200000;
private static uint char_mask = ~((uint) KeyModifier.All);
- public static Key Reload;
+ public static readonly Key Reload;
static Key ()
{
+ keysyms["null"] = 0x00;
keysyms["bs"] = keysyms["backspace"] = 0x08;
keysyms["tab"] = 0x09;
keysyms["lf"] = keysyms["linefeed"] = 0x10;
keymodifiers["altgr"] = KeyModifier.AltGr;
keymodifiers["super"] = KeyModifier.Super;
keymodifiers["hyper"] = KeyModifier.Hyper;
- Reload = new Key (keysym_base);
- keysyms["-reload"] = keysym_base++;
+ Reload = new Key ((MSymbol) "-reload");
}
private static uint decode_keysym (MSymbol keysym)
public int ToChar ()
{
- return (int) (key & 0x1FFFFF);
+ return (key & 0x3FFFFF) <= 0x1FFFFF ? (int) (key & 0x1FFFFF) : -1;
}
public override string ToString ()
MText mt = null;
if (c < 0x20)
foreach (KeyValuePair<string, uint> kv in keysyms)
- if ((uint) c == kv.Value)
+ if ((key & 0x3FFFFF) == kv.Value)
{
mt = kv.Key;
break;
internal class KeySeq : Xex.TermValue
{
+ private static Xex.Symbol name = "keyseq";
+ public static Xex.Symbol Name { get { return name; } }
+
public List<Key> keyseq = new List<Key> ();
public override Xex.TermValue Clone ()
}
}
- public static Xex.TermValue parser (Xex.Domain domain, XmlNode node)
+ public static Xex.TermValue Parser (Xex.Domain domain, XmlNode node)
{
Xex.Term term = new Xex.Term (domain, node.FirstChild).Eval (domain);
return (term.IsStr ? new KeySeq ((MText) term.Strval)
: new KeySeq (term.Listval));
}
+ public override bool Equals (object obj)
+ {
+ KeySeq ks = obj as KeySeq;
+ if (ks == null || ks.keyseq.Count != keyseq.Count)
+ return false;
+ for (int i = 0; i < keyseq.Count; i++)
+ if (keyseq[i] != ks.keyseq[i])
+ return false;
+ return true;
+ }
+
+ public override int GetHashCode ()
+ {
+ int code = 0;
+ for (int i = 0; i < keyseq.Count; i++)
+ code ^= keyseq[i].GetHashCode ();
+ return code;
+ }
+
public override string ToString ()
{
MText mt;
if (node.Name == "description")
description = parse_description (node);
else if (node.Name == "keyseq")
- keys.Add ((KeySeq) KeySeq.parser (null, node));
+ keys.Add ((KeySeq) KeySeq.Parser (null, node));
}
}
internal abstract class Marker : Xex.TermValue
{
- private MSymbol name;
+ private static Xex.Symbol name = "marker";
+ public static Xex.Symbol Name { get { return name; } }
- private Marker (MSymbol name)
+ private MSymbol mname;
+
+ private Marker (MSymbol mname)
{
- this.name = name;
+ this.mname = mname;
}
public abstract int Position (Context ic);
public virtual void Mark (Context ic)
{
- throw new Exception ("Can't set predefined marker: " + name);
+ throw new Exception ("Can't set predefined marker: " + mname);
}
public virtual int CharAt (Context ic)
{
- return ic.preedit[Position (ic)];
+ int pos = Position (ic);
+
+ return ((pos >= 0 && pos < ic.preedit.Length) ? ic.preedit[pos]
+ : -1);
}
public override string ToString ()
{
- return "<marker>" + name.Name + "</marker>";
+ return "<marker>" + mname + "</marker>";
}
- public static Xex.TermValue parser (Xex.Domain domain, XmlNode node)
+ public static Xex.TermValue Parser (Xex.Domain domain, XmlNode node)
{
return Get ((MSymbol) node.InnerText);
}
+
+ public override bool Equals (object obj)
+ {
+ Marker m = obj as Marker;
+ return (m != null && m.mname == mname);
+ }
+
+ public override int GetHashCode () { return mname.GetHashCode (); }
+
public class Named : Marker
{
- public Named (MSymbol name) : base (name) { }
+ public Named (MSymbol mname) : base (mname) { }
public override int Position (Context ic)
{
- MPlist p = ic.marker_positions.Find (name);
+ MPlist p = ic.marker_positions.Find (mname);
return (p == null ? 0 : p.Integer);
}
public override void Mark (Context ic)
{
- ic.marker_positions.Put (name, ic.cursor_pos);
+ ic.marker_positions.Put (mname, ic.cursor_pos);
}
}
{
private int pos;
- public PredefinedAbsolute (MSymbol name) : base (name)
+ public PredefinedAbsolute (MSymbol mname) : base (mname)
{
- if (! int.TryParse (((string) name).Substring (1), out pos))
- throw new Exception ("Invalid marker name: " + name);
+ if (! int.TryParse (((string) mname).Substring (1), out pos))
+ throw new Exception ("Invalid marker name: " + mname);
}
public override int Position (Context ic)
{
private int distance;
- public PredefinedSurround (MSymbol name) : base (name)
+ public PredefinedSurround (MSymbol mname) : base (mname)
{
- if (! int.TryParse (((string) name).Substring (2), out distance))
- throw new Exception ("Invalid marker name: " + name);
+ if (! int.TryParse (((string) name).Substring (1), out distance))
+ throw new Exception ("Invalid marker name: " + mname);
if (distance > 0)
distance--;
}
= new Predefined (']');
}
- public static Marker Get (MSymbol name)
+ public static Marker Get (MSymbol mname)
{
- string str = name.Name;
+ string str = mname.Name;
if (str[0] == '@')
{
Predefined pred;
- if (predefineds.TryGetValue (name, out pred))
+ if (predefineds.TryGetValue (mname, out pred))
return pred;
if (str.Length == 1)
- throw new Exception ("Invalid marker name: " + name);
+ throw new Exception ("Invalid marker name: " + mname);
if (Char.IsDigit (str[1]))
- return new PredefinedAbsolute (name);
- if (str.Length == 2 || name == Mat_minus_zero
+ return new PredefinedAbsolute (mname);
+ if (str.Length == 2 || mname == Mat_minus_zero
|| ! (str[1] == '-' || str[1] == '+'))
- throw new Exception ("Invalid marker name: " + name);
- return new PredefinedSurround (name);
+ throw new Exception ("Invalid marker name: " + mname);
+ return new PredefinedSurround (mname);
}
- return new Named (name);
+ return new Named (mname);
}
}
internal class Selector : Xex.TermValue
{
+ private static Xex.Symbol name = "selector";
+ public static Xex.Symbol Name { get { return name; } }
+
static new Dictionary<MSymbol, Selector> selectors;
static Selector ()
private Selector (char tag) { this.tag = tag; }
- public static Xex.TermValue parser (Xex.Domain domain, XmlNode node)
+ public static Xex.TermValue Parser (Xex.Domain domain, XmlNode node)
{
return Get ((MSymbol) node.InnerText);
}
throw new Exception ("Invalid selector name: " + name);
return selector;
}
+
+ public override bool Equals (object obj)
+ {
+ Selector s = obj as Selector;
+ return (s != null && s.tag == tag);
+ }
+
+ public override int GetHashCode () { return (int) tag; }
+
+ public override string ToString ()
+ {
+ return "<selector>@" + tag + "</selector>";
+ }
}
internal class Map
}
}
+ protected class Action
+ {
+ private Xex.Term action;
+
+ public Action (Xex.Domain domain, Xex.Term[] terms)
+ {
+ Xex.Term[] args = new Xex.Term[terms.Length];
+ args[0] = Tcatch_tag;
+ for (int i = 0; i < terms.Length; i++)
+ args[i + 1] = terms[i];
+ action = new Xex.Term (domain, Qcatch, args);
+ }
+
+ public bool Run (Xex.Domain domain)
+ {
+ Xex.Term result = action.Eval (domain);
+ if (result.IsError)
+ {
+ ((Context) domain.context).Error = result.ToString ();
+ return false;
+ }
+ return (result != Tcatch_tag);
+ }
+ }
+
internal class Keymap
{
public Dictionary<Key, Keymap> submaps;
static MInputMethod ()
{
- im_domain.DefTerm ("keyseq", KeySeq.parser);
- im_domain.DefTerm ("marker", Marker.parser);
- im_domain.DefTerm ("selector", Selector.parser);
+ im_domain.DefType (typeof (KeySeq));
+ im_domain.DefType (typeof (Marker));
+ im_domain.DefType (typeof (Selector));
im_domain.DefSubr (Finsert, "insert", false, 1, 1);
im_domain.DefSubr (Finsert_candidates, "insert-candidates", false, 1, -1);
XmlNode n = nd.FirstChild;
if (n.Name != Qkeyseq)
continue;
- KeySeq keyseq = (KeySeq) KeySeq.parser (domain, n);
+ KeySeq keyseq = (KeySeq) KeySeq.Parser (domain, n);
Xex.Term[] actions = Xex.ParseTerms (domain, n.NextSibling);
map.entries.Add (new Map.Entry (domain, keyseq, actions));
}
Xex.Term[] args)
{
((Context) domain.context).commit ();
- args = new Xex.Term[2];
- args[0] = args[1] = Tcatch_tag;
- return Xex.Fthrow (domain, vari, args);
+ return Xex.Fthrow (domain, vari, new Xex.Term[1] { Tcatch_tag });
}
private static Xex.Term Fshift (Xex.Domain domain, Xex.Variable vari,
Xex.Term[] args)
{
return new Xex.Term (((Context) domain.context).GetSurroundingText == null
- ? 0 : 1);
+ ? -2 : -1);
}
public override string ToString ()
internal ChangedStatus changed;
+ private string error_message;
+ public string Error {
+ get { return error_message; }
+ set { error_message = value; }
+ }
+
private void set_cursor (string prefix, int pos)
{
cursor_pos = pos;
{
if (DelSurroundingText != null)
{
+ Console.WriteLine ("deleting the prev {0} chars", - pos);
callback_arg.Set (MSymbol.integer, pos);
if (DelSurroundingText (this, callback_arg))
{
{
if (DelSurroundingText != null)
{
+ Console.WriteLine ("deleting the next {0} chars",
+ pos - preedit.Length);
callback_arg.Set (MSymbol.integer, pos - preedit.Length);
if (DelSurroundingText (this, callback_arg))
{
internal void commit ()
{
- Candidates.Detach (this);
- produced.Cat (preedit);
- preedit_replace (0, preedit.Length, null, null);
+ if (preedit.Length > 0)
+ {
+ Candidates.Detach (this);
+ produced.Cat (preedit);
+ preedit_replace (0, preedit.Length, null, null);
+ }
}
internal void shift (State state)
private bool handle_key ()
{
+ Console.WriteLine ("{0}:key='{1}'", state.name, keys.keyseq[key_head]);
Keymap sub = keymap.Lookup (keys, ref key_head);
if (sub != keymap)
}
return (! key_unhandled && produced.Length == 0);
}
+
+ public bool Filter ()
+ {
+ changed = ChangedStatus.None;
+ produced.Del ();
+ preceding_text.Del ();
+ following_text.Del ();
+
+ commit ();
+ 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 (produced.Length == 0);
+ }
}
public class Session
private bool del_surrounding_text (Context ic, MPlist args)
{
int pos = this.pos + args.Integer;
+ Console.WriteLine ("del-surround: {0}-{1}", this.pos, pos);
if (pos < this.pos)
{
mt.Del (pos, this.pos);
return true;
}
- public bool HandleKey (Key key)
+ public bool HandleKey (ref Key key)
{
- bool result = ic.Filter (key);
-
- if (! result)
+ if (! ic.Filter (key))
{
MText produced = ic.Produced;
mt.Ins (pos, produced);
pos += produced.Length;
- if (ic.UnhandledKey (out key))
+ Key unhandled;
+ if (ic.UnhandledKey (out unhandled))
{
- mt.Ins (pos, key.ToChar ());
- pos++;
+ key = unhandled;
+ return false;
}
}
+ return true;
+ }
+
+ public bool Close ()
+ {
+ bool result = ic.Filter ();
+ if (! result)
+ {
+ mt.Ins (pos, ic.Produced);
+ pos += ic.Produced.Length;
+ }
+ ic = null;
+ mt = null;
return result;
}
- public int CurrentPos { get { return pos; } }
+ public int CurrentPos { get { return pos; } set { pos = value; } }
public MText Preedit { get { return ic.Preedit; } }
}
}