From 1505322bdd2fef920e943f39557d01c3ee4bd81b Mon Sep 17 00:00:00 2001 From: Olivier Roques Date: Thu, 24 Dec 2020 13:41:30 +0100 Subject: [PATCH] Add dynamic colors --- lua/hardline.lua | 29 ++++---- lua/hardline/common.lua | 26 ++++++- lua/hardline/parts/filename.lua | 11 ++- lua/hardline/parts/filetype.lua | 19 +++--- lua/hardline/parts/git.lua | 39 ++++++----- lua/hardline/parts/line.lua | 47 +++++++++---- lua/hardline/parts/mode.lua | 58 ++++++---------- lua/hardline/themes/one.lua | 116 ++++++++++++++++++++++++++++++++ 8 files changed, 250 insertions(+), 95 deletions(-) diff --git a/lua/hardline.lua b/lua/hardline.lua index c0e27ec..ea2bc97 100644 --- a/lua/hardline.lua +++ b/lua/hardline.lua @@ -3,14 +3,14 @@ -- github.com/ojroques -------------------- VARIABLES ----------------------------- -local api, cmd, vim = vim.api, vim.cmd, vim +local api, cmd, fn, vim = vim.api, vim.cmd, vim.fn, vim local wo = vim.wo local common = require('hardline.common') local M = {} -------------------- OPTIONS ------------------------------- M.options = { - theme = 'default', + theme = 'one', events = { active = { 'WinEnter', @@ -20,20 +20,21 @@ M.options = { }, }, sections = { - -- {class = 'mode', item = require('hardline.parts.mode').item}, ' ', - -- {class = 'high', item = require('hardline.parts.git').item}, ' ', - {class = 'med', item = require('hardline.parts.filename').item}, ' ', + {class = 'mode', item = require('hardline.parts.mode').get_item}, + {class = 'high', item = require('hardline.parts.git').get_item}, + {class = 'med', item = require('hardline.parts.filename').get_item}, '%=', - -- {class = 'high', item = require('hardline.parts.filetype').item}, ' ', - -- {class = 'mode', item = require('hardline.parts.line').item}, + {class = 'high', item = require('hardline.parts.filetype').get_item}, + {class = 'mode', item = require('hardline.parts.line').get_item}, }, } -------------------- STATUSLINE ---------------------------- -local function color_item(item, class) - if not class then return item end - if not M.options.theme[class] then return item end - return string.format('%%#Hardline_%s_%s#%s%%*', class, 'active', item) +local function color_item(class, mode, item) + if not class or not mode then return item end + local hlgroup = string.format('Hardline_%s_%s', class, mode) + if fn.hlexists(hlgroup) == 0 then return item end + return string.format('%%#%s#%s%%*', hlgroup, item) end local function update_section(section) @@ -41,8 +42,9 @@ local function update_section(section) return section() elseif type(section) == 'string' then return section - elseif type(section) == 'table' then - return color_item(update_section(section.item), section.class) + elseif type(section) == 'table' and type(section.item) == 'function' then + local item = section.item() + return color_item(section.class, item.mode, item.text) end common.echo('WarningMsg', 'Invalid section.') return '' @@ -86,6 +88,7 @@ local function set_theme() end function M.set_statusline() + common.set_active('active') wo.statusline = [[%!luaeval('require("hardline").update()')]] end diff --git a/lua/hardline/common.lua b/lua/hardline/common.lua index 5b4d878..973c802 100644 --- a/lua/hardline/common.lua +++ b/lua/hardline/common.lua @@ -1,5 +1,20 @@ local M = {} +local modes = { + ['?'] = {text = '???', color = 'inactive'}, + ['n'] = {text = 'NORMAL', color = 'normal'}, + ['c'] = {text = 'COMMAND', color = 'normal'}, + ['i'] = {text = 'INSERT', color = 'insert'}, + ['R'] = {text = 'REPLACE', color = 'replace'}, + ['v'] = {text = 'VISUAL', color = 'visual'}, + ['V'] = {text = 'V-LINE', color = 'visual'}, + [''] = {text = 'V-BLOCK', color = 'visual'}, + ['s'] = {text = 'SELECT', color = 'visual'}, + ['S'] = {text = 'S-LINE', color = 'visual'}, + [''] = {text = 'S-BLOCK', color = 'visual'}, + ['t'] = {text = 'TERMINAL', color = 'normal'}, +} + function M.echo(hlgroup, msg) vim.cmd(string.format('echohl %s', hlgroup)) vim.cmd(string.format('echo "[hardline] %s"', msg)) @@ -10,8 +25,17 @@ function M.set_active(active) vim.api.nvim_win_set_var(0, 'hardline_active', active) end -function M.is_active() +function M.get_active() return vim.api.nvim_win_get_var(0, 'hardline_active') end +function M.is_active() + return M.get_active() == 'active' +end + +function M.get_mode() + if not modes[vim.fn.mode()] then return modes['?'] end + return modes[vim.fn.mode()] +end + return M diff --git a/lua/hardline/parts/filename.lua b/lua/hardline/parts/filename.lua index 2502768..11aa4e2 100644 --- a/lua/hardline/parts/filename.lua +++ b/lua/hardline/parts/filename.lua @@ -1,11 +1,16 @@ +local common = require('hardline.common') + local function get_name() return vim.fn.expand('%:~:.') end -local function get_mode() - return ' %h%r' +local function get_item() + return { + text = table.concat({' %<', get_name()}), + mode = common.get_active(), + } end return { - item = table.concat({'%<', get_name(), get_mode()}), + get_item = get_item, } diff --git a/lua/hardline/parts/filetype.lua b/lua/hardline/parts/filetype.lua index 6584f67..6162579 100644 --- a/lua/hardline/parts/filetype.lua +++ b/lua/hardline/parts/filetype.lua @@ -1,13 +1,16 @@ -local M = {} +local common = require('hardline.common') -function M.get_filetype() - return vim.bo.filetype +local function get_filetype() + return string.format(' %s ', vim.bo.filetype) end -function M.get_item() - return table.concat({ - [[%{luaeval('require("hardline.parts.filetype").get_filetype()')}]], - }) +local function get_item() + return { + text = get_filetype(), + mode = common.get_active(), + } end -return M +return { + get_item = get_item, +} diff --git a/lua/hardline/parts/git.lua b/lua/hardline/parts/git.lua index 6251c36..f6d3fe0 100644 --- a/lua/hardline/parts/git.lua +++ b/lua/hardline/parts/git.lua @@ -1,25 +1,28 @@ -local M = {} +local common = require('hardline.common') -function M.get_hunks() +local function get_hunks() if not vim.g.loaded_gitgutter then return '' end local summary = vim.fn.GitGutterGetHunkSummary() return table.concat({ - string.format('+%d', summary[1]), - string.format('~%d', summary[2]), - string.format('-%d', summary[3]), - }, ' ') -end - -function M.get_branch() - if not vim.g.loaded_gitgutter then return '' end - return string.format(' %s', vim.fn.FugitiveHead()) -end - -function M.get_item() - return table.concat({ - [[%{luaeval('require("hardline.parts.git").get_hunks()')}]], - [[%{luaeval('require("hardline.parts.git").get_branch()')}]], + ' ', + string.format('+%d', summary[1]), ' ', + string.format('~%d', summary[2]), ' ', + string.format('-%d', summary[3]), ' ', }) end -return M +local function get_branch() + if not vim.g.loaded_gitgutter then return '' end + return string.format('(%s) ', vim.fn.FugitiveHead()) +end + +local function get_item() + return { + text = table.concat({get_hunks(), get_branch()}), + mode = common.get_active(), + } +end + +return { + get_item = get_item, +} diff --git a/lua/hardline/parts/line.lua b/lua/hardline/parts/line.lua index 8c346fe..e101b2d 100644 --- a/lua/hardline/parts/line.lua +++ b/lua/hardline/parts/line.lua @@ -1,23 +1,42 @@ -local M = {} +local common = require('hardline.common') -function M.get_line() - return string.format('%03d/%03d', vim.fn.line('.'), vim.fn.line('$')) +local function get_dots(current, max) + current = string.len(tostring(current)) + max = string.len(tostring(max)) + return string.rep('ยท', max - current) end -function M.get_column() - return string.format('%03d/%03d', vim.fn.col('.'), vim.fn.col('$') - 1) +local function get_line() + local nb_lines = vim.fn.line('$') + local current_line = vim.fn.line('.') + local dots = get_dots(current_line, nb_lines) + return string.format(' %s%d/%d', dots, current_line, nb_lines) end -function M.get_percent() - return ' %03p%%' +local function get_column() + local nb_columns = vim.fn.col('$') + local current_column = vim.fn.col('.') + local dots = get_dots(current_column, 999) + local max_dots = get_dots(nb_columns, 999) + return string.format('|%s%d/%s%d', dots, current_column, max_dots, nb_columns) end -function M.get_item() - return table.concat({ - [[%{luaeval('require("hardline.parts.line").get_line()')}]], ':', - [[%{luaeval('require("hardline.parts.line").get_column()')}]], - M.get_percent(), - }) +local function get_percent() + local nb_lines = vim.fn.line('$') + local current_line = vim.fn.line('.') + local percent = math.floor(current_line * 100 / nb_lines) + local dots = get_dots(percent, 100) + return string.format('|%s%d%%%% ', dots, percent) end -return M +local function get_item() + local mode = common.get_mode() + return { + text = table.concat({get_line(), get_column(), get_percent()}), + mode = mode.color, + } +end + +return { + get_item = get_item, +} diff --git a/lua/hardline/parts/mode.lua b/lua/hardline/parts/mode.lua index c93afa3..b3567aa 100644 --- a/lua/hardline/parts/mode.lua +++ b/lua/hardline/parts/mode.lua @@ -1,47 +1,29 @@ -local M = {} -local modes = { - ['?'] = {text = '???', color = 'inactive'}, - ['n'] = {text = 'NORMAL', color = 'normal'}, - ['c'] = {text = 'COMMAND', color = 'normal'}, - ['i'] = {text = 'INSERT', color = 'insert'}, - ['R'] = {text = 'REPLACE', color = 'replace'}, - ['v'] = {text = 'VISUAL', color = 'visual'}, - ['V'] = {text = 'V-LINE', color = 'visual'}, - [''] = {text = 'V-BLOCK', color = 'visual'}, - ['s'] = {text = 'SELECT', color = 'visual'}, - ['S'] = {text = 'S-LINE', color = 'visual'}, - [''] = {text = 'S-BLOCK', color = 'visual'}, - ['t'] = {text = 'TERMINAL', color = 'normal'}, -} +local common = require('hardline.common') -local function color_item(item) - local color = modes[vim.fn.mode()].color - return string.format('%%#HardlineMode%s#%s%%##', color, item) -end - -function M.get_mode() - if not modes[vim.fn.mode()] then - return modes['?'].text - end - return modes[vim.fn.mode()].text -end - -function M.get_paste() +local function get_paste() if not vim.o.paste then return '' end - return ' | PASTE' + return '|PASTE' end -function M.get_spell() +local function get_spell() if not vim.wo.spell then return '' end - return string.format(' | SPELL [%s]', string.upper(vim.bo.spelllang)) + return string.format('|SPELL[%s]', string.upper(vim.bo.spelllang)) end -function M.get_item() - return color_item(table.concat({ - [[%{luaeval('require("hardline.parts.mode").get_mode()')}]], - [[%{luaeval('require("hardline.parts.mode").get_paste()')}]], - [[%{luaeval('require("hardline.parts.mode").get_spell()')}]], - })) +local function get_item() + local mode = common.get_mode() + return { + text = table.concat({ + ' ', + string.format('%s', mode.text), + get_paste(), + get_spell(), + ' ' + }), + mode = mode.color, + } end -return M +return { + get_item = get_item, +} diff --git a/lua/hardline/themes/one.lua b/lua/hardline/themes/one.lua index e69de29..46fe935 100644 --- a/lua/hardline/themes/one.lua +++ b/lua/hardline/themes/one.lua @@ -0,0 +1,116 @@ +local colors = { + red = {gui = '#E06C75', cterm = '204', cterm16 = '1'}, + green = {gui = '#98C379', cterm = '114', cterm16 = '2'}, + yellow = {gui = '#E5C07B', cterm = '180', cterm16 = '3'}, + blue = {gui = '#61AFEF', cterm = '39', cterm16 = '4'}, + purple = {gui = '#C678DD', cterm = '170', cterm16 = '5'}, + white = {gui = '#ABB2BF', cterm = '145', cterm16 = '7'}, + black = {gui = '#282C34', cterm = '235', cterm16 = '0'}, + visual_grey = {gui = "#3E4452", cterm = "237", cterm16 = "15"}, + cursor_grey = {gui = "#2C323C", cterm = "236", cterm16 = "8"}, +} + +return { + mode = { + inactive = { + guifg = colors.white.gui, + guibg = colors.visual_grey.gui, + ctermfg = colors.white.cterm, + ctermbg = colors.visual_grey.cterm, + }, + normal = { + guifg = colors.black.gui, + guibg = colors.green.gui, + ctermfg = colors.black.cterm, + ctermbg = colors.green.cterm, + }, + insert = { + guifg = colors.black.gui, + guibg = colors.blue.gui, + ctermfg = colors.black.cterm, + ctermbg = colors.blue.cterm, + }, + replace = { + guifg = colors.black.gui, + guibg = colors.red.gui, + ctermfg = colors.black.cterm, + ctermbg = colors.red.cterm, + }, + visual = { + guifg = colors.black.gui, + guibg = colors.purple.gui, + ctermfg = colors.black.cterm, + ctermbg = colors.purple.cterm, + }, + }, + low = { + active = { + guifg = colors.white.gui, + guibg = colors.cursor_grey.gui, + ctermfg = colors.white.cterm, + ctermbg = colors.cursor_grey.cterm, + }, + inactive = { + guifg = colors.visual_grey.gui, + guibg = colors.black.gui, + ctermfg = colors.visual_grey.cterm, + ctermbg = colors.black.cterm, + }, + }, + med = { + active = { + guifg = colors.white.gui, + guibg = colors.cursor_grey.gui, + ctermfg = colors.white.cterm, + ctermbg = colors.cursor_grey.cterm, + }, + inactive = { + guifg = colors.visual_grey.gui, + guibg = colors.black.gui, + ctermfg = colors.visual_grey.cterm, + ctermbg = colors.black.cterm, + }, + }, + high = { + active = { + guifg = colors.white.gui, + guibg = colors.visual_grey.gui, + ctermfg = colors.white.cterm, + ctermbg = colors.visual_grey.cterm, + }, + inactive = { + guifg = colors.visual_grey.gui, + guibg = colors.black.gui, + ctermfg = colors.visual_grey.cterm, + ctermbg = colors.black.cterm, + }, + }, + error = { + active = { + guifg = colors.black.gui, + guibg = colors.red.gui, + ctermfg = colors.black.cterm, + ctermbg = colors.red.cterm, + }, + inactive = { + guifg = colors.black.gui, + guibg = colors.white.gui, + ctermfg = colors.black.cterm, + ctermbg = colors.white.cterm, + }, + }, + warning = { + active = { + guifg = colors.black.gui, + guibg = colors.yellow.gui, + ctermfg = colors.black.cterm, + ctermbg = colors.yellow.cterm, + }, + inactive = { + guifg = colors.visual_grey.gui, + guibg = colors.white.gui, + ctermfg = colors.visual_grey.cterm, + ctermbg = colors.white.cterm, + }, + }, +}