187 lines
		
	
	
		
			7.3 KiB
		
	
	
	
		
			Lua
		
	
	
	
	
	
			
		
		
	
	
			187 lines
		
	
	
		
			7.3 KiB
		
	
	
	
		
			Lua
		
	
	
	
	
	
local statusline = {}
 | 
						|
 | 
						|
local theme = {
 | 
						|
  light_green  = { fg = '#262626', bg = '#59946f' },
 | 
						|
  light_blue   = { fg = '#262626', bg = '#5c91bf' },
 | 
						|
  light_orange = { fg = '#262626', bg = '#b6927b' },
 | 
						|
  light_red    = { fg = '#262626', bg = '#e46876' },
 | 
						|
  light_grey   = { fg = '#262626', bg = '#808080' },
 | 
						|
  light_violet = { fg = '#262626', bg = '#957fb8' },
 | 
						|
  dark_white   = { fg = '#ffffff', bg = '#121212' },
 | 
						|
  dark_yellow  = { fg = '#c4b28a', bg = '#121212' },
 | 
						|
  dark_grey    = { fg = '#808080', bg = '#121212' },
 | 
						|
}
 | 
						|
 | 
						|
local modes = {}
 | 
						|
modes[110]  = { name = 'Normal', color = 'light_green' }
 | 
						|
modes[105]  = { name = 'Insert', color = 'light_blue' }
 | 
						|
modes[99]   = { name = 'Command', color = 'light_green' }
 | 
						|
modes[118]  = { name = 'Visual', color = 'light_violet' }
 | 
						|
modes[86]   = { name = 'V-Line', color = 'light_violet' }
 | 
						|
modes[22]   = { name = 'V-Block', color = 'light_violet' }
 | 
						|
modes[82]   = { name = 'Replace', color = 'light_red' }
 | 
						|
modes[115]  = { name = 'Select', color = 'light_orange' }
 | 
						|
modes[83]   = { name = 'S-Line', color = 'light_orange' }
 | 
						|
modes[19]   = { name = 'S-Block', color = 'light_orange' }
 | 
						|
modes[116]  = { name = 'Terminal', color = 'light_blue' }
 | 
						|
modes[33]   = { name = 'Shell', color = 'light_grey' }
 | 
						|
 | 
						|
local function highlight(group, color, attrs)
 | 
						|
  local command = 'highlight ' .. group ..
 | 
						|
      ' guifg=' .. color.fg .. ' guibg=' .. color.bg
 | 
						|
  if attrs then
 | 
						|
    command = command .. ' gui=' .. attrs
 | 
						|
  end
 | 
						|
  vim.cmd(command)
 | 
						|
end
 | 
						|
 | 
						|
-- StatusLineLight is shows the mode and cursor information, it is dynamically
 | 
						|
-- changed by statusline#mode(), give it a default.
 | 
						|
highlight('StatusLineLight', theme.light_grey)
 | 
						|
-- StatusLineDusk is shows additional information which is not always present,
 | 
						|
-- give it a muted color.
 | 
						|
highlight('StatusLineDusk', theme.light_grey, 'bold')
 | 
						|
-- StatusLineDark shows the filename and filetype and takes up most of the
 | 
						|
-- statusline, give it a dark background.
 | 
						|
highlight('StatusLineDark', theme.dark_white)
 | 
						|
-- StatusLineChange shows changes in the file by changing the colour of the
 | 
						|
-- filename, give if a dark background.
 | 
						|
highlight('StatusLineChange', theme.dark_yellow)
 | 
						|
-- StatusLineFade shows the status of completion engines but using colors which
 | 
						|
-- fade into the background to avoid grabbing attention.
 | 
						|
highlight('StatusLineDuskFade', theme.dark_grey)
 | 
						|
 | 
						|
-- Get statusline mode and update StatusLineLight.
 | 
						|
