マルチ選択領域機能の考察 #977

Open
koron opened this Issue Nov 10, 2016 · 9 comments

Projects

None yet

5 participants

@koron
Member
koron commented Nov 10, 2016 edited

報告の内容

http://qiita.com/t9md/items/1c2f27684703847de2be で示された Occurrence を実現するために、
マルチ領域選択 があったらどうかと考えました。
リンク先のデモではオペレーターの拡張としての実装でしたが、より一般的に考えて
Visualのような選択領域を自在に追加・削除でき、複数の選択領域を管理できる
とすれば色々なことができるのではないかと。

基本的な操作としては以下の2つです。

  1. 指定した範囲を選択領域として追加できる
  2. 指定した選択領域を削除できる

この2つの基本操作をC言語やキー操作からだけではなくVim scriptなどからも使えるようにして、
例えば、特定のパラグラフ中のあるパターンにマッチする場所を選択領域に加える、とか
既に選択領域にとなっているもののうち任意の範囲を解除する
といった高度な操作が実装可能になります。

備考

  • もちろん、全ての選択領域は Visual選択のように c, s, d などの操作対象になる、という前提です

とりあえず実現のためのコストは考えないものとして、
このような仕組みがあったと仮定して、どのようなことができるのか
それは本当に便利なのか、少し考えてみてもらえたらな、と思ってissueにしました。

@koron koron self-assigned this Nov 10, 2016
@koron
Member
koron commented Nov 10, 2016

ポイントは操作対象(=選択領域)を編集できるって点。
イメージとしては、操作対象をカートにポンポン突っ込んで、最後に精算ボタンを押すと一気に編集が終わる。
ユーザーが覚えておくことを少なくしたい、という動機。

@tyru
Member
tyru commented Nov 10, 2016

こんな発表だったんですね…すごい。
色々と便利そうなケースを妄想してみました。

  1. 単純に2つ以上のテキストを選択して「これとこのテキストが…」と口頭で説明する場合(「テキスト」=「変数」と置き換えても構いません)
  2. 選択領域もレジスタの一種とみなすと、Vz のスタックレジスタの様に複数のテキストをコピーする場合
  3. ファイル内の全ての関数を選択・ヤンク・折り畳み

ファイル内の全て部分的に対象とできる訳ですから、可能性はかなり広がると思います。

あと 3 を書いてて思ったんですが、折り畳みは「全ての関数以外を折り畳み」とかできると嬉しそうなので、それを実現するために「選択した複数の選択領域を反転(選択した領域以外を選択)」とかできると便利そうです。
これは Vim 本体で実現しなくてもプラグインでできそうですが。

@itchyny
itchyny commented Nov 10, 2016

プラグインだと https://github.com/terryma/vim-multiple-cursors こういう感じでしょうか?

@tyru
Member
tyru commented Nov 10, 2016
@deris
Member
deris commented Nov 10, 2016

マルチ領域選択欲しいです!

ちなみに追加した選択領域と、普通にvなどでvisual modeで選択した追加していない領域に対する扱い(操作)は分ける用にした方がいいですよね?

たとえば件のデモの例で言うと、textをマルチ選択した後、lineをマルチ選択していましたが、Vimでの操作を想定すると、lineを選択するためにパラグラフをvisual modeで選択してからその中のlineを絞ることが想定されますが、絞る操作の際、マルチ選択されたtextが操作対象になるとやりたい操作ができなくなります。

@haya14busa
Member
haya14busa commented Nov 10, 2016 edited

マルチ選択ではないですが, vim-mode-plus のOccurrence が解決している(と僕が思っている)問題を
別の方法で解決するvim-metarepeatというの

