From 4906827ece7a51e8d92bd108fd7f15395f8248fc Mon Sep 17 00:00:00 2001 From: n3wborn Date: Wed, 1 Jul 2026 00:58:48 +0200 Subject: [PATCH] feat(ui): add basic winbar config --- lua/config/init.lua | 1 + lua/config/winbar.lua | 76 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 77 insertions(+) create mode 100644 lua/config/winbar.lua diff --git a/lua/config/init.lua b/lua/config/init.lua index 0a36d27a..b4c306c3 100644 --- a/lua/config/init.lua +++ b/lua/config/init.lua @@ -2,3 +2,4 @@ require('config.keymaps') require('config.autocommands') require('config.lsp') require('config.options') +require('config.winbar') diff --git a/lua/config/winbar.lua b/lua/config/winbar.lua new file mode 100644 index 00000000..4ba2c9f2 --- /dev/null +++ b/lua/config/winbar.lua @@ -0,0 +1,76 @@ +local folder_icon = require('config.icons').kinds.Folder + +local M = {} + +--- Window bar that shows the current file path (in a fancy way). +---@return string +function M.render() + -- Get the path and expand variables. + local path = vim.fs.normalize(vim.fn.expand('%:p') --[[@as string]]) + + -- No special styling for diff views. + if vim.startswith(path, 'diffview') then + return string.format('%%#Winbar#%s', path) + end + + -- Replace slashes by arrows. + local separator = ' %#WinbarSeparator# ' + local prefix, prefix_path = '', '' + + -- If the window gets too narrow, shorten the path and drop the prefix. + if vim.api.nvim_win_get_width(0) < math.floor(vim.o.columns / 3) then + path = vim.fn.pathshorten(path) + else + -- For some special folders, add a prefix instead of the full path (making + -- sure to pick the longest prefix). + ---@type table + local special_dirs = { + DOTFILES = vim.env.XDG_CONFIG_HOME, + HOME = vim.env.HOME, + GIT = vim.g.git_dir, + WORK = vim.env.HOME .. '/Projects', + } + for dir_name, dir_path in pairs(special_dirs) do + if vim.startswith(path, vim.fs.normalize(dir_path)) and #dir_path > #prefix_path then + prefix, prefix_path = dir_name, dir_path + end + end + if prefix ~= '' then + path = path:gsub('^' .. vim.pesc(prefix_path), '') + prefix = string.format('%%#WinBarDir#%s %s%s', folder_icon, prefix, separator) + end + end + + -- Remove leading slash. + path = path:gsub('^/', '') + + return table.concat({ + ' ', + prefix, + table.concat( + vim.iter(vim.split(path, '/')) + :map(function(segment) + return string.format('%%#Winbar#%s', segment) + end) + :totable(), + separator + ), + }) +end + +vim.api.nvim_create_autocmd('BufWinEnter', { + group = vim.api.nvim_create_augroup('my.winbar', { clear = true }), + desc = 'Attach winbar', + callback = function(args) + if + not vim.api.nvim_win_get_config(0).zindex -- Not a floating window + and vim.bo[args.buf].buftype == '' -- Normal buffer + and vim.api.nvim_buf_get_name(args.buf) ~= '' -- Has a file name + and not vim.wo[0].diff -- Not in diff mode + then + vim.wo.winbar = "%{%v:lua.require'config.winbar'.render()%}" + end + end, +}) + +return M