From ea0a8eefb9300efb17e4be847818f64c9ebce2b7 Mon Sep 17 00:00:00 2001 From: Fernando Schauenburg Date: Sun, 20 Aug 2023 03:08:49 +0200 Subject: [PATCH] Humble beginning... --- config/nvim/lua/fschauen/init.lua | 2 + .../plugins/{lualine.lua => lualine.lua.off} | 0 config/nvim/lua/testline.lua | 169 ++++++++++++++++++ 3 files changed, 171 insertions(+) rename config/nvim/lua/fschauen/plugins/{lualine.lua => lualine.lua.off} (100%) create mode 100644 config/nvim/lua/testline.lua diff --git a/config/nvim/lua/fschauen/init.lua b/config/nvim/lua/fschauen/init.lua index 69be5ab..eef8ad3 100644 --- a/config/nvim/lua/fschauen/init.lua +++ b/config/nvim/lua/fschauen/init.lua @@ -228,6 +228,8 @@ M.setup = function() if vim.v.errmsg ~= '' then vim.notify(('Colorscheme %s not found!'):format(colorscheme), vim.log.levels.WARN) end + + require('testline').setup() end return M diff --git a/config/nvim/lua/fschauen/plugins/lualine.lua b/config/nvim/lua/fschauen/plugins/lualine.lua.off similarity index 100% rename from config/nvim/lua/fschauen/plugins/lualine.lua rename to config/nvim/lua/fschauen/plugins/lualine.lua.off diff --git a/config/nvim/lua/testline.lua b/config/nvim/lua/testline.lua new file mode 100644 index 0000000..eb16fb5 --- /dev/null +++ b/config/nvim/lua/testline.lua @@ -0,0 +1,169 @@ +local M = {} + +local object = (function() + local obj = {} + obj.__index = obj + + function obj:init(...) end + + function obj:new(...) + local new = setmetatable({}, self) + new:init(...) + return new + end + + function obj:extend() + local cls = {} + cls.__index = cls + cls.super = self + return setmetatable(cls, self) + end + + return obj +end)() + +local segment = (function() + local segment = object:extend() + + function segment:init(opts) + self.opts = opts or {} + end + + function segment:render() + return self.opts + end + + function segment.make(f) + local new = segment:extend() + function new:render(...) return f(...) end + return new + end + + return segment +end)() + +local mode = (function() + local mode = segment:extend() + + mode.map = { + ['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'] = '', -- ' modeore ', -- -- modeORE -- + ['r?'] = '󰭚', -- 'Confirm', -- :confirm + ['!'] = '', -- ' Shell ', -- External command executing + ['t'] = '', -- ' Term ', -- Terminal + } + + function mode:render() + -- if not is_focused then return ' 󰒲 ' end -- TODO: handle inactive windows + local code = vim.api.nvim_get_mode().mode:lower() + local symbol = mode.map[code:sub(1, 2)] or mode.map[code:sub(1, 1)] or code + return ' ' .. symbol .. ' ' + end + + return mode +end)() + +-- FIX: actually find the branch +local branch = segment.make(function() return '󰘬 main' end) + +local filename = segment.make(function() return vim.fn.expand('%:~:.') end) + +local modified = segment.make(function() return vim.bo.modified and '' or '' end) + +local readonly = segment.make(function() return (vim.bo.readonly or not vim.bo.modifiable) and '󰏯' or '' end) + +local searchcount = segment.make(function() + if vim.v.hlsearch == 1 then + local count = vim.fn.searchcount { maxcount = 999, timeout = 250 } + if count.total > 1 then + return (' %d/%s'):format( + count.current, + count.total > count.maxcount and '' or ('%d'):format(count.total)) + end + end + return '' +end) + +-- TODO: handle inactive windows +-- TODO: add icons +local filetype = segment.make(function() return vim.bo.filetype end) + +local fileformat = segment.make(function() + local icons = { unix = '', dos = '', mac = '' } + return icons[vim.bo.fileformat] or vim.bo.fileformat +end) + +local progress = segment.make(function() + local line, total = vim.fn.line('.'), vim.fn.line('$') + return + line == 1 and ' 󰘣 ' or + line == total and ' 󰘡 ' or + ('%2d%%%%'):format(math.floor(100 * line / total)) +end) + +local location = segment.make(function() return ('%3d:%-2d'):format(vim.fn.line('.'), vim.fn.virtcol('.')) end) + +local whitespace = segment.make(function() + local trailing = [[\s\+$]] + local line = vim.fn.search(trailing, 'nwc') + if line == 0 then + return '' + else + local result = (' %d'):format(line) + local total = vim.fn.searchcount({ pattern = trailing }).total + return result .. (total > 1 and (' (%d total)'):format(total) or '') + end +end) + +local literal = function(s) return segment.make(function() return s end) end + +local defaults = { + -- TODO: paste + mode, + branch, + modified, + readonly, + filename, + literal '%=', + searchcount, + literal '%=', + -- TODO: diagnostics + filetype, + fileformat, + progress, + location, + whitespace, +} + +M.render = function() + local rendered = vim.tbl_map(function(comp) return comp:render() end, defaults) + local non_empty = vim.tbl_filter(function(item) return #item > 0 end, rendered) + return vim.fn.join(non_empty, ' ') +end + +M.setup = function() + local colors = require('gruvbox').colors() + vim.api.nvim_set_hl(0, 'StatusLine', { fg = colors.fg2, bg = colors.bg1 }) + + -- vim.api.nvim_set_hl(0, 'TestlineNormal', { fg = colors.bg0, bg = colors.blue }) + -- vim.api.nvim_set_hl(0, 'TestlineInsert', { fg = colors.bg0, bg = colors.green }) + -- vim.api.nvim_set_hl(0, 'TestlineVisual', { fg = colors.bg0, bg = colors.purple }) + -- vim.api.nvim_set_hl(0, 'TestlineReplace', { fg = colors.bg0, bg = colors.red }) + -- vim.api.nvim_set_hl(0, 'TestlineCommand', { fg = colors.bg0, bg = colors.yellow }) + + vim.opt.statusline=[[%{%v:lua.require('testline').render()%}]] +end + +return M +