vimのプラグインを整理したら、30くらい使ってた

## はじめに
VSCode使うの嫌だなと感じて、vimに移行してから数年...
いい環境になったなと思ったのでまとめてみました.
「ホームポジションを崩さない」「マウスを使用しない」を理念に試行錯誤しています.
最初はvimになれるのキツかったなと振り返っていました.
キーバインドになれるまでも時間かかるし、プラグイン周りも時間かかるしと、結構大変だったなと感じています.
この記事が、参考になれば幸いです.


## 表示系
### [nvim-lualine/lualine.nvim](https://github.com/nvim-lualine/lualine.nvim)
ステータスバー
![Screenshot 2024-06-12 at 12.04.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/325526/d74c488f-6817-bf34-07a6-6f3e194085b7.png)
設定内容は左から、
- モード
- ブランチ
- ファイル名
- 文字コード
- ファイルタイプ
- 行数：列数
```lualine.lua
local status, lualine = pcall(require, "lualine")
if not status then
	return
end

lualine.setup({
	options = {
		icons_enabled = true,
		theme = "nord",
		section_separators = { left = "", right = "" },
		component_separators = { left = "", right = "" },
		disabled_filetypes = {},
	},
	sections = {
		lualine_a = { "mode" },
		lualine_b = { "branch" },
		lualine_c = {
			{
				"filename",
				file_status = true, -- displays file status (readonly status, modified status)
				path = 1, -- 0 = just filename, 1 = relative path, 2 = absolute path
			},
		},
		lualine_x = {
			{
				"diagnostics",
				sources = { "nvim_diagnostic" },
				symbols = {
					error = " ",
					warn = " ",
					info = " ",
					hint = " ",
				},
			},
			"encoding",
			"filetype",
		},
		-- lualine_y = { "progress" },
		lualine_y = {},
		lualine_z = { "location" },
	},
	inactive_sections = {
		lualine_a = {},
		lualine_b = {},
		lualine_c = {
			{
				"filename",
				file_status = true, -- displays file status (readonly status, modified status)
				path = 1, -- 0 = just filename, 1 = relative path, 2 = absolute path
			},
		},
		lualine_x = { "location" },
		lualine_y = {},
		lualine_z = {},
	},
	tabline = {},
	extensions = { "fugitive" },
})
```

### [nvim-treesitter/nvim-treesitter-context](https://github.com/nvim-treesitter/nvim-treesitter-context)
ネストの頭を上部に表示してくれます.
![Screenshot 2024-06-12 at 12.31.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/325526/396cf3e1-57da-329a-5fe2-c45575c79af5.png)

```treesitter.lua
local context_status, context = pcall(require, "treesitter-context")
if not context_status then
	return
end
context.setup{
  enable = true, -- Enable this plugin (Can be enabled/disabled later via commands)
  max_lines = 5, -- How many lines the window should span. Values <= 0 mean no limit.
  min_window_height = 0, -- Minimum editor window height to enable context. Values <= 0 mean no limit.
  line_numbers = true,
  multiline_threshold = 20, -- Maximum number of lines to show for a single context
  trim_scope = 'outer', -- Which context lines to discard if `max_lines` is exceeded. Choices: 'inner', 'outer'
  mode = 'cursor',  -- Line used to calculate context. Choices: 'cursor', 'topline'
  -- Separator between context and content. Should be a single character string, like '-'.
  -- When separator is set, the context will only show up when there are at least 2 lines above cursorline.
  separator = nil,
  zindex = 20, -- The Z-index of the context window
  on_attach = nil, -- (fun(buf: integer): boolean) return false to disable attaching
}
```  

### [kyazdani42/nvim-web-devicons](https://github.com/nvim-tree/nvim-web-devicons/tree/master)
いい感じのアイコンを表示してくれます.
デフォルトのまま使用しています.
![Screenshot 2024-06-12 at 12.53.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/325526/931f24ab-c13b-5ea7-acb7-e8c2f75c0813.png)


