YamaKen
yamak****@bp*****
2004年 2月 23日 (月) 07:04:24 JST
At Fri, 20 Feb 2004 00:12:23 -1000 (HST), shiro****@lava***** wrote: > > From: NIIBE Yutaka <gniib****@m17n*****> > Subject: [Anthy-dev 578] Re: uimのキーバインド定義を簡単に > Date: Fri, 20 Feb 2004 18:39:22 +0900 (JST) > > > TOKUNAGA Hiroyuki wrote: > > > マクロを使わずに呼び出した側の環境(もしくはトップレベルの環境)に変数 > > > を束縛する方法ってあるんでしょうか? > > > > eval を使うというのが答えです。たぶん。 slib.cを調べてみましたが、やはりユーザ定義マクロはありませんでし た。Cで書かれた(lispレベルの)マクロにlet_macro()のような名前が付 いていたので、それらが目に入っていたようです。 > > 本質的にこれはその環境で eval せねばなりません。だからマクロではなくて, > > 上記の例では, 関数として, > > > > (define (my-set symbol expr) > > (eval `(set! ,symbol ,expr) (interaction-environment))) > > ^^^^^^^^^^^^^^^^^^^^^^^^^ ここは処理系に依る > > と作ることになります。 > > interaction-environmentはR5RSに定義されているので、一応 > ポータブルと言えると思います。R4RS以前の処理系ですと、evalが > 第2引数をとらなかったりしますけれど。 新部さん、川合さん、ありがとうございました。教えて頂いたように evalを使って以下のように実装しました。 (define define-key-internal (lambda (key-predicate-sym key-strs) (let* ((modified-key-strs (modify-key-strs-implicitly key-strs)) (predicate (make-key-predicate modified-key-strs)) (toplevel-env ())) (eval (list 'define key-predicate-sym predicate) toplevel-env)))) このままだとdefine-keyに渡す変数名をquoteする必要があるので、第1 引数をquoteしてdefine-key-internalを呼ぶだけのdefine-keyをCで定 義しました。これで、以下のようにキーバインドを定義できるようにな りました。この機能はuim 0.3.0に含まれています。 (define-key skk-commit-key? "<Control>j") (define-key skk-on-key? '(generic-on-key? "<Control>j")) 大文字・小文字とシフト状態の扱いですが、case sensitiveにして、シ フトキーの状態だけ無視するようにしました。"<Control>A"と "<Control>a"は区別され、CAPSキーやシフトprefix のようにシフトキー が押し下げられていない状態でも、入力された文字が大文字かどうかだ けを見ます。ただし、現在はdefine-keyで定義されたpredicateはシフ トキーを完全に無視してしまうので"<Shift>space"や"<Shift>home"の ような定義ができません。これについては後日改善しようと思います。 ------------------------------- ヤマケン yamak****@bp*****