## 背景
[[Fyler.nvim]]で[[oil.nvim]]のようにプレビュー表示・編集できる機能が欲しい。
既にissueは作成されていたが、起票者によるFeature Requestも含めて実装はされてなさそう。
<div class="link-card-v2">
<div class="link-card-v2-site">
<img class="link-card-v2-site-icon" src="https://github.githubassets.com/favicons/favicon.svg" />
<span class="link-card-v2-site-name">GitHub</span>
</div>
<div class="link-card-v2-title">
File preview mode · Issue #70 · A7Lavinraj/fyler.nvim
</div>
<div class="link-card-v2-content">
Description Thank you for creating the best file tree I've seen so far! Would it be possible to add a 'file prev ...
</div>
<img class="link-card-v2-image" src="https://opengraph.githubassets.com/76b2f5842084db90b282f42e72eee31e1c74f18e3f52bfc4e15dce0923dd6354/A7Lavinraj/fyler.nvim/issues/70" />
<a href="https://github.com/A7Lavinraj/fyler.nvim/issues/70"></a>
</div>
設定ファイルをゴリゴリにカスタマイズすれば、forkしなくても機能を追加できそうだったので対応してみた。
## できたもの
こんな感じ。
![[2026-05-05-18-56-02.webp]]
- `<C-p>` でプレビュー表示の切り替え
- ファイラーでカーソル配下のファイルが切り替わるとプレビューも自動で表示切り替え
- `<C-w>h` `<C-w>l` で ファイラーとプレビューの[[ウィンドウ (Vim)|ウィンドウ]]切り替え
- [[Diagnostic (Neovim)|Diagnostic]] や git status もほぼリアルタイムに表示
## 対応後の設定ファイル
自分の環境に特化したものなので汎用性は意識していない。[[フローティングウィンドウ (Neovim)|フローティングウィンドウ]]で[[Fyler.nvim]]を起動する前提であり、各種設定もベタ書き。
`nvim/lua/plugins/fyler.lua`
```lua
local preview_win
local preview_path
local preview_augroup
local fyler_win
local fyler_win_config
local fyler_origin_win
local close_preview
local function restore_origin_win(win)
if win and vim.api.nvim_win_is_valid(win) then
vim.api.nvim_set_current_win(win)
end
end
local function focus_fyler()
if fyler_win and vim.api.nvim_win_is_valid(fyler_win) then
vim.api.nvim_set_current_win(fyler_win)
end
end
local function focus_preview()
if preview_win and vim.api.nvim_win_is_valid(preview_win) then
vim.api.nvim_set_current_win(preview_win)
end
end
local function show_line_numbers(win)
if win and vim.api.nvim_win_is_valid(win) then
vim.wo[win].number = true
vim.wo[win].relativenumber = false
end
end
local function open_fyler()
vim.cmd("Fyler kind=float")
show_line_numbers(vim.api.nvim_get_current_win())
end
local function prepare_preview_buffer(path)
local buf = vim.fn.bufadd(path)
vim.fn.bufload(buf)
vim.bo[buf].buflisted = false
if vim.bo[buf].filetype == "" then
local filetype = vim.filetype.match({ filename = path, buf = buf })
if filetype then
vim.bo[buf].filetype = filetype
end
end
if vim.bo[buf].syntax == "" and vim.bo[buf].filetype ~= "" then
vim.bo[buf].syntax = vim.bo[buf].filetype
end
pcall(vim.treesitter.start, buf)
return buf
end
local function set_preview_keymaps(buf)
vim.keymap.set("n", "<C-w>h", focus_fyler, { buffer = buf, silent = true })
vim.keymap.set("n", "<C-p>", close_preview, { buffer = buf, silent = true })
end
local function update_preview(entry)
if not entry or entry.type ~= "file" then
return
end
if not preview_win or not vim.api.nvim_win_is_valid(preview_win) then
return
end
if preview_path == entry.path then
return
end
local buf = prepare_preview_buffer(entry.path)
vim.api.nvim_win_set_buf(preview_win, buf)
show_line_numbers(preview_win)
vim.wo[preview_win].wrap = false
set_preview_keymaps(buf)
preview_path = entry.path
end
function close_preview()
if preview_augroup then
vim.api.nvim_del_augroup_by_id(preview_augroup)
end
preview_augroup = nil
preview_path = nil
if preview_win and vim.api.nvim_win_is_valid(preview_win) then
vim.api.nvim_win_close(preview_win, true)
end
preview_win = nil
if fyler_win and vim.api.nvim_win_is_valid(fyler_win) and fyler_win_config then
vim.api.nvim_win_set_config(fyler_win, fyler_win_config)
end
fyler_win = nil
fyler_win_config = nil
end
local function close_preview_before_action(action)
return function(explorer)
local origin_win = fyler_origin_win
close_preview()
explorer:action_call(action)
if action == "n_close" then
restore_origin_win(origin_win)
fyler_origin_win = nil
end
end
end
local function close_preview_before_file_action(action)
return function(explorer)
local entry = explorer:cursor_node_entry()
if entry and entry.type == "file" then
close_preview()
end
explorer:action_call(action)
end
end
local function toggle_preview(explorer)
if preview_win then
local preview_win_is_valid = vim.api.nvim_win_is_valid(preview_win)
close_preview()
if preview_win_is_valid then
return
end
end
local entry = explorer:cursor_node_entry()
if not entry or entry.type ~= "file" then
return
end
if not explorer.win or not vim.api.nvim_win_is_valid(explorer.win.winid) then
return
end
fyler_win = explorer.win.winid
show_line_numbers(fyler_win)
fyler_win_config = vim.api.nvim_win_get_config(fyler_win)
if explorer.win.origin_win and vim.api.nvim_win_is_valid(explorer.win.origin_win) then
fyler_origin_win = explorer.win.origin_win
else
fyler_origin_win = nil
end
local margin = 2
local total_width = math.floor(vim.o.columns * 0.95)
local total_height = fyler_win_config.height
local fyler_width = math.floor(total_width * 0.45)
local preview_width = total_width - fyler_width - margin
local row = fyler_win_config.row
local col = math.floor((vim.o.columns - total_width) / 2)
vim.api.nvim_win_set_config(
fyler_win,
vim.tbl_extend("force", fyler_win_config, {
relative = "editor",
row = row,
col = col,
width = fyler_width,
height = total_height,
})
)
local buf = prepare_preview_buffer(entry.path)
preview_win = vim.api.nvim_open_win(buf, false, {
relative = "editor",
row = row,
col = col + fyler_width + margin,
width = preview_width,
height = total_height,
style = "minimal",
border = "rounded",
zindex = 40,
})
show_line_numbers(preview_win)
vim.wo[preview_win].wrap = false
set_preview_keymaps(buf)
preview_path = entry.path
preview_augroup = vim.api.nvim_create_augroup("fyler_preview", { clear = true })
vim.api.nvim_create_autocmd("CursorMoved", {
buffer = vim.api.nvim_win_get_buf(fyler_win),
group = preview_augroup,
callback = function()
update_preview(explorer:cursor_node_entry())
end,
})
vim.api.nvim_set_current_win(fyler_win)
end
return {
"A7Lavinraj/fyler.nvim",
dependencies = {
"nvim-tree/nvim-web-devicons",
},
keys = {
{ "<Space>t", open_fyler, desc = "Open Fyler" },
},
config = function(_, opts)
require("fyler").setup(opts)
local refresh_generation = 0
local group = vim.api.nvim_create_augroup("FylerAutoRefresh", { clear = true })
vim.api.nvim_create_autocmd({ "DiagnosticChanged", "BufWritePost", "FocusGained", "TermClose" }, {
group = group,
callback = function()
refresh_generation = refresh_generation + 1
local current_generation = refresh_generation
vim.defer_fn(function()
if current_generation ~= refresh_generation then
return
end
vim.api.nvim_exec_autocmds("User", { pattern = "DispatchRefresh" })
end, 500)
end,
})
end,
opts = {
integrations = {
icon = "nvim_web_devicons",
},
views = {
finder = {
columns_order = { "git", "diagnostic", "link", "permission", "size" },
columns = {
git = {
symbols = {
Untracked = "?",
Added = "",
Modified = "",
Deleted = "",
Renamed = "R",
Copied = "C",
Conflict = "!",
Ignored = " ",
},
},
diagnostic = {
symbols = {
Error = "",
Warn = "",
Info = "",
Hint = "",
},
},
},
icon = {
directory_empty = "",
directory_expanded = "",
directory_collapsed = "",
},
watcher = {
enabled = true,
},
mappings = {
["q"] = close_preview_before_action("n_close"),
["<CR>"] = close_preview_before_file_action("n_select"),
["<C-CR>"] = close_preview_before_file_action("n_select_v_split"),
["<C-s>"] = close_preview_before_file_action("n_select_split"),
["<C-t>"] = close_preview_before_file_action("n_select_tab"),
["-"] = "GotoParent",
["="] = "GotoCwd",
["<C-]>"] = close_preview_before_file_action("n_goto_node"),
["<C-p>"] = toggle_preview,
["<C-w>l"] = focus_preview,
["zC"] = "CollapseAll",
["zc"] = "CollapseNode",
-- Disable some default mappings
["|"] = "<nop>",
["^"] = "<nop>",
["."] = "<nop>",
["#"] = "<nop>",
["<BS>"] = "<nop>",
},
},
},
},
}
```
## リポジトリ
<div class="link-card-v2">
<div class="link-card-v2-site">
<img class="link-card-v2-site-icon" src="https://github.githubassets.com/favicons/favicon.svg" />
<span class="link-card-v2-site-name">GitHub</span>
</div>
<div class="link-card-v2-title">
toki/mnt/nvim/lua/plugins/fyler.lua at main · tadashi-aikawa/toki
</div>
<div class="link-card-v2-content">
macOSのセットアップ/カスタマイズプロジェクト 誓いの時は来た! 今 わたしは あなた(Windows)を超える!! - tadashi-aikawa/toki ...
</div>
<img class="link-card-v2-image" src="https://repository-images.githubusercontent.com/977129105/89cc86a4-ebae-4927-8d0e-a1707375fb45" />
<a href="https://github.com/tadashi-aikawa/toki/blob/main/mnt/nvim/lua/plugins/fyler.lua"></a>
</div>