解决了fcitx在vim切换模式时智能切换中英文的问题,但方向箭出了问题,求解决方法

55 views
Skip to first unread message

yetist

unread,
Oct 15, 2009, 9:52:02 PM10/15/09
to Vim...@googlegroups.com
修改过的fcitx源码及patch可以从这里下载:

http://dev.osprg.org/~yetist/archlinux/yetist/sources/fcitx4vim-3.6.1-1.src.tar.gz

在vim的配置中映射了ESC键,但是发现只要映射了ESC键之后,按下四个方向键在插入模式却输入了A、B、C、D四个字符。
不知道这应该如何解决。

--
Best regards!

yetist

Yongwei Wu

unread,
Oct 15, 2009, 10:43:03 PM10/15/09
to vim...@googlegroups.com
输入cat,然后按方向键,你就知道这些ABCD是哪来的了。

最好不要映射ESC。如果你要截获退出输入的话,考虑使用InsertLeave事件。

2009/10/16 yetist <yet...@gmail.com>:

--
Wu Yongwei
URL: http://wyw.dcweb.cn/

yetist

unread,
Oct 15, 2009, 11:09:11 PM10/15/09
to vim...@googlegroups.com
那请问这个映射怎样使用InsertLeave来做?
inoremap <ESC> <ESC>:call Fcitx2en()<CR>


2009/10/16 Yongwei Wu <wuyo...@gmail.com>



--
Best regards!

yetist

yetist

unread,
Oct 15, 2009, 11:29:48 PM10/15/09
to vim...@googlegroups.com
哈,搞定了。

autocmd! InsertLeave * call Fcitx2en()
autocmd! InsertEnter * call Fcitx2zh()


2009/10/16 yetist <yet...@gmail.com>



--
Best regards!

yetist

yetist

unread,
Oct 15, 2009, 11:48:44 PM10/15/09
to vim...@googlegroups.com
不过这样修改了以后,反应有点慢啊。如果按了ESC之后,fcitx的切换要1,2秒呢。有没有更好的办法?

2009/10/16 yetist <yet...@gmail.com>



--
Best regards!

yetist

闲耘(tm)

unread,
Oct 16, 2009, 12:03:50 AM10/16/09
to vim...@googlegroups.com
vim 在切换到普通模式时,本身会自动关闭输入法(如果不能关闭,可能是输入法本身的问题)。
建议还是不要改变<Esc>的映射

--
闲耘™ (@hotoo, xianyun.org)
Sent from Hangzhou, 33, China


2009/10/16 yetist <yet...@gmail.com>

yetist

unread,
Oct 16, 2009, 12:45:34 AM10/16/09
to vim...@googlegroups.com
2009/10/16 闲耘 <hotoo.cn@gmail.com>
vim 在切换到普通模式时,本身会自动关闭输入法(如果不能关闭,可能是输入法本身的问题)。
建议还是不要改变<Esc>的映射

你用的什么操作系统和输入法?
 



--
Best regards!

yetist

闲耘(tm)

unread,
Oct 16, 2009, 12:52:04 AM10/16/09
to vim...@googlegroups.com
Windows
:h IME

(Windows IME 支持) *multibyte-ime* *IME*

{仅对 Windows GUI 有效,而且编译时需加入 |+multi_byte_ime| 特性}
...

--
闲耘™ (@hotoo, xianyun.org)
Sent from Hangzhou, Zhejiang, China


2009/10/16 yetist <yet...@gmail.com>

yetist

unread,
Oct 16, 2009, 12:55:25 AM10/16/09
to vim...@googlegroups.com
那我们说的不是一回事,我讲的是linux。
--
Best regards!

yetist

蓝色基因

unread,
Oct 16, 2009, 3:19:00 PM10/16/09
to Vim.cn

> 输入cat,然后按方向键,你就知道这些ABCD是哪来的了。


---- 看不大明白,请大侠再解释一下。哪种模式下输入 cat,cat 是什么命令,插入这些字符是 Vim 的 bug 么?

---- 我遇到了同样的问题。我觉得 Vim 补全模式的操作太复杂不够直观,所以用 inoremap 加上按键映射函数,在 Vim 补全模式的
基础上做了个自定义补全模式。做的过分了些,把下面这些键都给映射了:

