]> granicus.if.org Git - vim/commitdiff
patch 8.0.1336: cannot use imactivatefunc() unless compiled with +xim v8.0.1336
authorBram Moolenaar <Bram@vim.org>
Sat, 25 Nov 2017 14:20:02 +0000 (15:20 +0100)
committerBram Moolenaar <Bram@vim.org>
Sat, 25 Nov 2017 14:20:02 +0000 (15:20 +0100)
Problem:    Cannot use imactivatefunc() unless compiled with +xim.
Solution:   Allow using imactivatefunc() when not compiled with +xim.
            (Yasuhiro Matsumoto, closes #2349)

runtime/doc/mbyte.txt
runtime/doc/options.txt
src/Makefile
src/mbyte.c
src/option.c
src/option.h
src/structs.h
src/testdir/Make_all.mak
src/testdir/test_iminsert.vim [new file with mode: 0644]
src/version.c
src/vim.h

index 1c3e2b13d4fb6133067005db4a6a18f0db748c84..8a25d83dcfb754bbaf3b43dc8d5649f899df1058 100644 (file)
@@ -26,8 +26,9 @@ For changing the language of messages and menus see |mlang.txt|.
 7.  Input on X11                       |mbyte-XIM|
 8.  Input on MS-Windows                        |mbyte-IME|
 9.  Input with a keymap                        |mbyte-keymap|
-10. Using UTF-8                                |mbyte-utf8|
-11. Overview of options                        |mbyte-options|
+10. Input with imactivatefunc()                |mbyte-func|
+11. Using UTF-8                                |mbyte-utf8|
+12. Overview of options                        |mbyte-options|
 
 NOTE: This file contains UTF-8 characters.  These may show up as strange
 characters or boxes when using another encoding.
@@ -1254,7 +1255,35 @@ Combining forms:
 ﭏ    0xfb4f  Xal  alef-lamed
 
 ==============================================================================
-10. Using UTF-8                                *mbyte-utf8* *UTF-8* *utf-8* *utf8*
+10.  Input with imactivatefunc()                               *mbyte-func*
+
+Vim has |imactivatefunc()| and |imstatusfunc()|. This is useful to
+activate/deativate input method from Vim in any way, also with an external
+command. For example, fcitx provide fcitx-remote command: >
+
+       set iminsert=2
+       set imsearch=2
+       set imcmdline
+
+       set imactivatefunc=ImActivate
+       function! ImActivate(active)
+         if a:active
+           call system('fcitx-remote -o')
+         else
+           call system('fcitx-remote -c')
+         endif
+       endfunction
+
+       set imstatusfunc=ImStatus
+       function! ImStatus()
+         return system('fcitx-remote')[0] is# '2'
+       endfunction
+
+Using this script, you can activate/deactivate XIM via Vim even when it is not
+compiled with |+xim|.
+
+==============================================================================
+11. Using UTF-8                                *mbyte-utf8* *UTF-8* *utf-8* *utf8*
                                                        *Unicode* *unicode*
 The Unicode character set was designed to include all characters from other
 character sets.  Therefore it is possible to write text in any language using
@@ -1402,7 +1431,7 @@ not everybody is able to type a composing character.
 
 
 ==============================================================================
-11. Overview of options                                        *mbyte-options*
+12. Overview of options                                        *mbyte-options*
 
 These options are relevant for editing multi-byte files.  Check the help in
 options.txt for detailed information.
index f9acff8186304a155ccd40006c73918d12e1fff4..d71e7f9c46bf98c95a74137cbabdb14fa8c7ac1d 100644 (file)
@@ -4256,8 +4256,7 @@ A jump table for the options with a short description can be found at |Q_op|.
 'imactivatefunc' 'imaf'        string (default "")
                        global
                        {not in Vi}
-                       {only available when compiled with |+xim| and
-                       |+GUI_GTK|}
+                       {only available when compiled with |+mbyte|}
        This option specifies a function that will be called to
        activate/inactivate Input Method.
 
@@ -4308,8 +4307,7 @@ A jump table for the options with a short description can be found at |Q_op|.
 'imcmdline' 'imc'      boolean (default off)
                        global
                        {not in Vi}
-                       {only available when compiled with the |+xim|,
-                       |+multi_byte_ime| or |global-ime| features}
+                       {only available when compiled with |+mbyte|}
        When set the Input Method is always on when starting to edit a command
        line, unless entering a search pattern (see 'imsearch' for that).
        Setting this option is useful when your input method allows entering
@@ -4320,8 +4318,7 @@ A jump table for the options with a short description can be found at |Q_op|.
 'imdisable' 'imd'      boolean (default off, on for some systems (SGI))
                        global
                        {not in Vi}
-                       {only available when compiled with the |+xim|,
-                       |+multi_byte_ime| or |global-ime| features}
+                       {only available when compiled with |+mbyte|}
        When set the Input Method is never used.  This is useful to disable
        the IM when it doesn't work properly.
        Currently this option is on by default for SGI/IRIX machines.  This
@@ -4336,8 +4333,6 @@ A jump table for the options with a short description can be found at |Q_op|.
                0       :lmap is off and IM is off
                1       :lmap is ON and IM is off
                2       :lmap is off and IM is ON
-       2 is available only when compiled with the |+multi_byte_ime|, |+xim|
-       or |global-ime|.
        To always reset the option to zero when leaving Insert mode with <Esc>
        this can be used: >
                :inoremap <ESC> <ESC>:set iminsert=0<CR>
@@ -4350,6 +4345,10 @@ A jump table for the options with a short description can be found at |Q_op|.
        The value 0 may not work correctly with Athena and Motif with some XIM
        methods.  Use 'imdisable' to disable XIM then.
 
+       You can set 'imactivatefunc' and 'imstatusfunc' to handle IME/XIM
+       via external command if vim is not compiled with the |+xim|,
+       |+multi_byte_ime| or |global-ime|.
+
                                                *'imsearch'* *'ims'*
 'imsearch' 'ims'       number (default -1)
                        local to buffer
@@ -4372,8 +4371,7 @@ A jump table for the options with a short description can be found at |Q_op|.
 'imstatusfunc' 'imsf'  string (default "")
                        global
                        {not in Vi}
-                       {only available when compiled with |+xim| and
-                       |+GUI_GTK|}
+                       {only available when compiled with |+mbyte|}
        This option specifies a function that is called to obtain the status
        of Input Method.  It must return a positive number when IME is active.
 
index 09cf21e8f22900c6aef422e9a6e2051e6133e1f4..7ccd766999c56702df13727dc62272d0794eae56 100644 (file)
@@ -2190,6 +2190,7 @@ test_arglist \
        test_highlight \
        test_history \
        test_hlsearch \
+       test_iminsert \
        test_increment \
        test_increment_dbcs \
        test_ins_complete \
index 3592ddbdd8eb77a660bff2ae6cef2890622ff744..54186d9c23174d1c38aa639f6881be70ce6fdec7 100644 (file)
@@ -4782,6 +4782,20 @@ iconv_end(void)
 
 #endif /* FEAT_MBYTE */
 
+#ifdef FEAT_EVAL
+    static void
+call_imactivatefunc(int active)
+{
+    char_u *argv[1];
+
+    if (active)
+       argv[0] = (char_u *)"1";
+    else
+       argv[0] = (char_u *)"0";
+    (void)call_func_retnr(p_imaf, 1, argv, FALSE);
+}
+#endif
+
 #if defined(FEAT_XIM) || defined(PROTO)
 
 # if defined(FEAT_GUI_GTK) || defined(PROTO)
@@ -4824,7 +4838,14 @@ im_set_active(int active)
     im_is_active = (active && !p_imdisable);
 
     if (im_is_active != was_active)
-       xim_reset();
+    {
+#ifdef FEAT_EVAL
+       if (p_imaf[0] != NUL)
+           call_imactivatefunc(im_is_active);
+       else
+#endif
+           xim_reset();
+    }
 }
 
     void
