hackline.vim 'hacks' your statusline so you don't have to.
An opinionated minimalistic statusline plugin for Vim and Neovim. It's lightweight, loads in no-time, still quite fully featured, with some features through optional plugins.
- No prerequisites like patched icon fonts. It has simple options for changing separators.
- Supports any colorscheme by being a normal Vim statusline. Highlight groups can be changed per mode, but changes the entire statusline for its context.
- Mode flag when not normal mode. Minimal by default.
- Responsive design adjusts and truncates on priority for smaller widths.
- All buffers uses same settings. No bloat with specific buffer/file type targeting. hackline.vim is just setup as dynamically as possible in how items are sorted and truncated, but still keeping them nice and logical for main buffers.
Integrations:
- LSP flag if connected to buffer. Supports Neovim's LSP. And vim-lsp (only simple flag if active LSP in buffer).
- Git info is bring-your-own function (from a plugin usually), or falls back to the built-in support for one of the following plugins (though maintenance of plugin support can not be ensured) connected to in order: gitsigns.nvim, vim-fugitive, vim-gitbranch. VGit can supplement the two latter with Git status.
Why another statusline plugin? Hackline.vim needs no customizing or no patched icon font. It’s not for the shallow, but hacked to be the lightest statusline plugin for pragmatic vimmers. In all honesty, the minimalism and barebones Vim features hackline.vim uses has drawbacks, but that’s worked around by hackline‘s design choices and are not really noticeable. Except the opinionated nature. The advantage is load time. Also, hackline.vim is generally fast.
For lazy.nvim (Neovim Lua):
{
"jssteinberg/hackline.vim",
dependencies = "itchyny/vim-gitbranch",
config = function()
-- to disable cmdline mode flag
vim.opt.showmode = false
end,
}
More examples
-- packer example (Neovim Lua)
use {
"jssteinberg/hackline.vim",
requires = { "itchyny/vim-gitbranch" },
config = function()
-- disable command line mode flag
vim.opt.showmode = false
end
}
" minpac (vimscript)
call minpac#add('jssteinberg/hackline.vim')
hackline.vim requires Neovim or Vim version > 8.2.1[something]---basically a newer version that supports re-evaluating expression results as a statusline format string. For Mac, you can use Vim from Homebrew.
hackline.vim is tested on Neovim and Vim compiled with lua (but should work without Lua).
Global variables for simple customization. Default values:
" Options:
let g:hackline_laststatus = 2 " corresponds to `laststatus`
let g:hackline_aggressive = 0 " or 1 for aggressive rerendering of statusline
" Items:
let g:hackline_mode = 1 " To activate mode flags and not deactivating `showmode`
" Separators and signs:
let g:hackline_separators = #{ l: ' / ', r: ' / ' }
" for vgit
let g:hackline_git_signs = #{
\added: "+",
\removed: "-",
\changed: "~",
\}
For full customization define your global Hackline function to customize.
function! Hackline(status) abort
return ""
endfunction
Vimscript:
hackline#ui#dir#info()
-- paramsmin_breakpoint = "lg", max_breakpoint = "xl"
(possible values:"md" | "lg" | "xl"
) -- returns current buffer relative directory, shortened between breakpoint, empty belowmin_breakpoint
.hackline#ui#git#info()
-- paramsappend_left = "*", display_breakpoint = "md"
(possibledisplay_breakpoint
values:"md" | "lg" | "xl"
) -- returns git info from gitsigns, fugitive, vim-branch, or vgit.hackline#ui#tab#info()
-- paramsstyle = "max"
(use"min"
to truncate info) -- returns tabs or spaces, and their size.hackline#ui#nvim_lsp#info()
-- paramsappend_left = " ", label = "LSP", preped_label = " ", seperator_servers = " ", prepend_right = " ", truncation_breakpoint = "xl"
(possibletruncation_breakpoint
values:"md" | "lg" | "xl"
) -- returns LSP connected servers by name/length (above/below breakpoint)- Also see
:help statusline
, https://jdhao.github.io/2019/11/03/vim_custom_statusline
Breakpoints can be redefined with g:hackline_breakpoints
. E.g.:
" default
let g:hackline_breakpoints = #{
md: 70, lg: 90, xl: 130
}
Number values refer to winwidth(0)
. Note that breakpoints are ignored if &laststatus == 3
.
For vim-lsp there's a buffer local variable that tells if LSP is active:
if get(b:, "hackline_use_vim_lsp", "0")
" LSP is active for buffer
endif
Full example
function! StatuslineModeLabels(sep_l = "", sep_r = "") abort
if mode() == "i" | return "I"
elseif mode() == "c" | return "C"
elseif mode() == "t" | return "T"
elseif mode() == "r" | return "R"
elseif mode() == "s" | return "S"
else | return "V"
endif
endfunction
function! Hackline(status) abort
let l:active = a:status
" separator label
let l:sep_l = " "
" separator sections
let l:sep = #{l: " -- ", r: " / "}
" seperator secondary
let l:sep_s = #{l: " " , r: " "}
" separator items
let l:sep_i = #{l: " " , r: " "}
" Statusline Start
" ----------------
let l:line = ""
" set statusline default color
let l:line .= l:active ? "%#StatusLine#" : "%#StatusLineNC#"
" set some mode colors
let l:line .= l:active && matchstr(mode(), "[itr]") != "" ? "%#IncSearch#" : ""
" Start spacing
let l:line .= " "
if l:active && matchstr(mode(), "[nc]") == ""
" (not normal or command mode)
let l:line .= "%1(%{StatuslineModeLabels()}%)"
else
" modified flag, fixed width 1
let l:line .= "%1(%M%)"
endif
" spacing
let l:line .= " "
" buffern number
let l:line .= "%(:b%{bufnr()}%)"
" filetype
let l:line .= "%(" . l:sep_i.l . "%{&filetype}%)"
let l:line .= l:sep.l
" file path
let l:line .= "%(%{hackline#ui#dir#info()}/%)"
" filename
let l:line .= "%(%t%)"
let l:line .= l:sep.l
" Cursor position
let l:line .= "l-%l/%L c-%c"
" Statusline END
" --------------
let l:line .= "%=" . l:sep_s.r
" truncation point
let l:line .= "%<"
" vim lsp
if l:active && get(b:, "hackline_use_vim_lsp", "0")
let l:line .= "LSP" . l:sep.r
endif
" nvim LSP
if l:active && has("nvim")
let l:line .= hackline#ui#nvim_lsp#info("", "LSP", l:sep_l, l:sep_i.r, l:sep.r)
endif
" spelllang
if l:active && &spell == 1
let l:line .= "%(spl=%{&spelllang}" . l:sep_i.r . "%)"
endif
" tabs/spaces
let l:line .= "%(%{hackline#ui#tab#info('min')}" . l:sep_i.r . "%)"
" encoding
let l:line .= "%(%{hackline#fileencoding#info()}%)"
" format
let l:line .= "%(" . l:sep_i.r . "%{&fileformat}%)"
" CWD
if len(getcwd(0)) > 1
let l:line .= l:sep.r
let l:line .= "%(%{split(getcwd(0), '/')[-1]}%)"
" Git
let l:line .= hackline#ui#git#info(" *")
endif
" End spacing
let l:line .= " "
return l:line
endfunction
This is v4.0.0-0.
Originally a fork of the lightweight skyline.vim which has a different look.
- Highlight group for unsaved
- Add Vim help documentation.
- Visual mode contextual information such column/line range, words in visual selection, etc.
- Nvim LSP number of buffer warning/errors?