inoremap <expr> ^[ g:ImodeMap_Escape()
inoremap <expr> ^M g:ImodeMap_Enter()
inoremap <expr> <Space> g:ImodeMap_Space()
inoremap <expr> <Tab> g:ImodeMap_Tab()
inoremap <expr> i g:ImodeMap_i()
inoremap <expr> k g:ImodeMap_k()
inoremap <expr> j g:ImodeMap_j()
inoremap <expr> l g:ImodeMap_l()

inoremap <expr> ^H g:ImodeMap_Ctrl_h()
inoremap <expr> ^J g:ImodeMap_Ctrl_j()
inoremap <expr> ^K g:ImodeMap_Ctrl_k()
inoremap <expr> ^L g:ImodeMap_Ctrl_l()

inoremap <expr> ^F pumvisible() ? "<Pagedown>" : "^F"
inoremap <expr> ^B pumvisible() ? "<Pageup>" : "^B"


---- 然后,用下面这些数据结构用来记录 自定义补全模式 的状态

"============================================================
"======= 当前所处的 Insert 模式下的自定义子模式
"======= 'completion' 代表自定义补全模式
"============================================================

let g:crtUserMode= 'none'

"============================================================
"======= 这部分是专属于 自定义补全模式 的数据结构
"============================================================

let g:myCplData= {}

" Vim 的 15 种补全模式分成四组,method A~D。这个变量记录当前在哪一组。
let g:myCplData.crtMethod= 'methodC'

" 下面两组子数据结构是相对应的,前一个用来在后一个内部寻址。
let g:myCplData.crtModeIdx= {}

let g:myCplData.crtModeIdx.methodA= 0
let g:myCplData.crtModeIdx.methodB= 0
let g:myCplData.crtModeIdx.methodC= 0
let g:myCplData.crtModeIdx.methodD= 0

" 这些是 15 种补全模式的缩略代号
let g:myCplData.modeString= {}

let g:myCplData.modeString.methodA= 'KHS'
let g:myCplData.modeString.methodB= 'FVTID'
let g:myCplData.modeString.methodC= 'pnPNL'
let g:myCplData.modeString.methodD= 'UO'

---- 下面是两个按键映射函数的例子:

---- ^K 按键的作用是进入第三个模式组群(methodC,一共有 'pnPNL' 五种补全模式),它的按键映射函数是这样写的:

" map 到 ^K 上
function! g:ImodeMap_Ctrl_k()

" 无论当前是否处于补全模式,都执行相同操作
if (g:crtUserMode =~ 'none') || (g:crtUserMode =~
'completion')
let g:crtUserMode= 'completion'

" 总是从该 method 的第一个 mode 进入,而不是最近一次使用的 mode。
let g:myCplData.crtMethod= 'methodC'
let g:myCplData.crtModeIdx.methodC= 0

" 临时变量,当前的 Vim 补全模式
let crtCplMode=
\ g:myCplData.modeString.methodC[g:myCplData.crtModeIdx.methodC]

return (crtCplMode == 'p') ? "^E^P" :
\ (crtCplMode == 'n') ? "^E^N" :
\ (crtCplMode == 'P') ? "^E^X^P" :
\ (crtCplMode == 'N') ? "^E^X^N" :
\ (crtCplMode == 'L') ? "^E^X^L" :
\ (crtCplMode == 'T') ? "^E^X^]" :
\ (crtCplMode == 'I') ? "^E^X^I" :
\ (crtCplMode == 'D') ? "^E^X^D" :
\ (crtCplMode == 'V') ? "^E^X^V" :
\ (crtCplMode == 'F') ? "^E^X^F" :
\ (crtCplMode == 'U') ? "^E^X^U" :
\ (crtCplMode == 'O') ? "^E^X^O" :
\ (crtCplMode == 'K') ? "^E^X^K" :
\ (crtCplMode == 'H') ? "^E^X^T" :
\ (crtCplMode == 'S') ? "^E^X^S" :
\ "^R=g:ImodeMessage('error! Completion Mode
unrecognizable')^M"
else
return "^R=g:ImodeMessage('No! What mode are you in right
now?')^M"
endif

endfunction

---- <Esc> 按键的作用是:第一次按退出 自定义补全模式,回到 Insert 模式。第二次按退出 Insert 模式,回到
Normal 模式。它的按键映射函数是这样的:

" map 到 <Esc> 上
function! g:ImodeMap_Escape()

if g:crtUserMode =~ 'none'
return "^["
elseif g:crtUserMode =~ 'completion'
" 回归 Insert 模式前,在自定义补全模式下通过 match 命令设置的任何高亮都要取消。
match none

let g:crtUserMode= 'none'
return "^E"
else
return "^R=g:ImodeMessage('No! What mode are you in right
now ?')^M"
endif

endfunction

---- 其他的按键映射函数写法类似。这些东西前两天刚写好,还没来得及作许多测试。初步用下来,大部分情况下操作都跟设想的一样,比较方便。但是今
天遇到一回,症状跟上面所说的很相似,就是按这些键的时候,会输入些莫名其妙的字符,不知是从哪来的。

---- 比如:我的程序里已经有了这样一句:

inoremap <expr> \\ g:ImodeMapShowLineRange()

然后下面在定义这个函数的时候,假设已经输入了以下部分:

function! g:ImodeMapShowL

然后按 ^K 来进行补全,但是结果却是插入了一个看上去没有任何关联的字符,比如:

function! g:ImodeMapShowLt

同时消息栏会说找不到匹配。而诡异的是,如果把这行 copy 到另外一处再进行同样操作,就又正常了。

---- 我被难到了,刚好这个贴子有讲到类似的问题,希望能找到答案。谢谢。


Yongwei Wu

unread,
Oct 17, 2009, 4:45:58 AM10/17/09
to vim...@googlegroups.com
在终端窗口里。我这边按上下左右的结果是:

$ cat
^[[A^[[B^[[D^[[C

也就是说,在应用程序里,你按上箭头,得到的键码是:ESC,[,A。注意里面包含了ESC(Ctrl-[)。

2009/10/17 蓝色基因 <bluege...@gmail.com>:

--

Yongwei Wu

unread,
Oct 17, 2009, 4:57:19 AM10/17/09
to vim...@googlegroups.com
不仅对Windows有效。理论上对Linux也有效。不过,我从来没在Linux下试过。Mac下用图形界面的MacVim也是可以的。具体可以查看:help
iminsert:

'iminsert' 'imi' number (default 0, 2 when an input method is supported)
local to buffer
{not in Vi}
Specifies whether :lmap or an Input Method (IM) is to be used in
Insert mode. Valid values:
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|.
⋯⋯

最后一句话说明,Linux下你至少需要把multi_byte_ime和xim两个特性编译进去。

2009/10/16 闲耘 <hoto...@gmail.com>:


> Windows
> :h IME
> (Windows IME 支持) *multibyte-ime* *IME*
> {仅对 Windows GUI 有效,而且编译时需加入 |+multi_byte_ime| 特性}
> ...

--

Reply all
Reply to author
Forward
0 new messages