どこからコピペしてきたのか分かりませんが、一つずつ意味を説明しましょう。
まず、現在 Lua からキーマップを定義するなら vim.keymap.set()
を使った方が良いです。wrap されているので nvim_set_keymap()
を直接触るより嵌ることは少ないでしょう。
次に、:m
は :move
コマンドの短縮形です。
help
1:[range]m[ove] {address} *:m* *:mo* *:move* *E134*
2 Move the lines given by [range] to below the line
3 given by {address}.
{address}
として指定した行の下に、[range]
で選択した行を移動させます。[range]
に何も指定しなければカーソル行1行を選択しているのと同じ動作になります。
{address}
の説明はこのようにあります。
help
1Line numbers may be specified with: *:range* *{address}*
2 {number} an absolute line number *E1247*
3 . the current line *:.*
4 $ the last line in the file *:$*
5 % equal to 1,$ (the entire file) *:%*
6 't position of mark t (lowercase) *:'*
7 'T position of mark T (uppercase); when the mark is in
8 another file it cannot be used in a range
9 /{pattern}[/] the next line where {pattern} matches *:/*
10 also see |:range-pattern| below
11 ?{pattern}[?] the previous line where {pattern} matches *:?*
12 also see |:range-pattern| below
13 \/ the next line where the previously used search
14 pattern matches
15 \? the previous line where the previously used search
16 pattern matches
17 \& the next line where the previously used substitute
18 pattern matches
つまり、:m .
は、「現在カーソルのある行を、現在の行の下に移動させる」という意味の Ex コマンドになり、何も起きません。
そして {adress}
は .
や $
のような特殊な文字を絶対行に変換したのち、式として評価されます。ですので、:m .+1
は、「現在カーソルのある行を、{現在の行+1}の下に移動させる」ことになります。実際に試してみるといいでしょう。
少し分かりにくいかもしれないので、具体例を出しておきます。
現在4行目にカーソルがあるとします。このとき、:m .+1
は :m 5
と等価です。これの意味は、「現在の4行目を、現在の5行目の下に動かす」です。ですので、結果として現在カーソルのある行が一つ下に動いたように見えます。上に動かす場合は -2 になることに気を付けて下さい。
つまり、ノーマルモードでのマッピングは以下のようになります。
lua
1vim.keymap.set("n", "<M-j>", "<Cmd>move .+1<CR>")
2vim.keymap.set("n", "<M-k>", "<Cmd>move .-2<CR>")
ノーマルモードから Ex コマンドを呼ぶ場合は、基本的に <Cmd>
を使うべきです。これについても語るとさらに長くなるので省略します。
次にビジュアルモードに移ります。
基本的には変わりませんが、range
と '<
, '>
について少し触れておきます。
ビジュアルモードで :
を打ちコマンドモードに入ると、勝手に :'<,'>
と入力されますよね。これは謎の呪文ではなく、意味があります。
先程の :move
コマンドの help をもう一度引用しましょう。
help
1:[range]m[ove] {address} *:m* *:mo* *:move* *E134*
2 Move the lines given by [range] to below the line
3 given by {address}.
さて。適当なファイルを開き :3,5move 6
というコマンドを実行してみてください。どうなるでしょうか。
3-5行目が6行目の下に移動しましたね?
rangeで複数行を指定するときは、:{start},{final}
という記法を使います。
つまり :'<,'>
は、'<
から '>
までという意味になるわけです。
'<
, '>
はそれぞれ、直前にビジュアルモードで選択していた範囲の先頭と最後を意味します。
ですので :'<,'>
は選択範囲全域を表します。
というわけで、ビジュアルモードでのマッピングは以下のようになります。
lua
1vim.keymap.set("x", "<M-j>", ":move '>+1<CR>gv")
2vim.keymap.set("x", "<M-k>", ":move '<-2<CR>gv")
モード指定には v
ではなく x
を使いましょう。歴史的経緯により v
はビジュアルモード+セレクトモードを意味します。
<Cmd>
ではなく :
なのは '<,'>
を機能させるためです。<Cmd>
はモードの変更を引き起こさないため、直前の選択範囲が更新されません。
gv
は、直前の選択範囲を再び選択します。これにより連続での移動が可能になります。
元の設定では =
でインデントを揃えるようにしていますね。
どうせ移動中は文法的に不正な崩れた状態になるでしょうし、無くてもいいだろうと思い省きました。
モダンに、適宜 prettier などのフォーマッタをかければいいでしょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2023/04/11 13:04