Skip to content
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

IMEのON/OFFをsyntaxで制御する #13

Closed
koron opened this issue Sep 13, 2011 · 15 comments
Closed

IMEのON/OFFをsyntaxで制御する #13

koron opened this issue Sep 13, 2011 · 15 comments

Comments

@koron
Copy link
Member

koron commented Sep 13, 2011

ちょっと面白い提案があったので、議論、検討用に転載します。

ダブルクオートとコメントの中でしか日本語入力をONにできないようにして欲しい

プログラマ的には「わかる」要求。

  • スクリプトだけでできるか?
  • 本体いじるならどうやるべきか?
@tyru
Copy link
Member

tyru commented Sep 13, 2011

本体もいじる案を提案したいです。
というか自分自身これで(skk.vim, eskk.vimで)悩んでいるので、
厚かましいですがパッチを書いてくれるのならぜひお願いしたいです...

自分の提案する案は、「VimスクリプトでInsertEnterの時にCommentの中にいたらIMEをonする」という案です。
次のコードはそれを意図したコードです。

autocmd InsertEnter *
\     for id in synstack(line('.'), col('.'))
\   |   if synIDattr(synIDtrans(id), 'name') ==# 'Comment'
\   |     let &l:iminsert = 2
\   |   endif
\   | endfor

しかし現状この挙動通りにはいかなくて、単純に
autocmd InsertEnter * let &l:iminsert = 1 のようにしてもインサートモードでlang modeになりません。
<Esc>iしてインサートモードに入り直すとlang modeになっています。
上のコードが意図通りになればスクリプトから制御できるようになり、便利だと思います。

また逆に「InsertEnterの時にCommentの外にいたらIMEをoffにする」
のような機能がEmacsのddskkというプラグインにあるので、
その機能を実現するためにonするだけでなくlet &l:iminsert = 0のようにしてoffにすることもできれば可能にしたいです。

@koron
Copy link
Member Author

koron commented Sep 13, 2011

tyruさんの提案はハイブリッドってところですね。
IMEのON/OFFをスクリプトから制御できる方法を用意し、
スクリプトでそれを使って細かく制御しようと。

私の最初の想定ではsyntaxにIME可/不可を設定できるようにして、
その制御までVim側でということも考えていました。

tyru案のほうが本体をいじる手間は少なくてステキそうなんですが、何か他に案はあるでしょうか?

もっとも環境によってIMEのON/OFFの制御は超むずかったりしますけどw

@ghost ghost assigned koron Sep 13, 2011
@thinca
Copy link
Member

thinca commented Sep 13, 2011

ふと思ったのですが、iminsert の変更と実際のIMの状態の変更のタイミングがずれていること自体がバグだったりしないでしょうか。

@koron
Copy link
Member Author

koron commented Sep 13, 2011

いやそれは意図した動作です。
iminsertはIMEの状態にマップされた変数では無く
あるタイミングで適用&更新されるだけの値なんですよ。

なのでIME制御用のeval funcを追加するのが確実な気がします。

@koron
Copy link
Member Author

koron commented Sep 26, 2011

なんかiminsertを即時適用しても良い気がしてきた。
ただタイミング次第ではバグになりそう。

  • iminsert したら非編集モードなのにimeがonになった

みたいな。

@koron
Copy link
Member Author

koron commented Oct 4, 2011

@tyru さん: 私の手元のWindowsだとそのコードで、コメントの中だけ自動的にIMEがONになる(意図どおりに動く)んですが…動かないといった環境を教えてもらえますか?

Vimのソースコードを確認してたら、src/edit.cのedit()の中でautocmd InsertEnterを実行したあとでiminsertの値を実際のIMEのON/OFFに適用するってなってました。私は勘違いでコレが逆になってて動かないだろうなと予測していたんですが、この順番ならInsertEnterで設定したiminsertは正しく反映されます。仮に反映できないとしたら、IME制御がうまくいかないOSとかUI環境があるという話で、また別の問題になります。

あと、もともとの提案はIMEをONにできないようにしたい、という提案とも読める。となるとimdisableでの制御ができるか。

@koron
Copy link
Member Author

koron commented Oct 4, 2011

ちょっとやってみたのだけれど
editモード(CursorMoveI)中のlet &l:imdisable = 0が効かないみたい。
逆のlet &l:imdisable = 1は効いてる。

