local M = {} local conditions = require("heirline.conditions") local utils = require("heirline.utils") M.Names = { condition = conditions.lsp_attached, update = { "LspAttach", "LspDetach" }, -- You can keep it simple, -- provider = " [LSP]", -- Or complicate things a bit and get the servers names provider = function() local names = {} for _, server in pairs(vim.lsp.get_clients({ bufnr = 0 })) do table.insert(names, server.name) end return "  [" .. table.concat(names, " ") .. "] " end, hl = { fg = "green_base", bold = true }, } M.Navic = utils.surround({ "\u{e0ba}", "\u{e0bc}" }, "bg2", { condition = function() return require("nvim-navic").is_available() end, static = { -- create a type highlight map type_hl = { File = "NavicIconsFile", Module = "NavicIconsModule", Namespace = "NavicIconsNamespace", Package = "NavicIconsPackage", Class = "NavicIconsClass", Method = "NavicIconsMethod", Property = "NavicIconsProperty", Field = "NavicIconsField", Constructor = "NavicIconsConstructor", Enum = "NavicIconsEnum", Interface = "NavicIconsInterface", Function = "NavicIconsFunction", Variable = "NavicIconsVariable", Constant = "NavicIconsConstant", String = "NavicIconsString", Number = "NavicIconsNumber", Boolean = "NavicIconsBoolean", Array = "NavicIconsArray", Object = "NavicIconsObject", Key = "NavicIconsKey", Null = "NavicIconsNull", EnumMember = "NavicIconsEnumMember", Struct = "NavicIconsStruct", Event = "NavicIconsEvent", Operator = "NavicIconsOperator", TypeParameter = "NavicIconsTypeParameter", }, depth_limit = 4, depth_limit_indicator = { provider = ".." }, separator = { provider = " > ", hl = { fg = utils.get_highlight("NavicSeparator").fg }, }, -- bit operation dark magic, see below... enc = function(line, col, winnr) return bit.bor(bit.lshift(line, 16), bit.lshift(col, 6), winnr) end, -- line: 16 bit (65535); col: 10 bit (1023); winnr: 6 bit (63) dec = function(c) local line = bit.rshift(c, 16) local col = bit.band(bit.rshift(c, 6), 1023) local winnr = bit.band(c, 63) return line, col, winnr end, }, init = function(self) local navic = require("nvim-navic").get_data() or {} local children = {} -- create a child for each level for index, data in ipairs(navic) do -- encode line and column numbers into a single integer local pos = self.enc(data.scope.start.line, data.scope.start.character, self.winnr) local child = { { provider = data.icon, hl = self.type_hl[data.type], }, { -- escape `%`s (elixir) and buggy default separators provider = data.name:gsub("%%", "%%%%"):gsub("%s*->%s*", ""), -- highlight icon only or location name as well hl = self.type_hl[data.type], on_click = { -- pass the encoded position through minwid minwid = pos, callback = function(_, minwid) -- decode local line, col, winnr = self.dec(minwid) vim.api.nvim_win_set_cursor(vim.fn.win_getid(winnr), { line, col }) end, name = "heirline_navic", }, }, } -- add a separator only if needed if #navic > 1 and index < #navic then table.insert(child, { provider = " > ", hl = { fg = utils.get_highlight("NavicSeparator").fg }, }) end table.insert(children, child) end if self.depth_limit < #children then while true do table.remove(children, 2) if self.depth_limit == #children then break end end table.insert(children, 2, { self.depth_limit_indicator, self.separator, }) end -- instantiate the new child, overwriting the previous one self.child = self:new(children, 1) end, -- evaluate the children containing navic components provider = function(self) return self.child:eval() end, hl = { fg = utils.get_highlight("NavicText").fg }, update = "CursorMoved", }) return M