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

reletivenumber の仕様が、:copy などの 行数指定コマンド類と 非常に相性が悪い #1432

Open
KSR-Yasuda opened this issue Jun 7, 2024 · 8 comments

Comments

@KSR-Yasuda
Copy link

内容

relativenumber (行数表示を、相対行数 で表示する) の設定について、
:copy 等の 行数を指定するコマンドと 非常に相性が悪い挙動をする気がします。

これらの挙動、ちょっと使いづらいような気がしますが、どうでしょうか?

範囲指定 → コマンド の際、選択範囲 末尾 基準の行数を表示する

Shift-V で、ビジュアルモードの 複数行数指定している際 の状況です。

この際、:'<,'> copy +N (N行目 後 にコピー) を実行する際の基準行は、
選択範囲の最初 (= '<) です。

しかし、選択状態から、: で コマンド入力しようとすると、
カーソルが 選択範囲 末尾 に移動するため、relativenumber の表示は、末尾基準 となります
(コマンドウィンドウに :'<,'> と入力されるので、最後の '> の位置 に移る、という意図?)。

vim_rnu_range_20240607_104635

そのため、relativenumber表示 をそのまま使うと、意図しないところにコピーされます。

実現方法

  • 範囲指定のコマンド実行 の際に、カーソル行を、基準行の先頭 に移動する

Pros 良くなる点

  • コマンド実行の際に、カーソル配置 と 相対行数指定の基準行 がズレない

Cons 悪くなる点

relativeの指定行 までの間に fold範囲 があると、行数指定がズレる

相対行数での指定の際に、指定行の間に foldしている領域 が挟まる場合です。

以下、L10 ~ L14, L20 ~ L29 の 2つのfold がある状態で、
カーソルは、それより前の L5 にいます。

vim_rnu_fold_20240607_105349

ここで、2つ目のfold範囲 L20 ~ L29 をコピーするため、
:+11 co -1 を実行すると、L16 (最初の fold を開いた状態での、5 + 11 = 16行目) がコピーされます。

絶対行数指定で、:20 co -1 をすると、L20 ~ L29 の fold範囲全体 がコピーされますが、
そのつもりで実施すると、おかしな挙動になります。

実現方法

  • 相対行数指定の際、foldの状況 を加味する

Pros 良くなる点

  • fold表示と、相対行数指定 が 一致する

Cons 悪くなる点

Vimのバージョン

  • Vim v9.1.445

OSの種類/ディストリ/バージョン

  • Windows 10 Pro 23H2 (v10.0.22631.3593)
    • MSYS2 (msys2-runtime v3.5.3-3)

その他

@h-east
Copy link
Member

h-east commented Jun 7, 2024

前半のみ回答します。

しかし、選択状態から、: で コマンド入力しようとすると、
カーソルが 選択範囲 末尾 に移動するため、relativenumber の表示は、末尾基準 となります
(コマンドウィンドウに :'<,'> と入力されるので、最後の '> の位置 に移る、という意図?)。

いえ、:を押す前にカーソルがビジュアル選択領域の最終行にあるのでそのような挙動になります。
ビジュアル選択領域を変えずにカーソル位置をビジュアル選択領域の先頭行/最終行に移動させる o コマンドがありますので、そちらを使用すると所望の動作にできると思います。(:h v_o)

@h-east
Copy link
Member

h-east commented Jun 7, 2024

後半の折り畳みの動作は、現状では仕様なのかな?って思いました。

:+11 co -1 を省略せずに書くと、:.+11,.+11 co -1 で、これの範囲絡みのhelpが以下でしょうか。
で、今回の折り畳みの件に関連する部分を抜粋しています。

:h cmdline-ranges
:h :.
:h :range-offset
:h :range-closed-fold
コンマの後の行番号が閉じた折り畳みにある場合、折り畳みの最後の行に調整されるた
め、折り畳み全体が含まれる。

数値を追加する場合は、折り畳みの最後の行を調整した後に追加される。これは、これ
らの行が範囲に追加で含まれることを意味する。

~~(64行ほど省略)~~

折り畳みと範囲指定

折り畳みがアクティブなときは、閉じられた折り畳み全体を含むように範囲が切り上げ
/切り下げられる。|fold-behavior| を参照。

相対行番号指定時は、それまでの行に折り畳みがあったら、折り畳まれている行数を加味して指定しないといけない気がします。
今回の場合、:.+5-1+11copy-1 つまり :+15copy-1 とすれば所望の動作になるということかと思います。
(+5は1つ目の折り畳まれている行数)
(-1は1つ目の折り畳み表示行数)

でも、そんなの面倒くさいので、目的の行数までの折り畳みはopenしておく運用でカバーする感じでしょうか。


### 相対行数指定の際、foldの状況 を加味する

'relativenumber' のfold加味対応、アリだと思います。
直ぐにではないですが、調査&検討してみます。

@thinca
Copy link
Member

thinca commented Jun 8, 2024

'relativenumber' は元々 <count>j などの際に使うことを想定して作られたので、fold を加味してしまうと今度はそちらで都合が悪くなってしまいます。
例えば、コマンドラインモードに入ったらその間だけ 'relativenumber' をオフにする、などはどうでしょう?相対行ではなく絶対行での指定になるので大きな行数の場合は入力が面倒かもしれないですが、混乱はなくなるかなと思います。

augroup cmdline-norelativenumber
  autocmd!
  autocmd CmdlineEnter : let s:save_relativenumber = &l:relativenumber
  \                    | setlocal norelativenumber
  \                    | redraw
  autocmd CmdlineLeave : let &l:relativenumber = s:save_relativenumber
augroup END

@KSR-Yasuda
Copy link
Author

しかし、選択状態から、: で コマンド入力しようとすると、
カーソルが 選択範囲 末尾 に移動するため、relativenumber の表示は、末尾基準 となります
(コマンドウィンドウに :'<,'> と入力されるので、最後の '> の位置 に移る、という意図?)。

いえ、:を押す前にカーソルがビジュアル選択領域の最終行にあるのでそのような挙動になります。 ビジュアル選択領域を変えずにカーソル位置をビジュアル選択領域の先頭行/最終行に移動させる o コマンドがありますので、そちらを使用すると所望の動作にできると思います。(:h v_o)

@h-east こちらの 前半、visual選択時の : 押下直後の relativenumber表示 についてのコメントですが、
選択範囲中で、カーソルを oキーで 範囲冒頭 ('<, 上記スクショ 10行目) に移動した状態でも、
そこで : を押すと、範囲末尾 ('>, 上記スクショ 14行目) を基準として relativenumber) が出ている表示になります (上記スクショの表示)。

具体的には、以下のショートカットキー操作 で確認しています:

10gg        # 10行目 に移動
Shift-V     # Visual選択 (行) モード
4j          # 10 ~ 14行目 を選択 (カーソル 末尾 '>, 14行目)
o           # 選択範囲先頭 '<, 10行目 に カーソル移動 (relativenumber表示、選択範囲 先頭 '<, 10行目 基準)
:           # コマンド入力 開始 (relativenumber表示、選択範囲 末尾 '>, 14行目 基準)

そのわりに、:'<,'> copy +N のコマンドの +N行目 の基準行数は 選択範囲冒頭 ('<, 上記スクショ 10行目) なので、
冒頭 + N行目 の次にコピーされます (上記スクショ 10 + N行目)。
なので、:押下時の relativenumber基準行 (= カーソル?) の強制移動 だけ、おかしい感じです。

こちらの環境 特有の現象でしょうか?

@KSR-Yasuda
Copy link
Author

2番目、折り畳み時のコマンド実行での相対行数 については、

@h-east

コンマの後の行番号が閉じた折り畳みにある場合、折り畳みの最後の行に調整されるた
め、折り畳み全体が含まれる。

数値を追加する場合は、折り畳みの最後の行を調整した後に追加される。これは、これ
らの行が範囲に追加で含まれることを意味する。
折り畳みと範囲指定

折り畳みがアクティブなときは、閉じられた折り畳み全体を含むように範囲が切り上げ
/切り下げられる。|fold-behavior| を参照。

このあたり、
折り畳み行 10 ~ 14 行 に対して、折り畳み全体 に範囲拡大する仕様 ですよね (e.g. :10p = :10,14p).

しかし、:copy先 などの指定だと、
『折り畳みの最後の行に調整』されてるのか、むしろ 余計に混乱してきました。

具体的には、以下のとき、

:new
:0 r !seq 1 100
:10,14 fold             " 10 ~ 14行目 を fold
:10 foldc               " fold閉じる

:5                      " 5行目 に移動
:.co+5                  " 5行目 の内容を、5行目 + 5行目 に コピー

実行結果としては、foldを開いて確認すると、
5行目 が、絶対行数 10行目 にコピーされました
(これは、絶対行数指定 :.co10 でやっても同様)。

5           # コマンド実行時 カーソル
6
7
8
9
10          # fold冒頭
5           # ← ここにコピー
11
12
13
14          # fold末尾
15

なので、10 ~ 14行目の折り畳み に対する、『折り畳みの最後の行に調整』、
つまり、:.co+5, :.co10 を、折り畳み末尾 :.co14 (= 折り畳みの次の行 にコピー)
には 調整していない挙動です。

相対行番号指定時は、それまでの行に折り畳みがあったら、折り畳まれている行数を加味して指定しないといけない気がします。

上記の説明だと、
『折り畳んでいる状態 を考慮して、vim側で 勝手に 行数を加味してくれる』という説明のように受け取りました。

『ユーザ側が 折り畳み行数を 自分で加味しないといけない』とは むしろ逆の説明、と思ったのですが、
理解 誤っているでしょうか?

基本的には vim側で勝手に加味してくれる挙動 の実感ですが、
:copy, :move については やや違っているような気がしています。

@KSR-Yasuda
Copy link
Author

@thinca

例えば、コマンドラインモードに入ったらその間だけ 'relativenumber' をオフにする、などはどうでしょう?

たしかに、現状だと、相対指定 避けたほうが無難そうですね。
ありがとうございます。

@h-east
Copy link
Member

h-east commented Jun 10, 2024

なので、:押下時の relativenumber基準行 (= カーソル?) の強制移動 だけ、おかしい感じです。

こちらの環境 特有の現象でしょうか?

うーん、こちらと現象違いますね。
一度、vimrcやプラグインを読み込まない状態で確認してもらえますか?

vim --clean

@KSR-Yasuda
Copy link
Author

@h-east 失礼しました、
こちらは、traces.vim のプラグインのせいでした。

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