質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Vim

VimとはUnix / Linux 系のOSに標準搭載されているターミナル上で動くテキストエディタです。

Q&A

解決済

1回答

1205閲覧

vscode の neovim プラグインで alt + j でカーソルがあたっている行の移動をしたい

asdfasfff

総合スコア3

Vim

VimとはUnix / Linux 系のOSに標準搭載されているターミナル上で動くテキストエディタです。

0グッド

0クリップ

投稿2023/04/10 13:13

vscode に neovim プラグインを入れています。

現在カーソルのあたっている行を alt + j で行の移動をしたいです。
(neovimプラグインを入れていない状態だと「alt + 矢印キー」で同じことが実現できます。)

init.lua に下記を入れても動きませんでした。

vim.api.nvim_set_keymap('n', '<A-j>', ':m .-2<CR>==', {noremap = true, silent = true}) vim.api.nvim_set_keymap('n', '<A-k>', ':m .+1<CR>==', {noremap = true, silent = true}) vim.api.nvim_set_keymap('v', '<A-j>', ":m '>+1<CR>gv=gv", {noremap = true, silent = true}) vim.api.nvim_set_keymap('v', '<A-k>', ":m '<-2<CR>gv=gv", {noremap = true, silent = true})

neovimのバージョンは 0.8.3 です。
お手数ですが、教えていただけないでしょうか。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

どこからコピペしてきたのか分かりませんが、一つずつ意味を説明しましょう。

まず、現在 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/10 14:51

編集2023/04/11 04:15
uga-rosa

総合スコア13

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

asdfasfff

2023/04/11 13:04

vim先生だぁ ご丁寧にありがとうございます!大変たすかりました
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問