New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

インサートモード時、 InsertLeave を発火させずにコマンドを実行したい #1059

Closed
acro5piano opened this Issue Jul 26, 2017 · 4 comments

Comments

Projects
None yet
4 participants
@acro5piano

acro5piano commented Jul 26, 2017

初めて質問させて頂きます。よろしくお願い致します。

質問の内容

インサートモードで、あるキーを押したらあるVimのコマンドを実行する、ということを実現したいです。
そこで、 InsertLeave を発火させずにコマンドを実行することは可能でしょうか?

実現方法として、

  1. <C-o> を使ってコマンドを実行する 例: inoremap a <C-o>:command
  2. ノーマルモードに一旦戻ってからコマンドを実行する 例: inoremap a <C-c>:command<CR>li

を考えました。が、どちらも InsertLeave が必ず発火してしまいます。

  1. に関しては、下記のIssueでVimの仕様ということでしたので、無理と分かりました。

i(nore)?mapが発動するとIMEが勝手にOFFになってしまう

  1. に関しては、 <C-c> は通常 InsertLeave を発火させないはずですが、 i(nore)map で割り当てた時は発火させてしまいます。

下記の ~/.vimrc で確認致しました。

autocmd InsertLeave * normal ggVG
inoremap a <C-c>
inoremap b <ESC>
inoremap c <C-[>

Vimのバージョン

IMproved 8.0 (2016 Sep 12, compiled Mar  6 2017 14:13:23)
Included patches: 1-427

OSの種類/ディストリ/バージョン

Arch Linux (64bit Rolling update)

使用している or 関係していそうなプラグイン

プラグイン無しの状態で再現しました。

その他

InsertLeave を発火させたくない理由は、 ノーマルモード時に日本語入力をOFFにしているためです。
日本語入力中に、あるコマンドを実行した後に、日本語入力がONのままになっていてほしいので・・・

autocmd InsertLeave * call system('fcitx-remote -c')

Best regards,
Kazuya Gosho

@presuku

This comment has been minimized.

Show comment
Hide comment
@presuku

presuku Jul 26, 2017

Member

自動コマンドを実行しないという対処は :help noa で、できると思います。

しかし、IME関連の制御なら、まず :help imaf:help imsf を使ってみると良いと思います。
Linuxで、gvimなら、ynkdirさんのパッチをk-takataさんがアップデートした over-the-spotパッチ を当てて、
imafimsf を適切に設定していると、 Windows 上の gvim 同様に日本語関係は快適になります。
パッチを当てた vim で :set imstyle=1 すると over-the-spot を使用するようになります。

Member

presuku commented Jul 26, 2017

自動コマンドを実行しないという対処は :help noa で、できると思います。

しかし、IME関連の制御なら、まず :help imaf:help imsf を使ってみると良いと思います。
Linuxで、gvimなら、ynkdirさんのパッチをk-takataさんがアップデートした over-the-spotパッチ を当てて、
imafimsf を適切に設定していると、 Windows 上の gvim 同様に日本語関係は快適になります。
パッチを当てた vim で :set imstyle=1 すると over-the-spot を使用するようになります。

@mattn

This comment has been minimized.

Show comment
Hide comment
@mattn

mattn Jul 26, 2017

Member

方法としては2つ

<expr> を使う

function! s:A()
  " ここで何かする
  return ''
endfunction
autocmd InsertLeave * normal ggVG
inoremap <expr> a <SID>A()

特に何か文字を挿入する必要がないのであれば関数では空文字を返して下さい。

InsertCharPre を使う

function! s:B()
  " ここで何かする
  return v:char
endfunction
autocmd InsertLeave * normal ggVG
autocmd InsertCharPre <buffer> let v:char = <SID>B()

InsertCharPre は挿入文字を変更する為に使われますが、それを利用します。何が押されたかは v:char を見ます。この場合、フックできるのは挿入されるような文字に限られます。

Member

mattn commented Jul 26, 2017

方法としては2つ

<expr> を使う

function! s:A()
  " ここで何かする
  return ''
endfunction
autocmd InsertLeave * normal ggVG
inoremap <expr> a <SID>A()

特に何か文字を挿入する必要がないのであれば関数では空文字を返して下さい。

InsertCharPre を使う

function! s:B()
  " ここで何かする
  return v:char
endfunction
autocmd InsertLeave * normal ggVG
autocmd InsertCharPre <buffer> let v:char = <SID>B()

InsertCharPre は挿入文字を変更する為に使われますが、それを利用します。何が押されたかは v:char を見ます。この場合、フックできるのは挿入されるような文字に限られます。

@mattn

This comment has been minimized.

Show comment
Hide comment
@mattn

mattn Jul 26, 2017

Member

一応、もう一つあります。

<c-r>= を使う

function! s:C()
  " ここで何かする
  return ''
endfunction
autocmd InsertLeave * normal ggVG
inoremap a <c-r>=<SID>C()<cr>
Member

mattn commented Jul 26, 2017

一応、もう一つあります。

<c-r>= を使う

function! s:C()
  " ここで何かする
  return ''
endfunction
autocmd InsertLeave * normal ggVG
inoremap a <c-r>=<SID>C()<cr>
@acro5piano

This comment has been minimized.

Show comment
Hide comment
@acro5piano

acro5piano Jul 26, 2017

素早いご返事ありがとうございますm(_ _)m

@presuku さん

noautocmd を使って無効にして、再度有効にするという方法も考えたのですが、 noautocmd を実行する時にノーマルモードになってしまったので諦めました。

gvim だと over-the-spot という機能があるのですね!勉強になります。
私はターミナルでしか Vim を使わないので、利用する機会は無いと思いますが、いつか gvim に移行したときに参考にさせて頂きます。

@mattn さん

サンプルコード含め、詳しく教えて頂きありがとうございます。
<expr> はそういう意味だったのですね。
自分が Vim Script に無知であることを感じました。
vim-jp.org を読んで勉強します!

acro5piano commented Jul 26, 2017

素早いご返事ありがとうございますm(_ _)m

@presuku さん

noautocmd を使って無効にして、再度有効にするという方法も考えたのですが、 noautocmd を実行する時にノーマルモードになってしまったので諦めました。

gvim だと over-the-spot という機能があるのですね!勉強になります。
私はターミナルでしか Vim を使わないので、利用する機会は無いと思いますが、いつか gvim に移行したときに参考にさせて頂きます。

@mattn さん

サンプルコード含め、詳しく教えて頂きありがとうございます。
<expr> はそういう意味だったのですね。
自分が Vim Script に無知であることを感じました。
vim-jp.org を読んで勉強します!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment