From 3f8e61a4e41bf9d921f2189e76bf4c31ea97b429 Mon Sep 17 00:00:00 2001 From: Olivier Roques Date: Fri, 25 Dec 2020 21:54:44 +0100 Subject: [PATCH] Refactor --- lua/hardline.lua | 81 +++++++++++++++++++++---------- lua/hardline/common.lua | 38 +++++++++------ lua/hardline/parts/filename.lua | 21 +++++++- lua/hardline/parts/filetype.lua | 6 +-- lua/hardline/parts/git.lua | 16 +++--- lua/hardline/parts/line.lua | 6 +-- lua/hardline/parts/lsp.lua | 2 +- lua/hardline/parts/mode.lua | 12 +++-- lua/hardline/parts/whitespace.lua | 20 ++++---- lua/hardline/parts/wordcount.lua | 16 +++--- 10 files changed, 138 insertions(+), 80 deletions(-) diff --git a/lua/hardline.lua b/lua/hardline.lua index 3bde6ef..94466f6 100644 --- a/lua/hardline.lua +++ b/lua/hardline.lua @@ -27,45 +27,76 @@ M.options = { } -------------------- STATUSLINE ---------------------------- -local function get_state(class) - if class == 'mode' and common.is_active() then - local mode = common.modes[vim.fn.mode()] - if not mode then return common.modes['?'].color end - return mode.color +local function color_sections(sections) + local function map(section) + if type(section) ~= 'table' then return section end + if section.class == 'none' then return section.item end + local state = common.get_state(section.class) + local hlgroup = string.format('Hardline_%s_%s', section.class, state) + if fn.hlexists(hlgroup) == 0 then return section.item end + return string.format('%%#%s#%s%%*', hlgroup, section.item) end - return common.is_active() and 'active' or 'inactive' + return vim.tbl_map(map, sections) end -local function color_section(section) - if type(section) ~= 'table' then return section end - if not section.class or section.class == 'none' then return section.item end - local state = get_state(section.class) - local hlgroup = string.format('Hardline_%s_%s', section.class, state) - if fn.hlexists(hlgroup) == 0 then return section.item end - return string.format('%%#%s#%s%%*', hlgroup, section.item) +local function aggregate_sections(sections) + local aggregated, piv = {}, 1 + while piv <= #sections do + if type(sections[piv]) == 'table' then + local items = {} + for j = piv, #sections + 1 do + if j == #sections + 1 or sections[j].class ~= sections[piv].class then + table.insert(aggregated, { + class = sections[piv].class, + item = string.format(' %s ', table.concat(items, ' ')) + }) + piv = j + break + end + table.insert(items, sections[j].item) + end + else + table.insert(aggregated, sections[piv]) + piv = piv + 1 + end + end + return aggregated end -local function update_section(section) - if type(section) == 'string' then - return section - elseif type(section) == 'function' then - return section() - elseif type(section) == 'table' then - return {class = section.class, item = update_section(section.item)} +local function remove_empty_sections(sections) + local function filter(section) + if type(section) == 'table' then return filter(section.item) end + return section ~= '' end - common.echo('WarningMsg', 'Invalid section.') - return '' + return vim.tbl_filter(filter, sections) +end + +local function reload_sections(sections) + local function map(section) + if type(section) == 'string' then + return section + elseif type(section) == 'function' then + return section() + elseif type(section) == 'table' then + return {class = section.class or 'none', item = map(section.item)} + end + common.echo('WarningMsg', 'Invalid section.') + return '' + end + return vim.tbl_map(map, sections) end function M.update() - local cache + local cache = M.options.sections if common.is_active() then - cache = vim.tbl_map(update_section, M.options.sections) + cache = reload_sections(cache) + cache = remove_empty_sections(cache) + cache = aggregate_sections(cache) api.nvim_win_set_var(g.statusline_winid, 'hardline_cache', cache) else cache = api.nvim_win_get_var(g.statusline_winid, 'hardline_cache') end - return table.concat(vim.tbl_map(color_section, cache)) + return table.concat(color_sections(cache)) end -------------------- SETUP ----------------------------- diff --git a/lua/hardline/common.lua b/lua/hardline/common.lua index 545042c..f57b2b7 100644 --- a/lua/hardline/common.lua +++ b/lua/hardline/common.lua @@ -1,20 +1,20 @@ local cmd, fn, vim = vim.cmd, vim.fn, vim local g = vim.g -local M = { - 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 M = {} + +M.modes = { + ['?'] = {text = '???', state = 'inactive'}, + ['n'] = {text = 'NORMAL', state = 'normal'}, + ['i'] = {text = 'INSERT', state = 'insert'}, + ['R'] = {text = 'REPLACE', state = 'replace'}, + ['v'] = {text = 'VISUAL', state = 'visual'}, + ['V'] = {text = 'V-LINE', state = 'visual'}, + [''] = {text = 'V-BLOCK', state = 'visual'}, + ['c'] = {text = 'COMMAND', state = 'normal'}, + ['s'] = {text = 'SELECT', state = 'visual'}, + ['S'] = {text = 'S-LINE', state = 'visual'}, + [''] = {text = 'S-BLOCK', state = 'visual'}, + ['t'] = {text = 'TERMINAL', state = 'normal'}, } function M.echo(hlgroup, msg) @@ -27,4 +27,12 @@ function M.is_active() return g.statusline_winid == fn.win_getid() end +function M.get_state(class) + if class == 'mode' and M.is_active() then + local mode = M.modes[fn.mode()] or M.modes['?'] + return mode.state + end + return M.is_active() and 'active' or 'inactive' +end + return M diff --git a/lua/hardline/parts/filename.lua b/lua/hardline/parts/filename.lua index 5d4d671..eaa37e4 100644 --- a/lua/hardline/parts/filename.lua +++ b/lua/hardline/parts/filename.lua @@ -1,7 +1,26 @@ local fn = vim.fn +local bo = vim.bo + +local function get_name() + return fn.expand('%:~:.') +end + +local function get_readonly() + if not bo.readonly then return '' end + return '[RO]' +end + +local function get_modified() + if bo.modified then return '[+]' end + if not bo.modifiable then return '[-]' end + return '' +end local function get_item() - return table.concat({' ', fn.expand('%:~:.'), ' %r%m '}) + local name, readonly, modified = get_name(), get_readonly(), get_modified() + if readonly ~= '' then readonly = ' ' .. readonly end + if modified ~= '' then modified = ' ' .. modified end + return table.concat({name, readonly, modified}) end return { diff --git a/lua/hardline/parts/filetype.lua b/lua/hardline/parts/filetype.lua index 9ada887..f35bd99 100644 --- a/lua/hardline/parts/filetype.lua +++ b/lua/hardline/parts/filetype.lua @@ -1,11 +1,7 @@ local bo = vim.bo -local function get_filetype() - return string.format('%s', bo.filetype) -end - local function get_item() - return table.concat({' ', get_filetype(), ' '}) + return bo.filetype end return { diff --git a/lua/hardline/parts/git.lua b/lua/hardline/parts/git.lua index 62abcfa..fe5beb1 100644 --- a/lua/hardline/parts/git.lua +++ b/lua/hardline/parts/git.lua @@ -5,20 +5,22 @@ local function get_hunks() if not g.loaded_gitgutter then return '' end local summary = fn.GitGutterGetHunkSummary() return table.concat({ - string.format('+%d', summary[1]), ' ', - string.format('~%d', summary[2]), ' ', - string.format('-%d', summary[3]), ' ', - }) + string.format('+%d', summary[1]), + string.format('~%d', summary[2]), + string.format('-%d', summary[3]), + }, ' ') end local function get_branch() if not g.loaded_gitgutter then return '' end - return string.format('(%s)', fn.FugitiveHead()) + local branch = fn.FugitiveHead() + return branch ~= '' and string.format('(%s)', branch) or '' end local function get_item() - local item = table.concat({' ', get_hunks(), get_branch(), ' '}) - return item == ' ' and '' or item + local hunks, branch = get_hunks(), get_branch() + if branch == '' then return '' end + return table.concat({hunks, ' ' .. branch}) end return { diff --git a/lua/hardline/parts/line.lua b/lua/hardline/parts/line.lua index 96b7eb3..0632466 100644 --- a/lua/hardline/parts/line.lua +++ b/lua/hardline/parts/line.lua @@ -9,18 +9,18 @@ end local function get_column() local nb_columns = fn.col('$') - 1 local column = fn.col('.') - return string.format(' %2d/%2d', column, nb_columns) + return string.format('%2d/%2d', column, nb_columns) end local function get_percent() local nb_lines = fn.line('$') local line = fn.line('.') local percent = math.floor(line * 100 / nb_lines) - return string.format(' %3d%%%%', percent) + return string.format('%3d%%%%', percent) end local function get_item() - return table.concat({' ', get_line(), get_column(), get_percent(), ' '}) + return table.concat({get_line(), get_column(), get_percent()}, ' ') end return { diff --git a/lua/hardline/parts/lsp.lua b/lua/hardline/parts/lsp.lua index 6cb87b4..797d490 100644 --- a/lua/hardline/parts/lsp.lua +++ b/lua/hardline/parts/lsp.lua @@ -4,7 +4,7 @@ local function get_diagnostic(prefix, severity) if vim.tbl_isempty(lsp.buf_get_clients(0)) then return '' end local count = lsp.diagnostic.get_count(0, severity) if count < 1 then return '' end - return table.concat({' ', string.format('%s:%d', prefix, count), ' '}) + return string.format('%s:%d', prefix, count) end local function get_error() diff --git a/lua/hardline/parts/mode.lua b/lua/hardline/parts/mode.lua index 12c9080..8248ccb 100644 --- a/lua/hardline/parts/mode.lua +++ b/lua/hardline/parts/mode.lua @@ -3,21 +3,25 @@ local o, bo, wo = vim.o, vim.bo, vim.wo local common = require('hardline.common') local function get_mode() - return common.modes[fn.mode()].text + local mode = common.modes[fn.mode()] or common.modes['?'] + return mode.text end local function get_paste() if not o.paste then return '' end - return ' PASTE' + return 'PASTE' end local function get_spell() if not wo.spell then return '' end - return string.format(' SPELL[%s]', string.upper(bo.spelllang)) + return string.format('SPELL[%s]', string.upper(bo.spelllang)) end local function get_item() - return table.concat({' ', get_mode(), get_paste(), get_spell(), ' ' }) + local mode, paste, spell = get_mode(), get_paste(), get_spell() + if paste ~= '' then paste = ' ' .. paste end + if spell ~= '' then spell = ' ' .. spell end + return table.concat({mode, paste, spell}) end return { diff --git a/lua/hardline/parts/whitespace.lua b/lua/hardline/parts/whitespace.lua index 1b2f812..be44242 100644 --- a/lua/hardline/parts/whitespace.lua +++ b/lua/hardline/parts/whitespace.lua @@ -1,5 +1,6 @@ local cmd, fn, vim = vim.cmd, vim.fn, vim local b, bo = vim.b, vim.bo + local enabled = false local cache = '' local options = { @@ -18,14 +19,14 @@ local function check_trailing() return search('trailing', [[\s$]]) end -local function check_mixed_indent() +local function check_mix_indent() local tst = [[(^\t* +\t\s*\S)]] local tls = string.format([[(^\t+ {%d,}\S)]], bo.tabstop) local pattern = string.format([[\v%s|%s]], tst, tls) return search('mix-indent', pattern) end -local function check_mixed_indent_file() +local function check_mix_indent_file() local head_spc = [[\v(^ +)]] if vim.tbl_contains(options.c_langs, bo.filetype) then head_spc = [[\v(^ +\*@!)]] @@ -51,22 +52,19 @@ local function get_item() cmd 'augroup hardline_whitespace' cmd 'autocmd!' cmd 'autocmd CursorHold,BufWritePost * unlet! b:hardline_whitespace' - cmd 'augroup end' + cmd 'augroup END' enabled = true end if bo.readonly or not bo.modifiable then return '' end if fn.line('$') > options.max_lines then return '' end - if fn.exists('b:hardline_whitespace') ~= 0 then return cache end - b.hardline_whitespace = 1 - local item = table.concat({ - ' ', + if b.hardline_whitespace then return cache end + b.hardline_whitespace = true + cache = table.concat({ check_trailing(), - check_mixed_indent(), - check_mixed_indent_file(), + check_mix_indent(), + check_mix_indent_file(), check_conflict(), - ' ', }) - cache = item == ' ' and '' or item return cache end diff --git a/lua/hardline/parts/wordcount.lua b/lua/hardline/parts/wordcount.lua index 7493fac..6b4260e 100644 --- a/lua/hardline/parts/wordcount.lua +++ b/lua/hardline/parts/wordcount.lua @@ -1,5 +1,7 @@ local cmd, fn, vim = vim.cmd, vim.fn, vim local b, bo = vim.b, vim.bo +local common = require('hardline.common') + local enabled = false local cache = '' local options = { @@ -19,7 +21,8 @@ local options = { } local function in_visual() - return vim.tbl_contains({'v', 'V', '', 's', 'S', ''}, fn.mode()) + local mode = common.modes[fn.mode()] or common.modes['?'] + return mode.state == 'visual' end local function get_wordcount() @@ -33,17 +36,14 @@ local function get_item() cmd 'augroup hardline_wordcount' cmd 'autocmd!' cmd 'autocmd CursorHold,BufWritePost * unlet! b:hardline_wordcount' - cmd 'augroup end' + cmd 'augroup END' enabled = true end if not vim.tbl_contains(options.filetypes, bo.filetype) then return '' end if fn.line('$') > options.max_lines then return '' end - if fn.exists('b:hardline_wordcount') ~= 0 and not in_visual() then - return cache - end - b.hardline_wordcount = 1 - local item = table.concat({' ', get_wordcount(), ' '}) - cache = item == ' ' and '' or item + if b.hardline_wordcount and not in_visual() then return cache end + b.hardline_wordcount = true + cache = get_wordcount() return cache end