### [akinsho/nvim-bufferline.lua](https://github.com/akinsho/bufferline.nvim)
タブ分けができます.
バックエンドとフロントエンド両方開発するため、ワークスペースを分ける要領でタブ分けをしています.
![Screenshot 2024-06-12 at 12.52.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/325526/ba459232-70cc-461d-456e-bbed54402048.png)

```bufferline.lua
local status, bufferline = pcall(require, "bufferline")
if not status then
	return
end

bufferline.setup({
	options = {
		mode = "tabs",
		separator_style = "slant",
		always_show_bufferline = false,
		show_buffer_close_icons = false,
		show_close_icon = false,
		color_icons = true,
	},
	highlights = {
		separator = {
			fg = "#073642",
			bg = "#002b36",
		},
		separator_selected = {
			fg = "#073642",
		},
		background = {
			fg = "#657b83",
			bg = "#002b36",
		},
		buffer_selected = {
			fg = "#fdf6e3",
			bold = true,
		},
		fill = {
			bg = "#073642",
		},
	},
})

vim.keymap.set("n", "<Tab>", "<Cmd>BufferLineCycleNext<CR>", {})
vim.keymap.set("n", "<S-Tab>", "<Cmd>BufferLineCyclePrev<CR>", {})

```  

### [folke/noice.nvim](https://github.com/folke/noice.nvim)
コマンドラインと通知をかっこよくしてくれます.
重いので、全てminiで表示しています.
```noice.lua
local status, noice = pcall(require, "noice")
if not status then
  return
end

local function myMiniView(pattern, kind)
	kind = kind or ""
	return {
		view = "mini",
		filter = {
			event = "msg_show",
			kind = kind,
			find = pattern,
		},
	}
end

local function hiddenView(pattern)
  return {
    filter = {
      event = "msg_show",
      kind = "",
      find = pattern,
    },
    opts = { skip = true },
  }
end

noice.setup({
	lsp = {
		override = {
			["vim.lsp.util.convert_input_to_markdown_lines"] = true,
			["vim.lsp.util.stylize_markdown"] = true,
			["cmp.entry.get_documentation"] = true,
		},
	},
  messages = {
    enabled = true, -- enables the Noice messages UI
    view = "mini", -- default view for messages
    view_error = "mini", -- view for errors
    view_warn = "mini", -- view for warnings
    view_history = "messages", -- view for :messages
    view_search = "mini", -- view for search count messages. Set to `false` to disable
  },
  presets = {
    bottom_search = false,
    command_palette = false, 
    long_message_to_split = true,
    inc_rename = false,
    lsp_doc_border = false, 
  },
  routes = {
    {
      filter = {
        event = "msg_show",
        kind = "search_count",
      },
      opts = { skip = true },
    },
    myMiniView("written"),
    hiddenView("yanked"),
    hiddenView("Already at .* change"),
    hiddenView("more lines?"),
    hiddenView("fewer lines?"),
    hiddenView("change; before"),
    hiddenView("change; after"),
    hiddenView("line less"),
    hiddenView("lines indented"),
    hiddenView("No lines in buffer"),
		myMiniView("search hit .*, continuing at", "wmsg"),
		myMiniView("E486: Pattern not found", "emsg"),
  },
  views = {
    cmdline_popup = {
      position = {
        row = 20,
        col = "50%",
      },
      size = {
        width = 60,
        height = "auto",
      },
    },
  },
})

```  

## 着色
### [EdenEast/nightfox.nvim](https://github.com/EdenEast/nightfox.nvim)
カラースキーム
icebergを使用していたが、Reactを触るようになりnightfoxに移行しました.
ある程度の暗さもあり、青さもあり、なんとなく使っている感じです.
自作してもいいですが、なかなか...ねぇ...

