From 5d5367ed00c22cc194b8a2411b2b4b828751003b Mon Sep 17 00:00:00 2001 From: nsfisis Date: Wed, 31 Aug 2022 23:30:53 +0900 Subject: update hugo --- .../vim-swap-order-of-selected-lines/index.html | 46 +++++++++++----------- 1 file changed, 23 insertions(+), 23 deletions(-) (limited to 'docs/posts/2021-10-02/vim-swap-order-of-selected-lines/index.html') diff --git a/docs/posts/2021-10-02/vim-swap-order-of-selected-lines/index.html b/docs/posts/2021-10-02/vim-swap-order-of-selected-lines/index.html index 4b530b3..eac828f 100644 --- a/docs/posts/2021-10-02/vim-swap-order-of-selected-lines/index.html +++ b/docs/posts/2021-10-02/vim-swap-order-of-selected-lines/index.html @@ -15,7 +15,7 @@ - + @@ -72,10 +72,10 @@ Huge version without GUI.

:g/^/m0 のように組み合わせると、「すべての行を1行ずつ 0行目(1行目の上)に動かす」という動きをする。これは確かに行の入れ替えになっている。

なお、:g/^/m0 は全ての行を入れ替えるが、:N,Mg/^/mN-1 とすることで N行目から M行目を処理範囲とするよう拡張できる。手でこれを入力するわけにはいかないので、次のようなコマンドを用意する。

-
command! -bar -range=%
-    \ Reverse
-    \ <line1>,<line2>g/^/m<line1>-1
-

これは望みの動作をするが、実際に実行してみると全行がハイライトされてしまう。次節で詳細を述べる。

+
command! -bar -range=%
+    \ Reverse
+    \ <line1>,<line2>g/^/m<line1>-1
+

これは望みの動作をするが、実際に実行してみると全行がハイライトされてしまう。次節で詳細を述べる。

:g/^/m0 の問題点

:global コマンドは各行に対してマッチングを行う際、現在の検索パターンを上書きしてしまう。^ は行の先頭にマッチするため、結果として全ての行がハイライトされてしまう。'hlsearch' オプションを無効にしている場合その限りではないが、その場合でも直前の検索パターンが失われてしまうと n コマンドなどの際に不便である。

@@ -87,14 +87,14 @@ Huge version without GUI.

より簡潔な方法を見つけたので次節に追記した

前述した :Reverse コマンドの定義を少し変えて、次のようにする:

-
function! s:reverse_lines(from, to) abort
-    execute printf("%d,%dg/^/m%d", a:from, a:to, a:from - 1)
-endfunction
-
-command! -bar -range=%
-    \ Reverse
-    \ call <SID>reverse_lines(<line1>, <line2>)
-

実行しているコマンドが変わったわけではないが、関数呼び出しを経由するようにした。これだけで前述の問題が解決する。

+
function! s:reverse_lines(from, to) abort
+    execute printf("%d,%dg/^/m%d", a:from, a:to, a:from - 1)
+endfunction
+
+command! -bar -range=%
+    \ Reverse
+    \ call <SID>reverse_lines(<line1>, <line2>)
+

実行しているコマンドが変わったわけではないが、関数呼び出しを経由するようにした。これだけで前述の問題が解決する。

この理由は、ユーザー定義関数を実行する際は検索パターンが一度保存され、実行が終了したあと復元されるため。結果として検索パターンが ^ で上書きされることがなくなる。

Vim のヘルプから該当箇所を引用する (強調は筆者による)。

@@ -118,20 +118,20 @@ executing autocommands |autocmd-searchpat|.

[2020/9/28追記] より簡潔な方法を見つけたため追記する

-
command! -bar -range=%
-    \ Reverse
-    \ keeppatterns <line1>,<line2>g/^/m<line1>-1
-

まさにこのための Exコマンド、:keeppatterns が存在する。:keeppatterns {command} のように使い、読んで字の如く、後ろに続く Exコマンドを「現在の検索パターンを保ったまま」実行する。はるかに分かりやすく意図を表現できる。

+
command! -bar -range=%
+    \ Reverse
+    \ keeppatterns <line1>,<line2>g/^/m<line1>-1
+

まさにこのための Exコマンド、:keeppatterns が存在する。:keeppatterns {command} のように使い、読んで字の如く、後ろに続く Exコマンドを「現在の検索パターンを保ったまま」実行する。はるかに分かりやすく意図を表現できる。

:h :keeppatterns

コピペ用再掲

-
" License: Public Domain
-
-command! -bar -range=%
-    \ Reverse
-    \ keeppatterns <line1>,<line2>g/^/m<line1>-1
-
+
" License: Public Domain
+
+command! -bar -range=%
+    \ Reverse
+    \ keeppatterns <line1>,<line2>g/^/m<line1>-1
+