neo-treeで選択したディレクトリでの新タブを開いたりgit操作を爆速で行おう！[neovim + neo-tree + lazygit ]

みなさんは快適なVimライフを送っていますか？また，ファイル操作，ディレクトリ操作，git操作を1箇所ででき，かつ，高速で操作できると気持ち良いですよね？(圧)
本記事ではテキストエディタの`neovim`とファイルシステムを視覚的に表示するためのコマンドラインツールである`neo-tree`とgit操作をTUIで行えるlazygitを組み合わせて，ディレクトリ移動やgit操作をターミナル上で行えるようにすることを目的にする．

# 今回行うこと
- ターミナル上でfinderのようなディレクトリ操作を行いたい
- ディレクトリ操作中に選択状態のディレクトリをカレントディレクトリとした新しいターミナルのタブを開きたい
- ディレクトリ操作中に選択状態のディレクトリのgit操作をターミナル上で行いたい

# 前提
neovim，neotree，lazygitはインストール済みだとします．neovim，neotreeに関しては他の方が書かれた記事でかなりわかりやすく説明されているのでそこで詳しくお話ししたいと思います．

lazygitに関してはこちらの記事から

https://qiita.com/JavaLangRuntimeException/items/42087d09728d5739d73d

vim操作はこちらから




# 詳細設計
以下のキーバインドで色々行いたい
**Ctrl + t**  選択中のパスで新しいWezTermタブを開く + 新しいタブでディレクトリを開く（vim全体で使用可能）
**Ctrl + g**  選択中のパスでLazyGitを開く 
**Ctrl + h**  隠しファイルの表示/非表示を切り替え


# neotreeの設定をいじる
```~/.config/nvim/lua/neo-tree.lua
return {
  -- neo-tree.nvimプラグインの定義
  "nvim-neo-tree/neo-tree.nvim",
  branch = "v3.x",  -- v3.xブランチを使用
  -- 必要な依存プラグインを指定
  dependencies = {
    "nvim-lua/plenary.nvim",     -- Luaユーティリティ関数群
    "nvim-tree/nvim-web-devicons", -- ファイルアイコン表示用
    "MunifTanjim/nui.nvim",      -- UIコンポーネントライブラリ
  },
  config = function()
    -- カレントディレクトリでLazyGitを開くカスタムコマンドを定義
    -- :LazyGitCurrent で呼び出し可能
    vim.api.nvim_create_user_command("LazyGitCurrent", function()
      local path = vim.fn.expand('%:p:h')  -- 現在のファイルの絶対パスを取得
      vim.cmd('tabnew | terminal lazygit -p ' .. path)  -- 新しいタブでLazyGitを開く
      vim.cmd('startinsert')  -- ターミナルモードを開始
    end, {})

    -- グローバルなCtrl+Tのマッピングを設定
    -- ディレクトリを新しいタブで開く機能
    vim.api.nvim_set_keymap('n', '<C-t>', 
      ':lua require("neo-tree.command").execute({ action = "open_directory_in_new_tab" })<CR>', 
      { noremap = true, silent = true })

    -- neo-treeの主要設定
    require("neo-tree").setup({
      filesystem = {
        filtered_items = {
          visible = false,      -- 隠しファイルはデフォルトで非表示
          hide_dotfiles = true, -- .で始まるファイルを非表示
          hide_gitignored = true, -- .gitignoreに記載されたファイルを非表示
        },
      },
      -- neo-treeウィンドウ内でのキーマッピング
      window = {
        mappings = {
          ["<C-g>"] = "open_lazygit",   -- Ctrl+G: LazyGitを開く
          ["<C-t>"] = "open_in_wezterm", -- Ctrl+T: WezTermで開く
          ["<C-h>"] = "toggle_hidden",   -- Ctrl+H: 隠しファイルの表示切替
        },
      },
      -- カスタムコマンドの定義
      commands = {
        -- 選択中のパスでLazyGitを開く
        open_lazygit = function(state)
          local node = state.tree:get_node()  -- 選択中のノード取得
          local path = node:get_id()          -- ノードのパス取得
          vim.cmd('tabnew | terminal lazygit -p ' .. path)  -- 新タブでLazyGit起動
          vim.cmd('startinsert')
        end,

        -- 選択中のパスで新しいWezTermタブを開く
        open_in_wezterm = function(state)
          local node = state.tree:get_node()
          local path = node:get_id()
          -- ファイルが選択されている場合は親ディレクトリを使用
          if node.type ~= "directory" then
            path = vim.fn.fnamemodify(path, ":h")
          end
          -- WeztTermコマンドを構築して実行
          local cmd = "wezterm cli spawn --cwd " .. vim.fn.shellescape(path)
          os.execute(cmd)
          -- 操作完了を通知
          vim.notify("WezTerm: 新しいタブを開きました - パス: " .. path, vim.log.levels.INFO)
        end,

        -- 隠しファイルの表示/非表示を切り替え
        toggle_hidden = function(state)
          -- ファイルシステムの現在の状態を取得
          local fs_state = require("neo-tree.sources.filesystem").get_state()
          -- 表示状態を反転
          fs_state.filtered_items.visible = not fs_state.filtered_items.visible
          fs_state.filtered_items.hide_dotfiles = not fs_state.filtered_items.hide_dotfiles
          fs_state.filtered_items.hide_gitignored = not fs_state.filtered_items.hide_gitignored
          -- ツリーを更新
          require("neo-tree.sources.filesystem").refresh(state)
          -- 現在の状態を通知
          local visibility = fs_state.filtered_items.visible and "表示" or "非表示"
          vim.notify("隠しファイルを" .. visibility .. "に設定しました", vim.log.levels.INFO)
        end,
      },
    })
  end,
}
```

これをnvimを開いてプラグインを適用させると反映される．

# 実際の動作環境
- **Ctrl + t** を押した場合
![Wondershare Uniconverter 15_000003.GIF](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3757442/5f8fa818-01c8-106e-4328-276948c28419.gif)

- **Ctrl + g** を押した場合
![Wondershare Uniconverter 15_000001.GIF](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3757442/95fceda4-889a-01dc-bb2e-8bf55ccab04f.gif)

- **Ctrl + h**を押した場合
![Wondershare Uniconverter 15_000004.GIF](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3757442/68ec9b6f-e5b4-e019-edf4-e228903b307f.gif)

このようにターミナルでさまざまな操作が可能になる．選択したディレクトリで新しいタブを開いたり，gitをうさができるのでぜひ作業効率アップに使ってほしい．

それではQiitaアドカレ.24企画の今日のクリスマスツリーです．

> 詳しくは[こちら](https://qiita.com/JavaLangRuntimeException/items/1f4a6febf957f522ba45)の記事から

![スクリーンショット 2024-12-08 22.39.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3757442/02d77bd2-36c6-d6dc-a158-4486c1cd9632.png)