@@ -5666,15 +5687,7 @@ xim_reset(void)
 
 #  ifdef FEAT_EVAL
            if (p_imaf[0] != NUL)
-           {
-               char_u *argv[1];
-
-               if (im_is_active)
-                   argv[0] = (char_u *)"1";
-               else
-                   argv[0] = (char_u *)"0";
-               (void)call_func_retnr(p_imaf, 1, argv, FALSE);
-           }
+               call_imactivatefunc(im_is_active);
            else
 #  endif
                if (im_activatekey_keyval != GDK_VoidSymbol)
@@ -6442,6 +6455,45 @@ xim_get_status_area_height(void)
 }
 # endif
 
+#else /* !defined(FEAT_XIM) */
+
+# ifndef FEAT_GUI_W32
+    int
+im_get_status()
+{
+#  ifdef FEAT_EVAL
+    if (p_imsf[0] != NUL)
+    {
+       int is_active;
+
+       /* FIXME: Don't execute user function in unsafe situation. */
+       if (exiting
+#   ifdef FEAT_AUTOCMD
+               || is_autocmd_blocked()
+#   endif
+               )
+           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;
+       return (is_active > 0);
+    }
+#  endif
+    return FALSE;
+}
+
+    void
+im_set_active(int active)
+{
+#  ifdef(USE_IM_CONTROL) && defined(FEAT_EVAL)
+    if (p_imaf[0] != NUL)
+       call_imactivatefunc(p_imdisable ? FALSE : active);
+#  endif
+}
+# endif
+
 #endif /* FEAT_XIM */
 
 #if defined(FEAT_MBYTE) || defined(PROTO)
index e09191f441b2975ada4e2eb25e3566e0ab72da8d..ac0918dacc2a438e0fd2bbca004667eefbed9cbd 100644 (file)
@@ -1539,7 +1539,7 @@ static struct vimoption options[] =
                            (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)
+#if defined(FEAT_EVAL) && defined(USE_IM_CONTROL)
                            (char_u *)&p_imaf, PV_NONE,
                            {(char_u *)"", (char_u *)NULL}
 # else
