Better Folding (part 2): Open and Close folds with `h` and `l`

· Nano Tips for Vim


A not very well known way to open folds is simply using l (or any other horizontal movement) on a closed fold. This is due to the hor option of foldopen, which is enabled by default.

So I thought, what if we could also close folds h? Obviously closing folds is a bit more tricky than opening them, since we want to be able to preserve the ability to move horizontally in a unfolded line. So the trick is to only make h fold in a situation where we normally wouldn't use h anymore—namely when the cursor is on the first non-blank character in a line or before. If we are anywhere after the first non-blank, h will just fallback to its default behavior of moving to the left.

1vim.keymap.set("n", "h", function()
2	local onIndentOrFirstNonBlank = vim.fn.virtcol(".") <= vim.fn.indent(".") + 1
3	local shouldCloseFold = vim.tbl_contains(vim.opt_local.foldopen:get(), "hor")
4	if onIndentOrFirstNonBlank and shouldCloseFold then
5		local wasFolded = pcall(vim.cmd.normal, "zc")
6		if wasFolded then return end
7	end
8	vim.cmd.normal{"h", bang = true}
9end, { desc = "h (+ close fold at BoL)" })

When you are in the habit of staying to the left anyway, this effectively allows you to use h and l to close and open folds. No more need for za, zc, zo, and similar bindings!

The snippet also pairs well with startofline, as this the option moves your cursor to the first non-blank character in a line more often.