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

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

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

Comments

Projects
None yet
7 participants
@koron
Member

koron commented Nov 10, 2016

報告の内容

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

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

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

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

備考

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

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

@koron

This comment has been minimized.

Show comment
Hide comment
@koron

koron Nov 10, 2016

Member

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

Member

koron commented Nov 10, 2016

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

@tyru

This comment has been minimized.

Show comment
Hide comment
@tyru

tyru Nov 10, 2016

Member

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

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

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

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

Member

tyru commented Nov 10, 2016

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

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

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

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

@itchyny

This comment has been minimized.

Show comment
Hide comment
@itchyny

itchyny Nov 10, 2016

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

itchyny commented Nov 10, 2016

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

@tyru

This comment has been minimized.

Show comment
Hide comment
@tyru
Member

tyru commented Nov 10, 2016

@deris

This comment has been minimized.

Show comment
Hide comment
@deris

deris Nov 10, 2016

Member

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

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

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

Member

deris commented Nov 10, 2016

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

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

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

@haya14busa

This comment has been minimized.

Show comment
Hide comment
@haya14busa

haya14busa Nov 10, 2016

Member

マルチ選択ではないですが, 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の機能をバックポートしたとは思ってませんが,こういう問題解決もあるのではというアレです.

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

Member

haya14busa commented Nov 10, 2016

マルチ選択ではないですが, 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

This comment has been minimized.

Show comment
Hide comment
@deris

deris Nov 10, 2016

Member

仕事早すぎワロタ 😄 👍

Member

deris commented Nov 10, 2016

仕事早すぎワロタ 😄 👍

@koron

This comment has been minimized.

Show comment
Hide comment
@koron

koron Nov 11, 2016

Member

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

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

Member

koron commented Nov 11, 2016

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

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

@koron

This comment has been minimized.

Show comment
Hide comment
@koron

koron Nov 11, 2016

Member

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

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

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

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

完全に妄想です。

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 Nov 17, 2016

Open

Write sample codes #7

0 of 2 tasks complete
@t9md

This comment has been minimized.

Show comment
Hide comment
@t9md

t9md Nov 5, 2017

今更のコメントですが、Occurrence の機能。@koron さんの指摘通り、マルチカーソル、マルチセレクションあるとやりやすいです。
vimconf2017 のここのスライドで概要書きました。当日はこのスライド説明してませんが。

ターゲット(a-function) の選択範囲の中の occurrence(マーカー) を選択し直した時点で、シングルセレクションからマルチセレクションになり、後は c なり d なりの operator が apply される、という流れです。

<追記>

Atom の vim-mode-plus で occurrence を導入した背景

  1. マルチセレクション自体が便利

cmd-d で次の occurrence にセレクションを追加, cmd-alt-g で ファイル内の全 occurrence にセレクションを追加、という機能は元々 Atom がネイティブでサポートしているもので便利。Sublime Text, VSCode 等、マルチセレクションをサポートしてるエディタはこの機能は持っているはず。

  1. ただ、いちいち cmd-d でセレクションを追加するのが面倒

面倒。imperative(not declarative). この関数内の foo のみ対象にセレクションを追加したい時、cmd-alt-g はバッファ全体を対象にしちゃうし、cmd-dfoo の数だけ何度も cmd-d 打たなきゃならんし。

  1. occurrence 誕生

occurrence をマークする。マークはバッファ全体を対象に行われる。
通常のオペレーション時、c i p 等、 i pのターゲット範囲にマーカーが含まれていれば、マーカーを選択し直す(ここでマルチセレクションになる)、あとは普通に c が各々のセレクションに適用される。

occurrence として マークする手段として2つの方法を用意しており、

  • g o, g O(subword 用) は normal モードで使える preset-occurrence というコマンド
  • o, Oc o i p 等として、使える Operator modifier. (短縮形として c o p も許すようなキーマップを定義しているが、ただの便利キーマップ設定であり実装には無関係)

t9md commented Nov 5, 2017

今更のコメントですが、Occurrence の機能。@koron さんの指摘通り、マルチカーソル、マルチセレクションあるとやりやすいです。
vimconf2017 のここのスライドで概要書きました。当日はこのスライド説明してませんが。

ターゲット(a-function) の選択範囲の中の occurrence(マーカー) を選択し直した時点で、シングルセレクションからマルチセレクションになり、後は c なり d なりの operator が apply される、という流れです。

<追記>

Atom の vim-mode-plus で occurrence を導入した背景

  1. マルチセレクション自体が便利

cmd-d で次の occurrence にセレクションを追加, cmd-alt-g で ファイル内の全 occurrence にセレクションを追加、という機能は元々 Atom がネイティブでサポートしているもので便利。Sublime Text, VSCode 等、マルチセレクションをサポートしてるエディタはこの機能は持っているはず。

  1. ただ、いちいち cmd-d でセレクションを追加するのが面倒

面倒。imperative(not declarative). この関数内の foo のみ対象にセレクションを追加したい時、cmd-alt-g はバッファ全体を対象にしちゃうし、cmd-dfoo の数だけ何度も cmd-d 打たなきゃならんし。

  1. occurrence 誕生

occurrence をマークする。マークはバッファ全体を対象に行われる。
通常のオペレーション時、c i p 等、 i pのターゲット範囲にマーカーが含まれていれば、マーカーを選択し直す(ここでマルチセレクションになる)、あとは普通に c が各々のセレクションに適用される。

occurrence として マークする手段として2つの方法を用意しており、

  • g o, g O(subword 用) は normal モードで使える preset-occurrence というコマンド
  • o, Oc o i p 等として、使える Operator modifier. (短縮形として c o p も許すようなキーマップを定義しているが、ただの便利キーマップ設定であり実装には無関係)
@machakann

This comment has been minimized.

Show comment
Hide comment
@machakann

machakann Feb 3, 2018

Vim script でできる範囲ですが、実験的なものを書きました。興味のある方がいらっしゃれば動くか試してもらえると嬉しいです。

machakann commented Feb 3, 2018

Vim script でできる範囲ですが、実験的なものを書きました。興味のある方がいらっしゃれば動くか試してもらえると嬉しいです。

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