Created
July 20, 2012 04:51
-
-
Save ynkdir/3148767 to your computer and use it in GitHub Desktop.
imactivateexpr
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
if !exists('&imstatusfunc') || !has('gui_running') | |
finish | |
endif | |
" Initialize after fork and GUI focus gained to get current input context. | |
autocmd FocusGained * call s:Init() | |
let s:init = 0 | |
function! s:Init() | |
if s:init | |
return | |
endif | |
python <<EOF | |
import ibus | |
im_bus = ibus.Bus() | |
im_ic = ibus.InputContext(im_bus, im_bus.current_input_contxt()) | |
def im_is_active(): | |
if im_ic.is_enabled(): | |
return 1 | |
else: | |
return 0 | |
def im_enable(): | |
im_ic.enable() | |
def im_disable(): | |
im_ic.disable() | |
EOF | |
set imstatusfunc=ImStatusFunc imactivatefunc=ImActivateFunc | |
let s:init = 1 | |
endfunction | |
function! ImStatusFunc() | |
return pyeval('im_is_active()') | |
endfunction | |
function! ImActivateFunc(active) | |
if a:active | |
python im_enable() | |
else | |
python im_disable() | |
endif | |
endfunction | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// gcc ibusctrl.c -o ibusctrl.so -shared -fPIC `pkg-config --cflags --libs ibus-1.0 glib-2.0` | |
#include <dlfcn.h> | |
#include <glib.h> | |
#include <ibus.h> | |
static IBusBus *bus = NULL; | |
static IBusInputContext *ic = NULL; | |
int im_init(const char *selfpath) | |
{ | |
gchar *path; | |
GDBusConnection *conn; | |
dlopen(selfpath, RTLD_LAZY); | |
ibus_init(); | |
bus = ibus_bus_new(); | |
if (bus == NULL) | |
return -1; | |
path = ibus_bus_current_input_context(bus); | |
if (path == NULL) | |
return -1; | |
conn = ibus_bus_get_connection(bus); | |
ic = ibus_input_context_get_input_context(path, conn); | |
if (ic == NULL) | |
return -1; | |
g_free(path); | |
return 0; | |
} | |
int im_is_enabled() | |
{ | |
return ibus_input_context_is_enabled(ic) ? 1 : 0; | |
} | |
int im_enable() | |
{ | |
ibus_input_context_enable(ic); | |
return 0; | |
} | |
int im_disable() | |
{ | |
ibus_input_context_disable(ic); | |
return 0; | |
} | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
if !exists('&imstatusfunc') || !has('gui_running') | |
finish | |
endif | |
" Initialize after fork and GUI focus gained to get current input context. | |
autocmd FocusGained * call s:Init() | |
let s:libpath = expand('<sfile>:p:h') . '/ibusctrl.so' | |
let s:init = 0 | |
function! s:Init() | |
if s:init | |
return | |
endif | |
call libcallnr(s:libpath, 'im_init', s:libpath) | |
set imstatusfunc=ImStatusFunc imactivatefunc=ImActivateFunc | |
let s:init = 1 | |
endfunction | |
function! ImStatusFunc() | |
return libcallnr(s:libpath, 'im_is_enabled', 0) | |
endfunction | |
function! ImActivateFunc(active) | |
if a:active | |
call libcallnr(s:libpath, 'im_enable', 0) | |
else | |
call libcallnr(s:libpath, 'im_disable', 0) | |
endif | |
endfunction | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff -r 536aa8b0c934 runtime/doc/options.txt | |
--- a/runtime/doc/options.txt Wed Aug 15 17:43:31 2012 +0200 | |
+++ b/runtime/doc/options.txt Thu Aug 16 03:00:53 2012 +0900 | |
@@ -3971,6 +3971,25 @@ | |
Can be overruled by using "\c" or "\C" in the pattern, see | |
|/ignorecase|. | |
+ *'imactivatefunc'* *'imaf'* | |
+'imactivatefunc' 'imaf' string (default "") | |
+ global | |
+ {not in Vi} | |
+ {only available when compiled with |+xim| and | |
+ |+GUI_GTK|} | |
+ This option specifies a function to be used to activate/inactivate | |
+ Input Method. | |
+ | |
+ Prototype is: > | |
+ :function ImActivateFunc(active) | |
+ : if a:active | |
+ : ... do something | |
+ : else | |
+ : ... do something | |
+ : endif | |
+ : " return value is not used | |
+ :endfunction | |
+< | |
*'imactivatekey'* *'imak'* | |
'imactivatekey' 'imak' string (default "") | |
global | |
@@ -4067,6 +4086,23 @@ | |
The value 0 may not work correctly with Athena and Motif with some XIM | |
methods. Use 'imdisable' to disable XIM then. | |
+ *'imstatusfunc'* *'imsf'* | |
+'imstatusfunc' 'imsf' string (default "") | |
+ global | |
+ {not in Vi} | |
+ {only available when compiled with |+xim| and | |
+ |+GUI_GTK|} | |
+ This option specifies a function to be used to get status of Input | |
+ Method. | |
+ | |
+ Prototype is: > | |
+ :function ImStatusFunc() | |
+ : let is_active = ...do something | |
+ : return is_active ? 1 : 0 | |
+ :endfunction | |
+< | |
+ NOTE: This function is invoked too often. Keep it fast. | |
+ | |
*'include'* *'inc'* | |
'include' 'inc' string (default "^\s*#\s*include") | |
global or local to buffer |global-local| | |
diff -r 536aa8b0c934 src/eval.c | |
--- a/src/eval.c Wed Aug 15 17:43:31 2012 +0200 | |
+++ b/src/eval.c Thu Aug 16 03:00:53 2012 +0900 | |
@@ -1660,7 +1660,7 @@ | |
} | |
# endif | |
-# if defined(FEAT_COMPL_FUNC) || defined(PROTO) | |
+# if defined(FEAT_GTK) || defined(FEAT_COMPL_FUNC) || defined(PROTO) | |
/* | |
* Call vimL function "func" and return the result as a number. | |
* Returns -1 when calling the function fails. | |
diff -r 536aa8b0c934 src/fileio.c | |
--- a/src/fileio.c Wed Aug 15 17:43:31 2012 +0200 | |
+++ b/src/fileio.c Thu Aug 16 03:00:53 2012 +0900 | |
@@ -9529,6 +9529,12 @@ | |
# endif | |
} | |
+ int | |
+is_autocmd_blocked() | |
+{ | |
+ return autocmd_blocked != 0; | |
+} | |
+ | |
/* | |
* Find next autocommand pattern that matches. | |
*/ | |
diff -r 536aa8b0c934 src/mbyte.c | |
--- a/src/mbyte.c Wed Aug 15 17:43:31 2012 +0200 | |
+++ b/src/mbyte.c Thu Aug 16 03:00:53 2012 +0900 | |
@@ -4390,7 +4390,7 @@ | |
{ | |
int was_active; | |
- was_active = !!im_is_active; | |
+ was_active = !!im_get_status(); | |
im_is_active = (active && !p_imdisable); | |
if (im_is_active != was_active) | |
@@ -5014,46 +5014,26 @@ | |
{ | |
if (xic != NULL) | |
{ | |
- /* | |
- * The third-party imhangul module (and maybe others too) ignores | |
- * gtk_im_context_reset() or at least doesn't reset the active state. | |
- * Thus sending imactivatekey would turn it off if it was on before, | |
- * which is clearly not what we want. Fortunately we can work around | |
- * that for imhangul by sending GDK_Escape, but I don't know if it | |
- * works with all IM modules that support an activation key :/ | |
- * | |
- * An alternative approach would be to destroy the IM context and | |
- * recreate it. But that means loading/unloading the IM module on | |
- * every mode switch, which causes a quite noticeable delay even on | |
- * my rather fast box... | |
- * * | |
- * Moreover, there are some XIM which cannot respond to | |
- * im_synthesize_keypress(). we hope that they reset by | |
- * xim_shutdown(). | |
- */ | |
- if (im_activatekey_keyval != GDK_VoidSymbol && im_is_active) | |
- im_synthesize_keypress(GDK_Escape, 0U); | |
- | |
gtk_im_context_reset(xic); | |
- /* | |
- * HACK for Ami: This sequence of function calls makes Ami handle | |
- * the IM reset graciously, without breaking loads of other stuff. | |
- * It seems to force English mode as well, which is exactly what we | |
- * want because it makes the Ami status display work reliably. | |
- */ | |
- gtk_im_context_set_use_preedit(xic, FALSE); | |
- | |
if (p_imdisable) | |
im_shutdown(); | |
else | |
{ | |
- gtk_im_context_set_use_preedit(xic, TRUE); | |
xim_set_focus(gui.in_focus); | |
- if (im_activatekey_keyval != GDK_VoidSymbol) | |
+ if (p_imaf[0] != NUL) | |
{ | |
+ char_u *argv[1]; | |
if (im_is_active) | |
+ argv[0] = "1"; | |
+ else | |
+ argv[0] = "0"; | |
+ (void)call_func_retnr(p_imaf, 1, argv, FALSE); | |
+ } | |
+ else if (im_activatekey_keyval != GDK_VoidSymbol) | |
+ { | |
+ if (im_is_active) | |
{ | |
g_signal_handler_block(xic, im_commit_handler_id); | |
im_synthesize_keypress(im_activatekey_keyval, | |
@@ -5211,6 +5191,21 @@ | |
int | |
im_get_status(void) | |
{ | |
+ if (p_imsf[0] != NUL) | |
+ { | |
+ int is_active; | |
+ /* FIXME: Don't execute user function in unsafe situation. */ | |
+ if (exiting || is_autocmd_blocked()) | |
+ return FALSE; | |
+ /* FIXME: :py print 'xxx' is shown duplicate result. | |
+ * Use silent to avoid it. */ | |
+ ++msg_silent; | |
+ is_active = call_func_retnr(p_imsf, 0, NULL, FALSE); | |
+ --msg_silent; | |
+ if (is_active == -1 || is_active == 0) | |
+ return FALSE; | |
+ return TRUE; | |
+ } | |
return im_is_active; | |
} | |
diff -r 536aa8b0c934 src/option.c | |
--- a/src/option.c Wed Aug 15 17:43:31 2012 +0200 | |
+++ b/src/option.c Thu Aug 16 03:00:53 2012 +0900 | |
@@ -1416,6 +1416,15 @@ | |
{"ignorecase", "ic", P_BOOL|P_VI_DEF, | |
(char_u *)&p_ic, PV_NONE, | |
{(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT}, | |
+ {"imactivatefunc","imaf",P_STRING|P_VI_DEF|P_SECURE, | |
+# if defined(FEAT_EVAL) && defined(FEAT_XIM) && defined(FEAT_GUI_GTK) | |
+ (char_u *)&p_imaf, PV_NONE, | |
+ {(char_u *)"", (char_u *)NULL} | |
+# else | |
+ (char_u *)NULL, PV_NONE, | |
+ {(char_u *)NULL, (char_u *)0L} | |
+# endif | |
+ SCRIPTID_INIT}, | |
{"imactivatekey","imak",P_STRING|P_VI_DEF, | |
#if defined(FEAT_XIM) && defined(FEAT_GUI_GTK) | |
(char_u *)&p_imak, PV_NONE, | |
@@ -1458,6 +1467,15 @@ | |
{(char_u *)B_IMODE_NONE, (char_u *)0L} | |
#endif | |
SCRIPTID_INIT}, | |
+ {"imstatusfunc","imse",P_STRING|P_VI_DEF|P_SECURE, | |
+# if defined(FEAT_EVAL) && defined(FEAT_XIM) && defined(FEAT_GUI_GTK) | |
+ (char_u *)&p_imsf, PV_NONE, | |
+ {(char_u *)"", (char_u *)NULL} | |
+# else | |
+ (char_u *)NULL, PV_NONE, | |
+ {(char_u *)NULL, (char_u *)0L} | |
+# endif | |
+ SCRIPTID_INIT}, | |
{"include", "inc", P_STRING|P_ALLOCED|P_VI_DEF, | |
#ifdef FEAT_FIND_ID | |
(char_u *)&p_inc, PV_INC, | |
diff -r 536aa8b0c934 src/option.h | |
--- a/src/option.h Wed Aug 15 17:43:31 2012 +0200 | |
+++ b/src/option.h Thu Aug 16 03:00:53 2012 +0900 | |
@@ -557,6 +557,8 @@ | |
EXTERN int p_ic; /* 'ignorecase' */ | |
#if defined(FEAT_XIM) && defined(FEAT_GUI_GTK) | |
EXTERN char_u *p_imak; /* 'imactivatekey' */ | |
+EXTERN char_u *p_imaf; /* 'imactivatefunc' */ | |
+EXTERN char_u *p_imsf; /* 'imstatusfunc' */ | |
#endif | |
#ifdef USE_IM_CONTROL | |
EXTERN int p_imcmdline; /* 'imcmdline' */ | |
diff -r 536aa8b0c934 src/proto/fileio.pro | |
--- a/src/proto/fileio.pro Wed Aug 15 17:43:31 2012 +0200 | |
+++ b/src/proto/fileio.pro Thu Aug 16 03:00:53 2012 +0900 | |
@@ -47,6 +47,7 @@ | |
int has_insertcharpre __ARGS((void)); | |
void block_autocmds __ARGS((void)); | |
void unblock_autocmds __ARGS((void)); | |
+int is_autocmd_blocked __ARGS((void)); | |
int has_autocmd __ARGS((event_T event, char_u *sfname, buf_T *buf)); | |
char_u *get_augroup_name __ARGS((expand_T *xp, int idx)); | |
char_u *set_context_in_autocmd __ARGS((expand_T *xp, char_u *arg, int doautocmd)); |
どうしたもんですかね。
個人的には消してもいいんですけど。
僕はいらない気がしますね。
そもそも間違った設計なので、いくら保守的なvimでも残す意味が無いし、exprでやろうと思えばやれるし
そうですねー。とりあえず消しときます。
imakて機能してたの?(ォ
仮に機能してたなら、パッチで取り込まれていきなり機能しなくなって「えっ」ってなるんだろうな…
imak、kinput2なら動くけど物によっては動かない。
アクティブに使っていたユーザも少ないと思われる。
え?kinput2?
時代はibusですよねー(ぉ
便利に使ってる人がいないとはいいきれないとこが心配といえば心配
いろんな人いますからね
オプション追加。
しかしこれ簡単に実装できるのはibusかfcitxくらいでわりと対応できるのは限られるのかなという気がしてきました。
まーいいのかな。
現状よりマシならいいかと
imakのコード消すと説明めんどいので戻しました。
現状説明しようと思ったけど
So, what is the conclusion about this patch? Is it really an
improvement and does not break IME for any language?
this patch ってどのパッチだろう...
僕の方じゃないすかね。中平さんのは試してないだけで上手くいくのは見えてるので。
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
imakは残すんすか?