NvChad / NvChad

Blazing fast Neovim config providing solid defaults and a beautiful UI, enhancing your neovim experience.

Home Page:https://nvchad.com/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Simplify overriding statusline

aryanjassal opened this issue · comments

Is your feature request related to a problem? Please describe.
I wanted to configure my statusline to have different symbols or just a new style. To do this, I tried importing nvchad.stl.utils to have access to all the utils functions but I kept getting cyclic dependency error. I tried to separate it out into its own file for cleanliness for my chadrc.lua but even importing another file kept giving me cyclic dependency error so I had to put all the relevant utility code in my own chadrc.lua file. I can understand that, for big changes like in my lsp module or simple module like cursor module, its better if i do it over by myself, but things like changing the icon for the mode module should be easier than re-declaring the entire module again. I couldn't import utility functions from the utils.lua module either in my own file tree or in nvchad.stl file tree, and even small cosmetic changes required rewriting the particular module.

-- snippet of my chadrc

local stbufnr = function()
  return vim.api.nvim_win_get_buf(vim.g.statusline_winid or 0)
end

local is_activewin = function()
  return vim.api.nvim_get_current_win() == vim.g.statusline_winid
end

M.ui = {
  statusline = {
    theme = "vscode_colored",
    order = { "mode", "file", "git_branch", "diagnostics", "%=", "lsp_msg", "%=", "cursor", "lsp", "cwd" },
    modules = {
      mode = function()
        if not is_activewin() then
          return ""
        end

        local m = vim.api.nvim_get_mode().mode
        return "%#St_" .. modes[m][2] .. "mode#" .. "" .. modes[m][1] .. " "
      end,

      cursor = function()
        return "%#StText# %l:%c "
      end,

      lsp = function()
        if rawget(vim, "lsp") then
          for _, client in ipairs(vim.lsp.get_active_clients()) do
            if client.attached_buffers[stbufnr()] and client.name ~= "null-ls" then
              return "%#St_Lsp#" .. ((vim.o.columns > 100 and " 󰅩 " .. client.name .. "  ") or " 󰅩 LSP  ")
            end
          end
        end
        return ""
      end,
    }
  }
}

Describe the solution you'd like
Add more options to customise the statusline and allow for the nvchad.stl.utils file to be usable in the config

Describe alternatives you've considered
Having these utililty functions in another file in my source tree to keep it clean, but cyclic dependency error happens with this approach too.

Additional context
Error message when I try to use either the nvchad.stl.utils or my own lua.utils file:

Failed to run `config` for ui

...ryanj/.local/share/nvim/lazy/ui/lua/nvchad/stl/utils.lua:2: loop or previous error loading module 'nvconfig'

# stacktrace:
  - /ui/lua/nvchad/stl/utils.lua:2
  - lua/chadrc.lua:4
  - /NvChad/lua/nvconfig.lua:106
  - /ui/lua/nvchad/init.lua:2
  - /NvChad/lua/nvchad/plugins/ui.lua:16 _in_ **config**
  - /NvChad/lua/nvchad/plugins/ui.lua:36 _in_ **values**
  - init.lua:17

A different error claiming that the file doesn't exist shows up if the file doesn't exist, but this error only happens when the file does exist.

try now

I'm still getting the same error when I run this in my chadrc. I also updated nvchad using Lazy before trying this.

local utils = require "nvchad.stl.utils"
Failed to run `config` for ui

...ryanj/.local/share/nvim/lazy/ui/lua/nvchad/stl/utils.lua:2: loop or previous error loading module 'nvconfig'

# stacktrace:
  - /ui/lua/nvchad/stl/utils.lua:2
  - lua/chadrc.lua:7
  - /NvChad/lua/nvconfig.lua:86
  - /ui/lua/nvchad/init.lua:2
  - /NvChad/lua/nvchad/plugins/ui.lua:16 _in_ **config**
  - /NvChad/lua/nvchad/plugins/ui.lua:37 _in_ **values**
  - init.lua:17

pls show your whole chadrc :/

---@type ChadrcConfig
local M = {}

-- local utils = require "nvchad.stl.utils"

-- helper function
local stbufnr = function()
  return vim.api.nvim_win_get_buf(vim.g.statusline_winid or 0)
end

local is_activewin = function()
  return vim.api.nvim_get_current_win() == vim.g.statusline_winid
end