### [nvim-treesitter/nvim-treesitter](https://github.com/nvim-treesitter/nvim-treesitter)
シンタックスハイライトをいい感じにしてくれます.
カラースキームによっては、対応していないものもあります.
```treesitter.lua
local status, ts = pcall(require, "nvim-treesitter.configs")
if not status then
	return
end

ts.setup({
	highlight = {
		enable = true,
	},
	indent = {
		enable = true,
	},
	ensure_installed = {
		"markdown",
        "xml",
		"yaml",
		"lua",
		"python",
		"php",
		"html",
		"scss",
		"javascript",
		"tsx",
		"json",
		"dot",
		"gitignore",
		"latex",
		"dart",
	},
	auto_install = true,
})

local parser_config = require("nvim-treesitter.parsers").get_parser_configs()
parser_config.tsx.filetype_to_parsername = { "javascript", "typescript.tsx", "javascript.jsx" }

```  

### [norcalli/nvim-colorizer.lua](https://github.com/norcalli/nvim-colorizer.lua)
テキスト上のカラーコードに該当色を当ててくれます.
scssを書く機会もあるため、入れています.
```colorizer.lua
local status, colorizer = pcall(require, "colorizer")
if not status then
	return
end

colorizer.setup(config, {
	RRGGBBAA = true,
	rgb_fn = true,
	hsl_fn = true,
})

```  

### [m-demare/hlargs.nvim](https://github.com/m-demare/hlargs.nvim)
treesitterを元に、シンタックスハイライトをよりいい感じにしてくれます.
```hlarts.lua
local status, hlargs = pcall(require, "hlargs")
if not status then
  return
end

hlargs.setup()

```  

