rhysd/vim-operator-surround

<Plug>(operator-surround-append) 時に textobj を入力する前に括弧を指定したい

Opened this issue · 48 comments

lingr で言っていたやつですが、こちらにも要望を出しておきます。
現在、<Plug>(operator-surround-append)

  • operator → textobj →任意の括弧の入力

という順番で処理されるのですが、これを

  • operator →任意の括弧の入力→textobj

という風に textobj の前に括弧の入力を行いたいです。
これは例えば次のように利用することを想定しています。

" <Plug>(operator-surround-append-before) は先に括弧の入力を受け付けるマッピング
" <Plug>(operator-surround-append){textobj}( と同等
" e.g. s(iw は単語の範囲を () で囲む
map s( <Plug>(operator-surround-append-before)(

operator#user#define() の第3引数でいけそうなので,少し試してみます.
ただ,変更箇所が多いので実装には時間がかかると思います.

了解です。お願いしますいぬ。
(ただ、結構欲しい機能だったりするので先に自分で簡単なラッパーを書いてしまうかも…。

簡単なラッパーを書いてみました。
https://github.com/osyo-manga/vim-operator-surround-before
これは次のように利用できます。

nmap sa <Plug>(operator-surround-append-before-getchar)
nmap s( <Plug>(operator-surround-append-before-getchar)(
nmap s{ <Plug>(operator-surround-append-before-getchar){
nmap s" <Plug>(operator-surround-append-before-getchar)"

ご参考までに。

現在実装中ですので,もうしばらくそちらのラッパーでお待ち下さい.

!?

すみません,ブラウザがコメント後遷移せず,反応が無いと勘違いしてクリック連打してしまいました…

連打力

うかさま!

うかさま!

試しに実装してみようとしましたが,operator#user#define() の第3引数で getchar() を呼んでもマッピングの後の入力を getchar() が食ってしまうのでうまくいかないですね.イヌゥ…

かなり汚い実装になりそうですが,別マッピング定義する方向で実装します.

ちなみにわたしの実装は先に getchar() を処理してから <Plug>(operator-surround-append) を呼び出していますね。

s/<Plug>(operator-surround-append)/operator#surround#append/

<Plug>(operator-surround-append) に対して,<Plug>(operator-surround-append-2) 的なマッピング用意します.

はい,そんな感じでいきます.

(operator-surround-append-2)

!?

input_in_advance ブランチにとりあえず実装してみました.<Plug>(operator-surround-* を上書きしてしまえば良いと気づいたので,余計なマッピングは定義しなくて済みました.operator#surround#input_block_in_advance1 にすると有効になります.
テスト書いて問題が無さそうなら master にマージ予定です.

ありがとうございます。試してみます。

input_in_advance ブランチにとりあえず実装してみました.(operator-surround-* を上書きしてしまえば良いと気づいたので,余計なマッピングは定義しなくて済みました.

個人的には <Plug>(operator-surround-append-before) みたいなマッピングを増やしてもらっても構わなかったですね(オプションで切り替えるよりは任意のマッピングを選択して使用する方が柔軟性が高いので。

こちらでも動作することを確認しました。ありがとうございます。
あと <Plug>(operator-surround-repace) にも対応する事って可能でしょうか。
こちらも先に括弧が入力する事ができれば便利そうです。

個人的には (operator-surround-append-before) みたいなマッピングを増やしてもらっても構わなかったですね(オプションで切り替えるよりは任意のマッピングを選択して使用する方が柔軟性が高いので。

これなのですがやはりオプションで切り替えるよりはマッピングを増やしてしまったほうが柔軟性が高いんじゃないかと思いました。
例えばマッピングごとに対応しておけば『<Plug>(operator-surround-append) は先に入力をしたいけど <Plug>(operator-surround-repace) は後から括弧を入力したい。』みたいな事が可能だと思います。

確認ありがとうございます.

あと (operator-surround-repace) にも対応する事って可能でしょうか。

あれ,appendreplace の両方に対応していたつもりだったんですが,できてませんでしたか… 確認してみます.報告ありがとうございます!

例えばマッピングごとに対応しておけば『(operator-surround-append) は先に入力をしたいけど (operator-surround-repace) は後から括弧を入力したい。』みたいな事が可能だと思います。

確かに可能ですが,それをやりたいユースケースが思いつかないです.おしょーさんがそうしたいという要望があるのであれば,実装します.

あれ,append と replace の両方に対応していたつもりだったんですが,できてませんでしたか… 確認してみます.報告ありがとうございます!

あにゃ、こちらでもう1回試してみましたがやはり <Plug>(operator-surround-replace) の方は後から括弧の入力になりますね。

確かに可能ですが,それをやりたいユースケースが思いつかないです.おしょーさんがそうしたいという要望があるのであれば,実装します.

んー『どうしてもほしい』という要望があるわけではないですが、『そういう要望があった場合に柔軟に対応できるよねー』という感じですかね
どちらかというとオプションで切り替える設計が気持ち悪いというのが強い

あれ、今気づいたんですが<Plug>(operator-surround-append)operator#surround#input_block_in_advance の値に関係なく『先にブロックを入力する処理』になりますね。

あとはなしは変わるんですが、以下のように『連続して CursorHold を呼び出すハック』を行っている場合、『ブロックの入力待ち』がupdatetimeの間隔でスキップされてしまうようです。

augroup test
    autocmd!
    autocmd CursorHold * call feedkeys(mode() =~# '[iR]' ? "\<C-g>\<ESC>" : "g\<ESC>", 'n')
augroup END

わたしの vim-operator-surround-before だとこの問題は起きないようですね。

あーあと『ブロックの入力』を <C-c> でキャンセルした場合、以下の様なエラーメッセージが出力されました。

function operator#surround#wrap の処理中にエラーが検出されました:
行    1:
E706: 変数の型が一致しません: s:input

反応遅くてすみません…なかなかまとまった時間取れないので,返信だけですが

あれ、今気づいたんですが(operator-surround-append) は operator#surround#input_block_in_advance の値に関係なく『先にブロックを入力する処理』になりますね。

こちらでは,初回のみ挙動がおかしくなりますね…どうしてだろう.

あとはなしは変わるんですが、以下のように『連続して CursorHold を呼び出すハック』を行っている場合、『ブロックの入力待ち』がupdatetimeの間隔でスキップされてしまうようです。

あー,多分 feedkeys() の入力を getchar() が食っちゃうからですね.おしょーさんのほうのは wrapper コマンドにも feedkeys() を使っているから大丈夫なんだと思います.ちょっと対応してみます.

あーあと『ブロックの入力』を でキャンセルした場合、以下の様なエラーメッセージが出力されました。

こちらでも再現しました.多分すぐに修正できます.

コメントありがとうございます.ちょっと引越し前で時間が取れないので,気長にお待ちください…

あとはなしは変わるんですが、以下のように『連続して CursorHold を呼び出すハック』を行っている場合、『ブロックの入力待ち』がupdatetimeの間隔でスキップされてしまうようです。

これについて feedkeys() 使ってみましたが,<SID> マッピングの入力に使われる特殊文字がうまく入らないですね…

コメントありがとうございます.ちょっと引越し前で時間が取れないので,気長にお待ちください…

りょーかいです。
新しい犬小屋づくりがんばってください!

いくつか試してみて

あれ、今気づいたんですが<Plug>(operator-surround-append) は operator#surround#input_block_in_advance の値に関係なく『先にブロックを入力する処理』になりますね。

あーあと『ブロックの入力』を でキャンセルした場合、以下の様なエラーメッセージが出力されました。

が修正されていることを確認しました。ありがとうございます。
あと <C-c> でキャンセルを行った場合でも textobj の入力待ちが発生するのですがこれは意図的なのでしょうか。
キャンセルしてしまっているのでもうこれも抜けてしまってもよいような気がします。

確かに可能ですが,それをやりたいユースケースが思いつかないです.おしょーさんがそうしたいという要望があるのであれば,実装します.

これですが、以下のようにキーマッピングしたい場合に『<Plug>(operator-surround-repace) は後から括弧を入力したい』というケースが出てきました。

" 対象となるブロックは a" や a( ではなくて <Plug>(textobj-multiblock-a) を使用する
" sr( や sr" などでカーソルから一番近い位置のブロックを置換できる
nmap sr <Plug>(operator-surround-replace)<Plug>(textobj-multiblock-a)

master で少し試してみましたがなかなかに便利そうな感じだったので対応されると嬉しい。

でキャンセルを行った場合でも textobj の入力待ちが発生するのですがこれは意図的なのでしょうか。

オペレータマッピング側からテキストオブジェクトの入力をキャンセルする方法ってありましたっけ.

これですが、以下のようにキーマッピングしたい場合に『(operator-surround-repace) は後から括弧を入力したい』というケースが出てきました。

なるほど,了解しました.では別マッピングとして提供する方向で修正します.

なるほど,了解しました.では別マッピングとして提供する方向で修正します.

ありがとうございます。

オペレータマッピング側からテキストオブジェクトの入力をキャンセルする方法ってありましたっけ.

んー処理の流れを理解していませんが call feedkeys("\<ESC>", "n") を呼ぶとか?

9298951 で実装してみました.
ちょっとマッピング名が長いですが,

  • <Plug>(operator-surround-append-input-in-advance)
  • <Plug>(operator-surround-replace-input-in-advance)

を normal mode のマッピングとして定義してみました.お時間あるときにでも試してもらえるとありがたいです.

ちなみに,CursorHold でポーリングするハックには対応できていない気がします(未確認)

ありがとうございます。

<Plug>(operator-surround-append-input-in-advance)
<Plug>(operator-surround-replace-input-in-advance)

この2つは動作することを確認しました。いい感じです。

ちなみに,CursorHold でポーリングするハックには対応できていない気がします(未確認)

これはまだ再現するようですねぇ。

今ふと思ったのですが,getchar() での入力待ち中って CursorHold 発火しましたっけ…?

(だいぶ時間が空いてしまった…)
うーん、どうでしょう。わたしは経験したことがないですねぇ。

ping

pong.

すみません,notification が埋れてしまっていて気付きませんでした.

これってまだ解決はしていない感じなのでしたっけ。

で、思い出したのですが、これが原因だったりするのかな。
vim-jp/issues#607

はい,まだ解決していませんでしたが,確かにその issue が原因の可能性ありますね… この issue 用の開発ブランチは input_in_advance として残してあるので,時間あるときに確認してみます.
ありがとうございます.

ありがとうございます.確か clever-f.vim のほうでも同じ対応を入れているはずなので,こちらでも試してみます.

ping

I could be wrong, but is this discussion about explicitly mapping for certain block symbol?
Maybe, you have solution for how to embed certain block symbol instead of prompt?
I use embedding for fast replacing any nearest block to quotes:

nmap qq <Plug>(operator-surround-replace)<Plug>(textobj-anyblock-a)"

But how to implement something similar for <Plug>(operator-surround-append)?