local modes = {
  ["n"] = { "NORMAL", "Normal" },
  ["no"] = { "NORMAL (no)", "Normal" },
  ["nov"] = { "NORMAL (nov)", "Normal" },
  ["noV"] = { "NORMAL (noV)", "Normal" },
  ["noCTRL-V"] = { "NORMAL", "Normal" },
  ["niI"] = { "NORMAL i", "Normal" },
  ["niR"] = { "NORMAL r", "Normal" },
  ["niV"] = { "NORMAL v", "Normal" },
  ["nt"] = { "NTERMINAL", "NTerminal" },
  ["ntT"] = { "NTERMINAL (ntT)", "NTerminal" },

  ["v"] = { "VISUAL", "Visual" },
  ["vs"] = { "V-CHAR (Ctrl O)", "Visual" },
  ["V"] = { "V-LINE", "Visual" },
  ["Vs"] = { "V-LINE", "Visual" },
  [""] = { "V-BLOCK", "Visual" },

  ["i"] = { "INSERT", "Insert" },
  ["ic"] = { "INSERT (completion)", "Insert" },
  ["ix"] = { "INSERT completion", "Insert" },

  ["t"] = { "TERMINAL", "Terminal" },

  ["R"] = { "REPLACE", "Replace" },
  ["Rc"] = { "REPLACE (Rc)", "Replace" },
  ["Rx"] = { "REPLACEa (Rx)", "Replace" },
  ["Rv"] = { "V-REPLACE", "Replace" },
  ["Rvc"] = { "V-REPLACE (Rvc)", "Replace" },
  ["Rvx"] = { "V-REPLACE (Rvx)", "Replace" },

  ["s"] = { "SELECT", "Select" },
  ["S"] = { "S-LINE", "Select" },
  [""] = { "S-BLOCK", "Select" },
  ["c"] = { "COMMAND", "Command" },
  ["cv"] = { "COMMAND", "Command" },
  ["ce"] = { "COMMAND", "Command" },
  ["r"] = { "PROMPT", "Confirm" },
  ["rm"] = { "MORE", "Confirm" },
  ["r?"] = { "CONFIRM", "Confirm" },
  ["x"] = { "CONFIRM", "Confirm" },
  ["!"] = { "SHELL", "Terminal" },
}

M.ui = {
  theme = "tokyodark",

  hl_override = {
    Comment = { italic = true },
    ["@comment"] = { italic = true },
  },

  hl_add = {
    St_gitAdded = { fg = "green" },
    St_gitChanged = { fg = "yellow" },
    St_gitRemoved = { fg = "red" },
    St_gitHead = { fg = "nord_blue" },
  },

  tabufline = {
    order = { "treeOffset", "buffers", "tabs" },
  },

  statusline = {
    theme = "vscode_colored",
    order = { "mode", "file", "git_branch", "diagnostics", "%=", "lsp_msg", "%=", "cursor", "lsp", "cwd" },
    modules = {
      mode = function()
        if not is_activewin() then
          return ""
        end

        local m = vim.api.nvim_get_mode().mode
        return "%#St_" .. modes[m][2] .. "mode#" .. "" .. modes[m][1] .. " "
      end,

      cursor = function()
        return "%#StText# %l:%c "
      end,

      lsp = function()
        if rawget(vim, "lsp") then
          for _, client in ipairs(vim.lsp.get_active_clients()) do
            if client.attached_buffers[stbufnr()] and client.name ~= "null-ls" then
              return "%#St_Lsp#" .. ((vim.o.columns > 100 and " 󰅩 " .. client.name .. "  ") or " 󰅩 LSP  ")
            end
          end
        end
        return ""
      end,

      git_branch = function()
        if not vim.b[stbufnr()].gitsigns_head or vim.b[stbufnr()].gitsigns_git_status then
          return ""
        end
        local git_status = vim.b[stbufnr()].gitsigns_status_dict
        local branch_name = "" .. git_status.head
        return " %#St_gitHead#" .. branch_name .. "%#StText# "
      end,

      git_changes = function()
        if not vim.b[stbufnr()].gitsigns_head or vim.b[stbufnr()].gitsigns_git_status then
          return ""
        end

        local git_status = vim.b[stbufnr()].gitsigns_status_dict

        local added = (git_status.added and git_status.added ~= 0) and ("%#St_gitAdded#  " .. git_status.added) or ""
        local changed = (git_status.changed and git_status.changed ~= 0)
            and ("%#St_gitChanged# 󰻂 " .. git_status.changed)
          or ""
        local removed = (git_status.removed and git_status.removed ~= 0)
            and ("%#St_gitRemoved#  " .. git_status.removed)
          or ""

        return " " .. added .. changed .. removed
      end,

      lsp_msg = function()
        if not rawget(vim, "lsp") or vim.lsp.status or not is_activewin() then
          return ""
        end

        local Lsp = vim.lsp.util.get_progress_messages()[1]

        if vim.o.columns < 120 or not Lsp then
          return ""
        end

        if Lsp.done then
          vim.defer_fn(function()
            vim.cmd.redrawstatus()
          end, 1000)
        end

        local msg = Lsp.message or ""
        local percentage = Lsp.percentage or 0
        local title = Lsp.title or ""
        local spinners = { "", "󰪞", "󰪟", "󰪠", "󰪢", "󰪣", "󰪤", "󰪥" }
        local ms = vim.loop.hrtime() / 1000000
        local frame = math.floor(ms / 120) % #spinners
        local content = string.format(" %%<%s %s %s (%s%%%%) ", spinners[frame + 1], title, msg, percentage)

        return "%#St_gitAdded#" .. (content or "")
      end,
    },
  },
}

return M

it works fine here

simplescreenrecorder-2024-04-05_18.07.52.mp4