1
0
mirror of https://github.com/SpaceVim/SpaceVim.git synced 2025-01-24 03:00:06 +08:00
SpaceVim/lua/spacevim/plugin/statusline.lua
2024-06-21 23:10:33 +08:00

1282 lines
34 KiB
Lua
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

--=============================================================================
-- statusline.lua ---
-- Copyright (c) 2019-2024 Wang Shidong & Contributors
-- Author: Wang Shidong < wsdjeg@outlook.com >
-- URL: https://spacevim.org
-- License: GPLv3
--=============================================================================
local highlight = require('spacevim.api.vim.highlight')
local system = require('spacevim.api.system')
local lang = require('spacevim.api.language')
local time = require('spacevim.api.time')
local JSON = require('spacevim.api.data.json')
local layer = require('spacevim.layer')
local messletters = require('spacevim.api.messletters')
local statusline = require('spacevim.api.vim.statusline')
local log = require('spacevim.logger').derive('stl')
local M = {}
local function index(t, v)
for n, m in ipairs(t) do
if m == v then
return n
end
end
return -1
end
-- https://github.com/ryanoasis/powerline-extra-symbols
local separators = {
arrow = { '', '' },
curve = { '', '' },
slant = { '', '' },
brace = { '', '' },
fire = { '', '' },
['nil'] = { '', '' },
}
local i_separators = {
arrow = { '', '' },
curve = { '', '' },
slant = { '', '' },
bar = { '|', '|' },
['nil'] = { '', '' },
}
local lsep = ''
local rsep = ''
local ilsep = ''
local irsep = ''
local loaded_modes = {}
local colors_template = vim.fn['SpaceVim#mapping#guide#theme#gruvbox#palette']()
local section_old_pos = {}
local modes = {
['center-cursor'] = {
icon = '',
icon_asc = '-',
desc = 'centered-cursor mode',
},
['hi-characters-for-long-lines'] = {
icon = '',
icon_asc = '8',
desc = 'toggle highlight of characters for long lines',
},
['fill-column-indicator'] = {
icon = messletters.circled_letter('f'),
icon_asc = 'f',
desc = 'fill-column-indicator mode',
},
['syntax-checking'] = {
icon = messletters.circled_letter('s'),
icon_asc = 's',
desc = 'syntax-checking mode',
},
['spell-checking'] = {
icon = messletters.circled_letter('S'),
icon_asc = 'S',
desc = 'spell-checking mode',
},
['paste-mode'] = {
icon = messletters.circled_letter('p'),
icon_asc = 'p',
desc = 'paste mode',
},
whitespace = {
icon = messletters.circled_letter('w'),
icon_asc = 'w',
desc = 'whitespace mode',
},
wrapline = {
icon = messletters.circled_letter('W'),
icon_asc = 'W',
desc = 'wrap line mode',
},
}
local major_mode_cache = true
if layer.isLoaded('checkers') then
table.insert(loaded_modes, 'syntax-checking')
end
if vim.o.spell then
table.insert(loaded_modes, 'spell-checking')
end
if vim.o.cc == '80' then
table.insert(loaded_modes, 'fill-column-indicator')
end
if index(vim.g.spacevim_statusline_right, 'whitespace') ~= -1 then
table.insert(loaded_modes, 'whitespace')
end
local function winnr(...)
if select(1, ...) then
if vim.g.spacevim_windows_index_type == 3 then
return ' %{ get(w:, "winid", winnr()) } '
else
return ' %{ v:lua.require("spacevim.plugin.statusline").winnr(get(w:, "winid", winnr())) } '
end
else
if vim.g.spacevim_enable_statusline_mode == 1 then
return '%{v:lua.require("spacevim.plugin.statusline").mode(mode())} %{ v:lua.require("spacevim.plugin.statusline").winnr(get(w:, "winid", winnr())) } %{v:lua.require("spacevim.plugin.statusline").mode_text(mode())} '
elseif vim.g.spacevim_windows_index_type == 3 then
return '%{v:lua.require("spacevim.plugin.statusline").mode(mode())} %{ get(w:, "winid", winnr()) } '
else
return '%{v:lua.require("spacevim.plugin.statusline").mode(mode())} %{ v:lua.require("spacevim.plugin.statusline").winnr(get(w:, "winid", winnr())) } '
end
end
end
function M.winnr(id)
return messletters.circled_num(id, vim.g.spacevim_windows_index_type)
end
local function whitespace()
local ln = vim.fn.search('\\s\\+$', 'nw')
if ln ~= 0 then
return ' trailing[' .. ln .. '] '
else
return ''
end
end
local function battery_status()
if vim.fn.executable('acpi') == 1 then
else
return ''
end
end
---@return string # The buffer name
local function buffer_name()
if vim.b._spacevim_statusline_showbfname == 1 or vim.g.spacevim_enable_statusline_bfpath == 1 then
return ' ' .. vim.fn.bufname('%')
else
return ''
end
end
local function input_method()
if vim.fn.executable('fcitx-remote') == 1 then
if vim.fn.system('fcitx-remote') == 1 then
return ' cn '
else
return ' en '
end
end
return ''
end
local function syntax_checking()
if vim.fn['SpaceVim#lsp#buf_server_ready']() then
local counts = require('spacevim.lsp').lsp_diagnostic_count()
local errors = counts[1] or 0
local warnings = counts[2] or 0
local infos = counts[3] or 0
local hints = counts[4] or 0
local errors_l = ''
if errors > 0 then
errors_l = '%#SpaceVim_statusline_error#● ' .. errors
end
local warnings_l = ''
if warnings > 0 then
warnings_l = '%#SpaceVim_statusline_warn#● ' .. warnings
end
local infos_l = ''
if infos > 0 then
infos_l = '%#SpaceVim_statusline_info#● ' .. infos
end
local hints_l = ''
if hints > 0 then
hints_l = '%#SpaceVim_statusline_hint#● ' .. hints
end
local l = table.concat(
vim.tbl_filter(function(t)
return t ~= ''
end, { errors_l, warnings_l, infos_l, hints_l }),
' '
)
if #l > 0 then
return ' ' .. l .. ' '
else
return ''
end
elseif vim.g.spacevim_lint_engine == 'neomake' then
if not vim.g.loaded_neomake then
return ''
end
local counts = vim.fn['neomake#statusline#LoclistCounts']()
local warnings = counts.W or 0
local errors = counts.E or 0
local l = ''
if warnings > 0 then
l = '%#SpaceVim_statusline_warn# ● ' .. warnings .. ' '
end
if errors > 0 then
l = l .. '%#SpaceVim_statusline_error#● ' .. errors
end
if l ~= '' then
return ' ' .. l .. ' '
else
return ''
end
elseif vim.g.spacevim_lint_engine == 'ale' then
if not vim.g.ale_enabled then
return ''
end
local counts = vim.fn['ale#statusline#Count'](vim.fn.bufnr(''))
local warnings = counts.warning + counts.style_warning
local errors = counts.error + counts.style_error
local l = ''
if warnings > 0 then
l = '%#SpaceVim_statusline_warn# ● ' .. warnings .. ' '
end
if errors > 0 then
l = l .. '%#SpaceVim_statusline_error#● ' .. errors
end
if l ~= '' then
return ' ' .. l .. ' '
else
return ''
end
else
if vim.fn.exists(':SyntasticCheck') == 0 then
return ''
end
local l = vim.fn.SyntasticStatuslineFlag()
if #l > 0 then
return l
else
return ''
end
end
end
local function search_status() end
local function search_count() end
local function filesize()
local size = vim.fn.getfsize(vim.fn.bufname('%'))
if size <= 0 then
return ''
elseif size < 1024 then
return size .. ' bytes '
elseif size < 1024 * 1024 then
return string.format('%.1f', size / 1024) .. 'k '
elseif size < 1024 * 1024 * 1024 then
return string.format('%.1f', size / 1024 / 1024) .. 'm '
else
return string.format('%.1f', size / 1024 / 1024 / 1024) .. 'g '
end
end
local function filename()
local name = vim.fn.fnamemodify(vim.fn.bufname('%'), ':t')
if name == '' then
name = 'No Name'
end
return "%{ &modified ? ' * ' : ' - '}" .. filesize() .. name .. ' '
end
local function fileformat()
if vim.g.spacevim_statusline_unicode == 1 then
vim.g._spacevim_statusline_fileformat = system.fileformat()
else
vim.g._spacevim_statusline_fileformat = vim.o.ff
end
return '%{ " " . g:_spacevim_statusline_fileformat . " '
.. irsep
.. ' " . (&fenc!=""?&fenc:&enc) . " "}'
end
local function major_mode()
local alias = lang.get_alias(vim.o.filetype)
if alias == '' then
return ''
else
return ' ' .. alias .. ' '
end
end
local function get_modes() -- same as s:modes() in vim statusline
local m
if vim.g.spacevim_statusline_unicode == 1 then
m = ''
else
m = ' # '
end
for _, mode in ipairs(loaded_modes) do
if vim.g.spacevim_statusline_unicode == 1 then
m = m .. modes[mode].icon .. ' '
else
m = m .. modes[mode].icon_asc .. ' '
end
end
return m .. ' '
end
local function totallines()
return ' %L '
end
local function percentage()
return ' %P '
end
local function cursorpos()
return [[%{' ' . join(map(getpos('.')[1:2], "printf('%3d', v:val)"), ':') . ' '}]]
end
local function current_time()
return ' ' .. time.current_time() .. ' '
end
local function current_date()
return ' ' .. time.current_date() .. ' '
end
local registed_sections = {
winnr = winnr,
['syntax checking'] = syntax_checking,
filename = filename,
fileformat = fileformat,
['major mode'] = major_mode,
['minor mode lighters'] = get_modes,
cursorpos = cursorpos,
percentage = percentage,
totallines = totallines,
time = current_time,
date = current_date,
whitespace = whitespace,
['battery status'] = battery_status,
['input method'] = input_method,
['search status'] = search_status,
['search count'] = search_count,
}
local function current_tag()
return '%{ v:lua.require("spacevim.plugin.statusline")._current_tag() }'
end
function M._current_tag()
local tag = ''
pcall(function()
-- current tag should be show only after vimenter
-- @fixme this make sure tagbar has been loaded
-- because when first run tagbar, it needs long time.
-- and also there no syntax highlight when first time open file.
if
vim.g._spacevim_after_vimenter == 1
and vim.g.spacevim_enable_statusline_tag == 1
and vim.g.loaded_tagbar == 1
then
tag = vim.fn['tagbar#currenttag']('%s ', '')
end
end)
return tag
end
local function active()
local lsec = {}
for _, section in ipairs(vim.g.spacevim_statusline_left) do
if registed_sections[section] then
local rst = ''
local ok, _ = pcall(function()
if type(registed_sections[section]) == 'function' then
rst = registed_sections[section]()
elseif type(registed_sections[section]) == 'string' then
rst = vim.fn[registed_sections[section]]()
end
end)
if not ok then
log.debug('failed to call section func:' .. section)
end
table.insert(lsec, rst)
end
end
local rsec = {}
for _, section in ipairs(vim.g.spacevim_statusline_right) do
if registed_sections[section] then
local rst = ''
local ok, _ = pcall(function()
if type(registed_sections[section]) == 'function' then
rst = registed_sections[section]()
elseif type(registed_sections[section]) == 'string' then
rst = vim.fn[registed_sections[section]]()
end
end)
if not ok then
log.debug('failed to call section func:' .. section)
end
table.insert(rsec, rst)
end
end
local fname = buffer_name()
local tag = current_tag()
local winwidth = vim.fn.winwidth(vim.fn.winnr())
if vim.o.laststatus == 3 then
winwidth = vim.o.columns
end
return statusline.build(
lsec,
rsec,
lsep,
rsep,
fname,
tag,
'SpaceVim_statusline_a',
'SpaceVim_statusline_b',
'SpaceVim_statusline_c',
'SpaceVim_statusline_z',
winwidth
)
end
local function inactive()
local l = '%#SpaceVim_statusline_ia#'
.. winnr(1)
.. '%#SpaceVim_statusline_ia_SpaceVim_statusline_b#'
.. lsep
.. '%#SpaceVim_statusline_b#'
local secs = { filename(), ' ' .. vim.o.filetype, get_modes() }
local base = 10
for _, sec in ipairs(secs) do
local len = statusline.len(sec)
base = base + len
l = l
.. '%{ get(w:, "winwidth", 150) < '
.. base
.. ' ? "" : (" '
.. statusline.eval(sec)
.. ' '
.. ilsep
.. '")}'
end
if (vim.w.winwidth or 150) > base + 10 then
l = l
.. table.concat({
'%=',
'%{" " . get(g:, "_spacevim_statusline_fileformat", "") . " "}',
'%{" " . (&fenc!=""?&fenc:&enc) . " "}',
' %P ',
}, irsep)
end
return l
end
---@return string # return a simple statusline with special name
local function simple_name(name)
return '%#SpaceVim_statusline_ia#'
.. winnr(1)
.. '%#SpaceVim_statusline_ia_SpaceVim_statusline_b#'
.. lsep
.. '%#SpaceVim_statusline_b# '
.. name
.. ' %#SpaceVim_statusline_b_SpaceVim_statusline_c#'
.. lsep
.. '%#SpaceVim_statusline_c#'
end
local special_statusline = {
vimfiler = function()
return simple_name('VimFiler')
end,
qf = function()
local l = ''
local wininfo = vim.fn.getwininfo(vim.api.nvim_get_current_win())[1]
if wininfo.quickfix == 1 and wininfo.loclist == 0 then
local title = vim.fn.getqflist({ title = 0 }).title
if title == ':setqflist()' then
title = ''
end
l = simple_name('QuickFix') .. ' ' .. title
elseif wininfo.loclist == 1 then
local title = vim.fn.getloclist(vim.fn.winnr(), { title = 0 }).title
if title == ':setloclist()' then
title = ''
end
l = simple_name('Location list') .. ' ' .. title
end
return l
end,
defx = function()
return simple_name('defx')
end,
['git-status'] = function()
return simple_name('Git status')
end,
startify = function()
pcall(vim.fn['fugitive#detect'], vim.fn.getcwd())
local st = '%#SpaceVim_statusline_ia#'
.. winnr(1)
.. '%#SpaceVim_statusline_ia_SpaceVim_statusline_b#'
.. lsep
.. '%#SpaceVim_statusline_b# startify %#SpaceVim_statusline_b_SpaceVim_statusline_c#'
.. lsep
if index(vim.g.spacevim_statusline_left, 'vcs') ~= -1 and registed_sections.vcs then
st = st .. '%#SpaceVim_statusline_c#'
if type(registed_sections.vcs) == 'string' then
st = st .. vim.fn[registed_sections.vcs]()
elseif type(registed_sections.vcs) == 'function' then
st = st .. registed_sections.vcs()
end
st = st .. '%#SpaceVim_statusline_c_SpaceVim_statusline_z#' .. lsep
end
return st
end,
NvimTree = function()
return simple_name('NvimTree')
end,
['neo-tree'] = function()
return simple_name('NeoTree')
end,
Fuzzy = function() end, -- todo
['git-commit'] = function()
return simple_name('Git commit')
end,
['git-rebase'] = function()
return simple_name('Git rebase')
end,
['git-blame'] = function()
return simple_name('Git blame')
end,
['git-log'] = function()
return simple_name('Git log')
end,
['git-diff'] = function()
return simple_name('Git diff')
end,
['git-config'] = function()
return simple_name('Git config')
end,
SpaceVimMessageBuffer = function()
return simple_name('Message')
end,
['gista-list'] = function()
return simple_name('Gista')
end,
terminal = function() end, -- todo
vimchat = function() end, -- todo
calender = function()
return simple_name('Calendar')
end,
['vader-result'] = function()
return simple_name('Vader result')
end,
['gina-status'] = function()
return simple_name('Gina status')
end,
['gina-commit'] = function()
return simple_name('Gina commit')
end,
nerdtree = function()
return simple_name('Nerdtree')
end,
Mundo = function()
return simple_name('Mundo')
end,
MundoDiff = function()
return simple_name('MundoDiff')
end,
SpaceVimLayerManager = function()
return simple_name('LayerManager')
end,
SpaceVimFindArgv = function()
return simple_name('Find')
end,
SpaceVimGitLogPopup = function()
return simple_name('Git log popup')
end,
['response.idris'] = function()
return simple_name('Idris Response')
end,
['markdown.lspdoc'] = function()
return simple_name('LSP hover info')
end,
SpaceVimWinDiskManager = function()
return simple_name('WinDisk')
end,
SpaceVimTodoManager = function()
return simple_name('TODO manager')
end,
SpaceVimTasksInfo = function()
return simple_name('Tasks manager')
end,
SpaceVimGitBranchManager = function()
return simple_name('Branch manager')
end,
SpaceVimGitRemoteManager = function()
return simple_name('Remote manager')
end,
SpaceVimPlugManager = function()
return simple_name('PlugManager')
end,
SpaceVimTabsManager = function()
return simple_name('TabsManager')
end,
fzf = function() end, -- todo
denite = function() end, -- todo
['denite-filter'] = function()
return '%#SpaceVim_statusline_a_bold#'
.. ' Filter '
.. '%#SpaceVim_statusline_a_SpaceVim_statusline_b#'
.. lsep
end,
unite = function() end, -- todo
SpaceVimFlyGrep = function() end, -- todo
TransientState = function()
return '%#SpaceVim_statusline_ia# Transient State %#SpaceVim_statusline_a_SpaceVim_statusline_b#'
end,
SpaceVimLog = function()
return simple_name('SpaceVim Runtime Log')
end,
SpaceVimTomlViewer = function()
return simple_name('Toml Json Viewer')
end,
vimcalc = function()
return simple_name('VimCalc')
end,
HelpDescribe = function()
return simple_name('HelpDescribe')
end,
SpaceVimRunner = function()
return simple_name('Runner') .. ' %{SpaceVim#plugins#runner#status()}'
end,
SpaceVimREPL = function()
return simple_name('REPL') .. ' %{SpaceVim#plugins#repl#status()}'
end,
VimMailClient = function() end, -- todo
SpaceVimQuickFix = function()
return simple_name('SpaceVimQuickFix')
end,
VebuggerShell = function()
return simple_name('VebuggerShell')
end,
VebuggerTerminal = function()
return simple_name('VebuggerTerminal')
end,
}
function M.get(...)
if special_statusline[vim.o.filetype] then
return special_statusline[vim.o.filetype]()
end
if select(1, ...) then
return active()
else
return inactive()
end
end
function M.def_colors()
local name = vim.g.colors_name or 'gruvbox'
local t
if #vim.g.spacevim_custom_color_palette > 0 then
t = vim.g.spacevim_custom_color_palette
else
local ok = pcall(function()
t = vim.fn['SpaceVim#mapping#guide#theme#' .. name .. '#palette']()
end)
if not ok then
t = vim.fn['SpaceVim#mapping#guide#theme#gruvbox#palette']()
end
end
colors_template = t
vim.api.nvim_set_hl(0, 'SpaceVim_statusline_a', {
fg = t[1][1],
bg = t[1][2],
ctermfg = t[1][4],
ctermbg = t[1][3],
})
vim.api.nvim_set_hl(0, 'SpaceVim_statusline_a_bold', {
bold = true,
fg = t[1][1],
bg = t[1][2],
ctermfg = t[1][4],
ctermbg = t[1][3],
})
vim.api.nvim_set_hl(0, 'SpaceVim_statusline_ia', {
fg = t[1][1],
bg = t[1][2],
ctermfg = t[1][4],
ctermbg = t[1][3],
})
vim.api.nvim_set_hl(0, 'SpaceVim_statusline_b', {
fg = t[2][1],
bg = t[2][2],
ctermfg = t[2][4],
ctermbg = t[2][3],
})
vim.api.nvim_set_hl(0, 'SpaceVim_statusline_c', {
fg = t[3][1],
bg = t[3][2],
ctermfg = t[3][4],
ctermbg = t[3][3],
})
vim.api.nvim_set_hl(0, 'SpaceVim_statusline_z', {
fg = t[3][1],
bg = t[4][1],
ctermfg = t[3][3],
ctermbg = t[4][2],
})
vim.api.nvim_set_hl(0, 'SpaceVim_statusline_error', {
bold = true,
fg = '#ffc0b9',
bg = t[2][2],
ctermfg = 'Black',
ctermbg = t[2][3],
})
vim.api.nvim_set_hl(0, 'SpaceVim_statusline_warn', {
bold = true,
fg = '#fce094',
bg = t[2][2],
ctermfg = 'Black',
ctermbg = t[2][3],
})
vim.api.nvim_set_hl(0, 'SpaceVim_statusline_info', {
bold = true,
fg = '#8cf8f7',
bg = t[2][2],
ctermfg = 'Black',
ctermbg = t[2][3],
})
vim.api.nvim_set_hl(0, 'SpaceVim_statusline_hint', {
bold = true,
fg = '#a6dbff',
bg = t[2][2],
ctermfg = 'Black',
ctermbg = t[2][3],
})
highlight.hi_separator('SpaceVim_statusline_a', 'SpaceVim_statusline_b')
highlight.hi_separator('SpaceVim_statusline_a_bold', 'SpaceVim_statusline_b')
highlight.hi_separator('SpaceVim_statusline_ia', 'SpaceVim_statusline_b')
highlight.hi_separator('SpaceVim_statusline_b', 'SpaceVim_statusline_c')
highlight.hi_separator('SpaceVim_statusline_b', 'SpaceVim_statusline_z')
highlight.hi_separator('SpaceVim_statusline_c', 'SpaceVim_statusline_z')
end
function M.register_mode(mode)
if modes[mode.key] and mode.func then
modes[mode.key].func = mode.func
log.debug('register major mode function:' .. mode.key)
else
modes[mode.key] = mode
end
end
local function update_conf()
log.debug('write major mode to major_mode.json')
local conf = {}
for key, _ in pairs(modes) do
if index(loaded_modes, key) > -1 then
conf[key] = true
else
conf[key] = false
end
end
if
vim.fn.writefile(
{ JSON.json_encode(conf) },
vim.fn.expand(vim.g.spacevim_data_dir .. 'SpaceVim/major_mode.json')
) == 0
then
log.debug('update major_mode.json done')
else
log.debug('failed to update major_mode.json')
end
end
function M.toggle_mode(name)
log.debug('toggle major mode:' .. name)
local mode = modes[name]
if not mode then
log.debug('can not find major mode:' .. name)
return
end
local done
if mode.func then
if type(mode.func) == 'string' then
done = vim.fn[mode.func]()
elseif type(mode.func) == 'function' then
done = mode.func()
end
end
local idx = index(loaded_modes, name)
if idx ~= -1 then
table.remove(loaded_modes, idx)
else
if done == 1 then
table.insert(loaded_modes, name)
end
end
vim.opt_local.statusline = M.get(1)
if major_mode_cache then
update_conf()
end
end
function M.toggle_section(name)
if
index(vim.g.spacevim_statusline_left, name) == -1
and index(vim.g.spacevim_statusline_right, name) == -1
and not section_old_pos[name]
then
if name == 'search status' then
local temp = vim.g.spacevim_statusline_left
table.insert(temp, 2, name)
vim.g.spacevim_statusline_left = temp
else
local temp = vim.g.spacevim_statusline_right
table.insert(temp, name)
vim.g.spacevim_statusline_right = temp
end
elseif index(vim.g.spacevim_statusline_right, name) ~= -1 then
section_old_pos[name] = { 'r', index(vim.g.spacevim_statusline_right, name) }
local temp = vim.g.spacevim_statusline_right
table.remove(temp, index(temp, name))
vim.g.spacevim_statusline_right = temp
elseif index(vim.g.spacevim_statusline_left, name) ~= -1 then
section_old_pos[name] = { 'l', index(vim.g.spacevim_statusline_left, name) }
local temp = vim.g.spacevim_statusline_left
table.remove(temp, index(temp, name))
vim.g.spacevim_statusline_left = temp
elseif section_old_pos[name] then
if section_old_pos[name][1] == #'r' then
local temp = vim.g.spacevim_statusline_right
table.insert(temp, section_old_pos[name][2], name)
vim.g.spacevim_statusline_right = temp
else
local temp = vim.g.spacevim_statusline_left
table.insert(temp, section_old_pos[name][2], name)
vim.g.spacevim_statusline_left = temp
end
end
vim.opt_local.statusline = M.get(1)
end
function M.ctrlp_status(str)
return statusline.build(
{ ' Ctrlp ', ' ' .. str .. ' ' },
{ ' ' .. vim.fn.getcwd() .. ' ' },
lsep,
rsep,
'',
'',
'SpaceVim_statusline_a',
'SpaceVim_statusline_b',
'SpaceVim_statusline_c',
'SpaceVim_statusline_z',
vim.fn.winwidth(vim.fn.winnr())
)
end
function M.config()
if separators[vim.g.spacevim_statusline_separator] then
lsep = separators[vim.g.spacevim_statusline_separator][1]
rsep = separators[vim.g.spacevim_statusline_separator][2]
end
if i_separators[vim.g.spacevim_statusline_iseparator] then
ilsep = i_separators[vim.g.spacevim_statusline_iseparator][1]
irsep = i_separators[vim.g.spacevim_statusline_iseparator][2]
end
vim.fn['SpaceVim#mapping#space#def'](
'nnoremap',
{ 't', 'm', 'm' },
'call SpaceVim#layers#core#statusline#toggle_section("minor mode lighters")',
'toggle the minor mode lighters',
1
)
vim.fn['SpaceVim#mapping#space#def'](
'nnoremap',
{ 't', 'm', 'M' },
'call SpaceVim#layers#core#statusline#toggle_section("major mode")',
'toggle the major mode',
1
)
vim.fn['SpaceVim#mapping#space#def'](
'nnoremap',
{ 't', 'm', 'b' },
'call SpaceVim#layers#core#statusline#toggle_section("battery status")',
'toggle the battery status',
1
)
vim.fn['SpaceVim#mapping#space#def'](
'nnoremap',
{ 't', 'm', 'd' },
'call SpaceVim#layers#core#statusline#toggle_section("date")',
'toggle the date',
1
)
vim.fn['SpaceVim#mapping#space#def'](
'nnoremap',
{ 't', 'm', 'i' },
'call SpaceVim#layers#core#statusline#toggle_section("input method")',
'toggle the input method',
1
)
vim.fn['SpaceVim#mapping#space#def'](
'nnoremap',
{ 't', 'm', 't' },
'call SpaceVim#layers#core#statusline#toggle_section("time")',
'toggle the time',
1
)
vim.fn['SpaceVim#mapping#space#def'](
'nnoremap',
{ 't', 'm', 'p' },
'call SpaceVim#layers#core#statusline#toggle_section("cursorpos")',
'toggle the cursor position',
1
)
vim.fn['SpaceVim#mapping#space#def'](
'nnoremap',
{ 't', 'm', 'T' },
'if &laststatus == 2 | let &laststatus = 0 | else | let &laststatus = 2 | endif',
'toggle the statusline itself',
1
)
local function TagbarStatusline(_, _, fname, _)
local name = ''
if vim.fn.strwidth(fname) > vim.g.spacevim_sidebar_width - 15 then
name = string.sub(fname, vim.g.spacevim_sidebar_width - 20) .. '..'
else
name = fname
end
return statusline.build(
{ winnr(1), ' Tagbar ', ' ' .. name .. ' ' },
{},
lsep,
rsep,
'',
'',
'SpaceVim_statusline_ia',
'SpaceVim_statusline_b',
'SpaceVim_statusline_c',
'SpaceVim_statusline_z',
vim.g.spacevim_sidebar_width
)
end
vim.g.tagbar_status_func = TagbarStatusline
vim.g.unite_force_overwrite_statusline = 0
vim.g.ctrlp_status_func = {
main = 'SpaceVim#layers#core#statusline#ctrlp',
prog = 'SpaceVim#layers#core#statusline#ctrlp_status',
}
if
vim.fn.filereadable(vim.fn.expand(vim.g.spacevim_data_dir .. 'SpaceVim/major_mode.json')) == 1
and major_mode_cache
then
log.debug('load cache from major_mode.json')
local conf = JSON.json_decode(
vim.fn.join(
vim.fn.readfile(vim.fn.expand(vim.g.spacevim_data_dir .. 'SpaceVim/major_mode.json'), ''),
''
)
)
if type(conf) == 'table' then
for k, v in pairs(conf) do
if v == 1 or v == true then
log.debug('cached major mode: ' .. k)
M.toggle_mode(k)
end
end
end
end
end
function M.ctrlp(focus, byfname, _, prev, item, next, _)
return statusline.build(
{ ' Ctrlp ', ' ' .. prev .. ' ', ' ' .. item .. ' ', ' ' .. next .. ' ' },
{ ' ' .. focus .. ' ', ' ' .. byfname .. ' ', ' ' .. vim.fn.getcwd() .. ' ' },
lsep,
rsep,
'',
'',
'SpaceVim_statusline_a_bold',
'SpaceVim_statusline_b',
'SpaceVim_statusline_c',
'SpaceVim_statusline_z',
vim.fn.winwidth(vim.fn.winnr())
)
end
function M.jump(i)
pcall(function()
vim.cmd(i .. 'wincmd w')
end)
end
function M.mode(mode)
local t = colors_template
local iedit_mode = vim.w.spacevim_iedit_mode or ''
if vim.w.spacevim_statusline_mode ~= mode then
if mode == 'n' then
if iedit_mode == 'n' then
vim.api.nvim_set_hl(0, 'SpaceVim_statusline_a', {
bold = true,
fg = t[9][1],
bg = t[9][2],
ctermfg = t[9][3],
ctermbg = t[9][4],
})
elseif iedit_mode == 'i' then
vim.api.nvim_set_hl(0, 'SpaceVim_statusline_a', {
bold = true,
fg = t[8][1],
bg = t[8][2],
ctermfg = t[8][3],
ctermbg = t[8][4],
})
else
vim.api.nvim_set_hl(0, 'SpaceVim_statusline_a', {
bold = true,
fg = t[1][1],
bg = t[1][2],
ctermfg = t[1][4],
ctermbg = t[1][3],
})
end
elseif mode == 'i' then
vim.api.nvim_set_hl(0, 'SpaceVim_statusline_a', {
bold = true,
fg = t[5][1],
bg = t[5][2],
ctermfg = t[5][3],
ctermbg = t[5][4],
})
elseif mode == 'R' then
vim.api.nvim_set_hl(0, 'SpaceVim_statusline_a', {
bold = true,
fg = t[7][1],
bg = t[7][2],
ctermfg = t[7][3],
ctermbg = t[7][4],
})
elseif
mode == 'v'
or mode == 'V'
or mode == #''
or mode == 's'
or mode == 'S'
or mode == #''
then
vim.api.nvim_set_hl(0, 'SpaceVim_statusline_a', {
bold = true,
fg = t[6][1],
bg = t[6][2],
ctermfg = t[6][3],
ctermbg = t[6][4],
})
end
highlight.hi_separator('SpaceVim_statusline_a', 'SpaceVim_statusline_b')
vim.w.spacevim_statusline_mode = mode
end
return ''
end
function M.mode_text(mode)
local past_mode = ''
if vim.o.paste then
past_mode = 'Paste ' .. ilsep .. ' '
end
local mode_text = ''
local iedit_mode = vim.w.spacevim_iedit_mode or ''
if mode == 'n' then
if iedit_mode ~= '' then
if iedit_mode == 'n' then
mode_text = 'IEDIT-NORMAL'
elseif iedit_mode == 'i' then
mode_text = 'IEDIT-INSERT'
end
else
mode_text = ' NORMAL'
end
elseif mode == 'i' then
mode_text = ' INSERT'
elseif mode == 'R' then
mode_text = 'REPLACE'
elseif mode == 'v' then
mode_text = ' VISUAL'
elseif mode == 'V' then
mode_text = ' V-LINE'
elseif mode == '' then
mode_text = 'V-BLOCK'
elseif mode == 'c' then
mode_text = 'COMMAND'
elseif mode == 't' then
mode_text = ' TERM'
elseif
mode == 'v'
or mode == 'V'
or mode == '^V'
or mode == 's'
or mode == 'S'
or mode == '^S'
then
mode_text = ' VISUAL'
end
return past_mode .. mode_text
end
function M.set_variable(var)
major_mode_cache = var.major_mode_cache or major_mode_cache
end
function M.check_section(name)
for _, v in ipairs(vim.g.spacevim_statusline_right) do
if v == name then
return true
end
end
for _, v in ipairs(vim.g.spacevim_statusline_left) do
if v == name then
return true
end
end
return false
end
function M.denite_status(argv)
local denite_ver ---@type number
if vim.fn.exists('*denite#get_status_mode') == 1 then
denite_ver = 2
else
denite_ver = 3
end
if denite_ver == 3 then
return vim.fn['denite#get_status'](argv)
else
return vim.fn['denite#get_status_' .. argv]()
end
end
function M.denite_mode()
local t = colors_template
local denite_ver ---@type number
if vim.fn.exists('*denite#get_status_mode') == 1 then
denite_ver = 2
else
denite_ver = 3
end
if denite_ver == 3 then
return 'Denite'
else
local dmode = vim.fn.split(vim.fn['denite#get_status_mode']())[2]
if vim.w.spacevim_statusline_mode ~= dmode then
if dmode == 'NORMAL' then
vim.api.nvim_set_hl(0, 'SpaceVim_statusline_a_bold', {
bold = true,
fg = t[1][1],
bg = t[1][2],
ctermfg = t[1][4],
ctermbg = t[1][3],
})
else
vim.api.nvim_set_hl(0, 'SpaceVim_statusline_a_bold', {
bold = true,
fg = t[5][1],
bg = t[5][2],
ctermfg = t[5][3],
ctermbg = t[5][4],
})
end
highlight.hi_separator('SpaceVim_statusline_a_bold', 'SpaceVim_statusline_b')
vim.w.spacevim_statusline_mode = dmode
end
return dmode
end
end
function M.unite_mode()
local t = colors_template
local dmode = vim.fn.mode()
if vim.w.spacevim_statusline_mode ~= dmode then
if dmode == 'n' then
vim.api.nvim_set_hl(0, 'SpaceVim_statusline_a_bold', {
bold = true,
fg = t[1][1],
bg = t[1][2],
ctermfg = t[1][4],
ctermbg = t[1][3],
})
elseif dmode == 'i' then
vim.api.nvim_set_hl(0, 'SpaceVim_statusline_a_bold', {
bold = true,
fg = t[5][1],
bg = t[5][2],
ctermfg = t[5][3],
ctermbg = t[5][4],
})
end
highlight.hi_separator('SpaceVim_statusline_a_bold', 'SpaceVim_statusline_b')
vim.w.spacevim_statusline_mode = dmode
end
return dmode
end
function M.register_sections(name, func)
if registed_sections[name] then
log.info('statusline build-in section ' .. name .. ' has been changed!')
end
if type(func) ~= 'function' and type(func) ~= 'string' then
log.warn('section' .. name .. ' need to be function or string')
return
end
registed_sections[name] = func
end
function M.remove_section(name)
local left = {}
local right = {}
for _, v in ipairs(vim.g.spacevim_statusline_left) do
if v ~= name then
table.insert(left, v)
end
end
vim.g.spacevim_statusline_left = left
for _, v in ipairs(vim.g.spacevim_statusline_right) do
if v ~= name then
table.insert(right, v)
end
end
vim.g.spacevim_statusline_right = right
vim.opt_local.statusline = M.get(1)
end
function M.health() end
function M.init()
local group = vim.api.nvim_create_augroup('spacevim_statusline', { clear = true })
vim.api.nvim_create_autocmd({ 'BufWinEnter', 'WinEnter', 'FileType', 'BufWritePost' }, {
group = group,
pattern = { '*' },
callback = function(_)
vim.opt_local.statusline = M.get(1)
end,
})
vim.api.nvim_create_autocmd({ 'WinLeave' }, {
group = group,
pattern = { '*' },
callback = function(_)
vim.opt_local.statusline = M.get()
end,
})
vim.api.nvim_create_autocmd({ 'ColorScheme' }, {
group = group,
pattern = { '*' },
callback = function(_)
M.def_colors()
end,
})
end
function M.rsep()
return separators[vim.g.spacevim_statusline_separator] or separators.arrow
end
return M