-
Notifications
You must be signed in to change notification settings - Fork 2
Usage_Statusline
Tip
You can disable this module for a buffer via vim.b[buffer].bars_statusline = false
.
You can also disable this module for a window via vim.w[buffer].bars_statusline = false
.
Usage guide for the Statusline module.
The relevant files are shown below,
📂 bars.nvim
├── 🔐 ///////
├── 📂 lua
│ ├── 📂 bars
│ │ ├── 📂 components
│ │ │ ├── 📄 ////////////////
│ │ │ ├── 📄 statusline.lua # Components
│ │ │ ├── 📄 ///////////
│ │ │ └── 📄 //////////
│ │ ├── 📄 global.lua # Click functions
│ │ ├── 📄 ////////////////
│ │ ├── 📄 statusline.lua # Statusline module
│ │ ├── 📄 ///////////
│ │ ├── 📄 utils.lua # Utilities
│ │ └── 📄 //////////
│ ├── 📄 ////////
│ └── 📂 definitions
│ ├── 📄 ////////
│ ├── 📄 ////////////////
│ ├── 📄 statusline.lua # Type definitions
│ ├── 📄 ///////////
│ └── 📄 //////////
├── 📂 plugin
│ └── 📄 ////////
└── 📄 /////////
This module can be configured via the statuscolumn
option in require("bars").setup()
or via require("bars.statuscolumn").setup()
directly.
Default configuration is given below,
See type definition
--- Statusline configuration table.
---@class statusline.config
---
--- Filetypes to ignore.
---@field ignore_filetypes? string[]
--- Buftypes to ignore.
---@field ignore_buftypes? string[]
---
--- Additional condition for attaching to new windows.
---@field condition? fun(buffer: integer, window: integer): boolean | nil
---
--- Default style.
---@field default statusline_style
---
--- Custom style.
---@field [string] statusline_style
---@alias statusline_style
---| statusline.components.section
---| statusline.components.ruler
---| statusline.components.mode
---| statusline.components.diagnostics
---| statusline.components.branch
---| statusline.components.bufname
---| statusline.components.custom
---@type statusline.config
statusline.config = {
ignore_filetypes = {},
ignore_buftypes = {},
default = {
---|fS "Default configuration"
components = {
{
kind = "mode",
compact = function (_, window)
if window ~= vim.api.nvim_get_current_win() then
return true;
else
return vim.api.nvim_win_get_width(window) < math.ceil(vim.o.columns * 0.5);
end
end,
---|fS "Mode configuration"
default = {
padding_left = " ",
padding_right = " ",
icon = " ",
hl = "Color8R",
},
["^n"] = { text = "Normal" },
["^t"] = { text = "Terminal" },
["^v$"] = {
icon = " ",
text = "Visual",
hl = "Color9R",
},
["^V$"] = {
icon = " ",
text = "Visual",
hl = "Color7R",
},
["^$"] = {
icon = " ",
text = "Visual",
hl = "Color2R",
},
["^s$"] = {
icon = " ",
text = "Select",
hl = "Color9R",
},
["^S$"] = {
icon = " ",
text = "Select",
hl = "Color7R",
},
["^$"] = {
icon = " ",
text = "Select",
hl = "Color2R",
},
["^i$"] = {
icon = " ",
text = "Insert",
hl = "Color10R",
},
["^ic$"] = {
icon = " ",
text = "Completion",
hl = "Color10R",
},
["^ix$"] = {
text = "Inser8",
hl = "Color10R",
},
["^R$"] = {
icon = " ",
text = "Replace",
hl = "Color8R",
},
["^Rc$"] = {
icon = " ",
text = "Completion",
hl = "Color8R",
},
["^c"] = {
icon = " ",
text = "Command",
hl = "Color4R",
},
["^r"] = { text = "Prompt" },
["^%!"] = {
icon = " ",
text = "Shell",
hl = "Color4R"
},
---|fE
},
{ kind = "section", hl = "Normal" },
{
kind = "bufname",
condition = function (_, win)
return vim.api.nvim_win_get_width(win) >= 42;
end,
max_len = 25,
default = {
padding_left = " ",
padding_right = " ",
icon = "",
nomodifiable_icon_hl = "Color1B",
nomodifiable_icon = " ",
icon_hl = {
"Color0B",
"Color1B", "Color2B", "Color3B",
"Color4B", "Color5B", "Color6B",
},
-- corner_left_hl = "Normal",
-- corner_right_hl = "Normal",
hl = "Layer1"
},
["^$"] = {
icon = " ",
text = "New file",
hl = "Layer0"
},
["^fish"] = {
icon = " ",
},
},
{ kind = "section", hl = "Normal" },
{
kind = "diagnostics",
default_mode = 5,
padding_left = " ",
padding_right = " ",
empty_icon = " ",
empty_hl = "Comment",
error_icon = " ",
error_hl = "DiagnosticError",
warn_icon = " ",
warn_hl = "DiagnosticWarn",
hint_icon = " ",
hint_hl = "DiagnosticHint",
info_icon = " ",
info_hl = "DiagnosticInfo"
},
{ kind = "empty", hl = "Normal" },
{
kind = "branch",
condition = function (_, win)
return win == vim.api.nvim_get_current_win();
end,
default = {
padding_left = " ",
padding_right = " ",
icon = " ",
hl = "Color0"
}
},
{
kind = "ruler",
mode = function ()
local mode = vim.api.nvim_get_mode().mode;
local visual_modes = { "v", "V", "" };
return vim.list_contains(visual_modes, mode) and "visual" or "normal";
end,
default = {
padding_left = " ",
padding_right = " ",
icon = " ",
separator = " ",
hl = "Color1R"
},
visual = {
icon = " ",
hl = "Color6R"
}
}
}
---|fE
},
["help"] = {
---|fS "Help statusline"
condition = function (buffer)
return vim.bo[buffer].buftype == "help";
end,
components = {
{ kind = "empty", hl = "Normal" },
{
kind = "mode",
---|fS "Mode configuration"
default = {
padding_left = " ",
padding_right = " ",
icon = " ",
hl = "Color8R",
},
["^n"] = { text = "Normal" },
["^t"] = { text = "Terminal" },
["^v$"] = {
icon = " ",
text = "Visual",
hl = "Color9R",
},
["^V$"] = {
icon = " ",
text = "Visual",
hl = "Color7R",
},
["^$"] = {
icon = " ",
text = "Visual",
hl = "Color2R",
},
["^s$"] = {
icon = " ",
text = "Select",
hl = "Color9R",
},
["^S$"] = {
icon = " ",
text = "Select",
hl = "Color4R",
},
["^$"] = {
icon = " ",
text = "Select",
hl = "Color9R",
},
["^i$"] = {
icon = " ",
text = "Insert",
hl = "Color10R",
},
["^ic$"] = {
icon = " ",
text = "Completion",
hl = "Color10R",
},
["^ix$"] = {
text = "Inser8",
hl = "Color10R",
},
["^R$"] = {
icon = " ",
text = "Replace",
hl = "Color8R",
},
["^Rc$"] = {
icon = " ",
text = "Completion",
hl = "Color8R",
},
["^c"] = {
icon = " ",
text = "Command",
hl = "Color4R",
},
["^r"] = { text = "Prompt" },
["^%!"] = {
icon = " ",
text = "Shell",
hl = "Color4R"
},
---|fE
},
{
kind = "ruler",
condition = function ()
local mode = vim.api.nvim_get_mode().mode;
local visual_modes = { "v", "V", "" };
return vim.list_contains(visual_modes, mode);
end,
default = {
padding_left = " ",
padding_right = " ",
icon = " ",
separator = " ",
hl = "Color6R"
},
visual = {
icon = " ",
hl = "Color6R"
}
},
{
kind = "bufname",
condition = function (_, win)
return vim.api.nvim_win_get_width(win) >= 42;
end,
default = {
padding_left = " ",
padding_right = " ",
icon = "",
nomodifiable_icon_hl = "Color1B",
nomodifiable_icon = " ",
icon_hl = {
"Color0B",
"Color1B", "Color2B", "Color3B",
"Color4B", "Color5B", "Color6B",
},
-- corner_left_hl = "Normal",
-- corner_right_hl = "Normal",
hl = "Layer1"
},
["^$"] = {
icon = " ",
text = "New file",
hl = "Layer0"
},
["^fish"] = {
icon = " ",
},
},
{ kind = "empty", hl = "Normal" },
}
---|fE
}
};
bars.nvim
comes with the following components by default,
Shows the current git branch.
See type definition
--- Shows current git branch.
---@class statusline.components.branch
---
--- Optional condition for this component.
---@field condition? boolean | fun(buffer: integer, window: integer): boolean
---
--- What kind of component is this?
---@field kind "branch"
---
--- Delay(in milliseconds) between branch
--- name updates.
---@field throttle? integer
---
--- Default configuration for git branch.
---@field default branch.opts
---
--- Configuration for branches whose name
--- matches `string`.
---@field [string] branch.opts
--- Git branch component options.
--- Drawn like so,
---
--- abc----de
--- │││ │└ corner_right
--- │││ └ padding_right
--- ││└ icon
--- │└ padding_left
--- └ corner_left
---
---@class branch.opts
---
---@field corner_left? string
---@field padding_left? string
---
--- Alternate branch name.
---@field text? string
---@field icon? string
---
---@field padding_right? string
---@field corner_right? string
---
--- Primary highlight group.
---@field hl? string
---
---@field corner_left_hl? string
---@field padding_left_hl? string
---
---@field icon_hl? string
---
---@field padding_right_hl? string
---@field corner_right_hl? string
{
kind = "branch",
condition = function (_, win)
return win == vim.api.nvim_get_current_win();
end,
default = {
padding_left = " ",
padding_right = " ",
icon = " ",
hl = "Color0"
}
},
Shows the buffer's name.
See type definition
--- Shows buffer name.
---@class statusline.components.bufname
---
--- Optional condition for this component.
---@field condition? boolean | fun(buffer: integer, window: integer): boolean
---
--- What kind of component is this?
---@field kind "bufname"
---
--- Maximum name length.
---@field max_len? integer
---
--- Symbol used to show truncation.
---@field truncate_symbol? string
---
---@field default bufname.opts
---@field [string] bufname.opts
--- Buffer name component options.
--- Drawn like so,
---
--- abc----de
--- │││ │└ corner_right
--- │││ └ padding_right
--- ││└ icon / nomodifiable_icon
--- │└ padding_left
--- └ corner_left
---
---@class bufname.opts
---
---@field corner_left? string
---@field padding_left? string
---
--- Alternate branch name.
---@field text? string
---@field icon? string
---
--- Icon for 'nomodifiable' buffers.
---@field nomodifiable_icon? string
---
---@field padding_right? string
---@field corner_right? string
---
--- Primary highlight group.
---@field hl? string
---
---@field corner_left_hl? string
---@field padding_left_hl? string
---
---@field icon_hl? string
---
--- Highlight group for `nomodifiable_icon`
---@field nomodifiable_icon_hl? string
---
---@field padding_right_hl? string
---@field corner_right_hl? string
{
kind = "bufname",
condition = function (_, win)
return vim.api.nvim_win_get_width(win) >= 42;
end,
default = {
padding_left = " ",
padding_right = " ",
icon = "",
nomodifiable_icon_hl = "Color1B",
nomodifiable_icon = " ",
icon_hl = {
"Color0B",
"Color1B", "Color2B", "Color3B",
"Color4B", "Color5B", "Color6B",
},
hl = "Layer1"
},
["^$"] = {
icon = " ",
text = "New file",
hl = "Layer0"
},
["^fish"] = {
icon = " ",
},
},
Shows the diagnostic count for different alert level(s).
Tip
This has mouse click support.
global.__change_diagnostic_state()
is used for going to line.
See type definition
--- Shows diagnostics count.
---@class statusline.components.diagnostics
---
--- Optional condition for this component.
---@field condition? boolean | fun(buffer: integer, window: integer): boolean
---
--- What kind of component is this?
---@field kind "diagnostics"
---
--- Should this component be automatically hidden?
---
--- > This component gets hidden if a buffer has
--- > no client attached to it.
---@field auto_hide? boolean
---
--- Determines what type of diagnostics are
--- shown.
---@field default_mode?
---| 1 Error
---| 2 Warning
---| 3 Info
---| 4 Hint
---| 5 All of the above
---
---@field error_icon? string
---@field error_hl? string
---
---@field warn_icon? string
---@field warn_hl? string
---
---@field info_icon? string
---@field info_hl? string
---
---@field hint_icon? string
---@field hint_hl? string
---
--- Icon to show when no diagnostics are available.
---@field empty_icon? string
---
--- Text to show when no diagnostics are available.
---@field empty_text? string
---
--- Highlight group to use when no diagnostics are
--- available.
---@field empty_hl? string
---
--- Text used as separator between each diagnostics
--- type.
---@field separator? string
---
--- Highlight group for the separator.
---@field separator_hl? string
---
--- Left corner of the component.
---@field corner_left? string
---@field corner_left_hl? string
---
--- Left padding of the component.
---@field padding_left? string
---@field padding_left_hl? string
---
--- Right padding of the component.
---@field padding_right? string
---@field padding_right_hl? string
---
--- Right corner of the component.
---@field corner_right? string
---@field corner_right_hl? string
---
--- Primary highlight group for the component
---@field hl? string
{
kind = "diagnostics",
default_mode = 5,
padding_left = " ",
padding_right = " ",
empty_icon = " ",
empty_hl = "Comment",
error_icon = " ",
error_hl = "DiagnosticError",
warn_icon = " ",
warn_hl = "DiagnosticWarn",
hint_icon = " ",
hint_hl = "DiagnosticHint",
info_icon = " ",
info_hl = "DiagnosticInfo"
},
Empty space between other section.
See type definition
--- Empty space.
---@class statusline.components.empty
---
--- Optional condition for this component.
---@field condition? boolean | fun(buffer: integer, window: integer): boolean
---
--- What kind of component is this?
---@field kind "empty"
---
--- Highlight group for this component.
---@field hl? string
{
kind = "empty",
hl = "Normal"
},
Shows current mode.
See type definition
--- Shows current mode.
---@class statusline.components.mode
---
--- Optional condition for this component.
---@field condition? boolean | fun(buffer: integer, window: integer): boolean
---
--- What kind of component is this?
---@field kind "mode"
---
--- Should we show a compact version?
---@field compact? boolean | fun(buffer: integer, window: integer): boolean
---
---@field default mode.opts
---@field [string] mode.opts
--- Mode name component options.
--- Drawn like so,
---
--- abc----de
--- │││ │└ corner_right
--- │││ └ padding_right
--- ││└ icon
--- │└ padding_left
--- └ corner_left
---
---@class mode.opts
---
---@field corner_left? string
---@field padding_left? string
---
--- Mode name.
---@field text? string
---@field icon? string
---
---@field padding_right? string
---@field corner_right? string
---
--- Primary highlight group.
---@field hl? string
---
---@field corner_left_hl? string
---@field padding_left_hl? string
---
---@field icon_hl? string
---
---@field padding_right_hl? string
---@field corner_right_hl? string
{
kind = "mode",
---|fS "Mode configuration"
default = {
padding_left = " ",
padding_right = " ",
icon = " ",
hl = "Color8R",
},
["^n"] = { text = "Normal" },
["^t"] = { text = "Terminal" },
["^v$"] = {
icon = " ",
text = "Visual",
hl = "Color9R",
},
["^V$"] = {
icon = " ",
text = "Visual",
hl = "Color7R",
},
["^$"] = {
icon = " ",
text = "Visual",
hl = "Color2R",
},
["^s$"] = {
icon = " ",
text = "Select",
hl = "Color9R",
},
["^S$"] = {
icon = " ",
text = "Select",
hl = "Color4R",
},
["^$"] = {
icon = " ",
text = "Select",
hl = "Color9R",
},
["^i$"] = {
icon = " ",
text = "Insert",
hl = "Color10R",
},
["^ic$"] = {
icon = " ",
text = "Completion",
hl = "Color10R",
},
["^ix$"] = {
text = "Inser8",
hl = "Color10R",
},
["^R$"] = {
icon = " ",
text = "Replace",
hl = "Color8R",
},
["^Rc$"] = {
icon = " ",
text = "Completion",
hl = "Color8R",
},
["^c"] = {
icon = " ",
text = "Command",
hl = "Color4R",
},
["^r"] = { text = "Prompt" },
["^%!"] = {
icon = " ",
text = "Shell",
hl = "Color4R"
},
---|fE
},
Custom section(a structured version of the custom
component).
See type definition
--- Custom section for the statusline.
--- Drawn like so,
---
--- abc-de
--- │││││└ corner_right
--- ││││└ padding_right
--- │││└ text
--- ││└ icon
--- │└ padding_left
--- └ corner_left
---@class statusline.components.section
---
--- Condition for this component.
---@field condition? fun(buffer: integer, window: integer): boolean
---
--- What kind of component is this?
---@field kind? "section"
---
--- Reference to a click handler.
---@field click? string
---
---@field corner_left? string
---@field padding_left? string
---@field icon? string
---
---@field text? string
---
---@field padding_right? string
---@field corner_right? string
---
--- Primary highlight group
---@field hl? string
---
---@field corner_left_hl? string
---@field padding_left_hl? string
---@field icon_hl? string
---
---@field text_hl? string
---
---@field padding_right_hl? string
---@field corner_right_hl? string
{
kind = "section",
hl = "Normal"
},
Custom ruler.
See type definition
--- Custom ruler.
---@class statusline.components.ruler
---
--- Optional condition for this component.
---@field condition? boolean | fun(buffer: integer, window: integer): boolean
---
--- What kind of component is this?
---@field kind "ruler"
---
--- Should visual modes be shown
---@field mode
---| "normal" Show cursor position.
---| "visual" Show selection size.
---| fun(buffer: integer, window: integer): ( "normal" | "visual" )
---
--- Default configuration.
---@field default ruler.opts
---
--- Configuration for visual modes.
---@field visual ruler.opts
--- Ruler component options.
--- Drawn like so,
---
---```txt
--- abcXX-YYde
--- │││ │ │└ corner_right
--- │││ │ └ padding_right
--- │││ └ separator
--- ││└ icon
--- │└ padding_left
--- └ corner_left
---@class ruler.opts
---
---@field corner_left? string
---@field padding_left? string
---
---@field icon? string
---
--- Separator between texts.
---@field separator? string
---
---@field padding_right? string
---@field corner_right? string
---
---
---@field corner_left_hl? string
---@field padding_left_hl? string
---
---@field icon_hl? string
---@field separator_hl? string
---
---@field padding_right_hl? string
---@field corner_right_hl? string
---
--- Primary highlight group.
---@field hl? string
{
kind = "ruler",
condition = function ()
local mode = vim.api.nvim_get_mode().mode;
local visual_modes = { "v", "V", "" };
return vim.list_contains(visual_modes, mode);
end,
default = {
padding_left = " ",
padding_right = " ",
icon = " ",
separator = " ",
hl = "Color6R"
},
visual = {
icon = " ",
hl = "Color6R"
}
},
Allows showing progress bars/spinners.
See type definition
---@class statusline.components.progress
---
--- Optional condition for this component.
---@field condition? boolean | fun(buffer: integer, window: integer): boolean
---
--- What kind of component is this?
---@field kind "progress"
---
---@field check? string The variable that holds the progress state, default is "progress_state".
---
---@field finish string Text used as the indicator for progress finish.
---@field finish_hl string Highlight group for the progress finish indicator.
---
---@field progress string[] Text used as the indicator for progress.
---@field progress_hl string[] Highlight group for the progress indicator.
---
---@field start string Text used as the indicator for progress start.
---@field start_hl string Highlight group for the progress start indicator.
---
---@field update_delay? integer Delay in milliseconds between state updates.
Note
The following example by itself doesn't do anything!
{
kind = "progress",
check = "lsp_loader_state",
update_delay = 250,
start = " ",
progress = { "|", "/", "-", "\\" },
finish = "✓ ",
start_hl = "@comment",
progress_hl = "@comment",
finish_hl = "DiagnosticOk"
}
To get it to indicate LspProgress
you can use this autocmd,
vim.api.nvim_create_autocmd("LspProgress", {
callback = function (event)
local kind = event.data.params.value.kind;
local attached = vim.lsp.get_buffers_by_client_id(event.data.client_id);
--- Sets buffer state
---@param state "start" | "progress" | "finish" | nil
local function set_state (state)
for _, buf in ipairs(attached) do
vim.b[buf].lsp_loader_state = state;
end
end
--- Gets the general state.
---@return "start" | "progress" | "finish" | nil
local function get_state ()
local states = {};
for _, buf in ipairs(attached) do
table.insert(states, vim.b[buf].lsp_loader_state);
end
local state = states[1];
for _, item in ipairs(states) do
if item ~= state then
return nil;
end
end
return state;
end
if kind == "begin" then
set_state("start");
local lsp_timer = vim.uv.new_timer();
lsp_timer:start(0, 200, vim.schedule_wrap(function ()
if get_state() == nil then
timer:stop();
return;
end
vim.api.nvim__redraw({ statusline = true });
end));
vim.api.nvim__redraw({ statusline = true });
elseif kind == "report" then
set_state("progress");
else
set_state("finish");
-- We defer this so that we can see the finish
-- indicator.
vim.defer_fn(function ()
if get_state() == "finish" then
set_state(nil);
end
vim.api.nvim__redraw({ statusline = true });
end, 500);
end
end
});
Custom component.
See type definition
--- Custom statusline component.
---@class statusline.components.custom
---
--- Optional condition for this component.
---@field condition? boolean | fun(buffer: integer, window: integer): boolean
---
--- What kind of component is this?
---@field kind "ruler"
---
--- Text to show for this component.
---@field value fun(buffer: integer, window: integer): string
{
kind = "ruler",
value = "Hello, Neovim!"
}
Also in vimdoc, :h bars-statusline
.