Neovim 0.12

เมื่อผ่านมาไม่นานมาานี้ neovim ได้ปล่อย version 0.12 แบบ stable มาให้เราได้ใช้กัน ใน version มีสิ่งที่ผมสนใจมาสักพักแล้ว ก็คือ built-in plugin manager ของ neovim

นั่นก็หมายความว่า ได้เวลาอัพเกรด

แต่จริงๆ แล้วก็ไม่ถึงกับอัพเกรดหรอก ก่อนหน้านี้ผมใช้ lazynvim เป็นตัว manager อยู่แล้ว แล้วก็ใช้งานได้ดีด้วย ถ้าเทียบกันแล้ว performance ของ lazy น่าจะดีกว่าเยอะ เพราะว่าเค้าสามารถจัดการเรื่อง lazy loding ได้ด้วย แถมมีหน้าต่างให้ใช้สมกับเป็น package manager ด้วย

ซึ่งก็คงจะเป็นคำถาม แล้วจะเปลี่ยนทำไม?

ขอพูดตรงๆ ว่า “ไม่มีเหตุผลสักเท่าไรครับ”

แต่ถ้าให้หาข้ออ้างก็คือ ผมชอบความ built in อะไรที่ติดมาให้ใช้ ผมรู้สึกชอบใช้แบบนั้นมากกว่า แล้วโดยส่วนตัวผมไม่มี plugin เยอะมาก แค่มีตัวช่วยโหลดให้ก็โอเคแล้ว เพราะงั้น ถ้ามันใช้งานได้ ก็อยากลองหน่อย

Setup

เริ่มจาก config แบบเพิ่มอะไรง่ายๆ ที่มันลงแล้วเห็นได้ชัดหน่อย อย่างเช่น Oil nvim เป็น plugin ที่ผมชอบมาก ถึงแม้จะไม่ค่อยได้ใช้ก็เถอะ

-- init.lua
local gh = function(x)
	return "https://github.com/" .. x
end

-- plugins
vim.pack.add({
	{ src = gh("stevearc/oil.nvim") },
})

-- manual setup
require("oil").setup({
	default_file_explorer = false,
})

พอเรียบร้อยแล้วก็ restart ดู จะเห็นว่ามี prompt ขึ้นมาให้เรายืนยันว่าจะลง plugin หรือไม่

first time install

run oil nvim

เรียบร้อยใช้งานได้เลย สะดวกสุดๆ เท่านี้ก็แค่วาง plugin ไว้ แล้วก็ setup ได้เลย

มาลองลง lsp server กับ outline กัน

-- init.lua
local gh = function(x)
	return "https://github.com/" .. x
end

local keymap = vim.keymap.set;

-- plugins
vim.pack.add({
	{ src = gh("stevearc/oil.nvim") },
	{ src = gh("hedyhli/outline.nvim") },

	gh("mason-org/mason.nvim"),
	gh("neovim/nvim-lspconfig"),
	gh("mason-org/mason-lspconfig.nvim"),
})

-- manual setup
require("oil").setup({
	default_file_explorer = false,
})

require("mason").setup()
require("mason-lspconfig").setup()
require("outline").setup({})

keymap("n","<leader>o", vim.cmd.Outline)

nvim lsp and outline

Lazy loading

แต่ว่าถึงยังไง ผมก็ยังชอบไอเดียของ lazy loading อยู่ดี สำหรับคนที่ยังไม่รู้ lazy loading คือการที่เราจะทำการ load สิ่งใดสิ่งหนึ่งเฉพาะตอนที่เราต้องการจะใช้มันครับ สิ่งมันจะส่งผลคือ start up time ทำให้เราเปิด editor ได้เร็วขึ้น เพราะว่ามัน load ของที่ต้องการเท่านั้นมา ส่วนที่เหลือก็จะค่อยๆ โหลดมาตอนที่เราใช้งาน จริงๆ ในกรณีของผมอาจจะไม่จำเป็นขนาดนั้น เพราะว่า plugin ผมน้อย ไม่ได้ส่งผลอะไรเห็นได้ชัดขนาดนั้น แต่ก็หลายๆ คนมักจะพูดว่า developer ที่ดี ควรจะจัดการ lazy load ของ plugin ตัวเองให้อยู่แล้ว เพราะงั้นส่วนใหญ่ของพวกนี้อาจจะไม่ต้องจำเป็นก็ได้ (คิดว่านะ)