@@ -1582,7 +1582,7 @@ static struct vimoption options[] =
                            {(char_u *)B_IMODE_USE_INSERT, (char_u *)0L}
                            SCRIPTID_INIT},
     {"imstatusfunc","imsf",P_STRING|P_VI_DEF|P_SECURE,
-#if defined(FEAT_EVAL) && defined(FEAT_XIM) && defined(FEAT_GUI_GTK)
+#if defined(FEAT_EVAL) && defined(USE_IM_CONTROL)
                            (char_u *)&p_imsf, PV_NONE,
                            {(char_u *)"", (char_u *)NULL}
 #else
index d963c1f39b805beaae554d4d046fe8ee7549c556..57126a31b62d4873915f5a75fcc7b8d9c8c05711 100644 (file)
@@ -581,11 +581,13 @@ EXTERN char_u     *p_iconstring;  /* 'iconstring' */
 EXTERN int     p_ic;           /* 'ignorecase' */
 #if defined(FEAT_XIM) && defined(FEAT_GUI_GTK)
 EXTERN char_u  *p_imak;        /* 'imactivatekey' */
+#define IM_ON_THE_SPOT         0L
+#define IM_OVER_THE_SPOT       1L
+EXTERN long    p_imst;         /* 'imstyle' */
+#endif
+#if defined(FEAT_EVAL) && defined(USE_IM_CONTROL)
 EXTERN char_u  *p_imaf;        /* 'imactivatefunc' */
 EXTERN char_u  *p_imsf;        /* 'imstatusfunc' */
-EXTERN long    p_imst;         /* 'imstyle' */
-# define IM_ON_THE_SPOT                0L
-# define IM_OVER_THE_SPOT      1L
 #endif
 #ifdef USE_IM_CONTROL
 EXTERN int     p_imcmdline;    /* 'imcmdline' */
index 774104cf5a8acb90dc321bea66f8cb7f9ac6aafa..6aaccc51191504e16267f4b672249a3580083bca 100644 (file)
@@ -2091,12 +2091,8 @@ struct file_buffer
 #define B_IMODE_USE_INSERT -1  /*      Use b_p_iminsert value for search */
 #define B_IMODE_NONE 0         /*      Input via none */
 #define B_IMODE_LMAP 1         /*      Input via langmap */
-#ifndef USE_IM_CONTROL
-# define B_IMODE_LAST 1
-#else
-# define B_IMODE_IM 2          /*      Input via input method */
-# define B_IMODE_LAST 2
-#endif
+#define B_IMODE_IM 2           /*      Input via input method */
+#define B_IMODE_LAST 2
 
 #ifdef FEAT_KEYMAP
     short      b_kmap_state;   /* using "lmap" mappings */
index d9ff056310da0e23dd0dfce0266070e18dfce6e1..df79e9ab9ab58d29d75d1e5b849a3e6689c1d24f 100644 (file)
@@ -115,6 +115,7 @@ NEW_TESTS = test_arabic.res \
            test_highlight.res \
            test_history.res \
            test_hlsearch.res \
+           test_iminsert.res \
            test_increment.res \
            test_increment_dbcs.res \
            test_ins_complete.res \
diff --git a/src/testdir/test_iminsert.vim b/src/testdir/test_iminsert.vim
new file mode 100644 (file)
index 0000000..603135a
--- /dev/null
@@ -0,0 +1,29 @@
+if !has('multi_byte')
+  finish
+endif
+
+source view_util.vim
+
+let s:imactivatefunc_called = 0
+let s:imstatusfunc_called = 0
+
+func IM_activatefunc(active)
+  let s:imactivatefunc_called = 1
+endfunc
+
+func IM_statusfunc()
+  let s:imstatusfunc_called = 1
+  return 0
+endfunc
+
+func Test_iminsert2()
+  set imactivatefunc=IM_activatefunc
+  set imstatusfunc=IM_statusfunc
+  set iminsert=2
+  normal! i
+  set iminsert=0
+  set imactivatefunc=
+  set imstatusfunc=
+  call assert_equal(1, s:imactivatefunc_called)
+  call assert_equal(1, s:imstatusfunc_called)
+endfunc
index e0ba19e2894360217882320bb56676667e7e21ef..57c457675b6ba30a87b31129feb5cca2834298c1 100644 (file)
@@ -771,6 +771,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    1336,
 /**/
     1335,
 /**/
index 83ffb293f440e77282574cfe25851356daa3110f..1d481ca466dd5e2929e39c570cbb7d627707f032 100644 (file)
--- a/src/vim.h
+++ b/src/vim.h
@@ -536,9 +536,7 @@ typedef unsigned long u8char_T;         /* long should be 32 bits or more */
 /*
  * Check input method control.
  */
-#if defined(FEAT_XIM) \
-    || (defined(FEAT_GUI) && (defined(FEAT_MBYTE_IME) || defined(GLOBAL_IME))) \
-    || (defined(FEAT_GUI_MAC) && defined(FEAT_MBYTE))
+#if defined(FEAT_MBYTE)
 # define USE_IM_CONTROL
 #endif