local function get_mode()
 | 
						|
  -- Map modes to a human readable name and a color.
 | 
						|
  local current_mode = modes[vim.fn.char2nr(vim.fn.mode())]
 | 
						|
  -- Update the StatusLineLight color.
 | 
						|
  highlight('StatusLineLight', theme[current_mode.color], 'bold')
 | 
						|
  return current_mode.name
 | 
						|
end
 | 
						|
 | 
						|
-- Display cusor line/total and column
 | 
						|
local position = '# ☰ %l/%L  %2c '
 | 
						|
 | 
						|
-- Construct a statusline for special buffer types.
 | 
						|
local function special(group, name, title)
 | 
						|
  -- Display current mode with dynamic highlights.
 | 
						|
  local line = '%#' .. group .. '# ' .. name .. ' '
 | 
						|
  -- Display filename with dark highlights.
 | 
						|
  line = line .. '%#StatusLineDark# ' .. title
 | 
						|
  -- Display current/total lines and column with dynamic highlights.
 | 
						|
  line = line .. '%=' .. '%#' .. group .. position
 | 
						|
  -- Combine the elements into a single string to be evaluated.
 | 
						|
  return line
 | 
						|
end
 | 
						|
 | 
						|
-- Construct a statusline for generic buffer types.
 | 
						|
local function generic(group, name, show_lsp)
 | 
						|
  -- Display current mode with dynamic highlights.
 | 
						|
  local line = '%#' .. group .. '# ' .. name .. ' '
 | 
						|
  -- Display spell or paste if set with dusk highlights in a group to swallow
 | 
						|
  -- the spaces when empty.
 | 
						|
  line = line .. '%#StatusLineDusk#%( ' .. '%{&spell ? "Spell " : ""}' ..
 | 
						|
      '%{&paste ? "Paste " : ""}' .. '%)'
 | 
						|
  -- Display filename with dark or changed highlights.
 | 
						|
  if vim.o.modified then
 | 
						|
    line = line .. '%#StatusLineChange#'
 | 
						|
  else
 | 
						|
    line = line .. '%#StatusLineDark#'
 | 
						|
  end
 | 
						|
  line = line .. ' %<%f'
 | 
						|
  -- Display readonly and nomodifiable if set.
 | 
						|
  line = line
 | 
						|
      .. '%#StatusLineDark#'
 | 
						|
      .. '%{&readonly ? " 🔒" : ""}'
 | 
						|
      .. '%{&modifiable ? "" : " ⛔"}'
 | 
						|
  -- Display filetype if set.
 | 
						|
  line = line .. '%=' .. '%#StatusLineDark# %{&filetype} '
 | 
						|
  -- Display fileencoding if not utf-8 and fileformat if not unix with dusk
 | 
						|
  -- highlights in a group to swallow spaces when empty.
 | 
						|
  line = line .. '%#StatusLineDusk#%( ' ..
 | 
						|
      '%{&fileencoding ==# "utf-8" ? "" : &fileencoding}' ..
 | 
						|
      '%{&fileformat ==# "unix" ? "" : "[".&fileformat."]"}' .. ' %)'
 | 
						|
  -- Display current/total lines and column with dynamic highlights.
 | 
						|
  line = line .. '%#' .. group .. position
 | 
						|
  -- Combine the elements into a single string to be evaluated.
 | 
						|
  return line
 | 
						|
end
 | 
						|
 | 
						|
-- Define active statusline, this statusline is dynamic with StatusLineLight
 | 
						|
-- being updated based on the current mode and only used for current buffer.
 | 
						|