augroup LimitIME
  autocmd!
  autocmd InsertEnter * call s:LimitIME()
  autocmd CursorMovedI * call s:LimitIME()
augroup END

function! s:LimitIME()
  let disable = 1

  for id in synstack(line('.'), col('.'))
    let attr = synIDattr(synIDtrans(id), 'name')
    if attr ==# 'Comment' || attr ==# 'String'
      let disable = 0
      break
    endif
  endfor

  if &l:imdisable != disable
    let &l:imdisable = disable
  endif
endfunction
  1. こんなスクリプトを*.cでsourceして、
  2. コメント内でInsertモードに入りIMEをON
  3. Insertモードのままコメント外へカーソルを動かしてIMEがOFFになる
  4. Insertモードのままコメント内へカーソルを動かしてもIMEはOFFのまま、IMEをONするキーを押しても変わらない

といった状況。再現環境はWindowsの香り屋版。imdisableの実装内容をチェックしなきゃダメっぽい。

@koron
Copy link
Member Author

koron commented Oct 4, 2011

推測だけど、CursorModeIはiminsertも当然働かないハズ…だよなぁ?

@koron
Copy link
Member Author

koron commented Oct 4, 2011

@tyru さん:
issue 64 に書いたように、
editモード中(特にCursorMovedI)の最中にiminsertをset/getしても正しく動かないのは確認しました。
それに対してInsertEnterでは正しく動作することを確認しています。
(Windowsだけですが)

ところがtyruさんの報告はInsertEnterでも動作しないとのことで、私の推測&観測とはズレています。
ちょっと報告の内容が再現するか確認し、するようなら環境等を細かく報告してください。

@ghost ghost assigned tyru Oct 4, 2011
@tyru
Copy link
Member

tyru commented Oct 5, 2011

@tyru さん: 私の手元のWindowsだとそのコードで、コメントの中だけ自動的にIMEがONになる(意図どおりに動く)んですが…動かないといった環境を教えてもらえますか?

@koronさん すみません、自分の環境(Ubuntu 11.04, Vim 7.3.322)でも正しく動きました。
前のバージョンで動いてなかったのですが、issue登録する前に確認してなかったです。すみませんorz

試してみたら、onするだけでなく、こんな風にoffにするのもできますね。
じゃあこれはもう実現できてるのかもしれません。
ちょっとまた詳しく調べてからcloseにします。(あ、今見たらそもそも権限なかった...)

autocmd InsertEnter *
\     for id in synstack(line('.'), col('.'))
\   |   let &l:iminsert = (synIDattr(synIDtrans(id), 'name') ==# 'Comment' ? 1 : 0)
\   | endfor

@tyru
Copy link
Member

tyru commented Oct 5, 2011

あと、もともとの提案はIMEをONにできないようにしたい、という提案とも読める。となるとimdisableでの制御ができるか。

自分の上のコメントで出した例のようにonとoff両方制御したいです。
なので、自分の要望としては見たとろ実現できているように思います。
eskk.vimでこれをやりたかったので、それで実装してうまく動いているようならcloseします。

@koron
Copy link
Member Author

koron commented Oct 6, 2011

あ、まだcloseしないでください。
なぜならCursorMovedI中のiminsertの制御はかなり変になってるので。

最悪のケースでもwon't fixという分類ができてからcloseしたいです。

@tyru
Copy link
Member

tyru commented Oct 6, 2011

了解です。

@koron
Copy link
Member Author

koron commented Jul 29, 2012

CursorMovedI中のiminsertの制御はかなり変

これは変わらないが、そこで変えたいという要求は今のところないので本issueは won't fix として閉じます。

@koron koron closed this as completed Jul 29, 2012
@tyru
Copy link
Member

tyru commented Jan 5, 2013

#228 を参照してpushしてしまいましたが、以下が動作するのをeskkで確認しました。(遅い)

@tyru さん:
issue 64 に書いたように、
editモード中(特にCursorMovedI)の最中にiminsertをset/getしても正しく動かないのは確認しました。
それに対してInsertEnterでは正しく動作することを確認しています。
(Windowsだけですが)

ところがtyruさんの報告はInsertEnterでも動作しないとのことで、私の推測&観測とはズレています。
ちょっと報告の内容が再現するか確認し、するようなら環境等を細かく報告してください。

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

No branches or pull requests

3 participants