aboutsummaryrefslogtreecommitdiffstats
path: root/plugin/50-oil.lua
blob: b2b17daacad3a6495f2c8eb18f92f2aec1146adf (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
--[[ 50-oil.lua — file explorer that edits the filesystem like a buffer (oil.nvim).

Replaces netrw's local directory browsing (`default_file_explorer`); netrw's remote handlers
(ftp://, scp://, …) live in a separate autocmd group and keep working. Deletions go to the
freedesktop trash rather than being removed permanently. oil-git-status.nvim shows each
entry's git status (files and folders) in the sign column.

Global keymaps:
`-`      open the parent directory in the current window
`<M-e>`  toggle oil in a floating window

Keymaps inside an oil buffer (merged with oil's defaults):
`<C-s>`  open the entry under the cursor in a horizontal split (like `CTRL-W_s`)
`<C-v>`  open the entry under the cursor in a vertical split (like `CTRL-W_v`)
`<C-d>`  scroll down in the preview window when one is open, otherwise in the oil buffer
`<C-u>`  scroll up in the preview window when one is open, otherwise in the oil buffer
`gd`     toggle the detail columns (permissions, size, mtime)
`zi`     toggle folding in the preview window
]]

local oil = require("oil")
local oil_util = require("oil.util")
local help = require("dotfiles.help")

-- Extra columns added on top of `icon` when detail is toggled on; off by default.
local detail_columns = { "icon", "permissions", "size", "mtime" }
local show_detail = false

-- Toggle the permissions/size/mtime columns, keeping the icon column.
local function toggle_detail_columns()
	show_detail = not show_detail
	oil.set_columns(show_detail and detail_columns or { "icon" })
end

--[[ Toggle folding in the oil preview window.
'foldenable' is not in `preview_win.win_options`, so the toggle survives preview refreshes;
folds start closed via `foldlevel = 0`, so this flips between the folded overview and full content. ]]
local function toggle_preview_folds()
	local preview_win = oil_util.get_preview_win()
	if not preview_win then
		vim.notify("No oil preview window open", vim.log.levels.WARN)
		return
	end
	vim.wo[preview_win].foldenable = not vim.wo[preview_win].foldenable
end

-- Run a normal-mode scroll key in the preview window when one is open, else in the current window.
local function scroll_win(key)
	local win = oil_util.get_preview_win() or vim.api.nvim_get_current_win()
	vim.api.nvim_win_call(win, function()
		vim.cmd.normal({ args = { vim.keycode(key) }, bang = true })
	end)
end

-- Scroll half a page down in the preview window, falling back to the oil buffer.
local function preview_scroll_down()
	scroll_win("<C-d>")
end

-- Scroll half a page up in the preview window, falling back to the oil buffer.
local function preview_scroll_up()
	scroll_win("<C-u>")
end

oil.setup({
	default_file_explorer = true,
	delete_to_trash = true,
	columns = { "icon" },
	view_options = { show_hidden = true },
	-- oil-git-status renders two sign columns (index + working tree).
	win_options = { signcolumn = "yes:2" },
	--[[ The scratch preview sets no 'filetype', so the FileType fold autocmd never fires.
	Drive treesitter folds on the preview window directly; `foldlevel = 0` closes them on open. ]]
	preview_win = {
		win_options = {
			foldmethod = "expr",
			foldexpr = "v:lua.vim.treesitter.foldexpr()",
			foldcolumn = "1",
			foldlevel = 0,
		},
	},
	keymaps = {
		["<C-h>"] = false,
		["<C-s>"] = { "actions.select", opts = { horizontal = true } },
		["<C-v>"] = { "actions.select", opts = { vertical = true } },
		-- stylua: ignore start
		["<C-d>"] = { callback = preview_scroll_down, desc = "Scroll down (preview if open)", mode = "n" },
		["<C-u>"] = { callback = preview_scroll_up, desc = "Scroll up (preview if open)", mode = "n" },
		-- stylua: ignore end
		["gd"] = { callback = toggle_detail_columns, desc = "Toggle detail columns", mode = "n" },
		["zi"] = { callback = toggle_preview_folds, desc = "Toggle preview folds", mode = "n" },
	},
})

require("oil-git-status").setup({ show_ignored = true })

vim.keymap.set("n", "-", "<Cmd>Oil<CR>", { desc = "Open parent directory (oil)" })
vim.keymap.set("n", "<M-e>", oil.toggle_float, { desc = "Toggle oil (floating)" })

help.register("oil", {
	maps = {
		{ "-", "Open parent directory (oil)" },
		{ "<M-e>", "Toggle oil (floating)" },
	},
})
help.register("oil (buffer-local)", {
	maps = {
		{ "<C-s>", "Open entry in a horizontal split" },
		{ "<C-v>", "Open entry in a vertical split" },
		{ "<C-d>", "Scroll down (preview if open)" },
		{ "<C-u>", "Scroll up (preview if open)" },
		{ "gd", "Toggle detail columns" },
		{ "zi", "Toggle preview folds" },
	},
})