function statusline.active()
 | 
						|
  local mode = get_mode()
 | 
						|
  if vim.o.buftype == 'help' then
 | 
						|
    if mode == 'Normal' then mode = 'Help' end
 | 
						|
    return special('StatusLineDusk', 'Help', '%F')
 | 
						|
  elseif vim.o.buftype == 'quickfix' then
 | 
						|
    -- Quickfix list and location list have the same buftype, the window has a
 | 
						|
    -- loclist flag, query the window info.
 | 
						|
    local info = vim.fn.getwininfo(vim.fn.win_getid())[1]
 | 
						|
    if mode == 'Normal' then
 | 
						|
      if info.loclist == 1 then
 | 
						|
        mode = 'Location'
 | 
						|
      else
 | 
						|
        mode = 'Quickfix'
 | 
						|
      end
 | 
						|
    end
 | 
						|
    local title = info.variables.quickfix_title
 | 
						|
    return special('StatusLineLight', mode, title)
 | 
						|
  elseif vim.o.buftype == 'terminal' then
 | 
						|
    return special('StatusLineLight', 'Terminal', '%f')
 | 
						|
  elseif vim.o.previewwindow then
 | 
						|
    if mode == 'Normal' then mode = 'Preview' end
 | 
						|
    return generic('StatusLineLight', mode, false)
 | 
						|
  elseif vim.o.filetype == 'man' then
 | 
						|
    return special('StatusLineDusk', 'Manual', '%f')
 | 
						|
  end
 | 
						|
  return generic('StatusLineLight', mode, true)
 | 
						|
end
 | 
						|
 | 
						|
function statusline.inactive()
 | 
						|
  local mode = modes[vim.fn.char2nr(vim.fn.mode())].name
 | 
						|
  local line = ''
 | 
						|
  if vim.o.buftype == 'help' then
 | 
						|
    line = special('StatusLineDusk', 'Help', '%F')
 | 
						|
  elseif vim.o.buftype == 'quickfix' then
 | 
						|
    -- Quickfix list and location list have the same buftype, the window has a
 | 
						|
    -- loclist flag, query the window info.
 | 
						|
    local info = vim.fn.getwininfo(vim.fn.win_getid())[1]
 | 
						|
    if info['loclist'] then mode = 'Location' else mode = 'Quickfix' end
 | 
						|
    line = special('StatusLineDusk', mode, info.variables.quickfix_title)
 | 
						|
  elseif vim.o.buftype == 'terminal' then
 | 
						|
    line = special('StatusLineDusk', 'Terminal', '%f')
 | 
						|
  elseif vim.o.previewwindow then
 | 
						|
    line = generic('StatusLineDusk', 'Preview', false)
 | 
						|
  elseif vim.o.filetype == 'man' then
 | 
						|
    line = special('StatusLineDusk', 'Manual', '%f')
 | 
						|
  else
 | 
						|
    line = generic('StatusLineDusk', 'Idle', false)
 | 
						|
  end
 | 
						|
  return line
 | 
						|
end
 | 
						|
 | 
						|
-- Setup autocmds to set the statusline per buffer.
 | 
						|
local group = vim.api.nvim_create_augroup('statusline', { clear = true })
 | 
						|
-- Dynamically update the current buffer mode and color changes using %! to
 | 
						|
-- call a function which is always evaluated on statusline update.
 | 
						|
vim.api.nvim_create_autocmd({ 'BufEnter', 'WinEnter', 'BufWinEnter' }, {
 | 
						|
  pattern = '*',
 | 
						|
  group = group,
 | 
						|
  callback = function()
 | 
						|
    vim.cmd [[ setlocal statusline=%{%v:lua.require('statusline').active()%} ]]
 | 
						|
  end
 | 
						|
})
 | 
						|
 | 
						|
-- Statically set the statusline when leaving the buffer.
 | 
						|
vim.api.nvim_create_autocmd({ 'BufLeave', 'WinLeave' }, {
 | 
						|
  pattern = '*',
 | 
						|
  group = group,
 | 
						|
  callback = function()
 | 
						|
    vim.cmd [[ setlocal statusline=%{%v:lua.require('statusline').inactive()%} ]]
 | 
						|
  end
 | 
						|
})
 | 
						|
 | 
						|
return statusline
 |