From 0dd5692687433ef07d2b7fb56257fa4e890a430c Mon Sep 17 00:00:00 2001 From: lilydjwg Date: Sun, 20 Dec 2020 19:52:05 +0800 Subject: [PATCH] initial fcitx5 version --- README.md | 24 ++++++++---------- plugin/fcitx.py | 65 ++++++++---------------------------------------- plugin/fcitx.vim | 58 +++++------------------------------------- so/fcitx.vim | 47 ---------------------------------- 4 files changed, 26 insertions(+), 168 deletions(-) delete mode 100644 so/fcitx.vim diff --git a/README.md b/README.md index 5f8f551..9fd6897 100644 --- a/README.md +++ b/README.md @@ -1,33 +1,29 @@ Keep and restore fcitx state for each buffer separately when leaving/re-entering insert mode. Like always typing English in normal mode, but Chinese in insert mode. -Requires: fcitx 3.6 or later, 4.0 or later will be better. +Requires: -Settings: environment variable `$FCITX_SOCKET` specifies a socket to connect instead of figuring out itself. This can be an abstract socket address starting with `@` from version 1.2.4 on. +* fcitx 5 +* Vim with Python 3 compiled in +* The python-dbus package * [git repo](https://github.com/lilydjwg/fcitx.vim) * [www.vim.org](https://www.vim.org/scripts/script.php?script_id=3764) Warning: -1. It will be faster and better with Python (3 or 2) enabled Vim. But some old version Vim enabled both Python 2 & 3 may have some issues. -2. If you use Vim in terminal, to avoid the Esc delay, please set `'ttimeoutlen'` to 100 or some other value. And check screen's `maptimeout` or tmux's `escape-time` option if you use it too. - -For Mac OS X users, you can use a "fcitx-remote" [here](https://github.com/CodeFalling/fcitx-remote-for-osx), together with the VimL version (the `so/fcitx.vim` file). +1. If you use Vim in terminal, to avoid the Esc delay, please set `'ttimeoutlen'` to 100 or some other value. And check screen's `maptimeout` or tmux's `escape-time` option if you use it too. 在离开或重新进入插入模式时自动记录和恢复每个缓冲区各自的输入法状态,以便在普通模式下始终是英文输入模式,切换回插入模式时恢复离开前的输入法输入模式。 -要求: fcitx 版本 3.6 以上,建议 fcitx 4.0 以上。 +要求: -配置:环境变量 `$FCITX_SOCKET` 指定要连接的套接字路径,而非默认的。自版本 1.2.4 起,此变量若以 `@` 字符开头,则被认为是抽象套接字地址。 +* fcitx 5 +* 带有 Python 3 支持的 Vim +* python-dbus 包 * [git 仓库](https://github.com/lilydjwg/fcitx.vim) * [www.vim.org](https://www.vim.org/scripts/script.php?script_id=3764) 注意事项: -1. Vim 如有 Python 3或2 支持可以获得更快更好的效果。但对于较旧的 Vim 版本,如果同时编译了 Python 2 & 3 支持,因为此 Vim 不能同时运行两个版本的 Python,而本脚本首先检查 Python 3,所以会导致出错或者 Python 2 不可用。 -2. 终端下请设置 Vim `'ttimeoutlen'` 选项为较小值(如100),否则退出插入模式时会有较严重的延迟。同样会造成延迟的还有 screen 的 `maptimeout` 选项以及 tmux 的 `escape-time` 选项。 - -如果你想跨主机使用 fcitx.vim,请参考此文:[fcitx-remote 接口通过 socat 跨主机使用](https://blog.lilydjwg.me/2012/7/27/using-fcitx-remote-interface-remotely-via-socat.34729.html)。 - -Mac OS X 用户可以使用[此项目](https://github.com/CodeFalling/fcitx-remote-for-osx)提供的 fcitx-remote 命令,配合本软件的 VimL 版(`so/fcitx.vim` 文件)来使用。 +1. 终端下请设置 Vim `'ttimeoutlen'` 选项为较小值(如100),否则退出插入模式时会有较严重的延迟。同样会造成延迟的还有 screen 的 `maptimeout` 选项以及 tmux 的 `escape-time` 选项。 diff --git a/plugin/fcitx.py b/plugin/fcitx.py index 59d8159..3e02377 100644 --- a/plugin/fcitx.py +++ b/plugin/fcitx.py @@ -1,68 +1,23 @@ -# vim:fileencoding=utf-8 - -import os import vim -import socket -import struct -import contextlib -fcitxsocketfile = vim.eval('s:fcitxsocketfile') +import dbus -class FcitxComm(object): - STATUS = struct.pack('i', 0) - ACTIVATE = struct.pack('i', 1 | (1 << 16)) - DEACTIVATE = struct.pack('i', 1) - INT_SIZE = struct.calcsize('i') - - def __init__(self, socketfile): - if socketfile[0] == '@': # abstract socket - socketfile = '\x00' + socketfile[1:] - self.socketfile = socketfile - self.sock = None +class FcitxComm(): + def __init__(self): + bus = dbus.SessionBus() + obj = bus.get_object('org.fcitx.Fcitx5', '/controller') + self.fcitx = dbus.Interface(obj, dbus_interface='org.fcitx.Fcitx.Controller1') def status(self): - return self._with_socket(self._status) == 2 + return self.fcitx.State() == 2 def activate(self): - self._with_socket(self._command, self.ACTIVATE) + self.fcitx.Activate() def deactivate(self): - self._with_socket(self._command, self.DEACTIVATE) + self.fcitx.Deactivate() - def _error(self, e): - estr = str(e).replace('"', r'\"') - file = self.socketfile.replace('"', r'\"') - vim.command('echohl WarningMsg | echo "fcitx.vim: socket %s error: %s" | echohl NONE' % (file, estr)) - - def _connect(self): - self.sock = sock = socket.socket(socket.AF_UNIX) - sock.settimeout(0.5) - try: - sock.connect(self.socketfile) - return True - except (socket.error, socket.timeout) as e: - self._error(e) - return False - - def _with_socket(self, func, *args, **kwargs): - # fcitx doesn't support connection reuse - if not self._connect(): - return - - with contextlib.closing(self.sock): - try: - return func(*args, **kwargs) - except (socket.error, socket.timeout, struct.error) as e: - self._error(e) - - def _status(self): - self.sock.send(self.STATUS) - return struct.unpack('i', self.sock.recv(self.INT_SIZE))[0] - - def _command(self, cmd): - self.sock.send(cmd) - -Fcitx = FcitxComm(fcitxsocketfile) +Fcitx = FcitxComm() def fcitx2en(): if Fcitx.status(): diff --git a/plugin/fcitx.vim b/plugin/fcitx.vim index 258e2f2..3d43647 100644 --- a/plugin/fcitx.vim +++ b/plugin/fcitx.vim @@ -1,67 +1,21 @@ scriptencoding utf-8 " fcitx.vim remember fcitx's input state for each buffer " Author: lilydjwg -" Version: 1.2.6 +" Version: 2.0a " URL: https://www.vim.org/scripts/script.php?script_id=3764 " --------------------------------------------------------------------- " Load Once: -if &cp || exists("g:loaded_fcitx") || ( - \ (!exists('$DISPLAY') || exists('$SSH_TTY') || has('gui_macvim')) - \ && !exists('$FCITX_SOCKET')) - finish -endif -if executable('fcitx5-remote') - " currently python version does not support fcitx5 - let g:fcitx_remote = 'fcitx5-remote' - runtime so/fcitx.vim - finish -else - let g:fcitx_remote = 'fcitx-remote' -endif -if has("python3") - let python3 = 1 -elseif has("python") - let python3 = 0 -else - runtime so/fcitx.vim +if &cp || exists("g:loaded_fcitx") || !exists('$DISPLAY') || !has('python3') finish endif let s:keepcpo = &cpo set cpo&vim -" this is quicker than expand() -if exists('$FCITX_SOCKET') - let s:fcitxsocketfile = $FCITX_SOCKET -else - let s:fcitxsocketfile = '/tmp/fcitx-socket-' . $DISPLAY - if !filewritable(s:fcitxsocketfile) "try again - if strridx(s:fcitxsocketfile, '.') > 0 - let s:fcitxsocketfile = strpart(s:fcitxsocketfile, 0, - \ strridx(s:fcitxsocketfile, '.')) - else - let s:fcitxsocketfile = s:fcitxsocketfile . '.0' - if !filewritable(s:fcitxsocketfile) - echohl WarningMsg - echomsg "socket file of fcitx not found, fcitx.vim not loaded." - echohl None - finish - endif - endif - endif -endif let g:loaded_fcitx = 1 -let pyfile = expand(':r') . '.py' -if python3 - exe 'py3file' pyfile - au InsertLeave * py3 fcitx2en() - au InsertEnter * py3 fcitx2zh() -else - exe 'pyfile' pyfile - au InsertLeave * py fcitx2en() - au InsertEnter * py fcitx2zh() -endif + +exe 'py3file' expand(':r') . '.py' +au InsertLeave * py3 fcitx2en() +au InsertEnter * py3 fcitx2zh() " --------------------------------------------------------------------- " Restoration And Modelines: -unlet python3 -unlet pyfile let &cpo=s:keepcpo unlet s:keepcpo diff --git a/so/fcitx.vim b/so/fcitx.vim deleted file mode 100644 index 45a85a8..0000000 --- a/so/fcitx.vim +++ /dev/null @@ -1,47 +0,0 @@ -" fcitx.vim 记住插入模式小企鹅输入法的状态 -" Author: lilydjwg -" Maintainer: lilydjwg -" Note: 另有使用 Python3 接口的新版本 -" --------------------------------------------------------------------- -" Load Once: -if (has("win32") || has("win95") || has("win64") || has("win16")) - " Windows 下不要载入 - finish -endif -if !(exists('$DISPLAY') || has('gui_macvim')) || exists('$SSH_TTY') - finish -endif -if &cp || exists("g:loaded_fcitx") || !executable(g:fcitx_remote) - finish -endif -let s:keepcpo = &cpo -let g:loaded_fcitx = 1 -set cpo&vim -" --------------------------------------------------------------------- -" Functions: -function Fcitx2en() - let inputstatus = system(g:fcitx_remote) - if inputstatus == 2 - let b:inputtoggle = 1 - call system(g:fcitx_remote . ' -c') - endif -endfunction -function Fcitx2zh() - try - if b:inputtoggle == 1 - call system(g:fcitx_remote . ' -o') - let b:inputtoggle = 0 - endif - catch /inputtoggle/ - let b:inputtoggle = 0 - endtry -endfunction -" --------------------------------------------------------------------- -" Autocmds: -au InsertLeave * call Fcitx2en() -au InsertEnter * call Fcitx2zh() -" --------------------------------------------------------------------- -" Restoration And Modelines: -let &cpo=s:keepcpo -unlet s:keepcpo -" vim:fdm=expr:fde=getline(v\:lnum-1)=~'\\v"\\s*-{20,}'?'>1'\:1