0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Zed vim modeの操作をNeovimに持ち込んでみる

0
Last updated at Posted at 2026-08-09

Zed vim modeの指をそのままNeovimに持ってきた

image.png

前に「すみませんZedが最強でした」という記事を書きましたが、今はNeovimも使っています。Zedを見限ったわけではなく、SSH先でも同じ指で作業したいからです。

Zedのvimモードは素のvimに独自バインド(g /] cd oなど)を足しています。出典は公式のassets/keymaps/vim.json。この記事はそれらをNeovimに移植した私の設定集です。


Gitハンク操作(一番の目玉)

ZedはdオペレータにGit操作をぶら下げています。doでハンク展開、dOでステージ、duでステージして次へ、dpで変更を捨てる。レビューしながらdu du duと叩けばコミットが組めます。

gitsigns.nvimのon_attachで同じキーに割り当てました。

-- Navigation (Zed: ]c / [c)
map("n", "]c", gs.next_hunk, "Next Change")
map("n", "[c", gs.prev_hunk, "Prev Change")
-- Expand diff hunk (Zed: do)
map("n", "do", gs.preview_hunk, "Expand Diff Hunk")

-- Toggle staged (Zed: dO)
map("n", "dO", gs.stage_hunk, "Toggle Staged")

-- Stage and next (Zed: du)
map("n", "du", function()
  gs.stage_hunk()
  gs.next_hunk()
end, "Stage and Next")

-- Unstage and next (Zed: dU)
map("n", "dU", function()
  gs.undo_stage_hunk()
  gs.next_hunk()
end, "Unstage and Next")

-- Restore change (Zed: dp)
map("n", "dp", gs.reset_hunk, "Restore Change")

-- Visual mode: line range for stage / restore
map("v", "dO", function() gs.stage_hunk({ vim.fn.line("."), vim.fn.line("v") }) end, "Toggle Staged")
map("v", "dp", function() gs.reset_hunk({ vim.fn.line("."), vim.fn.line("v") }) end, "Restore Change")

Zedのgit::StageAndNextは1コマンドですが、gitsignsには無いのでstage_hunk()next_hunk()を並べています。


移動・検索

Neovim Zed
H / L^ / $ shift-h / shift-l(自分のkeymap.json
<C-p> → find files ctrl-p
g/ → live grep g /
gd → definition g d
<F2> → rename f2
<C-s> → save ctrl-s
vim.keymap.set({ "n", "v" }, "H", "^", { desc = "Go to line start" })
vim.keymap.set({ "n", "v" }, "L", "$", { desc = "Go to line end" })
vim.keymap.set("n", "g/", builtin.live_grep, { desc = "Project Search" })
vim.keymap.set({ "n", "i", "v" }, "<C-s>", "<cmd>w<CR><Esc>", { desc = "Save" })

g/はZedのデフォルトなので、Zedユーザーの指は無意識に叩きます。Neovimでは何も起きないので自分で生やす必要があります。


leader系

Zed時代にkeymap.jsonへ書いていたspace系。

// ~/.config/zed/keymap.json
"space r n": "editor::Rename",
"space c a": "editor::ToggleCodeActions",
"space f": "editor::Format",
"space e": "project_panel::ToggleFocus",
"space g d": "git_panel::ToggleFocus",
"space space": "vim::HelixJumpToWord"

もともとNeovim界の流儀(LazyVim等)から拾ってきたものなので、そのまま<leader>に戻すだけでした。

map("<leader>rn", vim.lsp.buf.rename, "Rename")
map("<leader>ca", vim.lsp.buf.code_action, "Code Action")
map("<leader>f", function()
  vim.lsp.buf.format({ async = true })
end, "Format")

which-keyも両方で有効にしています。Zedのwhich_key.delay_ms: 1000は遅すぎたので、Neovim側はdelay = 500


Ctrl+Shift系は諦めた

Zedではctrl-shift-cにコピーを割り当てていましたが、ターミナルのNeovimでは移植できません。

  • 古典的な端末ではCtrl+CCtrl+Shift+Cが同じバイト(0x03)になりShiftが消える
  • kitty keyboard protocolで区別できる端末もあるが、tmuxやGNOME Terminal系で崩れる
  • そもそもCtrl+Shift+Cは端末エミュレータ自身のコピーに先に食われる

なので**Ctrl+Shift+*前提の操作は捨てて、leader系と単発Ctrl系に寄せる**方針にしました。コピーは遊んでいた<C-c>に行ヤンクを割り当てて代替。

vim.keymap.set({ "n" }, "<C-c>", "yy", { desc = "Yank line" })

space spaceジャンプはhop.nvimで日本語対応

Zedのvim::HelixJumpToWord(画面内の単語先頭にラベルを振って飛ぶ)はhop.nvimで再現。ただしhopの標準は\k\+区切りなので、日本語だと

私は特別強いエンジニアではありません

が丸ごと1候補になります。文字種の切り替わりを単語境界にする正規表現を書きました。

{
  "<leader><leader>",
  mode = { "n", "x" },
  function()
    local hop = require("hop")
    -- 漢字 / カタカナ / 英数字それぞれの連なりの先頭を候補にする。
    -- ひらがなは候補から外す: 助詞や送り仮名まで拾うと候補が倍増し、
    -- ラベルが 2 桁化して本文を読めなくする割に足場としての価値が低い。
    -- カタカナ類には長音符「ー」を含める(含めないと「アップロード」が 2 候補に割れる)。
    local re = vim.regex("\\v<\\w+|[一-龥]+|[ァ-ヶー]+")
    hop.hint_with_regex({
      -- oneshot=false: 1 行につき複数の候補を拾う
      oneshot = false,
      match = function(s)
        return re:match_str(s)
      end,
    }, hop.opts)
  end,
  desc = "Hop: Jump to word (JP aware)",
},

ポイントは2つ。

  • ひらがなを候補から外す:助詞や送り仮名まで拾うとラベルが2桁になって本文が読めない。「は」に飛びたい人間はいない
  • 長音符「ー」をカタカナに含める:忘れると「アップロード」が「アップロ」+「ド」に割れる

日本語の文章編集に関しては、正直Zedより快適になりました。

vim::HelixJumpToWordはジャンプ先がスカスカだが、hop.nvimは設定次第で文字境界を増やせる)
Screenshot From 2026-08-09 14-55-41.png

image.png


キー以外に揃えた挙動

Zedのdefault.jsonを根拠に合わせた設定。

Neovim Zedの設定 意味
clipboard = "unnamedplus" vim.use_system_clipboard: "always" ヤンクがそのままOSクリップボードへ
updatetime = 250 + CursorHoldで診断float hover_popover_delay: 300 カーソルを止めると情報が出る
ignorecasesmartcase search.case_sensitive: false / use_smartcase_search 検索の当たり方
relativenumber vim.toggle_relative_line_numbers: true 10jの数えやすさ
BufWritePreでフォーマット format_on_save 保存の副作用
vim.api.nvim_create_autocmd("CursorHold", {
  callback = function()
    vim.diagnostic.open_float(nil, { focusable = false, scope = "cursor" })
  end,
})
0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?