diff --git a/config/vim/autoload/crystalline/theme/gruvbox8.vim b/config/vim/autoload/crystalline/theme/gruvbox8.vim new file mode 100644 index 0000000..ea78a90 --- /dev/null +++ b/config/vim/autoload/crystalline/theme/gruvbox8.vim @@ -0,0 +1,87 @@ +vim9script + +const dark = { + bg0: ['#282828', 235], + bg1: ['#3c3836', 237], + bg2: ['#504945', 239], + bg4: ['#7c6f64', 243], + + fg1: ['#ebdbb2', 187], + fg4: ['#a89984', 137], + + green: ['#98971a', 100], + yellow: ['#d79921', 172], + blue: ['#458588', 66], + aqua: ['#689d6a', 71], + orange: ['#d65d0e', 166], + red: ['#fb4934', 203], +} + +const light = { + bg0: ['#fbf1c7', 230], + bg1: ['#ebdbb2', 187], + bg2: ['#d5c4a1', 187], + bg4: ['#a89984', 137], + + fg1: ['#3c3836', 237], + fg4: ['#7c6f64', 243], + + green: ['#98971a', 100], + yellow: ['#d79921', 172], + blue: ['#458588', 66], + aqua: ['#689d6a', 71], + orange: ['#d65d0e', 166], + red: ['#9d0006', 124], +} + +def ToCrystalline(fg: list, bg: list): list + return [ + [fg[1], bg[1]], + [fg[0], bg[0]], + '' + ] +enddef + +def MakeTheme(c: dict>): dict> + var theme = { + A: ToCrystalline(c.bg0, c.bg4), + B: ToCrystalline(c.fg4, c.bg2), + Fill: ToCrystalline(c.fg4, c.bg1), + + InactiveA: ToCrystalline(c.bg4, c.bg1), + InactiveB: ToCrystalline(c.bg4, c.bg1), + InactiveFill: ToCrystalline(c.bg4, c.bg1), + + InsertModeA: ToCrystalline(c.bg0, c.blue), + InsertModeFill: ToCrystalline(c.fg4, c.bg2), + + VisualModeA: ToCrystalline(c.bg0, c.orange), + ReplaceModeA: ToCrystalline(c.bg0, c.aqua), + ReplaceModeFill: ToCrystalline(c.fg4, c.bg2), + TerminalModeA: ToCrystalline(c.bg0, c.green), + + Modified: ToCrystalline(c.red, c.bg1), + InsertModeModified: ToCrystalline(c.red, c.bg2), + + TabSel: ToCrystalline(c.bg0, c.fg4), + ModifiedSel: ToCrystalline(c.bg1, c.fg4), + } + + theme->extend({ + Tab: theme.Fill, + NormalModeModified: theme.Modified, + CommandModeModified: theme.Modified, + VisualModeModified: theme.Modified, + ReplaceModeModified: theme.InsertModeModified, + }) + + return theme +enddef + +export def GetThemeColours(): dict> + return &background ==# 'dark' ? dark : light +enddef + +export def SetTheme(): void + GetThemeColours()->MakeTheme()->g:crystalline#GenerateTheme() +enddef diff --git a/config/vim/init.vim b/config/vim/init.vim index fc4a47a..c1e17b2 100644 --- a/config/vim/init.vim +++ b/config/vim/init.vim @@ -3,16 +3,7 @@ set encoding=utf-8 scriptencoding utf-8 def EnsureDir(dir: string): void - if filewritable(dir) != 2 - mkdir(dir, "p", 0700) - endif -enddef - -def PrependIfVisible(status: string, symbol: string): string - if empty(status) - return '' - endif - return symbol .. status + mkdir(dir, "p", 0700) enddef # These are really clever - minpac will actually be loaded on the fly only @@ -35,34 +26,6 @@ if has('gui_running') || has('termguicolors') set termguicolors endif -g:battery#component_format = '%s %v%%' - -set noshowmode -g:lightline = { - colorscheme: 'gruvbox8', - separator: {left: "\ue0b0", right: "\ue0b2"}, - subseparator: {left: "\ue0b1", right: "\ue0b3"}, - active: { - left: [['mode', 'paste'], ['git_branch', 'battery'], ['readonly', 'filename', 'modified']], - right: [['lineinfo'], ['percent'], ['fileencoding', 'filetype']], - }, - component: { - filetype: '%{&ft}[%{&ff}]', - lineinfo: '%3l:%-2c', - }, - component_function: { - battery: 'battery#component', - }, - component_funcref: { - git_branch: () => g:FugitiveHead()->PrependIfVisible(' '), - } -} - -# Allow Funcrefs, especially lambdas, to be used as lightline components. :) -for k in keys(g:lightline.component_funcref) - g:lightline.component_function[k] = $'lightline.component_funcref.{k}' -endfor - set background=dark g:gruvbox_transp_bg = 1 g:gruvbox_italicize_strings = 0 @@ -128,6 +91,9 @@ g:mucomplete#can_complete = { } } +import "./statusline.vim" +statusline.Init() + import "./lsp.vim" lsp.LazyConfigure() diff --git a/config/vim/plugins.vim b/config/vim/plugins.vim index 50c1052..67189a1 100644 --- a/config/vim/plugins.vim +++ b/config/vim/plugins.vim @@ -46,8 +46,9 @@ minpac#add('w0rp/ale') minpac#add('yegappan/lsp') minpac#add('00dani/SchemaStore.vim') -minpac#add('itchyny/lightline.vim') +minpac#add('rbong/vim-crystalline') minpac#add('lambdalisue/battery.vim') +minpac#add('lambdalisue/nerdfont.vim') minpac#add('alvan/vim-closetag') minpac#add('LaTeX-Box-Team/LaTeX-Box') diff --git a/config/vim/statusline.vim b/config/vim/statusline.vim new file mode 100644 index 0000000..04bc2a6 --- /dev/null +++ b/config/vim/statusline.vim @@ -0,0 +1,124 @@ +vim9script + +import autoload ($XDG_CACHE_HOME .. '/vim/pack/minpac/start/vim-crystalline/autoload/crystalline.vim') as cr + +def PrependIfVisible(status: string, prefix: string): string + if empty(status) + return '' + endif + return prefix .. status +enddef + +def AppendIfVisible(status: string, affix: string): string + if empty(status) + return '' + endif + return status .. affix +enddef + +def StatuslineSection(seps: number, group: string, components: list): string + const hiGroup = cr.ModeGroup(group) + return components->copy()->filter((_, s) => s != '') + ->join(' ' .. cr.Sep(seps, hiGroup, hiGroup) .. ' ') +enddef + +def GitStatus(): string + if empty(g:FugitiveGitDir()) + return '' + endif + + const branch = g:FugitiveHead()->PrependIfVisible("\ue0a0 ") # nf-pl-branch + if !empty(branch) + return branch + endif + + return g:FugitiveHead(7) + ->PrependIfVisible("\Uf135e (") # nf-md-head + ->AppendIfVisible(")") +enddef + +def StatuslineLeft(window: number, inactive: bool): string + const bufnr = window->winbufnr() + const b = bufnr->getbufvar('&') + const fileName = [ + bufname(bufnr)->g:nerdfont#find()->AppendIfVisible(' '), + b.buftype == '' ? '%t' : '%f', + b.modifiable && b.modified ? cr.ModeHiItem('Modified') .. '+' .. cr.ModeHiItem('Fill') : '', + b.readonly ? " \uf023" : '', # nf-fa-lock + ]->join('') + if inactive + return ' ' .. fileName + endif + + const info = StatuslineSection(0, 'B', [ + GitStatus(), + g:battery#component_escaped(), + ])->AppendIfVisible(' ' .. cr.Sep(0, cr.ModeGroup('B'), cr.ModeGroup('Fill'))) + const vimMode = cr.ModeSection(0, 'A', empty(info) ? 'Fill' : 'B') + + return join([vimMode, info, fileName]) +enddef + +def StatuslineRight(window: number, inactive: bool): string + const percent = '%3p%%' + const lineInfo = '%3l:%-2c' + const fileType = '%{&ft}[%{&ff}]' + if inactive + return StatuslineSection(1, 'Fill', [fileType, percent, lineInfo]) + endif + + const fileEncoding = &fileencoding + const fileInfo = StatuslineSection(1, 'Fill', [fileEncoding, fileType]) + + const prettyPercent = cr.Sep(1, cr.ModeGroup('Fill'), cr.ModeGroup('B')) .. ' ' .. percent + const prettyLineInfo = cr.Sep(1, cr.ModeGroup('B'), cr.ModeGroup('A')) .. lineInfo + + return join([fileInfo, prettyPercent, prettyLineInfo]) +enddef + +def ConfigurePlugins(): void + g:battery#component_format = '%s %v%%' + g:nerdfont#default = '' + g:crystalline_theme = 'gruvbox8' +enddef + +def InitStatus(): void + def g:CrystallineStatuslineFn(window: number): string + const inactive = window != winnr() + const statusLeft = StatuslineLeft(window, inactive) + const statusRight = StatuslineRight(window, inactive) + + return $'{statusLeft}%={statusRight}' + enddef +enddef + +def InitTab() + g:crystalline_tab_mod = '' + def g:CrystallineTablineFn(): string + return cr.DefaultTabline({auto_prefix_groups: false}) + enddef + + def g:CrystallineTabFn(tabnr: number, bufnr: number, maxWidth: number, isSel: bool): list + var [tabDisplay, width] = cr.DefaultTab(tabnr, bufnr, maxWidth, isSel) + + if bufnr->getbufvar('&modified') + const sel = isSel ? 'Sel' : '' + tabDisplay ..= cr.HiItem($'Modified{sel}') .. '+' .. cr.HiItem($'Tab{sel}') .. ' ' + width += 2 + endif + + const icon = bufname(bufnr)->g:nerdfont#find()->PrependIfVisible(' ') + if width + strchars(icon) >= maxWidth + return [tabDisplay, width] + endif + + return [icon .. tabDisplay, width + strchars(icon)] + enddef +enddef + +export def Init(): void + InitStatus() + InitTab() + ConfigurePlugins() + set noshowmode +enddef