แต่ว่าก็อยากได้อยู่ดี ผมอยากตั้งค่า keymap เมื่อกดแล้วค่อย load plugin นั้นมาใช้น่ะ ซึ่งจริงๆ เขียนเองได้ แต่ว่าผมขี้เกียจแล้วก็ไม่เทพขนาดจะเขียนเองได้แหละ ก็เลยมาถึง plugin อีกตัว lze ซึ่ง ผมจะใช้ตัวนี้แหละจัดการการโหลดของ plugin เพื่อมาทดแทน lazynvim

ปรับ spec กันหน่อย ถ้าคนที่เคยใช้ lazynvim มา ก็จะคล้ายๆ กันเลย

-- init.lua
-- lazy loader
vim.pack.add({ gh("birdeehub/lze") })

-- plugins
vim.pack.add({
	{ src = gh("stevearc/oil.nvim") },
	{ src = gh("hedyhli/outline.nvim") },

	gh("mason-org/mason.nvim"),
	gh("neovim/nvim-lspconfig"),
	gh("mason-org/mason-lspconfig.nvim"),

}, {
	load = function(_) end,
})

require("lze").load({
	{
		"mason.nvim",
		priority = 100, -- this need to be loaded first
		after = function()
			require("mason").setup()
		end,
	},
	{
		"mason-lspconfig.nvim",
		after = function()
			require("mason-lspconfig").setup()
		end,
	},
	{ "nvim-lspconfig" },
	{
		"oil.nvim",
		lazy = false,
		after = function(_)
			require("oil").setup({
				default_file_explorer = false,
			})
		end,
	},
	{
		"outline.nvim",
		lazy = true,
		cmd = { "Outline", "OutlineOpen" },
		keys = { -- Example mapping to toggle outline
			{ "<leader>o", vim.cmd.Outline, desc = "Toggle outline" },
		},
		after = function()
			require("outline").setup({})
		end,
	},
})

after using lze

ทีนี้เราก็จะได้ lazy loading มาใช้งานการแล้ว

Done

ก็นี่จะเป็นวิธีการใช้ vim pack ตัว plugin manager ที่ built in มาให้ใช้งานกันแบบไม่ต้องหา plugin เพื่อมาจัดการ plugin ซึ่งโดยส่วนตัวผมแล้ว ผมชอบแบบนี้มากกว่า ถึงแม้ว่าสุดท้ายผมก็ต้องหา plugin ที่ช่วยทำ lazy load มาอยู่ดี ซึ่งก็อาจจะบอกได้ว่าใช้ lazy nvim อย่างเดิมเลยก็ได้ แต่ผมมองว่ามันแยกส่วนกันได้ดีนะแบบนี้ มี plugin manager ที่คอยจัดการ plugin อย่างเดียว (โหลด และอัพเดต plugin) แล้วก็ใช้อีกหนึ่ง plugin ที่จัดการการโหลดใช้งาน plugin (lazy load)

ก็จบสั้นๆ สำหรับวันนี้นะครับ ไม่มีอะไรมาก ผมรู้สึกว่า neovim ในช่วงหลังมานี้เริ่มใช้งานง่ายขึ้นเรื่อยๆ เลยอยากจะมาแชร์เรื่องตรงนี้เก็บไว้ ขอบคุณสำหรับเวลามากครับผม ไว้เจอกันใหม่

สำหรับคนที่สนใจผมมี repo ของผมที่สามารถเข้าไปดูได้ ที่นี่เลยครับ