diff --git a/config/nvim/lua/fschauen/lualine.lua b/config/nvim/lua/fschauen/lualine.lua new file mode 100644 index 0000000..5b7789b --- /dev/null +++ b/config/nvim/lua/fschauen/lualine.lua @@ -0,0 +1,124 @@ +local M = {} + +local window = require('fschauen.window') + +local colored_when_focused = function(component) + local new = require(component):extend() + function new:update_status(is_focused) + self.options.colored = is_focused + return self.super.update_status(self, is_focused) + end + return new +end + +local diff = colored_when_focused('lualine.components.diff') + +local branch = { + 'branch', + icon = '', + cond = window.is_medium, +} + +local fileformat = { + 'fileformat', + cond = window.is_medium, +} + +local filename = { + function() + local shorten_path = function(path) + if window.is_wide() then + return path + elseif window.is_medium() then + return vim.fn.pathshorten(path) -- only first letter of directories + else + return vim.fn.fnamemodify(path, ':t') -- only tail + end + end + + return shorten_path(vim.fn.expand('%:~:.')) + end, + + padding = { left = 1, right = 0 }, +} + +local filetype = { + colored_when_focused('lualine.components.filetype'), + cond = window.is_medium, +} + +local mode = { + (function() + local MODES = { + ['n'] = '  ', -- 'Normal ', -- Normal + ['no'] = '  ', -- 'O-Pend ', -- Operator-pending + ['ni'] = '  ', -- 'Normal ', -- Normal via i_CTRL-O + ['v'] = ' 󰒉 ', -- 'Visual ', -- Visual by character + [''] = ' 󰩭 ', -- 'V-Block', -- Visual blockwise + ['s'] = ' 󰒉 ', -- 'Select ', -- Select by character + [''] = ' 󰩭 ', -- 'S-Block', -- Select blockwise + ['i'] = '  ', -- 'Insert ', -- Insert + ['r'] = ' 󰄾 ', -- 'Replace', -- Replace + ['rv'] = ' 󰶻 ', -- 'V-Repl ', -- Virtual Replace + ['c'] = '  ', -- 'Command', -- Command-line + ['cv'] = '  ', -- ' Ex ', -- Ex mode + ['rm'] = '  ', -- ' More ', -- -- MORE -- + ['r?'] = ' 󰭚 ', -- 'Confirm', -- :confirm + ['!'] = '  ', -- ' Shell ', -- External command executing + ['t'] = '  ', -- ' Term ', -- Terminal + } + return function() + local code = vim.api.nvim_get_mode().mode + return MODES[code:sub(1, 2):lower()] or MODES[code:sub(1, 1):lower()] or code + end + end)() +} + +local paste = { + function() return '' end, + color = { bg = '#fe8019' }, + cond = function() return vim.opt.paste:get() end +} + +local status = { + function() + local flags = vim.list_extend( + vim.bo.modified and { '+' } or {}, + (vim.bo.readonly or not vim.bo.modifiable) and { 'RO' } or {}) + return vim.fn.join(flags, ' ') + end, + + color = { + fg = '#eee8d5', + gui = 'bold' + }, +} + +local visual_multi = function() + local info = vim.F.npcall(vim.fn.VMInfos) + if info and info.status then + return info.current .. '/' .. info.total .. ' ' .. info.status + else + return '' + end +end + +local default = { + lualine_a = {}, + lualine_b = { visual_multi, branch }, + lualine_c = { diff, filename, status }, + lualine_x = { filetype }, + lualine_y = { fileformat, 'progress' }, + lualine_z = { 'location' }, +} + +M.sections = { + inactive = default, + active = vim.tbl_extend('force', default, { + lualine_a = vim.list_extend({ paste, mode }, default.lualine_a), + lualine_x = vim.list_extend({ 'diagnostics' }, default.lualine_x), + }) +} + +return M + diff --git a/config/nvim/lua/fschauen/plugins/lualine.lua b/config/nvim/lua/fschauen/plugins/lualine.lua index e4d844e..f44dbb7 100644 --- a/config/nvim/lua/fschauen/plugins/lualine.lua +++ b/config/nvim/lua/fschauen/plugins/lualine.lua @@ -1,152 +1,30 @@ -local config = function() - local get_mode_icon = function() - local MODES = { - ['n'] = '  ', -- 'Normal ', -- Normal - ['no'] = '  ', -- 'O-Pend ', -- Operator-pending - ['ni'] = '  ', -- 'Normal ', -- Normal via i_CTRL-O - ['v'] = ' 󰒉 ', -- 'Visual ', -- Visual by character - [''] = ' 󰩭 ', -- 'V-Block', -- Visual blockwise - ['s'] = ' 󰒉 ', -- 'Select ', -- Select by character - [''] = ' 󰩭 ', -- 'S-Block', -- Select blockwise - ['i'] = '  ', -- 'Insert ', -- Insert - ['r'] = ' 󰄾 ', -- 'Replace', -- Replace - ['rv'] = ' 󰶻 ', -- 'V-Repl ', -- Virtual Replace - ['c'] = '  ', -- 'Command', -- Command-line - ['cv'] = '  ', -- ' Ex ', -- Ex mode - ['rm'] = '  ', -- ' More ', -- -- MORE -- - ['r?'] = ' 󰭚 ', -- 'Confirm', -- :confirm - ['!'] = '  ', -- ' Shell ', -- External command executing - ['t'] = '  ', -- ' Term ', -- Terminal - } - return function() - local code = vim.api.nvim_get_mode().mode - return MODES[code:sub(1, 2):lower()] or MODES[code:sub(1, 1):lower()] or code - end - end - - local colored_when_focused = function(component) - local new = require(component):extend() - function new:update_status(is_focused) - self.options.colored = is_focused - return self.super.update_status(self, is_focused) - end - return new - end - - local window_is_at_least = function(width) - return function() return vim.fn.winwidth(0) > width end - end - - local window_is_wide = window_is_at_least(80) - local window_is_medium = window_is_at_least(50) - - local my = { - paste = { - function() return '' end, - color = { bg = '#bbaa00' }, - cond = function() - return vim.opt.paste:get() - end - }, - - diff = colored_when_focused('lualine.components.diff'), - - mode = { get_mode_icon() }, - - visual_multi = function() - local info = vim.F.npcall(vim.fn.VMInfos) - if info and info.status then - return info.current .. '/' .. info.total .. ' ' .. info.status - else - return '' - end - end, - - branch = { - 'branch', - icon = '', - cond = window_is_medium, - }, - - status = { - function() - local flags = vim.list_extend( - vim.bo.modified and {'+'} or {}, - (vim.bo.readonly or not vim.bo.modifiable) and {'RO'} or {}) - return vim.fn.join(flags, ' ') - end, - - color = { fg = '#eee8d5', gui = 'bold' }, - }, - - filename = { - function() - local shorten_path = function(path) - if window_is_wide() then - return path - elseif window_is_medium() then - return vim.fn.pathshorten(path) -- only first letter of directories - else - return vim.fn.fnamemodify(path, ':t') -- only tail - end - end - - return shorten_path(vim.fn.expand('%:~:.')) - end, - - padding = { left = 1, right = 0}, - }, - - filetype = { - colored_when_focused('lualine.components.filetype'), - cond = window_is_medium, - }, - - fileformat = { - 'fileformat', - cond = window_is_medium, - }, - } - - local inactive_sections = { - lualine_a = {}, - lualine_b = { my.visual_multi, my.branch }, - lualine_c = { my.diff, my.filename, my.status }, - lualine_x = { my.filetype }, - lualine_y = { my.fileformat, 'progress' }, - lualine_z = { 'location' }, - } - - - local active_sections = vim.tbl_extend('force', inactive_sections, { - lualine_a = vim.list_extend({ my.paste, my.mode }, inactive_sections.lualine_a), - lualine_x = vim.list_extend({ 'diagnostics' }, inactive_sections.lualine_x), - }) - - require('lualine').setup { - options = { - icons_enabled = true, - component_separators = { left = '', right = '' }, - section_separators = { left = '', right = '' }, - theme = 'gruvbox', - }, - - sections = active_sections, - inactive_sections = inactive_sections, - - extensions = { - 'fugitive', - 'quickfix', - 'nvim-tree', - 'lazy', - 'man', - 'trouble', - }, - } -end - return { 'nvim-lualine/lualine.nvim', - config = config, + opts = function() + return { + options = { + icons_enabled = true, + component_separators = { + left = '', + right = '' + }, + section_separators = { + left = '', + right = '' + }, + theme = 'gruvbox', + }, + sections = require('fschauen.lualine').sections.active, + inactive_sections = require('fschauen.lualine').sections.inactive, + extensions = { + 'fugitive', + 'quickfix', + 'nvim-tree', + 'lazy', + 'man', + 'trouble', + }, + } + end } diff --git a/config/nvim/lua/fschauen/window.lua b/config/nvim/lua/fschauen/window.lua index 8313ff3..d7909e4 100644 --- a/config/nvim/lua/fschauen/window.lua +++ b/config/nvim/lua/fschauen/window.lua @@ -1,4 +1,18 @@ -M = {} +local M = {} + +---Determine whether the window is wide. +---@param win_nr integer|nil: window number or window-ID, 0 for current window. +---@return boolean +M.is_wide = function(win_nr) + return vim.fn.winwidth(win_nr or 0) > 80 +end + +---Determine whether the window is medium. +---@param win_nr integer|nil: window number or window-ID, 0 for current window. +---@return boolean +M.is_medium = function(win_nr) + return vim.fn.winwidth(win_nr or 0) > 50 +end ---Whether the current window is the last in a given direction. ---@param direction string: one of 'h', 'j', 'k', or 'l'