From 0ddcf996575091d6de8b1d02b1df4b784d3e3666 Mon Sep 17 00:00:00 2001 From: alemi Date: Thu, 18 Aug 2022 04:13:50 +0200 Subject: [PATCH] chore: moved into its own repository this was originally just part of my dotfiles, but since neovim stuff became a pretty big chunk, I'm moving it into its own project and having .dotfiles just git clone this. --- init.lua | 122 ++++++++++++++++++++ lua/colors.lua | 276 +++++++++++++++++++++++++++++++++++++++++++++ lua/keybinds.lua | 104 +++++++++++++++++ lua/plugins.lua | 194 +++++++++++++++++++++++++++++++ lua/state.lua | 133 ++++++++++++++++++++++ lua/statusline.lua | 131 +++++++++++++++++++++ 6 files changed, 960 insertions(+) create mode 100644 init.lua create mode 100644 lua/colors.lua create mode 100644 lua/keybinds.lua create mode 100644 lua/plugins.lua create mode 100644 lua/state.lua create mode 100644 lua/statusline.lua diff --git a/init.lua b/init.lua new file mode 100644 index 0000000..ed5c6b2 --- /dev/null +++ b/init.lua @@ -0,0 +1,122 @@ +--[[ + &&& + &##& █████╗ ██╗ ███████╗███╗ ███╗██╗ + &##& ██╔══██╗██║ ██╔════╝████╗ ████║██║ + BB& ███████║██║ █████╗ ██╔████╔██║██║ + &GB & ██╔══██║██║ ██╔══╝ ██║╚██╔╝██║██║ + &GB &BGBBBBBBBB###& ██║ ██║███████╗███████╗██║ ╚═╝ ██║██║ + GG &GGGGGGGGGGGGGB#& ╚═╝ ╚═╝╚══════╝╚══════╝╚═╝ ╚═╝╚═╝ + #P# &&#BGGGGGGGGGGG# nvim configuration + BP& &GGGGGGGGGB# + &#BGPP& &#BGGGGGGGB# + &#BGGGGGPP& &&#BGGGGGGB##& + &#GPPPGGGGGBPB &&##BGGGGGBB#&& + #PPPPPPPGGPG BP& &&##BBGGGGGGBB#&& + PPPPPPPPPPPPGBPG&&& &&&&&&###BBBGGGGGGGBB##&& + &BGPPPPPPPPPPPPPPGGGGGGGGGGGGGGGGGGGBBB##&&& + &&##BBBBGGGGGGGPGBBBBBB####&&&& + &#B#& + && ###& + &G# &&#&&& + &&& +]]-- + +--|| CORE +vim.opt.mouse = 'a' -- mouse can be handy +vim.opt.number = true -- show line number +vim.opt.cursorline = true -- highlight current line, with theme only visible in number bar +vim.opt.tabstop = 4 -- default to tab of size 4 +vim.opt.shiftwidth = 4 -- default to autoindent by 4 +vim.opt.expandtab = false -- default to hard tabs +vim.opt.wrap = false -- default to no wrap +vim.opt.showmode = false -- my statusline handles this +vim.opt.showcmd = true +vim.opt.wildmode = 'longest,list,full' -- don't accept partial completions until we tab a lot +vim.opt.hls = false +vim.opt.sessionoptions = "buffers,curdir,localoptions,tabpages,winsize" +vim.opt.foldlevelstart = 50 +vim.opt.termguicolors = true +-- vim.opt.signcolumn = "yes" +vim.opt.switchbuf = "usetab" + +vim.opt.list = true -- always show whitespace chars +vim.opt.listchars = "tab:│ ,space:·,trail:•,nbsp:▭,precedes:◀,extends:▶" + +vim.opt.winheight = 3 +vim.opt.winminheight = 3 +vim.opt.winwidth = 12 +vim.opt.winminwidth = 12 + +-- Tabline +-- TODO customize structure to make selected tab use same hi as mode, maybe +-- check https://gist.github.com/kanterov/1517990 ? +vim.opt.showtabline = 1 -- set to 2 to always show tabline + +-- Statusline +STATUSLINE = require('statusline') +vim.opt.laststatus = 3 -- show one global statusline +vim.opt.statusline = "%!v:lua.STATUSLINE:display()" + + +-- Netrw settings +vim.g.netrw_liststyle = 4 +vim.g.netrw_banner = 0 +vim.g.netrw_browse_split = 2 +vim.g.netrw_winsize = 12 + +-- Wiki.vim settings +vim.g.wiki_root = "~/Documents/wiki" + +-- vim.opt.timeoutlen = 500 -- set shorter timeout for keys +-- vim.opt.ttimeoutlen = 10 -- set even shorter timeout for ESC + +-- relativenumbers are very handy for navigation, but absolute are useful in general +-- and better looking. Keep numbers relative only on active buffer and if in Normal mode. +vim.opt.relativenumber = true +local number_mode_group = vim.api.nvim_create_augroup("NumberModeGroup", {clear=true}) +vim.api.nvim_create_autocmd( + { "InsertLeave", "BufEnter", "FocusGained", "WinEnter" }, + { callback=function() vim.opt.relativenumber = true end, group=number_mode_group } +) +vim.api.nvim_create_autocmd( + { "InsertEnter", "BufLeave", "FocusLost", "WinLeave" }, + { callback=function() vim.opt.relativenumber = false end, group=number_mode_group } +) + + +--|| STATE MANAGEMENT +VIMDIR = vim.fn.stdpath('data') .. '/site/' + +-- add command :SaveSession which wraps around ':mksession! .session.vim' +-- when vim in started without args, try to load .session.vim in cwd +require("state") + +-- keep track of undos across sessions +local undo_path = VIMDIR .. "undo/" +if not vim.fn.isdirectory(undo_path) then + vim.fn.mkdir(undo_path, "p") +end +vim.opt.undofile = true +vim.opt.undodir = undo_path + + +--|| KEYBINDS +KEYBINDS = require('keybinds') +KEYBINDS:set_global_keys({}) +KEYBINDS:set_navigation_keys({}) +-- Telescope and nvim-lsp will set more keybinds if loaded + + +--|| PLUGINS +local install_path = VIMDIR..'/pack/packer/start/packer.nvim' +if vim.fn.empty(vim.fn.glob(install_path)) > 0 then + local packer_bootstrap = vim.fn.system({'git', 'clone', '--depth', '1', 'https://github.com/wbthomason/packer.nvim', install_path}) +end + +plugins = require('plugins') + + +--|| THEME +PALETTE = require('colors') + +PALETTE:set_colors() diff --git a/lua/colors.lua b/lua/colors.lua new file mode 100644 index 0000000..5fbd7bf --- /dev/null +++ b/lua/colors.lua @@ -0,0 +1,276 @@ +--[[ + + BBB ██████╗ ███████╗ █████╗ ██╗ ██╗ + B#BGG ██╔══██╗██╔════╝██╔══██╗██║ ██╔╝ + GB&BG ! G ██████╔╝█████╗ ███████║█████╔╝ + ##GGB&&BGGBG! B ██╔═══╝ ██╔══╝ ██╔══██║██╔═██╗ + B&&&@@@@&###G ~!~ ██║ ███████╗██║ ██║██║ ██╗ + GB&#@@@@&@B #&#G ~^ ╚═╝ ╚══════╝╚═╝ ╚═╝╚═╝ ╚═╝ + B&@@@@@@@& GG ~:! ^ ^ neovim color scheme + G#&@&@@&@&G ~ + GB&&@@&G@B GG ~ # ^ * a warm colorscheme with + #&@@@@@@#G . GG #G ## ^ ! blue and red tones, to + B B&&&&@@&&# ! ^ ## G GB&&#GG# B G~. keep you cozy at night + GGB G@@#&&#G ~ . B GBB###&@@B G ^ + GGG B&#B G .:! ! @B B#GB###GB ! ^ * by alemidev + GG ! GB@&BB : !.G#GG B#&&#G G G . .^.: + GB . GG#@@@&## : !. # G B&@@#B : GBG . .: !^G +B###### ^^&@@@&BG G . B##BGBB B #B && . !G .:B GB##B + &##B BBG!^&@&#B ^ :. ##GGG GG B #G G &B~ ^ .:!G#&&! #BB# +BGB&&&&&##G &###B# G . ~ B#&&&BBG#&B GGGBB GB !! BG :G GG GG G#&#&. :@@@&& +BG#&##&#G :G@@BG ! # ::B#! &&#G GB#G &@@@@@@@@@& # GGGG GGG B&&#:^ B@@@&@@@ +BBG#B .~ @@B .~ G B#G GB & GBBG !G&#&&&&&&&&&& : : G G&&#: &&@@@&&&@@ +#BGGG .!&#B ~!: . GG #BGBGB#### ~ ~ &BGGGB#&B ! !~ ^.:~GG B&&&! !&&&&&& GG& +~ G @&&G !!!G BGG B&&B G ^ ! . @&@&&&&B ^ ::###B&&GGGB! @@@@@ BG ~# + GGG #@#B BGG#BB##G###B ~.! &&&#B## : #&@&#B#B G BB#&&@@@@@& B~ ~ + BGG GB# G G B#&G :.. : GGB G &&&B GG GG#BBB G : G + BG GBBBG GGG BGBGGGGB#B B## : G G ! : &B##G &@&#GGBG G G G&& +]]-- + +--- utility function to define nested color table in one line +-- first three arguments are (dark, normal, bright) strings, in form #ACACAC +-- last three arguments are (dark, normal, bright) numbers from x11 color table +local function COLOR(dark, normal, bright, code_d, code_n, code_b) + return { + dark = {gui = dark, term = code_d}, + normal = {gui = normal, term = code_n}, + bright = {gui = bright, term = code_b}, + } +end + +--- utility function to define highlight table from palette colors +-- All params can be nil, will define an empty highlight colors +local function HIGHLIGHT(fg, bg, attrs) + local result = {} + if attrs ~= nil then + for k, v in pairs(attrs) do + if result.cterm == nil then + result.cterm = {} + end + if k == "bold" or k == "italic" or k == "underline" then + result.cterm[k] = v + end + result[k] = v + end + end + if fg ~= nil then + result.ctermfg = fg.term + result.fg = fg.gui + end + if bg ~= nil then + result.ctermbg = bg.term + result.bg = bg.gui + end + return result +end + +--- Color palette object, containing colors and setter methods +-- @field set_colors function to easily apply color scheme +local PALETTE = { + --|| DARK NORMAL BRIGHT ( x11 codes ) -- TODO map dark variants + black = COLOR("#19161A", "#252A2B", "#444444", nil, 235, 238), + gray = COLOR("#333333", "#808080", "#A8A499", nil, 244, nil), + white = COLOR("#ADA9A1", "#D4D2CF", "#E8E1D3", nil, 252, 15 ), + azure = COLOR("#5D748C", "#81A1C1", "#A6B4C2", nil, nil, nil), + blue = COLOR("#323F61", "#48589C", "#5B6EA3", nil, 67, 4 ), + purple = COLOR("#433B6B", "#574C85", "#7468B0", nil, 60, 6 ), + pink = COLOR("#63296E", "#84508C", "#AC7EA8", nil, nil, nil), + red = COLOR("#824E53", "#BF616A", "#D1888E", nil, 1, 9 ), + orange = COLOR("#735F4C", "#AF875F", "#D69C63", nil, 137, nil), + yellow = COLOR("#A8956D", "#EBCB8B", "#EBD4A7", nil, 11, nil), + green = COLOR("#32664A", "#2E8757", "#55886C", nil, 2, 10 ), + cyan = COLOR("#116E70", "#05979A", "#4AD9D9", nil, 6, nil), + none = COLOR( nil, nil, nil, nil, 0, 0 ), +} + +--|| THEME DEFINITIONS + +function PALETTE:set_syntax_colors() + -- FG BG ATTR + vim.api.nvim_set_hl(0, "Whitespace", HIGHLIGHT(self.black.normal, nil, nil)) -- set color for whitespace + vim.api.nvim_set_hl(0, "Comment", HIGHLIGHT(self.gray.normal, nil, nil)) + vim.api.nvim_set_hl(0, "Constant", HIGHLIGHT(self.purple.dark, nil, nil)) + vim.api.nvim_set_hl(0, "String", HIGHLIGHT(self.purple.normal, nil, nil)) + vim.api.nvim_set_hl(0, "Boolean", HIGHLIGHT(self.purple.bright, nil, {bold=true})) + vim.api.nvim_set_hl(0, "Function", HIGHLIGHT(self.azure.normal, nil, {bold=true})) + vim.api.nvim_set_hl(0, "Identifier", HIGHLIGHT(self.blue.normal, nil, nil)) + vim.api.nvim_set_hl(0, "Statement", HIGHLIGHT(self.red.bright, nil, nil)) + vim.api.nvim_set_hl(0, "PreProc", HIGHLIGHT(self.pink.bright, nil, nil)) + vim.api.nvim_set_hl(0, "Include", HIGHLIGHT(self.cyan.normal, nil, nil)) + vim.api.nvim_set_hl(0, "Type", HIGHLIGHT(self.orange.normal, nil, nil)) + vim.api.nvim_set_hl(0, "Special", HIGHLIGHT(self.yellow.bright, nil, {bold=true})) + vim.api.nvim_set_hl(0, "Delimiter", HIGHLIGHT(self.gray.bright, nil, nil)) +end + +function PALETTE:set_treesitter_colors() + -- FG BG ATTR + vim.api.nvim_set_hl(0, "TSText", HIGHLIGHT(self.white.bright, nil, nil)) + -- comment + vim.api.nvim_set_hl(0, "TSComment", HIGHLIGHT(self.gray.normal, nil, nil)) + -- constant + vim.api.nvim_set_hl(0, "TSConstant", HIGHLIGHT(self.purple.dark, nil, {bold=true})) + vim.api.nvim_set_hl(0, "TSFloat", HIGHLIGHT(self.purple.bright, nil, nil)) + vim.api.nvim_set_hl(0, "TSNumber", HIGHLIGHT(self.purple.bright, nil, nil)) + vim.api.nvim_set_hl(0, "TSCharacter", HIGHLIGHT(self.purple.bright, nil, nil)) + vim.api.nvim_set_hl(0, "TSLiteral", HIGHLIGHT(self.purple.dark, nil, nil)) + vim.api.nvim_set_hl(0, "TSConstBuiltin", HIGHLIGHT(self.purple.dark, nil, {bold=true})) + -- string + vim.api.nvim_set_hl(0, "TSString", HIGHLIGHT(self.purple.normal, nil, nil)) + vim.api.nvim_set_hl(0, "TSStringRegex", HIGHLIGHT(self.orange.dark, nil, nil)) + vim.api.nvim_set_hl(0, "TSStringEscape", HIGHLIGHT(self.gray.normal, nil, nil)) + -- boolean + vim.api.nvim_set_hl(0, "TSBoolean", HIGHLIGHT(self.purple.bright, nil, {bold=true})) + -- function + vim.api.nvim_set_hl(0, "TSFunction", HIGHLIGHT(self.azure.normal, nil, nil)) + vim.api.nvim_set_hl(0, "TSFuncBuiltin", HIGHLIGHT(self.azure.normal, nil, {bold=true})) + vim.api.nvim_set_hl(0, "TSMethod", HIGHLIGHT(self.azure.dark, nil, nil)) + -- identifier + vim.api.nvim_set_hl(0, "TSAttribute", HIGHLIGHT(self.blue.normal, nil, {bold=true})) + vim.api.nvim_set_hl(0, "TSField", HIGHLIGHT(self.blue.bright, nil, nil)) + vim.api.nvim_set_hl(0, "TSProperty", HIGHLIGHT(self.blue.bright, nil, {bold=true})) + vim.api.nvim_set_hl(0, "TSParameter", HIGHLIGHT(self.blue.dark, nil, {bold=true})) + vim.api.nvim_set_hl(0, "TSParameterReference", HIGHLIGHT(self.blue.dark, nil, nil)) + -- statement + vim.api.nvim_set_hl(0, "TSConditional", HIGHLIGHT(self.red.normal, nil, nil)) + vim.api.nvim_set_hl(0, "TSKeyword", HIGHLIGHT(self.red.bright, nil, nil)) + vim.api.nvim_set_hl(0, "TSKeywordFunction", HIGHLIGHT(self.red.bright, nil, {bold=true})) + vim.api.nvim_set_hl(0, "TSKeywordOperator", HIGHLIGHT(self.red.dark, nil, {bold=true})) + vim.api.nvim_set_hl(0, "TSOperator", HIGHLIGHT(self.red.dark, nil, nil)) + -- preproc + vim.api.nvim_set_hl(0, "TSAnnotation", HIGHLIGHT(self.pink.normal, nil, nil)) + vim.api.nvim_set_hl(0, "TSConstMacro", HIGHLIGHT(self.pink.dark, nil, {bold=true})) + vim.api.nvim_set_hl(0, "TSFuncMacro", HIGHLIGHT(self.pink.dark, nil, nil)) + -- include + vim.api.nvim_set_hl(0, "TSInclude", HIGHLIGHT(self.cyan.dark, nil, {bold=true})) + vim.api.nvim_set_hl(0, "TSNamespace", HIGHLIGHT(self.cyan.dark, nil, nil)) + vim.api.nvim_set_hl(0, "TSCurrentScope", HIGHLIGHT(self.cyan.normal, nil, nil)) + -- type + vim.api.nvim_set_hl(0, "TSType", HIGHLIGHT(self.orange.normal, nil, nil)) + vim.api.nvim_set_hl(0, "TSTypeBuiltin", HIGHLIGHT(self.orange.bright, nil, {bold=true})) + vim.api.nvim_set_hl(0, "TSConstructor", HIGHLIGHT(self.orange.dark, nil, {bold=true})) + -- special + vim.api.nvim_set_hl(0, "TSLabel", HIGHLIGHT(self.yellow.bright, nil, nil)) + vim.api.nvim_set_hl(0, "TSTag", HIGHLIGHT(self.yellow.normal, nil, nil)) + vim.api.nvim_set_hl(0, "TSTagDelimiter", HIGHLIGHT(self.yellow.dark, nil, nil)) + vim.api.nvim_set_hl(0, "TSVariableBuiltin", HIGHLIGHT(self.yellow.normal, nil, {bold=true})) + vim.api.nvim_set_hl(0, "TSURI", HIGHLIGHT(self.blue.normal, nil, {underline=true})) + -- delimiter + vim.api.nvim_set_hl(0, "TSPunctDelimiter", HIGHLIGHT(self.gray.bright, nil, nil)) + vim.api.nvim_set_hl(0, "TSPunctBracket", HIGHLIGHT(self.gray.bright, nil, nil)) + vim.api.nvim_set_hl(0, "TSPunctSpecial", HIGHLIGHT(self.gray.bright, nil, nil)) + -- ??? + vim.api.nvim_set_hl(0, "TSSymbol", HIGHLIGHT(self.gray.bright, nil, nil)) + vim.api.nvim_set_hl(0, "TSVariable", HIGHLIGHT(self.white.normal, nil, nil)) + -- vim.api.nvim_set_hl(0, "TSError", highlight(nil, self.red.dark, {underline=true})) + -- vim.api.nvim_set_hl(0, "TSException", highlight(nil, self.red.normal, {underline=true, bold=true})) + -- vim.api.nvim_set_hl(0, "TSRepeat", highlight(self.black.bright, nil, nil)) + -- vim.api.nvim_set_hl(0, "TSTitle", highlight(self.white.bright, nil, {bold=true})) + -- vim.api.nvim_set_hl(0, "TSStrong", highlight(nil, nil, {bold=true})) + -- vim.api.nvim_set_hl(0, "TSEmphasis", highlight(self.red.bright, nil, {bold=true})) + -- vim.api.nvim_set_hl(0, "TSUnderline", highlight(nil, nil, {underline=true})) + -- vim.api.nvim_set_hl(0, "TSStrike", highlight(nil, nil, {strikethrough=true})) + -- vim.api.nvim_set_hl(0, "TreesitterContext", highlight(self.black.bright, nil, {bold=true})) +end + +function PALETTE:set_ui_colors() + -- FG BG ATTR + vim.api.nvim_set_hl(0, "NonText", HIGHLIGHT(self.black.normal, nil, nil)) + vim.api.nvim_set_hl(0, "Visual", HIGHLIGHT(nil, self.black.bright, nil)) + vim.api.nvim_set_hl(0, "Search", HIGHLIGHT(self.white.normal, self.none.normal, {bold=true, underline=true})) + vim.api.nvim_set_hl(0, "Folded", HIGHLIGHT(self.cyan.normal, self.black.normal, nil)) + vim.api.nvim_set_hl(0, "FoldColumn", HIGHLIGHT(self.cyan.normal, nil, nil)) + vim.api.nvim_set_hl(0, "Pmenu", HIGHLIGHT(nil, self.black.normal, nil)) -- Balloon color + vim.api.nvim_set_hl(0, "VertSplit", HIGHLIGHT(self.black.normal, self.black.normal, nil)) -- Split divider color + vim.api.nvim_set_hl(0, "SignColumn", HIGHLIGHT(nil, nil, nil)) -- Gutter color + vim.api.nvim_set_hl(0, "CursorLine", HIGHLIGHT(nil, nil, nil)) -- Line number color + vim.api.nvim_set_hl(0, "CursorLineSign", HIGHLIGHT(nil, nil, nil)) -- CursorLine color (in sign column) + vim.api.nvim_set_hl(0, "CursorLineNr", HIGHLIGHT(self.yellow.normal, self.black.normal, {bold=true})) -- CursorLine color (in number column) + vim.api.nvim_set_hl(0, "LineNr", HIGHLIGHT(self.black.bright, nil, nil)) -- Number column color + + vim.api.nvim_set_hl(0, "Question", HIGHLIGHT(self.cyan.normal, nil, {bold=true})) + vim.api.nvim_set_hl(0, "MoreMsg", HIGHLIGHT(self.black.bright, nil, {bold=true})) + vim.api.nvim_set_hl(0, "ErrorMsg", HIGHLIGHT(self.white.normal, self.red.normal, nil)) + vim.api.nvim_set_hl(0, "WarningMsg", HIGHLIGHT(self.black.normal, self.yellow.normal, nil)) + vim.api.nvim_set_hl(0, "Title", HIGHLIGHT(self.pink.dark, nil, {bold=true})) + vim.api.nvim_set_hl(0, "WildMenu", HIGHLIGHT(self.gray.bright, self.orange.dark, nil)) + vim.api.nvim_set_hl(0, "ColorColumn", HIGHLIGHT(self.gray.dark, self.orange.normal, nil)) + + vim.api.nvim_set_hl(0, "DiagnosticWarn", HIGHLIGHT(self.orange.normal, nil, nil)); + vim.api.nvim_set_hl(0, "DiagnosticError", HIGHLIGHT(self.red.normal, nil, nil)); + vim.api.nvim_set_hl(0, "DiagnosticInfo", HIGHLIGHT(self.cyan.normal, nil, nil)); + vim.api.nvim_set_hl(0, "DiagnosticHint", HIGHLIGHT(self.gray.normal, nil, nil)); + vim.api.nvim_set_hl(0, "DiagnosticUnderlineWarn", HIGHLIGHT(nil, nil, {underdash=true, sp=self.orange.normal.gui})); + vim.api.nvim_set_hl(0, "DiagnosticUnderlineError", HIGHLIGHT(nil, nil, {underline=true, sp=self.red.normal.gui})); + vim.api.nvim_set_hl(0, "DiagnosticUnderlineInfo", HIGHLIGHT(nil, nil, {sp=self.cyan.normal.gui})); + vim.api.nvim_set_hl(0, "DiagnosticUnderlineHint", HIGHLIGHT(nil, nil, {sp=self.gray.normal.gui})); +end + +function PALETTE:set_diff_colors() + -- FG BG ATTR + vim.api.nvim_set_hl(0, "DiffAdd", HIGHLIGHT(nil, self.black.normal, nil)) + vim.api.nvim_set_hl(0, "DiffChange", HIGHLIGHT(nil, self.black.dark, nil)) + vim.api.nvim_set_hl(0, "DiffDelete", HIGHLIGHT(self.black.normal, self.black.dark, nil)) + vim.api.nvim_set_hl(0, "DiffText", HIGHLIGHT(nil, self.black.normal, nil)) +end + +function PALETTE:set_spell_colors() + -- FG BG ATTR + vim.api.nvim_set_hl(0, "SpellBad", HIGHLIGHT(nil, nil, {underline=true})) + vim.api.nvim_set_hl(0, "SpellCap", HIGHLIGHT(nil, nil, {underline=true})) + vim.api.nvim_set_hl(0, "SpellLocal", HIGHLIGHT(nil, nil, {underline=true})) + vim.api.nvim_set_hl(0, "SpellRare", HIGHLIGHT(nil, nil, {bold=true})) +end + +function PALETTE:set_tab_colors() + -- FG BG ATTR + vim.api.nvim_set_hl(0, "TabLineFill", HIGHLIGHT(self.yellow.normal, self.black.normal, nil)) + vim.api.nvim_set_hl(0, "TabLineSel", HIGHLIGHT(self.black.normal, self.gray.normal, {bold=true})) + vim.api.nvim_set_hl(0, "TabLine", HIGHLIGHT(self.gray.normal, self.black.normal, nil)) +end + +function PALETTE:set_statusline_colors() + -- FG BG ATTR + vim.api.nvim_set_hl(0, "StatusLine", HIGHLIGHT(self.gray.normal, self.black.normal, nil)) + vim.api.nvim_set_hl(0, "StatusLineBlock", HIGHLIGHT(self.gray.normal, self.black.bright, {bold=true})) + vim.api.nvim_set_hl(0, "NormalMode", HIGHLIGHT(self.black.normal, self.pink.bright, {bold=true})) + vim.api.nvim_set_hl(0, "InsertMode", HIGHLIGHT(self.black.normal, self.red.normal, {bold=true})) + vim.api.nvim_set_hl(0, "VisualMode", HIGHLIGHT(self.black.normal, self.blue.bright, {bold=true})) + vim.api.nvim_set_hl(0, "SpecialMode", HIGHLIGHT(self.black.normal, self.yellow.normal, {bold=true})) +end + +function PALETTE:set_gitsigns_colors() + -- FG BG ATTR + vim.api.nvim_set_hl(0, "GitSignsChange", HIGHLIGHT(self.yellow.normal, nil, nil)) + vim.api.nvim_set_hl(0, "GitSignsDelete", HIGHLIGHT(self.red.bright, nil, nil)) +end + +function PALETTE:set_telescope_colors() + -- FG BG ATTR + vim.api.nvim_set_hl(0, "TelescopeBorder", HIGHLIGHT(self.black.bright, nil, nil)); + -- vim.api.nvim_set_hl(0, "TelescopePromptBorder", highlight(self.black.bright, nil, nil)); + -- vim.api.nvim_set_hl(0, "TelescopePromptNormal", highlight()); + -- vim.api.nvim_set_hl(0, "TelescopePromptPrefix", highlight()); + -- vim.api.nvim_set_hl(0, "TelescopeNormal", highlight()); + -- vim.api.nvim_set_hl(0, "TelescopePreviewTitle", highlight()); + -- vim.api.nvim_set_hl(0, "TelescopePromptTitle", highlight()); + -- vim.api.nvim_set_hl(0, "TelescopeResultsTitle", highlight()); + -- vim.api.nvim_set_hl(0, "TelescopeSelection", highlight()); + -- vim.api.nvim_set_hl(0, "TelescopePreviewLine", highlight()); +end + +--- set all theme highlight groups +function PALETTE:set_colors() + -- core + self:set_syntax_colors() + self:set_ui_colors() + self:set_diff_colors() + self:set_spell_colors() + self:set_tab_colors() + self:set_statusline_colors() + -- addons + self:set_treesitter_colors() + self:set_gitsigns_colors() + self:set_telescope_colors() +end + +return PALETTE diff --git a/lua/keybinds.lua b/lua/keybinds.lua new file mode 100644 index 0000000..44a21bf --- /dev/null +++ b/lua/keybinds.lua @@ -0,0 +1,104 @@ +--[[ + &&& + &##& █████╗ ██╗ ███████╗███╗ ███╗██╗ + &##& ██╔══██╗██║ ██╔════╝████╗ ████║██║ + BB& ███████║██║ █████╗ ██╔████╔██║██║ + &GB & ██╔══██║██║ ██╔══╝ ██║╚██╔╝██║██║ + &GB &BGBBBBBBBB###& ██║ ██║███████╗███████╗██║ ╚═╝ ██║██║ + GG &GGGGGGGGGGGGGB#& ╚═╝ ╚═╝╚══════╝╚══════╝╚═╝ ╚═╝╚═╝ + #P# &&#BGGGGGGGGGGG# nvim keybinds + BP& &GGGGGGGGGB# + &#BGPP& &#BGGGGGGGB# * keybinds are scoped in methods and + &#BGGGGGPP& &&#BGGGGGGB##& only enabled if the relevant plugin + &#GPPPGGGGGBPB &&##BGGGGGBB#&& is loaded + #PPPPPPPGGPG BP& &&##BBGGGGGGBB#&& * binds are kinda arbitrary, if you + PPPPPPPPPPPPGBPG&&& &&&&&&###BBBGGGGGGGBB##&& have good suggestions tell me + &BGPPPPPPPPPPPPPPGGGGGGGGGGGGGGGGGGGBBB##&&& about it + &&##BBBBGGGGGGGPGBBBBBB####&&&& + &#B#& + && ###& + &G# &&#&&& + &&& +]]-- + +local MAPPINGS = { } + +--|| GLOBAL KEYBINDS +function MAPPINGS:set_global_keys(opts) + -- Quick settings + vim.keymap.set('n', '', ':set hls!', opts) + vim.keymap.set('n', '', ':set wrap!', opts) + vim.keymap.set('n', '', ':set list!', opts) + vim.keymap.set('n', '', ':set spell!', opts) + vim.keymap.set('n', '', ':Hexmode', opts) + vim.keymap.set('n', '', ':Telescope oldfiles', opts) + -- Files navigation + vim.keymap.set('n', '', ':tabnew', opts) + vim.keymap.set('n', '', ':tabnew', opts) -- fallback for windows + vim.keymap.set('n', '', ':NvimTreeToggle', {noremap=true}) + -- Esc goes back to normal mode in terminal + vim.keymap.set('t', '', '', opts) +end + +function MAPPINGS:set_navigation_keys(opts) + -- lazy arrow scrolling + vim.keymap.set('n', '', '', opts) + vim.keymap.set('n', '', '', opts) + vim.keymap.set('n', '', '', opts) + vim.keymap.set('n', '', '', opts) + vim.keymap.set('n', '', ':resize +1', opts) + vim.keymap.set('n', '', ':resize -1', opts) + vim.keymap.set('n', '', ':vertical resize +1', opts) + vim.keymap.set('n', '', ':vertical resize -1', opts) +end + +function MAPPINGS:set_lsp_keys(opts) + -- Enable completion triggered by + vim.api.nvim_buf_set_option(opts.buffer, 'omnifunc', 'v:lua.vim.lsp.omnifunc') + -- Enable Lsp tagfunc + vim.api.nvim_buf_set_option(opts.buffer, 'tagfunc', 'v:lua.vim.lsp.tagfunc') + -- See `:help vim.lsp.*` for documentation on any of the below functions + vim.keymap.set('n', 'gD', vim.lsp.buf.declaration, opts) + vim.keymap.set('n', 'gd', vim.lsp.buf.definition, opts) + vim.keymap.set('n', 'gy', vim.lsp.buf.type_definition, opts) + vim.keymap.set('n', 'gi', vim.lsp.buf.implementation, opts) + vim.keymap.set('n', 'gr', vim.lsp.buf.references, opts) + vim.keymap.set('n', '', vim.lsp.buf.hover, opts) + vim.keymap.set('n', '', vim.lsp.buf.hover, opts) + vim.keymap.set('n', '', vim.lsp.buf.signature_help, opts) + -- vim.keymap.set('n', 'wa', vim.lsp.buf.add_workspace_folder, opts) + -- vim.keymap.set('n', 'wr', vim.lsp.buf.remove_workspace_folder, opts) + vim.keymap.set('n', '', vim.lsp.buf.rename, opts) + vim.keymap.set('n', '', vim.lsp.buf.code_action, opts) + vim.keymap.set('n', '', vim.lsp.buf.formatting, opts) + vim.keymap.set('n', '', vim.diagnostic.open_float, opts) + vim.keymap.set('n', '', vim.diagnostic.open_float, opts) -- fallback for windows + -- It's not really a keybind but whatever + vim.api.nvim_create_user_command('Format', ':lua vim.lsp.buf.formatting()', {}) -- TODO if function is passed directly, it doesn't work! +end + +function MAPPINGS:set_telescope_keys(opts) + -- File navigation + vim.keymap.set('n', '', ':Telescope find_files', opts) + vim.keymap.set('n', 'F', ':Telescope find_files', opts) -- fallback for windows + vim.keymap.set('n', '', ':Telescope live_grep', opts) + vim.keymap.set('n', '', ':Telescope live_grep', opts) -- fallback for windows + vim.keymap.set('n', '', ':Telescope lsp_references', opts) + vim.keymap.set('n', '', ':Telescope git_bcommits', opts) + vim.keymap.set('n', '', ':Telescope git_bcommits', opts) -- fallback for windows + -- Marks and buffers with telescope + vim.keymap.set('n', '', ':Telescope buffers', opts) + vim.keymap.set('n', '', ':Telescope marks', opts) + vim.keymap.set('n', '', ':Telescope marks', opts) -- fallback for windows + vim.keymap.set('n', '', ':Telescope current_buffer_fuzzy_find', opts) + vim.keymap.set('n', '', ':Telescope current_buffer_fuzzy_find', opts) -- fallback for windows + -- Symbols with telescope + vim.keymap.set('n', '', ':Telescope lsp_document_symbols', opts) + vim.keymap.set('n', '', ':Telescope lsp_workspace_symbols', opts) + vim.keymap.set('n', '', ':Telescope lsp_workspace_symbols', opts) -- fallback for windows + -- Error list with telescope + vim.keymap.set('n', '', ':Telescope diagnostics', opts) + vim.keymap.set('n', '', ':Telescope diagnostics bufnr=0', opts) +end + +return MAPPINGS diff --git a/lua/plugins.lua b/lua/plugins.lua new file mode 100644 index 0000000..3310e8b --- /dev/null +++ b/lua/plugins.lua @@ -0,0 +1,194 @@ +--[[ + &&& + &##& █████╗ ██╗ ███████╗███╗ ███╗██╗ + &##& ██╔══██╗██║ ██╔════╝████╗ ████║██║ + BB& ███████║██║ █████╗ ██╔████╔██║██║ + &GB & ██╔══██║██║ ██╔══╝ ██║╚██╔╝██║██║ + &GB &BGBBBBBBBB###& ██║ ██║███████╗███████╗██║ ╚═╝ ██║██║ + GG &GGGGGGGGGGGGGB#& ╚═╝ ╚═╝╚══════╝╚══════╝╚═╝ ╚═╝╚═╝ + #P# &&#BGGGGGGGGGGG# nvim plugins + BP& &GGGGGGGGGB# + &#BGPP& &#BGGGGGGGB# * tldr: managed with packer.nvim + &#BGGGGGPP& &&#BGGGGGGB##& - lsp: integrated + nvim-lspconfig + &#GPPPGGGGGBPB &&##BGGGGGBB#&& - completion: nvim-cmp + LuaSnip + #PPPPPPPGGPG BP& &&##BBGGGGGGBB#&& - syntax: nvim-treesitter + PPPPPPPPPPPPGBPG&&& &&&&&&###BBBGGGGGGGBB##&& - pickers: telescope.nvim + &BGPPPPPPPPPPPPPPGGGGGGGGGGGGGGGGGGGBBB##&&& - files: nvim-tree.lua + &&##BBBBGGGGGGGPGBBBBBB####&&&& - git: vim-fugitive + gitsigns.nvim + &#B#& - extra: hexmode, vim-combo, + && ###& rust-tools, nvim-colorizer + &G# &&#&&& + &&& +]]-- + +local init_fn = function(use) + use 'wbthomason/packer.nvim' -- packer can manage itself + + -- trying this thing out + use 'lervag/wiki.vim' -- utilities for managing my wiki + use 'lervag/wiki-ft.vim' -- wiki format syntax + -- really idk about it, need to use it for a while + + use 'fidian/hexmode' -- convert buffers into hex view with xxd + use 'alemidev/vim-combo' -- track code combos + use 'editorconfig/editorconfig-vim' -- respect editorconfig + + use 'tpope/vim-fugitive' -- better git commands + + use 'neovim/nvim-lspconfig' -- import LSP configurations + use 'simrat39/rust-tools.nvim' -- extra LSP defaults for rust + + use 'hrsh7th/nvim-cmp' -- completion engine core + use 'hrsh7th/cmp-nvim-lsp' -- completions based on LSP + use 'hrsh7th/cmp-path' -- completions based on paths + use 'hrsh7th/cmp-buffer' -- completions based on buffer + + use 'L3MON4D3/LuaSnip' -- snippet engine + use 'saadparwaiz1/cmp_luasnip' -- incorporate with completions + + use { + 'norcalli/nvim-colorizer.lua', + config = function () require('colorizer').setup() end + } + + use { + 'nvim-telescope/telescope.nvim', -- fuzzy finder, GUI component + requires = { + {'nvim-lua/plenary.nvim'}, -- some utilities made for telescope + {'nvim-telescope/telescope-fzf-native.nvim', run = 'make' }, -- fzf algorithm implemented in C for faster searches + {'nvim-telescope/telescope-ui-select.nvim'}, + }, + config = function() + require('telescope').load_extension('fzf') + require("telescope").load_extension("ui-select") + require('keybinds').set_telescope_keys({}) + end + } + + use { + 'lewis6991/gitsigns.nvim', -- show diff signs in gutter + config = function() + require('gitsigns').setup { -- configure symbols and colors + signs = { + add = {hl = 'GitSignsChange', text = '╎'}, + change = {hl = 'GitSignsChange', text = '│'}, + delete = {hl = 'GitSignsDelete', text = '_'}, + topdelete = {hl = 'GitSignsDelete', text = '‾'}, + changedelete = {hl = 'GitSignsDelete', text = '~'}, + }, + } + end + } + + use { + 'nvim-treesitter/nvim-treesitter', + run = ':TSUpdate', + config = function() + require('nvim-treesitter.configs').setup { + highlight = { enable = true }, + incremental_selection = { enable = true }, + textobjects = { enable = true } + } + vim.opt.foldmethod = "expr" + vim.opt.foldexpr = "nvim_treesitter#foldexpr()" + end + } + + use { + 'kyazdani42/nvim-tree.lua', -- tree file explorer, alternative to nerdtree in lua + requires = { 'kyazdani42/nvim-web-devicons' }, -- optional, for file icons + config = function() + require('nvim-tree').setup({ + view={ + adaptive_size = false, + mappings={ + list={ + { key = "", action = "close" }, + { key = "t", action = "tabnew" }, + { key = "s", action = "split" }, + { key = "", action = "vsplit" }, + } + } + } + }) + end + } + + -- TODO this part is messy, can I make it cleaner? + -- TODO can I put these setup steps inside their respective config callback? + -- TODO can I make them also load their highlight groups? + + local cmp = require('cmp') + cmp.setup({ + snippet = { + expand = function(args) require('luasnip').lsp_expand(args.body) end, + }, + mapping = cmp.mapping.preset.insert({ + [''] = cmp.mapping.complete(), + [''] = cmp.mapping.abort(), + [''] = function(fallback) if cmp.visible() then cmp.select_next_item() else fallback() end end, + [''] = cmp.mapping.confirm({ select = true }), + }), + sources = cmp.config.sources({ + { name = 'nvim_lsp' }, + }, { + { name = 'path' }, + }, { + { name = 'buffer' }, + }) + }) + + -- Setup lspconfig. + capabilities = require('cmp_nvim_lsp').update_capabilities(vim.lsp.protocol.make_client_capabilities()) + -- Replace with each lsp server you've enabled. + local lspconfig = require("lspconfig") + + local function set_lsp_binds(_, bufnr) + require('keybinds').set_lsp_keys({buffer=bufnr}) + end + + local rust_tools = require("rust-tools") + rust_tools.setup({ + tools = { + inlay_hints = { auto = true }, + hover_actions = { border = "none" }, + }, + server = { + capabilities = capabilities, + on_attach = set_lsp_binds, + } + }) + rust_tools.inlay_hints.enable() + + lspconfig.bashls.setup({capabilities=capabilities, on_attach=set_lsp_binds}) + lspconfig.pyright.setup({capabilites=capabilities, on_attach=set_lsp_binds}) + lspconfig.clangd.setup({capabilities=capabilities, on_attach=set_lsp_binds}) + + local jdtls_bin_path = os.getenv("JDTLS_BIN_PATH") or "jdtls" + local home_path = os.getenv("HOME") -- TODO this is not windows friendly + lspconfig.jdtls.setup({ + capabilities=capabilities, + on_attach=set_lsp_binds, + cmd = {jdtls_bin_path, "-configuration", home_path .. "/.cache/jdtls/config", "-data", home_path .. "/.cache/jdtls/workspace" }, + workspace = home_path .. "/.cache/jdtls/workspace", + -- root_dir = require('jdtls.setup').find_root({'.git', 'mvnw', 'gradlew'}), + }) + lspconfig.sumneko_lua.setup({ + capabilites=capabilities, + on_attach=set_lsp_binds, + settings = { + Lua = { + runtime = { version = 'LuaJIT' }, + diagnostics = { globals = {'vim'} }, + workspace = { library = vim.api.nvim_get_runtime_file("", true) }, + telemetry = { enable = false }, + } + } + }) + + -- lspconfig.jedi_language_server.setup({capabilites=capabilites}) +end + +return require('packer').startup(init_fn) + + diff --git a/lua/state.lua b/lua/state.lua new file mode 100644 index 0000000..de9853c --- /dev/null +++ b/lua/state.lua @@ -0,0 +1,133 @@ +--[[ + + ...::....:~77~^~^~~~:. ██████╗██████╗ ██╗ ██╗███╗ ███╗██████╗ ███████╗ + .~!777!!~!7!~^75J^~^^~~~!~^::::.. ██╔════╝██╔══██╗██║ ██║████╗ ████║██╔══██╗██╔════╝ + ..^?YJ7^.^.:::^:!~^?J:..^^:..~JJ5J~~~:. ██║ ██████╔╝██║ ██║██╔████╔██║██████╔╝███████╗ + .:^~~!!77~^7!J!...:....:^~77... .....!JY^:::^^: ██║ ██╔══██╗██║ ██║██║╚██╔╝██║██╔══██╗╚════██║ + .~!~!~^^^~~~!!^7JJ....... .:!J:....... .~Y~.....:^ ╚██████╗██║ ██║╚██████╔╝██║ ╚═╝ ██║██████╔╝███████║ + .!7~:^^^^:^^^::.:^!J?. ... .. .7: . . .~: .... :: ╚═════╝╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚═╝╚═════╝ ╚══════╝ + .~!~^^:..::...:.. ..:?^ ....... .. . . . ... :^ + :?~::.... ..... . .. .:......... . ... . . ..:^~^ * pick up where you left + ^^:~^... . .................... . .. ...:^^^~~^: * wraps around vim sessions: an hidden file + .~:~::^^:..:............. . ......::^~~~~~~^: named .session.vim can be created with a + .~~^^^::^^::....:..::::^:^^~!!!7~!~^ command. if nvim is started without args, + .:^!7!~~77!~7!!77?7?777!~:: this file is loaded if present. + ..::::^::::... * by alemidev + * https://vim.fandom.com/wiki/Go_away_and_come_back +]]-- + +--|| CORE FUNCTIONS + +local sep = vim.fn.has('win32') ~= 0 and '\\' or '/' + +-- Creates a session +function SaveSession(sess_name) + local session_file = vim.fn.getcwd() .. sep .. (sess_name or ".session.vim") + vim.cmd("mksession! " .. session_file) + print("[+] saved session: " .. session_file) +end + +-- Loads a session if it exists +function LoadSession(sess_name) + local session_file = vim.fn.getcwd() .. sep .. (sess_name or ".session.vim") + if vim.fn.filereadable(session_file) ~= 0 then + vim.cmd("source " .. session_file) + vim.cmd("edit %") + print("[*] loaded session: " .. session_file) + end +end + +function ClearSession(sess_name) + local session_file = vim.fn.getcwd() .. sep .. (sess_name or ".session.vim") + if vim.fn.filereadable(session_file) ~= 0 then + vim.fn.system("rm ".. session_file) + print("[-] cleared session: " .. session_file) + end +end + +-- INTERNAL HANDLERS + +local function local_changes_pending() + local buffers = vim.fn.getbufinfo() + for n, buf in pairs(buffers) do + if buf ~= nil and buf.changed == 1 then + print(string.format("[!] buffer #%d has local changes", n)) + return n + end + end + return nil +end + +vim.api.nvim_create_user_command( + 'SaveSession', + function(args) + local sess_name = nil + if #args.args > 0 then + sess_name = args.args + end + if args.bang then + ClearSession(sess_name) + else + + end + SaveSession(sess_name) + end, + {bang=true, nargs='?'} +) + +vim.api.nvim_create_user_command( + 'ClearSession', + function(_) ClearSession() end, + {} +) + +vim.api.nvim_create_user_command( + 'LoadSession', + function(args) + if not args.bang and local_changes_pending() then + return + end + local sess_name = nil + if #args.args > 0 then + sess_name = args.args + end + LoadSession(sess_name) + end, + {bang=true, nargs='?'} +) + +vim.api.nvim_create_user_command( + 'QuitSaving', + function(args) + if not args.bang and local_changes_pending() then + return + end + local sess_name = nil + if #args.args > 0 then + sess_name = args.args + end + SaveSession(sess_name) + vim.cmd("qa") -- TODO can I do this from nvim api? + end, + {bang=true, nargs='?'} +) + +local session_management_group = vim.api.nvim_create_augroup("SessionManagementGroup", {clear=true}) +vim.api.nvim_create_autocmd( + { "VimEnter" }, + { + callback=function() + if vim.fn.argc() == 0 then + LoadSession(nil) + -- TODO why do these get reset??? + vim.opt.winheight = 3 + vim.opt.winminheight = 3 + vim.opt.winwidth = 12 + vim.opt.winminwidth = 12 + end + end, + nested=true, + group=session_management_group + } +) + diff --git a/lua/statusline.lua b/lua/statusline.lua new file mode 100644 index 0000000..76a7709 --- /dev/null +++ b/lua/statusline.lua @@ -0,0 +1,131 @@ +--[[ + + GJ5GPP# #### ██████╗ ██╗██╗ ██╗███████╗ + 5:. !5 #^!??7B ██╔══██╗██║██║ ██╔╝██╔════╝ + !Y ###########7^ ██████╔╝██║█████╔╝ █████╗ + G ~J?JJJJJJJJJJ^? ██╔══██╗██║██╔═██╗ ██╔══╝ + #^!:# G 5 ██████╔╝██║██║ ██╗███████╗ + #G5JJ?JJ5:?@J: #?7J.JJ?JJYPB ╚═════╝ ╚═╝╚═╝ ╚═╝╚══════╝ + #?!JPBB##G.~77B!! #J~!7??.B##BGY7!P + P:Y# ^? P:J:Y 5~J~J# ?7 B~! * simple statusbar for +B.G ~7 #.Y.G G!?#~? ~Y ~7 when you'd rather +J: 7.YYY55G:!?.7!B #.B #~B P. use something you +P.# BBGGPPPY 7Y7P :Y # 7^ can fix yourself + ?^B #~7 G:5 J:B + P~7P## #P?~5 B!!YB# #BY~7# * by alemidev + GJ?7???7?JG BY?7???77?5# + ### #### * inspired by airline, but + straight and simpler +]]-- + +--- global statusline object +local STATUSLINE = { + mode_string = { + ['n' ] = 'NORMAL', + ['no'] = 'NORMAL op', + ['v' ] = 'VISUAL', + ['V' ] = 'V LINE', + [''] = 'V BLOCK', + ['s' ] = 'SELECT', + ['S' ] = 'S LINE', + [''] = 'S BLOCK', + ['i' ] = 'INSERT', + ['R' ] = 'REPLACE', + ['Rv'] = 'V REPLACE', + ['c' ] = 'CMD', + ['cv'] = 'VIM EX', + ['ce'] = 'EX', + ['r' ] = 'PROMPT', + ['rm'] = 'MORE', + ['r?'] = 'CONFIRM', + ['!' ] = 'SHELL', + ['t' ] = 'TERMINAL', + }, + mode_highlight = { + ['n' ] = '%#NormalMode#', + ['no'] = '%#NormalMode#', + ['v' ] = '%#VisualMode#', + ['V' ] = '%#VisualMode#', + [''] = '%#VisualMode#', + ['s' ] = '%#VisualMode#', + ['S' ] = '%#VisualMode#', + [''] = '%#VisualMode#', + ['i' ] = '%#InsertMode#', + ['R' ] = '%#InsertMode#', + ['Rv'] = '%#InsertMode#', + ['c' ] = '%#SpecialMode#', + ['cv'] = '%#SpecialMode#', + ['ce'] = '%#SpecialMode#', + ['r' ] = '%#SpecialMode#', + ['rm'] = '%#SpecialMode#', + ['r?'] = '%#SpecialMode#', + ['!' ] = '%#SpecialMode#', + ['t' ] = '%#SpecialMode#' + }, +} + +function STATUSLINE:linter() + local n_warns = 0 + local warns = vim.diagnostic.get(0, { severity = vim.diagnostic.severity.WARN }) + if warns ~= nil then n_warns = #warns end + + local n_errors = 0 + local errors = vim.diagnostic.get(0, { severity = vim.diagnostic.severity.ERROR }) + if errors ~= nil then n_errors = #errors end + + if n_warns == 0 and n_errors == 0 then + return 'OK' + else + return string.format("%dE %dW", n_errors, n_warns) + end +end + +function STATUSLINE:combo() + if vim.g.combo ~= nil then + return vim.g.combo + end + return "" +end + +function STATUSLINE:git() + if vim.fn['fugitive#Head']() ~= nil then + return vim.fn['fugitive#Head']() + else + return "" + end +end + +function STATUSLINE:lsp() + local clients = vim.lsp.buf_get_clients(0) + if #clients > 0 then + local client_names = {} + for _, client in pairs(clients) do + client_names[#client_names+1] = client.name + end + return "[" .. table.concat(client_names, ",") .. "]" + else + return "" + end +end + +function STATUSLINE:display() + local mode = vim.fn.mode() + local line = { + self.mode_highlight[mode] .. " " .. self.mode_string[mode], + "%#StatusLineBlock# %Y", + "%{v:lua.statusline.combo()}", + "%{v:lua.statusline.linter()}", + "%#StatusLine#", + "%{v:lua.statusline.git()}", + "%r%h%w%m %<%F ", + "%=", -- change alignment + "%{v:lua.statusline.lsp()}", + "%{&fileencoding?&fileencoding:&encoding}", + "%{&fileformat}", + "%#StatusLineBlock# %3l:%-3c %3p%%", + self.mode_highlight[mode] .. " %n " .. "%0*" + } + return table.concat(line, " ") +end + +return STATUSLINE