## LSP・補完
### [neoclide/coc.nvim](https://github.com/neoclide/coc.nvim)
`CocInstall xxx`で入れられ、LSPなどをまとめて管理できます.
簡単にVSCodeのような環境にすることができます.
- [coc-spell-checker](https://github.com/iamcco/coc-spell-checker)
- [coc-snipeets](https://github.com/neoclide/coc-snippets)
- [coc-prettier](https://github.com/neoclide/coc-prettier)
- [coc-esilnt](https://github.com/neoclide/coc-eslint)
- [coc-diagnostic](https://github.com/iamcco/coc-diagnostic)
- [coc-tsserver](https://github.com/neoclide/coc-tsserver)
- [coc-jedi](https://github.com/pappasam/coc-jedi)
- [coc-tailwindcss3](https://github.com/yaegassy/coc-tailwindcss3)
- [coc-black-formatter](https://github.com/yaegassy/coc-black-formatter)

### [nathom/filetype.nvim](https://github.com/nathom/filetype.nvim)
開いたファイルのタイプを判定します.
```filetype.lua
local status, filetype = pcall(require, "filetype")
if not status then
  return
end

filetype.setup({
 overrides = {
        complex = {
            -- Set the filetype of any full filename matching the regex to gitconfig
            [".*git/config"] = "gitconfig", -- Included in the plugin
        },

        -- The same as the ones above except the keys map to functions
        function_extensions = {
            ["html"] = function()
                vim.bo.filetype = "html"
                -- Remove annoying indent jumping
            end,
            ["sql"] = function()
                vim.bo.filetype = "sql"
            end,
            ["php"] = function()
                vim.bo.filetype = "php"
            end,
        },
    },
})
```  

### [windwp/nvim-ts-autotag](https://github.com/windwp/nvim-ts-autotag)
React開発をしているため必須です.
``` ts-autota.lua
local status, autotag = pcall(require, "nvim-ts-autotag")
if not status then
	return
end

autotag.setup({
  opts = {
    -- Defaults
    enable_close = true, -- Auto close tags
    enable_rename = true, -- Auto rename pairs of tags
    enable_close_on_slash = false -- Auto close on trailing </
  },
  -- Also override individual filetype configs, these take priority.
  -- Empty by default, useful if one of the "opts" global settings
  -- doesn't work well in a specific filetype
  per_filetype = {
    ["html"] = {
      enable_close = false
    }
  }
})
```  

### [hrsh7th/cmp-cmdline](https://github.com/hrsh7th/cmp-cmdline)
コマンドラインの補完してくれます.

### [hrsh7th/cmp-buffer](https://github.com/hrsh7th/cmp-buffer)
バッファを元に、キーワード補完してくれます.

### [hrsh7th/cmp-path](https://github.com/hrsh7th/cmp-path)
ファイルパスの補完をしてくれます.

### [hrsh7th/nvim-cmp](https://github.com/hrsh7th/nvim-cmp)
保管するためのエンジンです

## ファジーファインダー
### [nvim-telescope/telescope.nvim](https://github.com/nvim-telescope/telescope.nvim)
一番シェアが高そうなファジーファインダー
全体grep検索するのによく使用します.
たまに、file-browserを使用します.
主に、`; + ⚪︎`で設定しています.
fzf : `;f`
grep : `;r`
file-browser : `sf`
buffer : `;bb`
fullter : `;c`
fullterで開発する機会があったため、;cでflutterのコマンドを開くようにしています.
```plugin.lua
  {
    "nvim-telescope/telescope.nvim",
    dependencies = {
      {
        "nvim-telescope/telescope-live-grep-args.nvim",
        version = "^1.0.0",
      },
    },
    config = function()
      require("telescope").load_extension("live_grep_args")
    end
  },
  "nvim-telescope/telescope-file-browser.nvim",
``` 
``` telescope.lua
local status, telescope = pcall(require, "telescope")
if not status then
	return
end
local actions = require("telescope.actions")
local builtin = require("telescope.builtin")
local live_grep_args = require('telescope').extensions.live_grep_args

local function telescope_buffer_dir()
	return vim.fn.expand("%:p:h")
end

local fb_actions = require("telescope").extensions.file_browser.actions

telescope.setup({
	defaults = {
		file_ignore_patterns = {
			"^.git/",
			"^.cache/",
			"^Library/",
			"Parallels",
			"^Movies",
			"^Music",
			"node_modules",
			"vendor",
		},
		vimgrep_arguments = {
			"rg",
			"--color=never",
			"--no-heading",
			"--with-filename",
			"--line-number",
			"--column",
			"--smart-case",
			"-uu",
		},
		mappings = {
			n = {
				["q"] = actions.close,
        ['d'] = actions.delete_buffer
			},
		},
	},
	extensions = {
		file_browser = {
			theme = "dropdown",
			-- disables netrw and use telescope-file-browser in its place
			hijack_netrw = true,
			mappings = {
				-- your custom insert mode mappings
				["i"] = {
					["<C-w>"] = function()
						vim.cmd("normal vbd")
					end,
				},
				-- your custom normal mode mappings
				["n"] = {
					["<C-u>"] = fb_actions.goto_parent_dir,
					["/"] = function()
						vim.cmd("startinsert")
					end,
				},
			},
		},
	},
})

telescope.load_extension("file_browser")

vim.keymap.set("n", ";f", function()
	builtin.find_files({
		no_ignore = false,
		hidden = true,
	})
end)
vim.keymap.set("n", ";r", function()
  live_grep_args.live_grep_args()
end)
vim.keymap.set("n", ";bb", function()
	builtin.buffers()
end)
vim.keymap.set("n", "sf", function()
	telescope.extensions.file_browser.file_browser({
		path = "%:p:h",
		cwd = telescope_buffer_dir(),
		respect_gitignore = false,
		hidden = true,
		grouped = true,
		previewer = false,
		initial_mode = "normal",
		layout_config = { height = 40 },
	})
end)

telescope.load_extension("flutter")
vim.keymap.set("n", ";c", ":Telescope flutter commands<CR>")

```  

## git
### [dinhhuy258/git.nvim](https://github.com/dinhhuy258/git.nvim)
blameとdiffを表示するために使用しています.
```git.lua
local status, git = pcall(require, "git")
if not status then
	return
end

git.setup({
  keymaps = {
    -- Open blame window
    blame = "<Leader>gb",
    -- Close blame window
    quit_blame = "q",
    -- Open blame commit
    blame_commit = "<CR>",
    -- Open file/folder in git repository
    browse = "<Leader>go",
    -- Open pull request of the current branch
    open_pull_request = "<Leader>gp",
    -- Create a pull request with the target branch is set in the `target_branch` option
    create_pull_request = "<Leader>gn",
    -- Opens a new diff that compares against the current index
    diff = "<Leader>gd",
    -- Close git diff
    diff_close = "<Leader>gD",
    -- Revert to the specific commit
    revert = "<Leader>gr",
    -- Revert the current file to the specific commit
    revert_file = "<Leader>gR",
  },
})

```  

### [lewis6991/gitsigns.nvim](https://github.com/lewis6991/gitsigns.nvim)
どこを編集・追加・削除したかを表示してくれます.
```gitsings.lua
local status, gitsigns = pcall(require, "gitsigns")
if not status then
  return
end

gitsigns.setup({
  signs = {
    add = { text = "│" },
    change = { text = "│" },
    delete = { text = "_" },
    topdelete = { text = "‾" },
    changedelete = { text = "~" },
    untracked = { text = "┆" },
  },
  signcolumn = true, -- Toggle with `:Gitsigns toggle_signs`
  numhl = false,    -- Toggle with `:Gitsigns toggle_numhl`
  linehl = false,   -- Toggle with `:Gitsigns toggle_linehl`
  word_diff = false, -- Toggle with `:Gitsigns toggle_word_diff`
  watch_gitdir = {
    follow_files = true,
  },
  attach_to_untracked = true,
  current_line_blame = true, -- Toggle with `:Gitsigns toggle_current_line_blame`
  current_line_blame_opts = {
    virt_text = true,
    virt_text_pos = "eol", -- 'eol' | 'overlay' | 'right_align'
    delay = 1000,
    ignore_whitespace = false,
  },
  current_line_blame_formatter = "<author>, <author_time:%Y-%m-%d> - <summary>",
  sign_priority = 6,
  update_debounce = 100,
  status_formatter = nil, -- Use default
  max_file_length = 40000, -- Disable if file is longer than this (in lines)
  preview_config = {
    -- Options passed to nvim_open_win
    border = "single",
    style = "minimal",
    relative = "cursor",
    row = 0,
    col = 1,
  },
  yadm = {
    enable = false,
  },
  on_attach = function(bufnr)
    local gs = package.loaded.gitsigns

    local function map(mode, l, r, opts)
      opts = opts or {}
      opts.buffer = bufnr
      vim.keymap.set(mode, l, r, opts)
    end

    -- Navigation
    map("n", "]c", function()
      if vim.wo.diff then
        return "]c"
      end
      vim.schedule(function()
        gs.next_hunk()
      end)
      return "<Ignore>"
    end, { expr = true })

    map("n", "[c", function()
      if vim.wo.diff then
        return "[c"
      end
      vim.schedule(function()
        gs.prev_hunk()
      end)
      return "<Ignore>"
    end, { expr = true })

    -- Actions
    map("n", "<leader>hr", gs.reset_buffer)
    map("n", "<leader>hp", gs.preview_hunk)
  end,
})

vim.cmd("highlight GitSignsCurrentLineBlame guifg=#555555 gui=bold")
```  

### [akinsho/git-conflict.nvim](https://github.com/akinsho/git-conflict.nvim)
コンフリクトに対応するために入れています.
```conflict.lua
local status, gconflict = pcall(require, "git-conflict")
if not status then
	return
end

gconflict.setup()
vim.keymap.set("n", "co", "<Plug>(git-conflict-ours)")
vim.keymap.set("n", "ct", "<Plug>(git-conflict-theirs)")
vim.keymap.set("n", "cb", "<Plug>(git-conflict-both)")
vim.keymap.set("n", "c0", "<Plug>(git-conflict-none)")
vim.keymap.set("n", "]x", "<Plug>(git-conflict-prev-conflict)")
vim.keymap.set("n", "[x", "<Plug>(git-conflict-next-conflict)")

```  

### [sindrets/diffview.nvim](https://github.com/sindrets/diffview.nvim)
差分を確認するために入れています.
git.nvimでは編集内容の差分を確認しますが、diffview.nvimでは、コミットごとの差分を確認します.
neogit用にも入れています.
```diffview.lua
local status, diffview = pcall(require, "diffview")
if not status then
	return
end

diffview.setup({})

vim.keymap.set("n", ";df", ":DiffviewFileHistory %<Return>")
vim.keymap.set("n", ";db", ":DiffviewFileHistory<Return>")

```  

### [NeogitOrg/neogit](https://github.com/NeogitOrg/neogit)
gitの主な操作ができます.
add, commit, pushをする時に使用します.
特にaddする前に、差分をまとめて確認したい時に使用しています.
checkoutなどもできますが、toggletermでコマンド操作しています.
```neogit.lua
local status, neogit = pcall(require, "neogit")
if not status then
  return
end

neogit.setup({
  integrations = { diffview = true, telescope = true },
})

vim.api.nvim_set_keymap("n", "<C-g><C-g>", ":Neogit<CR>", { noremap = true, silent = true })
```  


## 便利系
### [folke/which-key.nvim](https://github.com/folke/which-key.nvim)
キーバインドがわからない時に使用します.
そんなに使用する機会はないが、「あああ...なんだっけ忘れた...」という時があるため、 一応入れています.

### [kylechui/nvim-surround](https://github.com/kylechui/nvim-surround)
カッコでラップしたり、ラップされているものを置換したり、
使用している意識はあまり無いですが、あるのとないのとでは大違いです.

### [nvim-neo-tree/neo-tree.nvim](https://github.com/nvim-neo-tree/neo-tree.nvim)
ファイラです.
基本非表示で、モーダルで表示するようにしています.
```neo-tree.lua
local status, tree = pcall(require, "neo-tree")
if not status then
	return
end

tree.setup({
	default_component_configs = {
		indent = {
			with_expanders = "",
		},
	},
	window = {
		position = "float",
		mappings = {
			["Z"] = "expand_all_nodes",
		},
	},
	filesystem = {
		filtered_items = {
			visible = false, -- when true, they will just be displayed differently than normal items
			hide_gitignored = true,
			hide_hidden = true, -- only works on Windows for hidden files/directories
			hide_by_name = {
				"node_modules",
			},
			hide_by_pattern = { -- uses glob style patterns
				"*.meta",
			},
			always_show = { -- remains visible even if other settings would normally hide it
				".gitignored",
			},
			never_show = { -- remains hidden even if visible is toggled to true, this overrides always_show
				".DS_Store",
				"thumbs.db",
			},
			never_show_by_pattern = { -- uses glob style patterns
				".null-ls_*",
			},
		},
	},
})

vim.api.nvim_set_keymap("n", "<C-f><C-f>", ":Neotree<CR>", { noremap = true, silent = true })
```  
### [folke/todo-comments.nvim](https://github.com/folke/todo-comments.nvim)
todoコメントにハイライトをつけてくれて、telescopeで検索もできます.
```todo-comment.lua
local status, todo = pcall(require, "todo-comments")
if not status then
  return
end

todo.setup({
  -- your configuration comes here
  -- or leave it empty to use the default settings
  -- refer to the configuration section below
  keywords = {
    FIX = {
      icon = " ", -- icon used for the sign, and in search results
      color = "error", -- can be a hex color, or a named color (see below)
      alt = { "FIXME", "BUG", "FIXIT", "ISSUE" }, -- a set of other keywords that all map to this FIX keywords
      -- signs = false, -- configure signs for some keywords individually
    },
    TODO = { icon = " ", color = "info" },
    HACK = { icon = " ", color = "warning" },
    WARN = { icon = " ", color = "warning", alt = { "WARNING", "XXX" } },
    PERF = { icon = " ", alt = { "OPTIM", "PERFORMANCE", "OPTIMIZE" } },
    NOTE = { icon = " ", color = "hint", alt = { "INFO" } },
  },
})

vim.keymap.set("n", "]t", function()
  require("todo-comments").jump_next()
end, { desc = "Next todo comment" })

vim.keymap.set("n", "[t", function()
  require("todo-comments").jump_prev()
end, { desc = "Previous todo comment" })


vim.keymap.set("n", ";t", ":TodoTelescope<CR>")
```  

### [numToStr/Comment.nvim](https://github.com/numToStr/Comment.nvim)
選択した範囲をまとめてコメントできます.
デフォルトのまま使用しています.