Compare commits

..

36 commits

Author SHA1 Message Date
lilydjwg
28d5bcc86d add another function FcitxCurrentIMwithRime to show RIME info too
see https://github.com/lilydjwg/fcitx.vim/issues/33#issuecomment-2002346047
2024-04-21 16:21:34 +08:00
lilydjwg
451d277bbd don't execute when executing a macro 2023-08-03 23:51:05 +08:00
lilydjwg
92247352c6 fallback to cmd if Python's dbus module isn't available
closes #36.
2023-02-02 15:55:50 +08:00
lilydjwg
dc95d0301b fix not returning IM name when it's not rime 2022-11-15 22:06:01 +08:00
lilydjwg
eb62569b3b if current im is rime, return rime's schema name 2022-11-15 20:47:21 +08:00
lilydjwg
d79d816e24 add a function for current IM name
for showing info e.g. on the status line. closes #32.
2022-11-15 16:20:41 +08:00
lilydjwg
7f06ccfa8a fix reconnecting not using the RIME interface 2022-11-15 16:18:44 +08:00
lilydjwg
fe899f6aec update README about fcitx5_rime 2022-11-09 14:59:45 +08:00
lilydjwg
e962387307 add support for fcitx5-rime
https://github.com/fcitx/fcitx5-rime/issues/30#issuecomment-957001110
2022-11-09 12:32:49 +08:00
依云
c689083ffb
Merge pull request #29 from T2hhbmEK/wayland
add WAYLAND_DISPLAY
2021-10-26 18:25:01 +08:00
T2hhbmEK
84a183b46d add WAYLAND_DISPLAY 2021-10-26 17:55:02 +08:00
lilydjwg
3554b279a0 update README to make two modes' benefit clear 2021-08-20 16:32:24 +08:00
oxalica
5c7b8e5833
Also support fcitx5-remote to toggle IME state (#27)
* Also support fcitx5-remote to toggle IME state

* Fix types and wording
2021-08-20 16:31:07 +08:00
lilydjwg
4042bbb29c add LICENSE 2021-08-15 22:21:32 +08:00
依云
fcef347398
Merge pull request #24 from zeertzjq/patch-1
feat: support backward search mode
2021-06-25 16:01:20 +08:00
zeertzjq
bc068d0556
feat: support backward search mode 2021-06-25 15:54:03 +08:00
lilydjwg
92ef27262d make it possible to silent the warning on dbus errors
fixes #22.
2021-05-24 12:43:22 +08:00
依云
4c6ec0e384
Merge pull request #21 from lokiiart/patch-1
为rime用户节省一些时间吧。
2021-05-12 19:16:55 +08:00
lokiiart
2b86740c87
为rime用户节省一些时间吧。 2021-05-12 17:30:57 +08:00
依云
07b608571d
Merge pull request #20 from ouuan/fcitx5
feat: support search mode
2021-04-18 16:36:27 +08:00
Yufan You
bbca697f3c
feat: support search mode 2021-04-18 13:01:57 +08:00
lilydjwg
c038116610 support for earlier Vim that doesn't have InsertLeavePre 2021-02-08 14:29:37 +08:00
lilydjwg
1efd21b9aa README: update for the fcitx5-server branch 2021-02-05 16:34:07 +08:00
lilydjwg
695ee2b958 fix error handling from python to vim 2020-12-29 19:46:06 +08:00
lilydjwg
d619809504 better error handling 2020-12-23 15:40:21 +08:00
lilydjwg
056f8c580d reconnect dbus on error (maybe fcitx5 just was restarted) 2020-12-22 01:02:43 +08:00
lilydjwg
0d95b09914 README: fix lists being combined as one 2020-12-21 19:46:15 +08:00
lilydjwg
0dd5692687 initial fcitx5 version 2020-12-20 19:52:05 +08:00
lilydjwg
99a27b4323 remove modeline 2020-05-12 20:41:58 +08:00
lilydjwg
6267a6c073 bump version 2019-05-22 13:02:48 +08:00
lilydjwg
cd5b278dc4 README: better formatted 2018-08-29 16:09:41 +08:00
lilydjwg
bab3fd3afe GitHub renders plain text files too small, switching to markdown
closes #7.
2018-08-29 16:04:20 +08:00
依云
49983f1c49
Merge pull request #6 from meijieru/fcitx5
[RDY] fcitx5 vimscript
2018-05-31 18:51:01 +08:00
meijieru
b6fc70ffba fcitx5 vimscript 2018-05-31 18:45:22 +08:00
依云
83519f4ed3 Merge pull request #1 from gou4shi1/master
sockets in Python 2 don't support "with". use contextlib.closing instead.
2017-05-29 18:19:21 +08:00
gou4shi1
5b33e919d9 there is no _EXIT_ in socket in python2 2017-05-15 19:07:15 +08:00
6 changed files with 238 additions and 172 deletions

21
LICENSE Normal file
View file

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2011-2021 lilydjwg <lilydjwg@gmail.com>, et al.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

31
README
View file

@ -1,31 +0,0 @@
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.
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.
Git repo: https://github.com/lilydjwg/fcitx.vim
www.vim.org: http://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).
在离开或重新进入插入模式时自动记录和恢复每个缓冲区各自的输入法状态,以便在普通模式下始终是英文输入模式,切换回插入模式时恢复离开前的输入法输入模式。
要求: fcitx 版本 3.6 以上,建议 fcitx 4.0 以上。
配置:环境变量 $FCITX_SOCKET 指定要连接的套接字路径,而非默认的。自版本 1.2.4 起,此变量若以 "@" 字符开头,则被认为是抽象套接字地址。
Git 仓库: https://github.com/lilydjwg/fcitx.vim
www.vim.org: http://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请参考此文 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 文件)来使用。

72
README.md Normal file
View file

@ -0,0 +1,72 @@
Keep and restore fcitx state for each buffer separately when leaving/re-entering insert mode or search mode. Like always typing English in normal mode, but Chinese in insert mode.
D-Bus only works with the same user so this won't work with `sudo vim`. See the `fcitx5-server` branch for an experimental implementation that supports `sudo vim`.
By default, it use python3 and D-Bus to toggle IME state.
If you set `g:fcitx5_remote` to the executable path of `fcitx5-remote` **BEFORE** loading the plugin, it will use `fcitx5-remote` instead of python and D-Bus. In this case, python3 support is optional.
Usually `fcitx5-remote` mode is way faster to start up since Python script need quite some time for the initial load if you don't use any other plugins that load Python. The Python version will be faster while switching.
Base requirements:
* fcitx 5
Requirements for Python mode (`g:fcitx5_remote` is not set):
* Vim with Python 3 compiled in
* The python-dbus package
Requirements for `fcitx5-remote` mode (`g:fcitx5_remote` is set):
* fcitx5-remote
If you are using `fcitx5-rime` (which has its own state), `let g:fcitx5_rime = 1` in your `.vimrc`.
The `FcitxCurrentIM()` function can be used to get current IM's name.
Links:
* [git repo](https://github.com/lilydjwg/fcitx.vim)
* [www.vim.org](https://www.vim.org/scripts/script.php?script_id=3764)
Warning:
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.
----
在离开或重新进入插入模式或搜索模式时自动记录和恢复每个缓冲区各自的输入法状态,以便在普通模式下始终是英文输入模式,切换回插入模式时恢复离开前的输入法输入模式。
D-Bus 只在同一用户时有效,所以使用 `sudo vim` 时本代码就失效了。在 `fcitx5-server` 分支有一个实验性的版本支持 `sudo vim` 的用法。
本插件默认会使用 Python 3 并通过 D-Bus 来切换输入法状态。
但如果你在加载插件**之前**设置了 `g:fcitx5_remote` 为你已安装的 `fcitx5-remote` 可执行文件的路径,那么本插件会使用它来切换输入法状态;此模式下本插件并不需要 Python。
如果你没有其他使用 Python 的 Vim 插件,本插件的 Python 模式初始化可能会显著拖慢启动时间;而 `fcitx5-remote` 模式则没有这个问题。Python 模式会在切换时更快。
基本要求:
* fcitx 5
使用 Python 模式的要求(未设置 `g:fcitx5_remote`
* 带有 Python 3 支持的 Vim
* python-dbus 包
使用 `fcitx5-remote` 模式的要求(需设置 `g:fcitx5_remote`
* fcitx5-remote
如果使用 `fcitx5-rime`(它自己有输入状态),在 `.vimrc` 中设置 `let g:fcitx5_rime = 1`
`FcitxCurrentIM()` 函数可以用于获取当前输入法的名字。
链接:
* [git 仓库](https://github.com/lilydjwg/fcitx.vim)
* [www.vim.org](https://www.vim.org/scripts/script.php?script_id=3764)
注意事项:
1. 终端下请设置 Vim `'ttimeoutlen'` 选项为较小值如100否则退出插入模式时会有较严重的延迟。同样会造成延迟的还有 screen 的 `maptimeout` 选项以及 tmux 的 `escape-time` 选项。
2. 请在 fcitx5-configtool 中确认英语是第一个输入法中文是第二个输入法rime 用户可能需要设置 `g:fcitx5_rime = 1`

View file

@ -1,73 +1,91 @@
# vim:fileencoding=utf-8
import os
import vim import vim
import socket import functools
import struct
fcitxsocketfile = vim.eval('s:fcitxsocketfile') import dbus
class FcitxComm(object): class FcitxComm:
STATUS = struct.pack('i', 0) def __init__(self):
ACTIVATE = struct.pack('i', 1 | (1 << 16)) self.bus = bus = dbus.SessionBus()
DEACTIVATE = struct.pack('i', 1) obj = bus.get_object('org.fcitx.Fcitx5', '/controller')
INT_SIZE = struct.calcsize('i') self.fcitx = dbus.Interface(obj, dbus_interface='org.fcitx.Fcitx.Controller1')
self._rime = None
def __init__(self, socketfile):
if socketfile[0] == '@': # abstract socket
socketfile = '\x00' + socketfile[1:]
self.socketfile = socketfile
self.sock = None
def status(self): def status(self):
return self._with_socket(self._status) == 2 return self.fcitx.State() == 2
def activate(self): def activate(self):
self._with_socket(self._command, self.ACTIVATE) self.fcitx.Activate()
def deactivate(self): def deactivate(self):
self._with_socket(self._command, self.DEACTIVATE) self.fcitx.Deactivate()
def _error(self, e): def current(self):
estr = str(e).replace('"', r'\"') im = self.fcitx.CurrentInputMethod()
file = self.socketfile.replace('"', r'\"') if im == 'rime':
vim.command('echohl WarningMsg | echo "fcitx.vim: socket %s error: %s" | echohl NONE' % (file, estr)) return self._get_rime().GetCurrentSchema()
else:
return im
def _connect(self): def current_and_rime(self):
self.sock = sock = socket.socket(socket.AF_UNIX) im = self.fcitx.CurrentInputMethod()
sock.settimeout(0.5) if im == 'rime':
try: return 'rime:' + self._get_rime().GetCurrentSchema()
sock.connect(self.socketfile) else:
return True return im
except (socket.error, socket.timeout) as e:
self._error(e)
return False
def _with_socket(self, func, *args, **kwargs): def _get_rime(self):
# fcitx doesn't support connection reuse if self._rime is None:
if not self._connect(): obj = self.bus.get_object('org.fcitx.Fcitx5', '/rime')
return self._rime = dbus.Interface(obj, dbus_interface='org.fcitx.Fcitx.Rime1')
return self._rime
with self.sock: class FcitxRimeComm:
def __init__(self):
bus = dbus.SessionBus()
obj = bus.get_object('org.fcitx.Fcitx5', '/rime')
self.fcitx = dbus.Interface(obj, dbus_interface='org.fcitx.Fcitx.Rime1')
def status(self):
return self.fcitx.IsAsciiMode()
def activate(self):
self.fcitx.SetAsciiMode(False)
def deactivate(self):
self.fcitx.SetAsciiMode(True)
def current(self):
return self.fcitx.GetCurrentSchema()
try:
if vim.eval('get(g:, "fcitx5_rime")') == '1':
FcitxComm = FcitxRimeComm
Fcitx = FcitxComm()
fcitx_loaded = True
except dbus.exceptions.DBusException as e:
if not vim.vars.get('silent_unsupported'):
vim.command('echohl WarningMsg | echom "fcitx.vim not loaded: %s" | echohl NONE' % e)
fcitx_loaded = False
def may_reconnect(func):
@functools.wraps(func)
def wrapped():
global Fcitx
for _ in range(2):
try: try:
return func(*args, **kwargs) return func()
except (socket.error, socket.timeout, struct.error) as e: except Exception as e:
self._error(e) vim.command('echohl WarningMsg | echom "fcitx.vim: %s: %s" | echohl NONE' % (type(e).__name__, e))
Fcitx = FcitxComm()
def _status(self): return wrapped
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)
@may_reconnect
def fcitx2en(): def fcitx2en():
if Fcitx.status(): if Fcitx.status():
vim.command('let b:inputtoggle = 1') vim.command('let b:inputtoggle = 1')
Fcitx.deactivate() Fcitx.deactivate()
@may_reconnect
def fcitx2zh(): def fcitx2zh():
if vim.eval('exists("b:inputtoggle")') == '1': if vim.eval('exists("b:inputtoggle")') == '1':
if vim.eval('b:inputtoggle') == '1': if vim.eval('b:inputtoggle') == '1':
@ -75,3 +93,11 @@ def fcitx2zh():
vim.command('let b:inputtoggle = 0') vim.command('let b:inputtoggle = 0')
else: else:
vim.command('let b:inputtoggle = 0') vim.command('let b:inputtoggle = 0')
@may_reconnect
def fcitx_current_im():
return Fcitx.current()
@may_reconnect
def fcitx_current_im_and_rime():
return Fcitx.current_and_rime()

View file

@ -1,60 +1,85 @@
scriptencoding utf-8 scriptencoding utf-8
" fcitx.vim remember fcitx's input state for each buffer " fcitx.vim remember fcitx's input state for each buffer
" Author: lilydjwg " Author: lilydjwg
" Version: 1.2.5 " Version: 2.0a
" URL: http://www.vim.org/scripts/script.php?script_id=3764 " URL: https://www.vim.org/scripts/script.php?script_id=3764
" --------------------------------------------------------------------- " ---------------------------------------------------------------------
" Load Once: " Load Once:
if &cp || exists("g:loaded_fcitx") || ( if &cp || exists("g:loaded_fcitx") || (!exists('$DISPLAY') && !exists('$WAYLAND_DISPLAY'))
\ (!exists('$DISPLAY') || exists('$SSH_TTY') || has('gui_macvim'))
\ && !exists('$FCITX_SOCKET'))
finish
endif
if has("python3")
let python3 = 1
elseif has("python")
let python3 = 0
else
runtime so/fcitx.vim
finish finish
endif endif
let s:keepcpo = &cpo let s:keepcpo = &cpo
set cpo&vim set cpo&vim
" this is quicker than expand()
if exists('$FCITX_SOCKET') function s:setup_cmd()
let s:fcitxsocketfile = $FCITX_SOCKET function Fcitx2en()
else let inputstatus = trim(system(g:fcitx5_remote))
let s:fcitxsocketfile = '/tmp/fcitx-socket-' . $DISPLAY if inputstatus == '2'
if !filewritable(s:fcitxsocketfile) "try again let b:inputtoggle = 1
if strridx(s:fcitxsocketfile, '.') > 0 call system(g:fcitx5_remote . ' -c')
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
endfunction
function Fcitx2zh()
try
if b:inputtoggle == 1
call system(g:fcitx5_remote . ' -o')
let b:inputtoggle = 0
endif
catch /inputtoggle/
let b:inputtoggle = 0
endtry
endfunction
let g:loaded_fcitx = 1
endfunction
" If g:fcitx5_remote is set (to the path to `fcitx5-remove`), use it to toggle IME state.
if exists("g:fcitx5_remote")
call s:setup_cmd()
" Otherwise, if python3 is available, use python and dbus to toggle IME state.
elseif has('python3')
try " abort on fail
exe 'py3file' expand('<sfile>:r') . '.py'
if py3eval('fcitx_loaded')
function Fcitx2en()
py3 fcitx2en()
endfunction
function Fcitx2zh()
py3 fcitx2zh()
endfunction
function FcitxCurrentIM()
return py3eval('fcitx_current_im()')
endfunction
function FcitxCurrentIMwithRime()
return py3eval('fcitx_current_im_and_rime()')
endfunction
let g:loaded_fcitx = 1
endif
catch
if executable('fcitx5-remote')
let g:fcitx5_remote = 'fcitx5-remote'
call s:setup_cmd()
endif
endtry
endif
" Register autocmd if successfully loaded.
if exists("g:loaded_fcitx")
if exists('##InsertLeavePre')
au InsertLeavePre * if reg_executing() == "" | call Fcitx2en() | endif
else
au InsertLeave * if reg_executing() == "" | call Fcitx2en() | endif
endif endif
au InsertEnter * if reg_executing() == "" | call Fcitx2zh() | endif
au CmdlineEnter [/\?] if reg_executing() == "" | call Fcitx2zh() | endif
au CmdlineLeave [/\?] if reg_executing() == "" | call Fcitx2en() | endif
endif endif
let g:loaded_fcitx = 1
let pyfile = expand('<sfile>: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
" --------------------------------------------------------------------- " ---------------------------------------------------------------------
" Restoration And Modelines: " Restoration And Modelines:
unlet python3
unlet pyfile
let &cpo=s:keepcpo let &cpo=s:keepcpo
unlet s:keepcpo unlet s:keepcpo
" vim:fdm=expr:fde=getline(v\:lnum-1)=~'\\v"\\s*-{20,}'?'>1'\:1
" vim: sw=2 :

View file

@ -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("fcitx-remote")
finish
endif
let s:keepcpo = &cpo
let g:loaded_fcitx = 1
set cpo&vim
" ---------------------------------------------------------------------
" Functions:
function Fcitx2en()
let inputstatus = system("fcitx-remote")
if inputstatus == 2
let b:inputtoggle = 1
call system("fcitx-remote -c")
endif
endfunction
function Fcitx2zh()
try
if b:inputtoggle == 1
call system("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