vim-operator-surround icon indicating copy to clipboard operation
vim-operator-surround copied to clipboard

ブロックキーが入力されるまでインプットを保持するオプションを追加

Open zeero opened this issue 11 years ago • 18 comments

こんにちは。素晴らしいプラグインをありがとうございます。

surroundを使うときにブロック以外の文字を足したい時があります。 vimスクリプトを書いていると処理の順と記述の順が逆なので特にそう思います。

(例)ファンクションAを呼んで、結果にファンクションBを呼びたい

  1. A()を書く
  2. A()をビジュアル選択
  3. surroundで()を付与するときに、B(と書きたい

このためにオプションを一つ足してみました。 g:keeps_input_if_no_block

  • 有効にすると、ブロックキー以外の文字を溜めこんで、ブロックキーが出現したときに溜めこんだ文字を先頭に付与します。
  • プロンプトがchars & block :に変わります。
  • デフォルトは無効にしています。g:uses_input_if_no_blockを無視することになるので、既存の動きを変えないほうがいいかと思いました。

VACの hoge() で囲みたい症候群 - vim 初心者の作業メモ を読んで、 同じようなことを思っている人がいるなら、オプションでできるようになれば便利かなと思った次第です。

ご検討よろしくお願いします。

zeero avatar Mar 28 '14 19:03 zeero

こんにちわ。

  • 一応, vim-operator-furround で実現できます.
    • http://d.hatena.ne.jp/syngan/20140316/1394920671
  • surround.vim を使った例ですが上記の記事で書いているように、a を使って hoge() を入力する設定をしている場合に、hage() を入力できないので中途半端な機能にならないでしょうか.

syngan avatar Mar 29 '14 12:03 syngan

コメントありがとうございます。

一応, vim-operator-furround で実現できます.

  • furroundでインプット待ちの対応をしていたのですね。yankしてからという操作が不便に思っていたので、やりたかったことはほぼ実現できているように思います。
  • ただ逆にいうとsurroundのオプションを増やすことでsurroundでもできるようになるのであれば、操作を統一できるというメリットがあるのではないでしょうか?
  • 使い分けたい人と操作を統一したい人、それぞれの選択を阻害する理由はないように思います。

a を使って hoge() を入力する設定をしている場合に、hage() を入力できないので中途半端な機能にならないでしょうか.

  • aといった短い単語でキー設定している場合、そういった事象は起こりうると思います。その場合にはおすすめできるものではないですが、それは極端なケースだと思います。
  • 専用特化することと汎用性をもたせることは時に相反するものだと思います。ブロックキーの設定をデフォルト状態で使っている人には有効であるし、オプションでユーザが選択できるようになっているのであれば、十分に機能すると思います。

zeero avatar Mar 29 '14 15:03 zeero

取り込むかどうかは、@rhysd さんの判断なので、阻害するつもりはないのですが。

それぞれの選択を阻害する理由はないように思います。

vim-operator-furround でできることをご存じないと予想したのでお知らせしただけなんですが。

それは極端なケースだと思います。

「それ」はどれを指していますか? そして「それは極稀」というのはどこで得た情報ですか?

十分に機能する

ブロックキーの設定を使っている人も使えるようになればより良いのではないですか? -> パッチ改善の余地 ブロックキー設定を使っている人は使うべきではないという方針ですか? -> ドキュメント改善の余地

syngan avatar Mar 29 '14 16:03 syngan

「それ」はどれを指していますか? そして「それは極稀」というのはどこで得た情報ですか?

「稀」なんて書いていません。 「それ」=「aといった短い単語でキー設定している場合」=「極端なケース」と表現したまでです。

ブロックキーの設定を使っている人も使えるようになればより良いのではないですか? -> パッチ改善の余地 ブロックキー設定を使っている人は使うべきではないという方針ですか? -> ドキュメント改善の余地

どちらかというと後者に近いですが、極端に短いブロックキー設定をしている場合にこの設定との相性は悪い、というレベルと思います。 「相性が悪い」といった情報をドキュメントに書くべきかどうか含めて@rhysdさんに判断してもらうのがよいのではないでしょうか。

操作を統一できるというメリットがあるのではないでしょうか?

こちらについてはどのような意見でしょうか?

zeero avatar Mar 30 '14 03:03 zeero

プルリクエストありがとうございます.

すでに vim-operator-furround で同様の機能は提供されていますが,本家にあっても良いと考えているので,マージする方向でやりたいです. xbrackes 的な機能は vim-operator-furround や #6 で需要があることは理解していましたが,ヤンクを使うのはプラグインの機能が複雑になってしまうので,「何かを囲む」以上のことをしたくなかったため見送っていました.今回のプルリクエストは良さそうに見えます.

いくつか気になった点を上記議論踏まえて

  • keeps_input_if_no_block この変数名は分かりにくいと思います.機能に名前を付けてしまって,enable_function_call_mode とか enable_xbrackets_mode 的なものにしたほうが良いかなぁと思いますが,いかがでしょうか.
  • プロンプトの chars & block :chars が何を指しているのか分からないため,これならプロンプトを変えないほうが良いと感じます.上記のように何かモード名を付けるなら block (xbrackes): のようにするのは分かりやすくて良さそうです.
  • 下記のコメント

a を使って hoge() を入力する設定をしている場合に、hage() を入力できない

これが理解できていないのですが,言及されているという記事の該当箇所がどこかを教えていただけませんでしょうか.

ちょっと今日は試す時間が無いため,後日私の手元でも動作確認してみます.

rhysd avatar Mar 30 '14 07:03 rhysd

回答ありがとうございます。前向きに検討頂けてすごく嬉しいです。

keeps_input_if_no_block この変数名は分かりにくいと思います.

uses_input_if_no_block にあわせてみたのですが、仰る通りと思います。私の意見としては enable_xbrackets_modeの方がわかりやすいかと思います。ファンクションに使い方を限定していない(ブロックキーであればなんでも同様に働く)のでenable_function_call_modeだと語弊がありそうです。 同様にプロンプトもblock (xbrackets):とするのがよいと思います。

コードレビュー頂いた中で一つ認識齟齬がありそうです。 ドキュメント中のnon-zerozeroの部分ですが、ここはnon-zeroが正しいです。オプションを有効(non-zero)にした場合にuses_input_if_no_block を無視するようになります。

a を使って hoge() を入力する設定をしている場合に、hage() を入力できない

すみません、言及箇所は私もよくわかっていません。 意味としてはブロックキーにa、ブロックに["hoge(", ")"]と登録していて、このオプションを有効にした場合、hage(と入力しようとするとhaの時点でブロックキーに該当することになり、hhoge()で囲まれてしまうということかと思います。

zeero avatar Mar 30 '14 09:03 zeero

a を使って hoge() を入力する設定をしている場合に、hage() を入力できない

これの意図は, @zeero さんの説明の通りです。

a を使って hoge() を入力する設定をしている場合

言及しているのは、上記の部分のみをさしているつもりでした。

操作を統一できるというメリット

(後者の場合に)統一したいだけなら, operator-surround-append を使わずに operator-furround-append を使えば良いだけだと思います (といっても operator-furround<CR> を要求するので動作が違いますが)

「それ」=「aといった短い単語でキー設定している場合」=「極端なケース」

稀, 失礼しました。 で、極端なんでしょうか。 surround.vim の後継として使っていたら自然な設定だと思うのですが。

surround.vim の設定例: https://github.com/t9md/vim-surround_custom_mapping

例えば、xbrackes-mode の入力待ちなら、デフォルトのカッコしか使わないとかになってくれると嬉しいかも。それでも、 a で始まる afo() では囲めないですが。

syngan avatar Mar 30 '14 12:03 syngan

いったんコードレビューの指摘とオプション名の変更に対応しました。ドキュメントについてはもう少し書きっぷりを変える必要がある認識ですが取り急ぎ。

operator-surround-append を使わずに operator-furround-append を使えば良いだけだと思います

operator-surroundのPRの話をしているのにoperator-surroundを使わなければよいというのは如何なものかと思います。

で、極端なんでしょうか。 設定可能な最小文字数で短縮登録するのであれば極端であると思います。 デフォルトで有効になっているuses_input_if_no_blockも意味を為さなくなる使い方ではないでしょうか。(再三出ている例の場合、aで囲むことができなくなる。)

例えば、xbrackes-mode の入力待ちなら、デフォルトのカッコしか使わないとかになってくれると嬉しいかも。

その場合せっかく設定できるブロックキー設定が意味を為さなくなるのではないでしょうか。オプションはコロコロと切り替えるようなものでもないと思いますので。

zeero avatar Mar 31 '14 00:03 zeero

如何なものかと思います。

前提を無視するからでしょう.

私はこの機能をいまの前者を無視した仕様で取り込むべきではないと思っています.

  • 後者(デフォルト設定使用)のみを対象とした, 統一した操作は furround で実現可能
  • 前者(カスタマイズ使用)を切り捨てている
    • すでに極端なキー設定をしている人は使えない機能である
    • このオプションを有効にして使用 -> 同じ関数で囲うことが多いのでキー設定をしようと思った場合に、この機能のために設定できるキーが制限される

surround で設定する block 数はそんなに多くないと思っています. 極端と表現されますが, 長いキー設定をする理由がわかりません.

デフォルトで有効になっているuses_input_if_no_blockも意味を為さなくなる使い方ではないでしょうか。(再三出ている例の場合、aで囲むことができなくなる。)

  • 今の動作では hoge でキー設定したら uses_input_if_no_blockh で囲えません
  • 必要なものは定義しなければ回避できます. ユーザの意思で a ではなく hoge() で囲みたいのですから何も問題はないと思います
    • a で囲みたい具体的な状況があれば教えてください
    • LaTeX 中に $ で囲みたいとかそういうときに定義追加なしで使える機能だと理解しています
  • xbrackes-mode はそもそも無効にするんですよね

その場合せっかく設定できるブロックキー設定が意味を為さなくなるのではないでしょうか。

ごめんなさい. だいぶ説明がおかしいですね. 元々、回避策として十分ではないとの認識で書いたものなので, 取り下げます.

syngan avatar Apr 01 '14 12:04 syngan

a を使って hoge() を入力する設定をしている場合に、hage() を入力できない

これの意図は, @zeero さんの説明の通りです。

ええっと,理解力が無くて申し訳ないのですが,上記のコメントを全部読んだ上で理解していないので,そうコメントされてもやはり理解できません. 推測ですが,a をキーとするブロックを定義するということで良いでしょうか?

{ 'block' : ['hoge(', ')'], 'motionwise' : ['char', 'line', 'block'], 'keys' : ['a'] }

正直,アルファベット1字とかは想定していないので何とも言えないところはありますが,その辺りはユーザのほうで調整してほしいなぁと思います. プルリク見る限りでは,この機能はデフォルトで有効にならないのでユーザは機能を理解した上で使うことを想定して良いと思いますし,furround と違ってメインの機能でないおまけ的な位置づけだと思っています.なので,この機能を enable にしたときに大きく挙動が変わるなどの複雑な挙動は実装しません(上記のような,デフォルトのブロックしか使えなくなるといった感じのもの).

これはブロックを入力した時点で確定される仕様になっている以上仕方ない気がしているのですが,何か良い案あるでしょうか?

ちなみに,もし僕の解釈がまだ間違っている場合は,困る場合の設定例を Vim script で書いていただけると一番助かります.

@syngan さんがある程度納得できる案で摺り寄せて,僕なり @zeero さんが実装修正して最終的に取り込む感じでいきたいです.

uses_input_if_no_block にあわせてみたのですが、仰る通りと思います。私の意見としては enable_xbrackets_modeの方がわかりやすいかと思います。ファンクションに使い方を限定していない(ブロックキーであればなんでも同様に働く)のでenable_function_call_modeだと語弊がありそうです。 同様にプロンプトもblock (xbrackets):とするのがよいと思います。

この点は異論ないです.

rhysd avatar Apr 01 '14 15:04 rhysd

@syngan さんがある程度納得できる案で摺り寄せて,僕なり @zeero さんが実装修正して最終的に取り込む感じでいきたいです.

わかりました。以下の案ではどうでしょうか?

  • xbracketsの文字部分とブロックを二段階で入力させる
    • はじめのプロンプトで文字を入力させる
    • Enterで次のプロンプトに移り、ブロックを入力させる

ただ、デフォルト設定のままの人には現在の実装が最適だと思います。 なので、モードを複数用意する方式(let g:operator#surround#xbrackets_mode = 2のような)にするのはどうでしょうか。

zeero avatar Apr 03 '14 02:04 zeero

ただ、デフォルト設定のままの人には現在の実装が最適だと思います。

そうですね。私は mode=2 なら使わないと思います.

ちなみに,もし僕の解釈がまだ間違っている場合は,困る場合の設定例を Vim script で書いていただけると一番助かります.

あっています。説明が下手ですいません。

これはブロックを入力した時点で確定される仕様になっている以上仕方ない気がしているのですが,何か良い案あるでしょうか?

他に私が考えていたのは prefix を付ける方法ですが、これだと @zeero さんの要望とあわないので避けていました。

https://gist.github.com/syngan/9949509 これが、説明がおかしくて取り下げたものの実装です。 (昨日追加してもらった, g:operator#surround#default_blocks を使用しています)

これなら、以下の設定(ahoge() が入力できる状態)のときに、

{ 'block' : ['hoge(', ')'], 'motionwise' : ['char', 'line', 'block'], 'keys' : ['a'] }
  • afo() は使えませんが、hage() では囲えます。 (回避策としては不十分)
    • afo() と入力したときに aechon されていませんね
  • xbrackets=0 の場合に性能影響が小さい
  • takohoge() のように既存の設定に追加して囲みたい人はいないという仮定をいれています。

syngan avatar Apr 03 '14 07:04 syngan

極端なんでしょうか。 surround.vim の後継として使っていたら自然な設定

「surround.vim は一文字しか設定できなかった」ので、その設定のまま移行すると一文字なのが一番自然だと思っていました。 (私はそれなんです。手が一文字で覚えているので長くしたくなかった)

正直,アルファベット1字とかは想定していないので何とも言えないところはありますが,その辺りはユーザのほうで調整してほしいなぁと思います.

私の設定が「極端である」が真であるなら、私の仮定がおかしい突込みなので無視してもらって構わないです。


ところで、この機能っていつ使われるか @zeero さんはイメージされていますか? furround 作っておいてあれですが、あとから関数で囲いたいと思うケースってかなり稀(かつ同じ関数であることが多い)だと思っています。

syngan avatar Apr 03 '14 07:04 syngan

コメントありがとうございます.返信遅くてすみません.

  • xbracketsの文字部分とブロックを二段階で入力させる
    • はじめのプロンプトで文字を入力させる
    • Enterで次のプロンプトに移り、ブロックを入力させる

提案ありがとうございます.本機能は「普通に関数名を入力して,その後引数部分を自分で囲む」のに比べてどれくらい便利かが勝負だと考えています.最初の提案では「関数入力→引数を囲む」が1ステップで出来ていたので普通に入力する場合に比べて良いなぁと思っていたのですが,そのメリットが潰れてしまうのがつらいところですね… ただ,「最初の実装」と「もう少し凝った実装」の2モードを実装するのは賛成です.

極端なんでしょうか。 surround.vim の後継として使っていたら自然な設定 「surround.vim は一文字しか設定できなかった」ので、その設定のまま移行すると一文字なのが一番自然だと思っていました。

極端かどうかは程度問題と使い方次第な気がするので,そこをあまり議論しても仕方ない気もします…

furround 作っておいてあれですが、あとから関数で囲いたいと思うケースってかなり稀(かつ同じ関数であることが多い)だと思っています。

なるほど,参考になります.そうすると,<Tab> キーでヤンク履歴から入力領域にペーストできる(入力内容をヤンク履歴で補完できるイメージ)とかあると良さそうですね.それなら本来の機能が複雑にならなくて良い気がします.

rhysd avatar Apr 04 '14 16:04 rhysd

https://gist.github.com/syngan/9949509 これが、説明がおかしくて取り下げたものの実装です。

コードまでよく見れていないのですが,その下の説明を読む感じ, キーがアルファベットのブロックの場合は入力の一番最初の1文字だけ判定するという感じでしょうか?

rhysd avatar Apr 04 '14 17:04 rhysd

返事遅くなっていてすみません。

極端かどうかについては@rhysdさんと同意見です。

ところで、この機能っていつ使われるか @zeero さんはイメージされていますか? furround 作っておいてあれですが、あとから関数で囲いたいと思うケースってかなり稀(かつ同じ関数であることが多い)だと思っています。

初めに書いた通り、特にVimScriptを書いているときに便利だと思っています。私の場合はすでに手放せないレベルです。 JavaやRubyなどの他の言語の場合はメソッドチェーンでつなぐことができるので処理の順番と記述の順番を一致することができるので特に必要に感じません。 VimScriptの場合は逆なのでこの機能が無いと書きづらく思います。あまり特定の関数に偏ることもなく、頻繁に使用しています。

そう考えると、b:変数での設定を優先的に見るようにできることが有効だったりしますか? autocmd FileType vim let b:enable_xbrackets_mode = 1 のイメージですが。

zeero avatar Apr 07 '14 01:04 zeero

極端かどうかは程度問題と使い方次第な気がするので,そこをあまり議論しても仕方ない気もします… 極端かどうかについては@rhysdさんと同意見です。

考慮すべきかどうかで重要かと思っていたんですが、んじゃ了解です。

(入力内容をヤンク履歴で補完できるイメージ)

ぬ。これは furround でほしい機能だ。

コードまでよく見れていないのですが,その下の説明を読む感じ, キーがアルファベットのブロックの場合は入力の一番最初の1文字だけ判定するという感じでしょうか?

一文字というか、入力の頭でマッチしない場合はユーザ定義を使用しない感じです. fo をキーとして foo() で囲う定義なら、 foh() では囲えないけど, foge() でなら囲えます。

初めに書いた通り、特にVimScriptを書いているときに便利だと思っています。

りんだんさんも zeero さんも私が思っているのと違う使い方を想定されているんですね。。 私は頭がそういう風に動かないので通常の入力ではなくあとから追加する (VimL だとデバッグ用の出力に string() が漏れてた)感じでfurroundを実装しました.

お二人の使用イメージだと、関数で囲ったあとカーソル位置は閉じかっこの場所に移動するほうが自然なんでしょうか.

仮に mode=3 として別の案を. furround と同じ動作になるのですが 改行を入力の区切りにする。入力の末尾で、定義されているものにマッチするもの以外を補完する。

  • hoge(<CR> なら hoge() で囲う
  • takoa<CR> なら takohoge() で囲う ( ahoge を囲う設定の場合)

mode=3mode=2 の場合は uses_input_if_no_block を有効にできますね。

syngan avatar Apr 07 '14 03:04 syngan

仮に mode=3 として別の案を. furround と同じ動作になるのですが 改行を入力の区切りにする。入力の末尾で、定義されているものにマッチするもの以外を補完する。

上記をmode = 2として実装する、でいいのではないかと思います。 私のmode = 2は代替案として提示して@synganさんの同意も得られなかったので取り下げます。

zeero avatar Apr 12 '14 09:04 zeero