XUL/Migemoが長らく更新されてないわけですが,しかしVimperatorと組み合わせて使ってる人もいるわけでして.んで,C/MigemoでXUL/Migemoが提供しているAPI部分を代替できるんじゃないのと思って,js-ctypesとAdd-on SDKの練習がてらさらさらっと書いてみた.必要でしたら持って行ってください.パッケージング化する気力はないので必要としている人がやってくれ.
注意事項:
- query関数しかテストしてないです.
- migemo.dllと辞書へのPathは適宜書き換えてください.設定UIつける気力ないです.
- Windowsじゃない人はctypes.winapi_abiをctypes.default_abiに置換しないといけないはずです.
- *Functional系関数はよく分からないので実装してません.
//migemo.js
const {Cc,Ci,Cm,Cr,Cu} = require("chrome");
Cu.import("resource://gre/modules/ctypes.jsm", this);
/* for migemo_load() */
var MIGEMO_DICTID_INVALID = 0;
var MIGEMO_DICTID_MIGEMO = 1;
var MIGEMO_DICTID_ROMA2HIRA = 2;
var MIGEMO_DICTID_HIRA2KATA = 3;
var MIGEMO_DICTID_HAN2ZEN = 4;
var MIGEMO_DICTID_ZEN2HAN = 5;
/* for migemo_set_operator()/migemo_get_operator(). see: rxgen.h */
var MIGEMO_OPINDEX_OR = 0;
var MIGEMO_OPINDEX_NEST_IN = 1;
var MIGEMO_OPINDEX_NEST_OUT = 2;
var MIGEMO_OPINDEX_SELECT_IN = 3;
var MIGEMO_OPINDEX_SELECT_OUT = 4;
var MIGEMO_OPINDEX_NEWLINE = 5;
const migemo = new ctypes.StructType(
'migemo',
[
{'enable': ctypes.int32_t},
{'mtree': ctypes.voidptr_t},
{'charset': ctypes.int32_t},
{'roma2hira': ctypes.voidptr_t},
{'hira2kata': ctypes.voidptr_t},
{'han2zen': ctypes.voidptr_t},
{'zen2han': ctypes.voidptr_t},
{'rx': ctypes.voidptr_t},
{'addword': ctypes.voidptr_t},
{'char2int': ctypes.voidptr_t}
]);
var migemo_open;
var migemo_close;
var migemo_query;
var migemo_release;
var migemo_set_operator;
var migemo_get_operator;
var migemo_setproc_char2int;
var migemo_setproc_int2char;
var migemo_load;
var migemo_is_enable;
var m;
var lib;
function ensureLoaded(){
var path = "C:\\path\\to\\migemo.dll";
var dict = "C:\\path\\to\\dict\\utf-8\\migemo-dict";
if(!lib){
return load(path, dict);
}else{
return m;
}
return null;
}
function load(path, dict){
if(!lib){
lib = ctypes.open(path);
if(!lib) throw "can't load migemo dll";
}else{
unload();
}
migemo_open = lib.declare("migemo_open",
ctypes.winapi_abi,
migemo.ptr,
ctypes.char.ptr); //path to dict
migemo_close = lib.declare("migemo_close",
ctypes.winapi_abi,
ctypes.void_t,
migemo.ptr); //migemo object
migemo_query = lib.declare("migemo_query",
ctypes.winapi_abi,
ctypes.unsigned_char.ptr,
migemo.ptr, //migemo object
ctypes.unsigned_char.ptr); //query
migemo_release = lib.declare("migemo_release",
ctypes.winapi_abi,
ctypes.void_t,
migemo.ptr, //migemo object
ctypes.unsigned_char.ptr); //query
/* TODO:
int MIGEMO_CALLTYPE migemo_set_operator(migemo* object, int index,
const unsigned char* op);
const unsigned char* MIGEMO_CALLTYPE migemo_get_operator(migemo* object,
int index);
void MIGEMO_CALLTYPE migemo_setproc_char2int(migemo* object,
MIGEMO_PROC_CHAR2INT proc);
void MIGEMO_CALLTYPE migemo_setproc_int2char(migemo* object,
MIGEMO_PROC_INT2CHAR proc);
*/
migemo_load = lib.declare("migemo_load",
ctypes.winapi_abi,
ctypes.int32_t,
migemo.ptr, //migemo object
ctypes.int32_t, //dict_id
ctypes.char.ptr); //path to dict file
migemo_is_enable = lib.declare("migemo_is_enable",
ctypes.winapi_abi,
ctypes.int32_t,
migemo.ptr); //migemo object
if(!m){
m = migemo_open(null);
}
if(!m.address()) throw "creation of migemo object failed";
var rv = migemo_load(m, MIGEMO_DICTID_MIGEMO, dict);
if(rv == 0){
throw "failed to load migemo dict:" + dict;
}
return m;
}
function unload(){
migemo_close(m);
lib.close();
m = null;
lib = null;
}
function provider(){
return "C/Migemo bridge 0.0.1"
}
function version(){
return "0.0.1";
}
function lang(){
return "ja"; //temporary
}
function query(aInput){
ensureLoaded();
var p;
p = migemo_query(m, aInput);
var rawstr = p.readString();
console.log(rawstr);
migemo_release(m, p);
return rawstr;
}
function queries(aInput){
var arr = aInput.split(" ");
arr = arr.filter(function(e) {
return e != "";
});
return arr.map(function(e){ return query(e); });
}
function queryFunctional(aInput){
if(!ensureLoaded()) return "";
throw "not implemented";
}
function queriesFunctional(aInput){
if(!ensureLoaded()) return "";
throw "not implemented";
}
function getRegExp(aInput, aFlags){
return new RegExp(query(aInput), aFlags);
}
function getRegExps(aInput, aFlags){
var rxs = queries(aInput);
return rxs.map(function(e){ return new RegExp(e, aFlags); });
}
function getRegExpFunctional(aInput, aFlags){
if(!ensureLoaded()) return null;
throw "not implemented";
}
function getRegExpsFunctional(aInput, aFlags){
if(!ensureLoaded()) return null;
throw "not implemented";
}
exports.query = query;
exports.queries = queries;
exports.getRegExp = getRegExp;
exports.getRegExps = getRegExps;
//main.js
//こんな感じで使えるはず,たぶんXUL/Migemo互換.
var migemo = require("migemo");
var notifications = require("notifications");
var rawstr = migemo.query("$");
notifications.notify({ title: "Migemo", text: rawstr });
C/Migemoのソース見たらXPCOM化するためのソースも入ってたんですね,でもjs-ctypesのお陰でこの労力も要らなくなるわけだ.