つくりました https://gist.github.com/haya14busa/0b3587918b97e7cbe28c7b4890beb5b7
(edit: plugin https://github.com/haya14busa/vim-metarepeat)

gif はvim-mode-plusの最後から2番目のgif 相当で3つの導入された機能が全部含まれてる.

anim

This is 1st paragraph text.
2nd line also include text text text.
3rd line include text text text

This is 2nd paragraph text.
2nd line also include text text text.
3rd line include text text text
4th text
  1. gg0/te (text に移動)
  2. *j0wgo (text を@/に入れた上lineに移動し,lineもpreset)
  3. cgnabc (最初に1つの対象に対して操作する)
  4. ggVjjjjg. (最初の5行に対して↑の操作を適用)
  5. jjg.Vj (2nd paragrap の2nd line を飛ばして残りの2行に対して操作を適用)
    (そういえば vim-asterisk いれてた)

あくまでdot-repeatを拡張して似た操作を実現する目的.

そもそもvim-mode-plusが解決してる問題は端的に言うと

ドットリピート便利だけどドットリピート自体を繰り返すのが面倒くさいよね?

ということだと思う.

普通にvimの機能で似たようなことをすると{operator} + gn + ドットリピート x N回 (または置換の操作に限るなら:s)
でサンプルのような操作はできる.しかし何回ドットリピートうたなあかんねん!めんどいやろ!って気持ちだとおもう.

vim-mode-plus はそこで "occurence modifier" という概念を導入して,
さらにpreset-occurence と persistent-selection を導入して操作対象を増やしたり,操作範囲を変更できるようにしてる.

もちろん先に選択したり, multiple-curosr 機能を使うことによってインテラクティブに編集できるという強みもある.
けどこれはVimでやるのはツライ...のでこれは一旦僕が解決したい問題としては置いておく.
(そもそもvim-mode-plusの機能以前に普通の operator + textobj も似たような問題がある)

そこでドットリピートを対象のtextobj内のそれぞれのoccurence相当に適用する手段があればドットリピートをリピートするのが面倒くさい問題は
解決するかなぁと思って作ったのが vim-metarepeat.
persistent-selection 機能については選択する際に同時に操作を行ってしまえばokというスタンス.
これだと個別にundoできるという強みもある(逆にundoが複数できるともいえるけど)

vim-mode-plusと比べた際の欠点としては操作が2度(以上)行われる(最初のoperationとg.)ってところだけど,
Vim の ドットで編集を繰り返せる機能を正統進化させると割とこんな感じかなと思いました.
途中で普通のドットリピートを挟むこともできたりして便利.
(実はvimconf懇親会でぼそっとvim-mode-plusの提供してる新機能が本当にVimライクな機能なのかわからない...みたいなことを話したんですが,_僕が思ってる_Vimっぽい機能があくまで操作->対象という順番なのにたいして,vim-mode-plus の複数選択->インテラクティブ操作はatom+vimの思想っぽいと思った.どっちがいいとかではなく.)

まぁもちろん突貫工事でつくったものでアレな部分もありそうだし,完全にvim-mode-plusの機能をバックポートしたとは思ってませんが,こういう問題解決もあるのではというアレです.

マルチ選択領域機能 がいらないとかいうわけではなくて便利だとは思ってます.

@deris
Member
deris commented Nov 10, 2016

仕事早すぎワロタ 😄 👍

@koron
Member
koron commented Nov 11, 2016

ドットリピート便利だけどドットリピート自体を繰り返すのが面倒くさいよね?

この説明はなるほどと思いました。 👍

@koron
Member
koron commented Nov 11, 2016

ちなみに追加した選択領域と、普通にvなどでvisual modeで選択した追加していない領域に対する扱い(操作)は分ける用にした方がいいですよね?

たとえば件のデモの例で言うと、textをマルチ選択した後、lineをマルチ選択していましたが、Vimでの操作を想定すると、lineを選択するためにパラグラフをvisual modeで選択してからその中のlineを絞ることが想定されますが、絞る操作の際、マルチ選択されたtextが操作対象になるとやりたい操作ができなくなります。

今のところ、操作としては分けたほうが良いと思っていますが、
実装は流用するところが多くてもよいのかなと。

例を示すと、マルチ選択領域のうち最初のもの(0番目)をプライマリとしてVisual選択として利用。
そこから何かしらの操作を経て1番目以降の選択領域に変換追加、
もしくは0番目を使って1番目以降の選択領域を変更、
みたいなことができないかなぁと。

完全に妄想です。

@tyru tyru referenced this issue in tyru/karakuri.vim Nov 17, 2016
Open

Write sample codes #7

0 of 2 tasks complete
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment