diff options
Diffstat (limited to 'lua/plugins/heirline.backup.lua')
| -rw-r--r-- | lua/plugins/heirline.backup.lua | 733 |
1 files changed, 733 insertions, 0 deletions
diff --git a/lua/plugins/heirline.backup.lua b/lua/plugins/heirline.backup.lua new file mode 100644 index 0000000..d65de92 --- /dev/null +++ b/lua/plugins/heirline.backup.lua @@ -0,0 +1,733 @@ +local conditions = require("heirline.conditions") +local utils = require("heirline.utils") + +require("nvim-gps").setup({ + icons = { + ["class-name"] = " ", + ["function-name"] = " ", + ["method-name"] = " ", + ["container-name"] = "炙", + ["tag-name"] = "炙", + }, +}) + +vim.o.laststatus = 3 + +local colors = { + bg = "#333842", + brown = "#504945", + white = "#f8f8f0", + grey = "#8F908A", + black = "#000000", + pink = "#f92672", + green = "#a6e22e", + blue = "#66d9ef", + yellow = "#e6db74", + orange = "#fd971f", + purple = "#ae81ff", + red = "#e95678", + diag = { + warn = utils.get_highlight("DiagnosticSignWarn").fg, + error = utils.get_highlight("DiagnosticSignError").fg, + hint = utils.get_highlight("DiagnosticSignHint").fg, + info = utils.get_highlight("DiagnosticSignInfo").fg, + }, + git = { + del = "#e95678", + add = "#a6e22e", + change = "#ae81ff", + }, +} + +local ViMode = { + -- get vim current mode, this information will be required by the provider + -- and the highlight functions, so we compute it only once per component + -- evaluation and store it as a component attribute + init = function(self) + self.mode = vim.fn.mode(1) -- :h mode() + end, + -- Now we define some dictionaries to map the output of mode() to the + -- corresponding string and color. We can put these into `static` to compute + -- them at initialisation time. + static = { + mode_names = { + -- change the strings if you like it vvvvverbose! + ["n"] = "NORMAL ", + ["no"] = "N·OPERATOR PENDING ", + ["v"] = "VISUAL ", + ["V"] = "V·LINE ", + [""] = "V·BLOCK ", + ["s"] = "SELECT ", + ["S"] = "S·LINE ", + [""] = "S·BLOCK ", + ["i"] = "INSERT ", + ["R"] = "REPLACE ", + ["Rv"] = "V·REPLACE ", + ["c"] = "COMMAND ", + ["cv"] = "VIM EX ", + ["ce"] = "EX ", + ["r"] = "PROMPT ", + ["rm"] = "MORE ", + ["r?"] = "CONFIRM ", + ["!"] = "SHELL ", + ["t"] = "TERMINAL ", + }, + mode_colors = { + n = colors.green, + i = colors.pink, + v = colors.blue, + V = colors.blue, + [""] = colors.blue, + c = colors.red, + s = colors.purple, + S = colors.purple, + [""] = colors.purple, + R = colors.orange, + r = colors.orange, + ["!"] = colors.red, + t = colors.red, + }, + }, + -- We can now access the value of mode() that, by now, would have been + -- computed by `init()` and use it to index our strings dictionary. + -- note how `static` fields become just regular attributes once the + -- component is instantiated. + -- To be extra meticulous, we can also add some vim statusline syntax to + -- control the padding and make sure our string is always at least 2 + -- characters long. Plus a nice Icon. + provider = function(self) + return " %2(" .. self.mode_names[self.mode] .. "%)" + end, + -- Same goes for the highlight. Now the foreground will change according to the current mode. + hl = function(self) + local mode = self.mode:sub(1, 1) -- get only the first mode character + return { bg = self.mode_colors[mode], fg = colors.bg, bold = true } + end, +} + +local FileNameBlock = { + -- let's first set up some attributes needed by this component and it's children + init = function(self) + self.filename = vim.api.nvim_buf_get_name(0) + end, +} +-- We can now define some children separately and add them later + +local FileIcon = { + init = function(self) + local filename = self.filename + local extension = vim.fn.fnamemodify(filename, ":e") + self.icon, self.icon_color = + require("nvim-web-devicons").get_icon_color(filename, extension, { default = true }) + end, + provider = function(self) + return self.icon and (self.icon .. " ") + end, + hl = function(self) + return { fg = self.icon_color, bg = colors.bg } + end, +} + +local FileName = { + provider = function(self) + -- first, trim the pattern relative to the current directory. For other + -- options, see :h filename-modifers + local filename = vim.fn.fnamemodify(self.filename, ":.") + if filename == "" then + return "[No Name]" + end + -- now, if the filename would occupy more than 1/4th of the available + -- space, we trim the file path to its initials + -- See Flexible Components section below for dynamic truncation + if not conditions.width_percent_below(#filename, 0.25) then + filename = vim.fn.pathshorten(filename) + end + return filename + end, + hl = { fg = utils.get_highlight("Directory").fg, bg = colors.bg }, +} + +local FileFlags = { + { + provider = function() + if vim.bo.modified then + return " [+]" + end + end, + hl = { fg = colors.green, bg = colors.bg }, + }, + { + provider = function() + if not vim.bo.modifiable or vim.bo.readonly then + return "" + end + end, + hl = { fg = colors.orange }, + }, +} + +-- Now, let's say that we want the filename color to change if the buffer is +-- modified. Of course, we could do that directly using the FileName.hl field, +-- but we'll see how easy it is to alter existing components using a "modifier" +-- component + +local FileNameModifer = { + hl = function() + if vim.bo.modified then + -- use `force` because we need to override the child's hl foreground + return { fg = colors.cyan, bold = true, force = true, bg = colors.bg } + end + end, +} + +-- let's add the children to our FileNameBlock component +FileNameBlock = utils.insert( + FileNameBlock, + FileIcon, + utils.insert(FileNameModifer, FileName), -- a new table where FileName is a child of FileNameModifier + unpack(FileFlags), -- A small optimisation, since their parent does nothing + { provider = "%<" } -- this means that the statusline is cut here when there's not enough space +) + +local Diagnostics = { + condition = conditions.has_diagnostics, + static = { + error_icon = vim.fn.sign_getdefined("DiagnosticSignError")[1].text, + warn_icon = vim.fn.sign_getdefined("DiagnosticSignWarn")[1].text, + info_icon = vim.fn.sign_getdefined("DiagnosticSignInfo")[1].text, + hint_icon = vim.fn.sign_getdefined("DiagnosticSignHint")[1].text, + }, + init = function(self) + self.errors = #vim.diagnostic.get(0, { severity = vim.diagnostic.severity.ERROR }) + self.warnings = #vim.diagnostic.get(0, { severity = vim.diagnostic.severity.WARN }) + self.hints = #vim.diagnostic.get(0, { severity = vim.diagnostic.severity.HINT }) + self.info = #vim.diagnostic.get(0, { severity = vim.diagnostic.severity.INFO }) + end, + { + provider = function(self) + -- 0 is just another output, we can decide to print it or not! + return self.errors > 0 and (self.error_icon .. self.errors .. " ") + end, + hl = { fg = colors.diag.error, bg = colors.bg }, + }, + { + provider = function(self) + return self.warnings > 0 and (self.warn_icon .. self.warnings .. " ") + end, + hl = { fg = colors.diag.warn, bg = colors.bg }, + }, + { + provider = function(self) + return self.info > 0 and (self.info_icon .. self.info .. " ") + end, + hl = { fg = colors.diag.info, bg = colors.bg }, + }, + { + provider = function(self) + return self.hints > 0 and (self.hint_icon .. self.hints) + end, + hl = { fg = colors.diag.hint, bg = colors.bg }, + }, +} + +local Git = { + condition = conditions.is_git_repo, + init = function(self) + self.status_dict = vim.b.gitsigns_status_dict + self.has_changes = self.status_dict.added ~= 0 or self.status_dict.removed ~= 0 or self.status_dict.changed ~= 0 + end, + hl = { fg = colors.orange, bg = colors.bg }, + { + -- git branch name + provider = function(self) + return " " .. self.status_dict.head + end, + hl = { bold = true, bg = colors.bg }, + }, + -- You could handle delimiters, icons and counts similar to Diagnostics + { + condition = function(self) + return self.has_changes + end, + provider = " ", + }, + { + provider = function(self) + local count = self.status_dict.added or 0 + return count > 0 and (" " .. count) + end, + hl = { fg = colors.git.add, bg = colors.bg }, + }, + { + provider = function(self) + local count = self.status_dict.removed or 0 + return count > 0 and (" " .. count) + end, + hl = { fg = colors.git.del, bg = colors.bg }, + }, + { + provider = function(self) + local count = self.status_dict.changed or 0 + return count > 0 and (" " .. count) + end, + hl = { fg = colors.git.change, bg = colors.bg }, + }, +} + +local WorkDir = { + provider = function() + local icon = " " + local cwd = vim.fn.getcwd(0) + cwd = vim.fn.fnamemodify(cwd, ":~") + if not conditions.width_percent_below(#cwd, 0.25) then + cwd = vim.fn.pathshorten(cwd) + end + local trail = cwd:sub(-1) == "/" and "" or "/" + return icon .. cwd .. trail + end, + hl = { fg = colors.blue, bold = true, bg = colors.bg }, +} + +local TerminalName = { + -- we could add a condition to check that buftype == 'terminal' + -- or we could do that later (see #conditional-statuslines below) + provider = function() + local tname, _ = vim.api.nvim_buf_get_name(0):gsub(".*:", "") + return " " .. tname + end, + hl = { bold = true, bg = colors.bg }, +} + +local Ruler = { + -- %l = current line number + -- %L = number of lines in the buffer + -- %c = column number + -- %P = percentage through file of displayed window + provider = "%7 %p%% Ln %l, Col %c", +} + +local Align = { provider = "%=", hl = { bg = colors.bg } } +local Space = { provider = " " } + +local FileInfoBlock = { + -- let's first set up some attributes needed by this component and it's children + init = function(self) + self.filename = vim.api.nvim_buf_get_name(0) + end, +} + +local FileType = { + provider = function() + return vim.bo.filetype + end, + hl = { fg = utils.get_highlight("Statusline").fg, bold = true, bg = colors.bg }, +} + +local FileEncoding = { + provider = function() + local enc = (vim.bo.fenc ~= "" and vim.bo.fenc) or vim.o.enc -- :h 'enc' + return enc:upper() + end, +} + +FileInfoBlock = utils.insert( + FileInfoBlock, + FileEncoding, + Space, + FileIcon, + FileType, + { provider = "%<" } -- this means that the statusline is cut here when there's not enough space +) + +local FileNameShort = { + provider = function(self) + -- first, trim the pattern relative to the current directory. For other + -- options, see :h filename-modifers + local filename = vim.fn.fnamemodify(self.filename, ":t") + if filename == "" then + return "[No Name]" + end + return filename + end, + hl = { fg = colors.gray, bg = colors.bg }, +} + +local FileNameShortBlock = { + init = function(self) + self.filename = vim.api.nvim_buf_get_name(0) + end, +} + +FileNameShortBlock = utils.insert( + FileNameShortBlock, + FileIcon, + FileNameShort, + { provider = "%<" } -- this means that the statusline is cut here when there's not enough space +) + +local Gps = { + condition = require("nvim-gps").is_available, + provider = function() + local loc = require("nvim-gps").get_location() + if loc == "" then + return "" + end + return "> " .. loc + end, + hl = { fg = colors.gray, bg = colors.bg }, +} + +local DefaultStatusline = { + ViMode, + Space, + FileNameBlock, + Space, + Diagnostics, + Align, + Ruler, + Space, + FileInfoBlock, + Space, + Git, +} + +local SpecialStatusline = { + condition = function() + return conditions.buffer_matches({ + buftype = { "nofile", "prompt", "help", "quickfix" }, + filetype = { "^git.*", "fugitive" }, + }) + end, + FileType, + Space, + Align, +} + +local TerminalStatusline = { + condition = function() + return conditions.buffer_matches({ buftype = { "terminal" } }) + end, + TerminalName, + Align, +} + +local StatusLines = { + fallthrough = false, + SpecialStatusline, + TerminalStatusline, + DefaultStatusline, +} + +local GSpace = { provider = " ", hl = { bg = colors.bg } } + +local WinBars = { + fallthrough = false, + { + -- Hide the winbar for special buffers + condition = function() + return conditions.buffer_matches({ + buftype = { "nofile", "prompt", "help", "quickfix", "nofile", "promt" }, + filetype = { "^git.*", "fugitive" }, + }) + end, + provider = "", + }, + { + -- An inactive winbar for regular files + condition = function() + return conditions.buffer_matches({ buftype = { "terminal" } }) and not conditions.is_active() + end, + utils.surround( + { "", "" }, + colors.bright_bg, + { hl = { fg = "gray", force = true }, GSpace, TerminalName, Align } + ), + }, + { + -- A special winbar for terminals + condition = function() + return conditions.buffer_matches({ buftype = { "terminal" } }) + end, + utils.surround({ "", "" }, colors.dark_red, { + GSpace, + TerminalName, + Align, + }), + }, + { + -- An inactive winbar for regular files + condition = function() + return not conditions.is_active() + end, + utils.surround( + { "", "" }, + colors.bright_bg, + { hl = { fg = "gray", force = true }, GSpace, FileNameShortBlock, Align } + ), + }, + -- A winbar for regular files + { GSpace, FileNameShortBlock, GSpace, Gps, Align }, +} + +vim.api.nvim_create_autocmd("User", { + pattern = "HeirlineInitWinbar", + callback = function(args) + local buf = args.buf + local buftype = vim.tbl_contains({ "prompt", "nofile", "help", "quickfix" }, vim.bo[buf].buftype) + local filetype = vim.tbl_contains({ "gitcommit", "fugitive" }, vim.bo[buf].filetype) + if buftype or filetype then + vim.opt_local.winbar = nil + end + end, +}) + +-- we redefine the filename component, as we probably only want the tail and not the relative path +local TablineFileName = { + provider = function(self) + -- self.filename will be defined later, just keep looking at the example! + local filename = self.filename + filename = filename == "" and "[No Name]" or vim.fn.fnamemodify(filename, ":t") + return filename + end, + hl = function(self) + return { bold = self.is_active or self.is_visible, italic = true } + end, +} + +local TablineFileFlags = { + { + provider = function(self) + if vim.bo[self.bufnr].modified then + return " [+]" + end + end, + hl = { fg = colors.green }, + }, + { + provider = function(self) + if not vim.bo[self.bufnr].modifiable or vim.bo[self.bufnr].readonly then + return "" + end + end, + hl = { fg = "orange" }, + }, +} + +local TablineDiagnostics = { + static = { + error_icon = " " .. vim.fn.sign_getdefined("DiagnosticSignError")[1].text, + warn_icon = " " .. vim.fn.sign_getdefined("DiagnosticSignWarn")[1].text, + info_icon = " " .. vim.fn.sign_getdefined("DiagnosticSignInfo")[1].text, + hint_icon = " " .. vim.fn.sign_getdefined("DiagnosticSignHint")[1].text, + }, + init = function(self) + self.errors = #vim.diagnostic.get(self.bufnr, { severity = vim.diagnostic.severity.ERROR }) + self.warnings = #vim.diagnostic.get(self.bufnr, { severity = vim.diagnostic.severity.WARN }) + self.hints = #vim.diagnostic.get(self.bufnr, { severity = vim.diagnostic.severity.HINT }) + self.info = #vim.diagnostic.get(self.bufnr, { severity = vim.diagnostic.severity.INFO }) + end, + { + provider = function(self) + return self.errors > 0 and (self.error_icon .. self.errors .. " ") + end, + hl = { fg = colors.diag.error }, + }, + { + provider = function(self) + return self.warnings > 0 and (self.warn_icon .. self.warnings .. " ") + end, + hl = { fg = colors.diag.warn }, + }, + { + provider = function(self) + return self.info > 0 and (self.info_icon .. self.info .. " ") + end, + hl = { fg = colors.diag.info }, + }, + { + provider = function(self) + return self.hints > 0 and (self.hint_icon .. self.hints) + end, + hl = { fg = colors.diag.hint }, + }, +} + +local TablineFileIcon = { + init = function(self) + local filename = self.filename + local extension = vim.fn.fnamemodify(filename, ":e") + self.icon, self.icon_color = + require("nvim-web-devicons").get_icon_color(filename, extension, { default = true }) + end, + provider = function(self) + return self.icon and (" " .. self.icon .. " ") + end, + hl = function(self) + return { fg = self.icon_color } + end, +} + +-- Here the filename block finally comes together +local TablineFileNameBlock = { + init = function(self) + self.filename = vim.api.nvim_buf_get_name(self.bufnr) + end, + hl = function(self) + if self.is_active then + return "TabLineSel" + else + return "TabLine" + end + end, + on_click = { + callback = function(_, minwid, _, button) + if button == "m" then -- close on mouse middle click + vim.api.nvim_buf_delete(minwid, { force = true }) + else + vim.api.nvim_win_set_buf(0, minwid) + end + end, + minwid = function(self) + return self.bufnr + end, + name = "heirline_tabline_buffer_callback", + }, + TablineFileIcon, + TablineFileName, + TablineFileFlags, + TablineDiagnostics, +} + +-- a nice "x" button to close the buffer +local TablineCloseButton = { + condition = function(self) + return not vim.bo[self.bufnr].modified + end, + { provider = " " }, + { + provider = "", + hl = { fg = "gray" }, + on_click = { + callback = function(_, minwid) + vim.api.nvim_buf_delete(minwid, { force = false }) + end, + minwid = function(self) + return self.bufnr + end, + name = "heirline_tabline_close_buffer_callback", + }, + }, +} + +-- The final touch! +local TablineBufferBlock = utils.surround({ "", "" }, function(self) + if self.is_active then + return utils.get_highlight("TabLineSel").bg + else + return utils.get_highlight("TabLine").bg + end +end, { TablineFileNameBlock, TablineCloseButton }) + +-- and here we go +local BufferLine = utils.make_buflist( + TablineBufferBlock, + { provider = "", hl = { fg = "gray" } }, -- left truncation, optional (defaults to "<") + { provider = "", hl = { fg = "gray" } } -- right trunctation, also optional (defaults to ...... yep, ">") + -- by the way, open a lot of buffers and try clicking them ;) +) + +local TabLineOffset = { + condition = function(self) + local win = vim.api.nvim_tabpage_list_wins(0)[1] + local bufnr = vim.api.nvim_win_get_buf(win) + self.winid = win + + if vim.bo[bufnr].filetype == "NvimTree" then + self.title = "NvimTree" + return true + -- elseif vim.bo[bufnr].filetype == "TagBar" then + -- ... + end + end, + provider = function(self) + local title = self.title + local width = vim.api.nvim_win_get_width(self.winid) + local pad = math.ceil((width - #title) / 2) + return string.rep(" ", pad) .. title .. string.rep(" ", pad) + end, + hl = function(self) + if vim.api.nvim_get_current_win() == self.winid then + return "TablineSel" + else + return "Tabline" + end + end, +} + +local Tabpage = { + provider = function(self) + return "%" .. self.tabnr .. "T " .. self.tabnr .. " %T" + end, + hl = function(self) + if not self.is_active then + return "TabLine" + else + return "TabLineSel" + end + end, +} + +local TabpageClose = { + provider = "%999X %X", + hl = "TabLine", +} + +local TabPages = { + -- only show this component if there's 2 or more tabpages + condition = function() + return #vim.api.nvim_list_tabpages() >= 2 + end, + { provider = "%=" }, + utils.make_tablist(Tabpage), + TabpageClose, +} + +local TabLine = { TabLineOffset, BufferLine, TabPages } + +require("heirline").setup(StatusLines, WinBars, TabLine) + +vim.cmd([[au FileType * if index(['wipe', 'delete', 'unload'], &bufhidden) >= 0 | set nobuflisted | endif]]) + +vim.api.nvim_create_augroup("Heirline", { clear = true }) +vim.api.nvim_create_autocmd("ColorScheme", { + callback = function() + local colors = setup_colors() + utils.on_colorscheme(colors) + end, + group = "Heirline", +}) + +local function get_bufs() + return vim.tbl_filter(function(bufnr) + return vim.api.nvim_buf_is_loaded(bufnr) and vim.bo[bufnr].buflisted + end, vim.api.nvim_list_bufs()) +end + +local function goto_buf(index) + local bufs = get_bufs() + if index > #bufs then + index = #bufs + end + vim.api.nvim_win_set_buf(0, bufs[index]) +end + +local function addKey(key, index) + vim.keymap.set("", "<A-" .. key .. ">", function() + goto_buf(index) + end, { noremap = true, silent = true }) +end + +for i = 1, 9 do + addKey(i, i) +end +addKey("0", 10) |
