Repository: zcodes/IMESupport Branch: master Commit: d544494d5f20 Files: 18 Total size: 20.5 KB Directory structure: gitextract_0i6bqump/ ├── .gitignore ├── .no-sublime-package ├── IMESupport.sublime-settings ├── README.md ├── README_en.org ├── README_jp.org ├── hook/ │ ├── imesupport_hook.c │ ├── imesupport_hook.h │ ├── make_mingw32.mak │ ├── make_mingw64.mak │ ├── make_msvc32.mak │ ├── make_msvc32_win7.mak │ ├── make_msvc64.mak │ └── make_msvc64_win7.mak ├── imesupport/ │ ├── __init__.py │ └── globalhook.py ├── imesupportplugin.py └── packages.json ================================================ FILE CONTENTS ================================================ ================================================ FILE: .gitignore ================================================ .ropeproject font_name.txt imesupport.log hook/*.obj hook/*.dll hook/*.exp hook/*.lib ================================================ FILE: .no-sublime-package ================================================ ================================================ FILE: IMESupport.sublime-settings ================================================ { "imesupport_screen_scaling": 100 } ================================================ FILE: README.md ================================================ ## Sublime Text Build 3186 从 BUILD 3186 开始,ST 官方支持 IME 了,此插件或许可以被标注 Deprecated 了。 ## IMESupport Sublime Text 中文输入法支持,解决输入法候选框无法跟随 st 光标 (cursor) 的问题。 ## 须知 ### 原理 由于 st 默认不支持 IME (Input Method Editor),导致在使用微软拼音、搜狗拼音等输入法输入中文的时候,候选框会固定在屏幕的一个角上,不会跟随光标的移动而移动。这个插件就是利用 st 的 api 接口和 Windows 的 hook (钩子) 机制,用 hackable (一种无奈且并不优雅) 的方式让 st 支持 IME (或者说 IMM/Input Method Manager)。 插件的主要操作分为两步: 1. 在光标位置改变时,通过 st 内置的事件监听接口触发获取光标位置操作(现在 st 内置 api 支持获取光标位置),然后将位置信息传递给加载的钩子处理。 2. hook 中的主要操作使用 Windows Api (ImmSetCompositionWindow) 设置输入法候选框的位置。 ### Sublime Text 版本 由于旧版本的 st 没有获取光标相对于 st 窗口 (window) 的 api,最开始插件获取光标位置是通过获取当光标相对于 st 布局 (layout) 的位置,再配合侧边栏的宽度、手动配置调整参数等信息手动计算的,这样导致光标的位置极其不准确(换个主题可能侧边栏的宽度等就不同了),候选框跟随定位准确也就无从说起了。 从 BUILD 3143 起,st 有了可以获取光标(cursor)相对于窗口位置的 api(View.text_to_window()), 并鉴于以前手动计算问题太多、太不可靠,所有对代码做了精简,直接使用新的 api,而不再支持手动计算方式,所以,此插件支持 Sublime Text 3 Build 3143+(注意:跟 3143 比较临近的版本 api 实现并不是很好,如光标在搜索等输入框时位置也无法获取,so,尽量用最新版本吧)。 ### Windows 系统版本和高清屏 鉴于 Windows 对于高清屏(缩放率大于 100%)的支持并不是很好,从 Windows 10 起这种状况才有所改观,并且某些针对缩放率等信息的 Windows api 从 Windows 10 起才开始支持,所以插件支持最好的 Windows 版本是 10。 如果 Windows 系统版本低于 Windows 10, 该插件也可以使用,唯一的区别就是无法自动获取显示的缩放率,如果使用缩放率大于 100,且小于 Windows 10 版本的 Windows,可以通过设置 ime_support_screen_scaling 手动配置一下。 缩放率 100% 的默认配置: ```json { "imesupport_screen_scaling": 100 } ``` 目前,这是该插件唯一需要手动设置的,以前的配置信息(offset 之类的)已经不再需要。 ## 安装 注意:这是 [chikatoike/IMESupport](https://github.com/chikatoike/IMESupport) 的 fork 版本,所以不要使用 package_control 安装。 直接将该项目克隆或是下载到 Sublime_Text_3_Install_Path/Data/Packages 目录下就好,不知道该目录在哪的同学可以使用菜单 Perference > Browse Packages 打开。 ## 已知问题 ### 第一次输入定位不准 目前测试来看,这个问题主要原因还是插件未加载完成造成的,所以刚打开 st 的时候,稍等等,等插件加载完就好了。 ## ChangeLog ### 2018-11-25 * 简化代码,放弃支持 Sublime Text 老版本 (Sublime Text 3.0+ 起) * 兼容 Windows 7 + * 兼容 搜狗拼音、QQ 拼音、手心输入法、小狼毫输入法 ### 2017-07-31 * 新版本 (dev build 3142) 可以使用 View.text_to_view 获取光标的位置。 * 使用 Visual Studio 2017 Community 重新编译 dll 文件。 ================================================ FILE: README_en.org ================================================ * IMESupport for Sublime Text 2/3 * Description In current version of Sublime Text 2/3, there is a problem that can not be displayed IME composition window correctly. This plugin solves this problem. * Target platform This plugin works only on windows. * Screenshot Before installed this plugin. Inptting using IME, but IME composition window is not displayed correct position. [[https://raw.github.com/chikatoike/IMESupport/master/img/inline1.png]] After installed this plugin, IME comosition window is displayed correctly. [[https://raw.github.com/chikatoike/IMESupport/master/img/inline2.png]] * Reference http://sublimetext.userecho.com/topic/98697-handling-ime-message-on-windows-for-koreanjapanese-and-chinese-user/ ================================================ FILE: README_jp.org ================================================ * IMESupport for Sublime Text English: https://github.com/chikatoike/IMESupport/blob/master/README_en.org * 概要 IMESupportは、Windows の Sublime Text で IME を利用した文字入力をサポートするパッケージです。 IME でインライン変換の入力文字が正しい位置に表示されない問題をある程度解決できます。 * 動作環境 Windows OS のみ対応しています。 以下のバージョンで動作します。 - Sublime Text 2 32bit - Sublime Text 2 64bit - Sublime Text 3 32bit - Sublime Text 3 64bit 以下の環境で動作確認しました。 - Sublime Text 2 32bit + Windows Vista 32bit + Microsoft Office IME 2007 - Sublime Text 2 32bit + Windows Vista 32bit + Google日本語入力 - Sublime Text 2 32bit + Windows Vista 32bit + SKK日本語入力FEP - Sublime Text 2 32bit + Windows 7 32bit + Microsoft Office IME 2010 - Sublime Text 2 32bit + Windows 7 32bit + Google日本語入力 - Sublime Text 2 32bit + Windows 7 32bit + SKK日本語入力FEP - Sublime Text 2 64bit + Windows 8 64bit + Microsoft IME 2012 - Sublime Text 3 32bit + Windows 8 64bit + Microsoft IME 2012 - Sublime Text 3 64bit + Windows 8 64bit + Microsoft IME 2012 ATOK等、上に書かれていないIMEでも動作するはずですが、確認していません。 * インストール方法 Package Controlを使ってインストールしてください。 Package Controlをインストールした状態で、以下の手順でインストールできます。 1. コマンドパレットで「Package Control: Install Package」を絞り込んでEnter 2. パッケージ一覧から「IMESupport」を絞り込んでEnter 3. ステータスバーにインストール完了のメッセージが表示されたら Sublime Text 2 を再起動 手動でインストールする場合: コマンドプロンプト等で C:\Users\(ユーザー名)\AppData\Roaming\Sublime Text 2\Packages に移動して、 git clone してください。 * 機能 以下の機能が利用できます。 - インライン変換の表示位置補正 * インライン変換の表示位置補正について この機能はインストールするだけで有効になります。ユーザー側での設定は必要ありません。 現行バージョンの Sublime Text 2 では、IMEをONにして日本語入力しようとすると、以下のようにカーソル位置とは別の場所に入力中のテキストが表示されます。 [[https://raw.github.com/chikatoike/IMESupport/master/img/inline1.png]] これを、カーソル位置に表示されるように補正します。 [[https://raw.github.com/chikatoike/IMESupport/master/img/inline2.png]] ** 既知の不具合 - IME ON で連続で入力するときに、変換確定後の次の1文字が、前の入力開始位置と同じ場所に表示されてしまいます。 これは2文字以上入力すれば、正しい位置に移動します。 - File→New View into File で現在開いているファイルを新しいViewに表示した場合、最初のView以外では正しく動作しない可能性があります。 これは Sublime Text 自体の不具合が原因です。適当な対策を実装していますが、パッケージ側で完全に対策するのは困難です。もし正しく動作していない場合はご報告下さい。 ** 制限事項 - ファイル編集以外の入力は対応していません。例えば、検索文字列の入力、Goto Anything などです。これらに入力フォーカスがある場合、強制的に画面左上に表示します。 - 垂直分割時に、左側に1つもタブ(View)が表示されていない場合、右側のViewでは正しい位置に表示されません。これは、Viewがないとウィンドウ左端からの距離が計算出来ないためです。同様に、水平分割時に上側にViewがない場合は下側で正しい位置に表示されません。 * 参考 - http://d.hatena.ne.jp/chikatoike/20121030/1351552567 - http://sublimetext.userecho.com/topic/98697-handling-ime-message-on-windows-for-koreanjapanese-and-chinese-user/ * CHANGELOG 2013-02-26 - File→New View into File で開いたビューでの不具合対策(ST2/ST3) 2013-02-09 - Sublime text 3 でside barが表示されているときに、IMEの表示位置がずれていた問題を修正 (shirosakiさん、ありがとうごさいます) 2013-01-30 - Sublime Text 3 に対応 - ver.0.2 開発開始 2013-01-29 - ver.0.1 リリース 2013-01-22 - Package Controlを使ったインストール方法を追加 2013-01-21 - line_padding_top, line_padding_bottom が設定されているときのフォントの大きさを修正 (shspageさん、ありがとうごさいます) 2012-11-19 - x64版に対応 - メニューからのプロジェクト選択でクラッシュする問題を修正 2012-11-11 - 対応するIMEについて追記 2012-11-07 - IME起動時のフォントの大きさを修正 (tkmusic1976さん、ありがとうございます) 2012-10-30 - 64bit版のWindowsのサポートについて記載 2012-10-29 - 分割の比率が 1:1 ではない場合の表示位置がおかしい問題を修正 - 最初のリリース ================================================ FILE: hook/imesupport_hook.c ================================================ #define _CRT_SECURE_NO_WARNINGS #include #include #include #include #include #include "imesupport_hook.h" static LRESULT CALLBACK MyHookProc(int nCode, WPARAM wp, LPARAM lp); static LRESULT CALLBACK WindowMessageHookProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); static void Trace(const TCHAR *str, BOOL append); static HINSTANCE hModule = NULL; static HHOOK hHook = NULL; BOOL WINAPI DllMain(HINSTANCE hModuleDLL, DWORD fdwReason, LPVOID lpvReserved) { hModule = hModuleDLL; switch (fdwReason) { case DLL_PROCESS_ATTACH: break; case DLL_PROCESS_DETACH: if (hHook != NULL) { EndHook(); } break; } return TRUE; } EXPORT BOOL StartHook(HWND hwnd) { if (hHook != NULL) { return FALSE; } DWORD tid = GetWindowThreadProcessId(hwnd, NULL); hHook = SetWindowsHookEx(WH_GETMESSAGE, MyHookProc, hModule, tid); return hHook != NULL; } EXPORT BOOL EndHook(void) { if (hHook == NULL) { return FALSE; } BOOL ret = UnhookWindowsHookEx(hHook); hHook = NULL; return ret; } void SetFont(LOGFONT *lf) { FILE *fp; TCHAR szFontInfoFile[_MAX_PATH]; TCHAR szFull[_MAX_PATH]; TCHAR szDrive[_MAX_PATH]; TCHAR szDir[_MAX_DIR]; TCHAR szFontName[128] = {0}; GetModuleFileName(hModule, szFull, sizeof(szFull) / sizeof(TCHAR)); _tsplitpath(szFull, szDrive, szDir, NULL, NULL); _tmakepath(szFontInfoFile, szDrive, szDir, _T("font_name"), _T("txt")); if ((fp = fopen(szFontInfoFile, _T("r"))) != NULL) { if (fread(szFontName, sizeof(TCHAR), 128, fp) > 0) { _sntprintf((LPSTR) lf->lfFaceName, LF_FACESIZE, _T("%s"), szFontName); } fclose(fp); } } EXPORT int GetMessageId(void) { static UINT message = 0; if (message == 0) { message = RegisterWindowMessage(_T("WM_IMESUPPORT_SET_INLINE_POSITION")); } return message; } static LRESULT CALLBACK MyHookProc(int nCode, WPARAM wParam, LPARAM lParam) { if (nCode < 0) { return CallNextHookEx(hHook, nCode, wParam, lParam); } else if (nCode == HC_ACTION) { const MSG *p = (const MSG *)lParam; WindowMessageHookProc(p->hwnd, p->message, p->wParam, p->lParam); } return CallNextHookEx(hHook, nCode, wParam, lParam); } static void im_set_composition(HWND hWnd, int x, int y, LOGFONT *lf) { HIMC hImc; if ((hImc = ImmGetContext(hWnd)) != (HIMC) 0) { if (ImmGetOpenStatus(hImc)) { ImmSetCompositionFont(hImc, lf); COMPOSITIONFORM cfs; cfs.dwStyle = CFS_POINT; cfs.ptCurrentPos.x = x; cfs.ptCurrentPos.y = y; // MapWindowPoints(HWND_DESKTOP, hWnd, &cfs.ptCurrentPos, 1); ImmSetCompositionWindow(hImc, &cfs); } ImmReleaseContext(hWnd, hImc); } } static LRESULT CALLBACK WindowMessageHookProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { static int x = INVALID_VALUE; static int y = INVALID_VALUE; static int font_size = INVALID_VALUE; static LOGFONT lf = { -12, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, PROOF_QUALITY, FIXED_PITCH | FF_DONTCARE, "Consolas" }; static UINT uDpi = 96; static float scaling = 1.0; HIMC hImc; SetFont(&lf); switch (msg) { // about ime messages, see: https://docs.microsoft.com/en-us/windows/desktop/Intl/ime-messages // WM_IME_CONTROL: change the position of a composition window // WM_IME_COMPOSITION: notifies the application about changes to the composition string // WM_IME_NOTIFY: general changes to the status of the IME windows // // case WM_IME_CONTROL: case WM_IME_COMPOSITION: case WM_IME_NOTIFY: if (x == INVALID_VALUE || y == INVALID_VALUE) { break; } // sogou use WM_IME_COMPOSITION,and send WM_IME_NOTIFY + // IMN_SETCOMPOSITIONWINDOW, it will cause a dead loop if (msg == WM_IME_NOTIFY && wParam == IMN_SETCOMPOSITIONWINDOW) { break; } if ((hImc = ImmGetContext(hWnd)) != (HIMC) 0) { im_set_composition(hWnd, x, y, &lf); ImmReleaseContext(hWnd, hImc); } break; default: if (msg == GetMessageId()) { if (wParam != INVALID_VALUE && lParam != INVALID_VALUE) { x = (wParam >> 16) & 0xffff; y = wParam & 0xffff; font_size = (lParam >> 16) & 0xffff; scaling = (float) ((lParam & 0xffff) / 100.0); HDC hdc; hdc = GetDC(hWnd); lf.lfHeight = - MulDiv(font_size, GetDeviceCaps(hdc, LOGPIXELSY), 72); ReleaseDC(hWnd, hdc); #if WINVER > 0x6010 // only windows 10 support these api DPI_AWARENESS dpiAwareness = GetAwarenessFromDpiAwarenessContext(GetThreadDpiAwarenessContext()); switch (dpiAwareness) { case DPI_AWARENESS_SYSTEM_AWARE: uDpi = GetDpiForSystem(); break; case DPI_AWARENESS_PER_MONITOR_AWARE: uDpi = GetDpiForWindow(hWnd); break; } scaling = (float) (uDpi / 96.0); #endif x = (int) (x * scaling); y = (int) (y * scaling); if ((hImc = ImmGetContext(hWnd)) != (HIMC) 0) { im_set_composition(hWnd, x, y, &lf); ImmReleaseContext(hWnd, hImc); } } else { x = INVALID_VALUE; y = INVALID_VALUE; font_size = INVALID_VALUE; } } break; } return 0; } static void Trace(const TCHAR *str, BOOL append) { FILE *fp; TCHAR szLogFile[_MAX_PATH]; TCHAR szFull[_MAX_PATH]; TCHAR szDrive[_MAX_DRIVE]; TCHAR szDir[_MAX_DIR]; GetModuleFileName(hModule, szFull, sizeof(szFull) / sizeof(TCHAR)); _tsplitpath(szFull, szDrive, szDir, NULL, NULL); _tmakepath(szLogFile, szDrive, szDir, _T("imesupport"), _T("log")); fp = _tfopen(szLogFile, append ? _T("a") : _T("w")); if (fp == NULL) { return; } _ftprintf(fp, _T("%s"), str); _ftprintf(fp, _T("\n")); fclose(fp); } // vim: st=4 sts=4 ts=4 et ================================================ FILE: hook/imesupport_hook.h ================================================ #ifndef _IMESUPPORT_HOOK_H_ #define _IMESUPPORT_HOOK_H_ #include #ifdef _MSC_VER #define EXPORT __declspec(dllexport) #else #define EXPORT #endif #define INVALID_VALUE 0xffffffff #ifndef WINVER #define WINVER 0x6010 #endif EXPORT BOOL StartHook(HWND hwnd); EXPORT BOOL EndHook(void); EXPORT int GetMessageId(void); #endif // vim: st=4 sts=4 ts=4 et ================================================ FILE: hook/make_mingw32.mak ================================================ # for MinGW. TARGET=../imesupport_hook_x86.dll SRC=imesupport_hook.c HEADER=imesupport_hook.h CFLAGS=-O2 -Wall -shared -m32 LDFLAGS+=-limm32 OPT= all: $(TARGET) $(TARGET): $(SRC) $(HEADER) gcc $(CFLAGS) $(OPT) -o $(TARGET) $(SRC) $(LDFLAGS) .PHONY: clean clean: rm -f $(TARGET) ================================================ FILE: hook/make_mingw64.mak ================================================ # for MinGW. TARGET=../imesupport_hook_x64.dll SRC=imesupport_hook.c HEADER=imesupport_hook.h CFLAGS=-O2 -Wall -shared -m64 LDFLAGS+=-limm32 OPT= all: $(TARGET) $(TARGET): $(SRC) $(HEADER) gcc $(CFLAGS) $(OPT) -o $(TARGET) $(SRC) $(LDFLAGS) .PHONY: clean clean: rm -f $(TARGET) ================================================ FILE: hook/make_msvc32.mak ================================================ all: ..\imesupport_hook_x86.dll ..\imesupport_hook_x86.dll: imesupport_hook_x86.dll copy imesupport_hook_x86.dll ..\imesupport_hook_x86.dll imesupport_hook_x86.dll: imesupport_hook.c cl /DWINVER=0xA000 /wd4996 /LD /Feimesupport_hook_x86.dll imesupport_hook.c imm32.lib user32.lib user32.lib gdi32.lib kernel32.lib ntdll.lib clean: cmd /C "del ..\imesupport_hook_x86.dll imesupport_hook_x86.dll imesupport_hook_x86.exp imesupport_hook_x86.lib imesupport_hook.obj" /F /Q ================================================ FILE: hook/make_msvc32_win7.mak ================================================ all: ..\imesupport_hook_x86_win7.dll ..\imesupport_hook_x86_win7.dll: imesupport_hook_x86_win7.dll copy imesupport_hook_x86_win7.dll ..\imesupport_hook_x86_win7.dll imesupport_hook_x86_win7.dll: imesupport_hook.c imesupport_hook.h cl /DWINVER=0xA000 /wd4996 /LD /Feimesupport_hook_x86_win7.dll imesupport_hook.c imm32.lib user32.lib user32.lib gdi32.lib kernel32.lib ntdll.lib clean: cmd /C "del ..\imesupport_hook_x86_win7.dll imesupport_hook_x86_win7.dll imesupport_hook_x86_win7.exp imesupport_hook_x86_win7.lib imesupport_hook.obj" /F /Q ================================================ FILE: hook/make_msvc64.mak ================================================ all: ..\imesupport_hook_x64.dll ..\imesupport_hook_x64.dll: imesupport_hook_x64.dll copy imesupport_hook_x64.dll ..\imesupport_hook_x64.dll imesupport_hook_x64.dll: imesupport_hook.c imesupport_hook.h cl /DWINVER=0xA000 /wd4996 /LD /Feimesupport_hook_x64.dll imesupport_hook.c imm32.lib user32.lib gdi32.lib kernel32.lib ntdll.lib clean: cmd /C "del ..\imesupport_hook_x64.dll imesupport_hook_x64.dll imesupport_hook_x64.exp imesupport_hook_x64.lib imesupport_hook.obj" /F /Q ================================================ FILE: hook/make_msvc64_win7.mak ================================================ all: ..\imesupport_hook_x64_win7.dll ..\imesupport_hook_x64_win7.dll: imesupport_hook_x64_win7.dll copy imesupport_hook_x64_win7.dll ..\imesupport_hook_x64_win7.dll imesupport_hook_x64_win7.dll: imesupport_hook.c imesupport_hook.h cl /wd4996 /LD /Feimesupport_hook_x64_win7.dll imesupport_hook.c imm32.lib user32.lib gdi32.lib kernel32.lib ntdll.lib clean: cmd /C "del ..\imesupport_hook_x64_win7.dll imesupport_hook_x64_win7.dll imesupport_hook_x64_win7.exp imesupport_hook_x64_win7.lib imesupport_hook.obj" /F /Q ================================================ FILE: imesupport/__init__.py ================================================ ================================================ FILE: imesupport/globalhook.py ================================================ # -*- coding: utf-8 -*- import ctypes from os.path import join, dirname, abspath from os import popen INVALID_VALUE = 0xffff WM_IMESUPPORT_SET_INLINE_POSITION = -1 imesupport_dll = None def setup(hwnd, arch_x64, dll_dir=dirname(dirname(abspath(__file__)))): # Default DLL location: ../imesupport_hook_xxx.dll global imesupport_dll global WM_IMESUPPORT_SET_INLINE_POSITION if imesupport_dll is not None: return True dll_name = 'imesupport_hook' if arch_x64: dll_name += '_x64' else: dll_name += '_x86' with popen('wmic os get caption') as ret: systeminfo = ret.read() if systeminfo.find('Windows 10') < 0: dll_name += '_win7' dll_name += '.dll' print(dll_name) imesupport_dll = ctypes.cdll.LoadLibrary(join(dll_dir, dll_name)) WM_IMESUPPORT_SET_INLINE_POSITION = imesupport_dll.GetMessageId() return imesupport_dll.StartHook(hwnd) def cleanup(): global imesupport_dll imesupport_dll.EndHook() return ctypes.cdll.FreeLibrary(imesupport_dll) def set_inline_position(hwnd, x, y, font_size, scaling): if imesupport_dll is not None: ctypes.windll.user32.PostMessageW( hwnd, WM_IMESUPPORT_SET_INLINE_POSITION, x << 16 | y, font_size << 16 | scaling) def clear_inline_position(hwnd): if imesupport_dll is not None: ctypes.windll.user32.PostMessageW(hwnd, WM_IMESUPPORT_SET_INLINE_POSITION, INVALID_VALUE, INVALID_VALUE) ================================================ FILE: imesupportplugin.py ================================================ import os import time import sublime import sublime_plugin try: from imesupport import globalhook except ImportError: from .imesupport import globalhook class SlackCommand(sublime_plugin.TextCommand): def run(self, edit): self.view.insert(edit, 0, "Hello, World!") class WindowLayout(object): def __init__(self, window): self.window = window self.last_extents = None self.settings = sublime.load_settings('IMESupport.sublime-settings') def calc_cursor_position(self, view, cursor): if "text_to_window" in dir(view): pos = view.text_to_window(cursor) font_size = self.get_font_size(view) caret_width = view.settings().get('caret_extra_width') scaling = self.settings.get('imesupport_screen_scaling') return (int(pos[0]) + caret_width, int(pos[1]), font_size, scaling) @staticmethod def get_font_face(view): return view.settings().get('font_face', '') @staticmethod def get_font_size(view): return int(view.settings().get('font_size', '')) def setup(hwnd): if int(sublime.version()) < 3000: pass else: # load dll globalhook.setup(hwnd, sublime.arch() == 'x64') class ImeSupportEventListener(sublime_plugin.EventListener): def __init__(self): self.layouts = {} self.initialized = False def on_new(self, view): sublime.set_timeout(lambda: self.update(view), 400) def on_activated(self, view): sublime.set_timeout(lambda: self.update(view), 200) def on_deactivated(self, view): sublime.set_timeout(lambda: self.update(view), 200) def on_modified(self, view): sublime.set_timeout(lambda: self.update(view), 200) def on_selection_modified(self, view): sublime.set_timeout(lambda: self.update(view), 200) def on_post_window_command(self, window, command_name, args): sublime.set_timeout(lambda: self.update(window.active_view()), 400) def update(self, view): if view is None: return window = view.window() if window is None: return if not self.initialized: setup(window.hwnd()) fontFile = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'font_name.txt') with open(fontFile, 'wb') as f: f.write(view.settings().get('font_face', '').encode('utf-8')) self.initialized = True id = window.id() if id not in self.layouts: self.layouts[id] = WindowLayout(window) pos = self.layouts[id].calc_cursor_position(view, view.sel()[0].b) globalhook.set_inline_position(window.hwnd(), *pos) def plugin_unload(): globalhook.cleanup() ================================================ FILE: packages.json ================================================ { "schema_version": "2.0", "packages": [ { "name": "IMESupport", "details": "https://github.com/chikatoike/IMESupport", "releases": [ { "sublime_text": "*", "platforms": "windows", "details": "https://github.com/chikatoike/IMESupport" } ] } ] }