From ca591495f7ac2db1abf3ca285e0ec3f2feb337d4 Mon Sep 17 00:00:00 2001 From: Vladimir Popov <6939832+vladimir-popov@users.noreply.github.com> Date: Mon, 15 Aug 2022 18:57:34 +0300 Subject: [PATCH] Improve render theme (#9) * refactor!: change theme schema. Introduce new way to set separators * refactor: new algorithm to build zone and section * refactor: change algorithm for section's separators * feat: add new ligthening_color and darkening_color utility methods * refactor!: new schema for theme, plus using hi groups for sections * refactor!: remove default hi groups * fix: improve example * refactor!: new way to setup statusline * refactor!: clean up refactor!: clean up * refactor!: actualize the schema * feat: add global variable to work with current statusline * add vi_mode to example stylua fix tests * add feline and lua-schema to CI * refactor!: rename to feline-theme * refactor: improve colors in the example * docs: create the Guide stylua fix: typo fir: typo --- .github/workflows/ci.yml | 2 + Guide.md | 336 ++++++++++++++++++ README.md | 84 ++--- dark_example.png | Bin 52355 -> 32088 bytes light_example.png | Bin 48821 -> 31754 bytes lua/compline/components.lua | 82 ----- lua/compline/conditions.lua | 40 --- lua/compline/cosmosline/init.lua | 27 -- lua/compline/cosmosline/theme.lua | 90 ----- lua/compline/example/components.lua | 13 - lua/compline/example/highlights.lua | 12 - lua/compline/example/init.lua | 23 -- lua/compline/example/theme.lua | 40 --- lua/compline/highlights.lua | 124 ------- lua/compline/icons.lua | 85 ----- lua/compline/metadata.lua | 67 ---- lua/compline/providers.lua | 85 ----- lua/compline/schema/feline.lua | 25 -- lua/compline/schema/init.lua | 431 ------------------------ lua/compline/schema/statusline.lua | 46 --- lua/compline/schema/theme.lua | 97 ------ lua/compline/statusline.lua | 183 ---------- lua/compline/test.lua | 35 -- lua/compline/utils.lua | 137 -------- lua/feline-theme/example/colors.lua | 34 ++ lua/feline-theme/example/components.lua | 37 ++ lua/feline-theme/example/init.lua | 19 ++ lua/feline-theme/example/theme.lua | 75 +++++ lua/feline-theme/init.lua | 198 +++++++++++ lua/feline-theme/schema/colors.lua | 23 ++ lua/feline-theme/schema/feline.lua | 54 +++ lua/feline-theme/schema/statusline.lua | 38 +++ lua/feline-theme/schema/theme.lua | 68 ++++ lua/feline-theme/utils.lua | 126 +++++++ test/cosmosline_spec.lua | 9 - test/init.lua | 17 +- test/schema_spec.lua | 403 ++++++---------------- test/statusline_schema_spec.lua | 109 ------ test/statusline_spec.lua | 308 +++++++++++------ test/try.sh | 10 +- test/utils_spec.lua | 75 ++--- 41 files changed, 1385 insertions(+), 2282 deletions(-) delete mode 100644 lua/compline/components.lua delete mode 100644 lua/compline/conditions.lua delete mode 100644 lua/compline/cosmosline/init.lua delete mode 100644 lua/compline/cosmosline/theme.lua delete mode 100644 lua/compline/example/components.lua delete mode 100644 lua/compline/example/highlights.lua delete mode 100644 lua/compline/example/init.lua delete mode 100644 lua/compline/example/theme.lua delete mode 100644 lua/compline/highlights.lua delete mode 100644 lua/compline/icons.lua delete mode 100644 lua/compline/metadata.lua delete mode 100644 lua/compline/providers.lua delete mode 100644 lua/compline/schema/feline.lua delete mode 100644 lua/compline/schema/init.lua delete mode 100644 lua/compline/schema/statusline.lua delete mode 100644 lua/compline/schema/theme.lua delete mode 100644 lua/compline/statusline.lua delete mode 100644 lua/compline/test.lua delete mode 100644 lua/compline/utils.lua create mode 100644 lua/feline-theme/example/colors.lua create mode 100644 lua/feline-theme/example/components.lua create mode 100644 lua/feline-theme/example/init.lua create mode 100644 lua/feline-theme/example/theme.lua create mode 100644 lua/feline-theme/init.lua create mode 100644 lua/feline-theme/schema/colors.lua create mode 100644 lua/feline-theme/schema/feline.lua create mode 100644 lua/feline-theme/schema/statusline.lua create mode 100644 lua/feline-theme/schema/theme.lua create mode 100644 lua/feline-theme/utils.lua delete mode 100644 test/cosmosline_spec.lua delete mode 100644 test/statusline_schema_spec.lua diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 22fc222..6771717 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -50,6 +50,8 @@ jobs: run: | git clone --depth 1 https://github.com/nvim-lua/plenary.nvim ~/.local/share/nvim/site/pack/vendor/start/plenary.nvim git clone --depth 1 https://github.com/kyazdani42/nvim-web-devicons ~/.local/share/nvim/site/pack/vendor/start/nvim-web-devicons + git clone --depth 1 https://github.com/feline-nvim/feline.nvim ~/.local/share/nvim/site/pack/vendor/start/feline.nvim + git clone --depth 1 https://github.com/dokwork/lua-schema.nvim ~/.local/share/nvim/site/pack/vendor/start/lua-schema.nvim ln -s $(pwd) ~/.local/share/nvim/site/pack/vendor/start - name: Run tests diff --git a/Guide.md b/Guide.md index e69de29..e153b4d 100644 --- a/Guide.md +++ b/Guide.md @@ -0,0 +1,336 @@ +# Guide to feline-theme + +The best way to understand how something works is using it to create some example. +Here we're going to create a simple statusline theme with dynamic colors, which depends on +the background: + +```viml +:echo &background +> light +``` +![light_example](light_example.png) + +```viml +:echo &background +> dark +``` +![dark_example](dark_example.png) + +_Note, that changing background will not affect the statusline. Only changing the colorscheme will +have an effect._ + +## Configuration of the statusline + +### Describe statusline + +`Feline-theme` provides a way to describe components for _active_ and _inactive_ statusline. +In both cases the statusline has three zones: _left_, _middle_ and _right_. Every zone can have +unlimited sections. Sections can have arbitrary names. But, it would be better to follow next +convention: left and middle zones should have sections with chars from a to z as their names, +and right zone should have sections with names from z to a. Names can intersect in different zones, +it's ok. + +In this example we'll turn our minds only to the _active_ line. The _inactive_ line has completely +the same rules, as _active_. + +```lua +local statusline = { + active = { + left = { + -- in the first section 'a' we will have a name of the current vi mode: + a = { 'vi_mode' }, + -- then a shorten full path to the working directory will be in the section 'b': + b = { 'short_working_directory' }, + -- and the name of the current file will be in the last section 'c': + c = { 'file_name' }, + }, + middle = { + -- we'll put a current time to the middle: + a = { 'time' }, + }, + right = { + -- far right component will show the current cursor position: + z = { 'position' }, + -- info abount encoding and format of the file will go before the section + -- with cursor position: + y = { 'file_encoding', 'file_format' }, + }, + }, +} +``` + +### Describe components + +Now, let's prepare components for our statusline. Every component mentioned in the statusline +will be looked in the table with components. If a key with the name of the component is found, the +value will be used as a component description, which should follow the feline's rules of components +describing: [USAGE.md#component +values](https://github.com/feline-nvim/feline.nvim/blob/master/USAGE.md#component-values). +Otherwise, a new component with eponymous provider will be created. Regardless of how component was +created, the `name` property will be added to it. + +```lua +statusline.components = { + vi_mode = { + provider = 'vi_mode', + -- turn icon off and use full name of the mode + icon = '' + } + + short_working_directory = { + provider = function() + return vim.fn.pathshorten(vim.fn.fnamemodify(vim.fn.getcwd(), ':p')) + end, + } + + file_name = { + provider = function() + return vim.fn.expand('%:t') + end, + } + + time = { + provider = function() + return vim.fn.strftime('%H:%M') + end, + } + + file_format = { + provider = { + name = 'file_type', + opts = { + filetype_icon = true, + case = 'lowercase', + }, + }, + } +} +``` + + +### Describe colors + +Our statusline is ready, but looks ugly. To fix it we need to describe which colors should be used +in the every section and maybe add separators between sections and zones. But, before we begin +describing a theme, we need prepare palette of colors. A palette is a table with colors, where the +keys are names of the colors, and values are `#RRGGBB` colors. `feline-theme` can have a few +palettes, which will be chosen depending on the `background` option and current `statusline`. So, you +can specify colors for `dark` and/or `light` background, and/or create palette for particular +colorscheme with appropriate key. But the simplest way is create `default` palette, which will be +used when nor palette with the name of the current colorscheme, nor `light`/`dark` palettes will be +found. + +Ok, let's create a default palette with `fg` and `bg` colors, plus colors for sections `a`, `b`, +`c`, `d`, and `z`, `y`, `x`, `w`. Colors in our palette will be generated automatically, changing +brightness of the `bg` color for every next section: + +```lua +local u = require('feline-theme.utils') + +-- We begin from the default background for Statusline +-- and will make it lighter/darker (depends on vim.go.background) +-- for every next section +local gradient_colors = function() + local function change(color) + if vim.go.background == 'light' then + return u.darkening_color(color, 0.4, 0.3, 0.1) + else + return u.ligthening_color(color, 0.2, 0.2, 0.3) + end + end + local colors = {} + colors.fg = vim.go.background == 'light' and 'White' or 'Black' + colors.bg = u.get_hl_bg('Statusline') or (vim.go.background == 'light' and '#c8c8cd' or '#505050') + colors.d = change(colors.bg) + colors.c = change(colors.d) + colors.b = change(colors.c) + colors.a = change(colors.b) + + colors.z = colors.a + colors.y = colors.b + colors.x = colors.c + colors.w = colors.d + + return colors +end + +statusline.colors = { default = gradient_colors } +``` + +Colors must be recalculated, when user will change the colorscheme. This is why palette can be +represented as a function, which returns table with colors. + + +### Describe theme + +When we have prepared palettes, we're ready to create a theme for our statusline. The theme has +pretty similar structure as a statusline, but instead of list of components, sections should have +description of their highlights. The highlights follow the same rules as feline: [USAGE.md#component +highlight](https://github.com/feline-nvim/feline.nvim/blob/master/USAGE.md#component-highlight). + +Additionally to highlights, we can specify separators for zones and sections in the theme. All +separators will be added to the extreme components by the follow rules: +1. zones' separators will override sections' separators; +1. zones' separators will be created with property `always_visible = true`; +1. separators, which were described directly in the components will override any separators from the + theme. + +Rules for describe a separator the same as in the feline: [USAGE.md#component +separators](https://github.com/feline-nvim/feline.nvim/blob/master/USAGE.md#component-separators). + +We will use two utility functions, to use colors, specific for the current vi mode: +```lua +local vi_mode_bg = function() + return { + bg = require('feline.providers.vi_mode').get_mode_color(), + } +end + +-- NOTE: this function return another function! +-- This is done to be able to specify a different bacground color: +local vi_mode_fg = function(bg) + return function() + return { + fg = require('feline.providers.vi_mode').get_mode_color(), + bg = bg, + } + end +end +``` + +Our left and right zones should have  and  as separators respectively. It'll separate them from +the middle zone. The sections inside zones will have symbols  and  as separators: + +```lua +statusline.theme = { + active = { + left = { + separators = { right = ' ' }, + a = { + hl = vi_mode_bg, + separators = { right = { str = '', hl = vi_mode_fg('b') } }, + }, + b = { + hl = { bg = 'b' }, + separators = { right = { str = '', hl = { fg = 'b', bg = 'c' } } }, + }, + c = { + hl = { bg = 'c' }, + separators = { right = { str = '', hl = { fg = 'c', bg = 'd' } } }, + }, + d = { + hl = { bg = 'd' }, + separators = { right = { str = '', hl = { fg = 'd', bg = 'bg' } } }, + }, + }, + right = { + separators = { left = ' ' }, + w = { + hl = { bg = 'w' }, + separators = { left = { str = '', hl = { bg = 'bg' } } }, + }, + x = { + hl = { bg = 'x' }, + separators = { left = { str = '', hl = { bg = 'w' } } }, + }, + y = { + hl = { bg = 'y' }, + separators = { left = { str = '', hl = { bg = 'x' } } }, + }, + z = { + hl = vi_mode_bg, + separators = { left = { str = '', hl = vi_mode_fg('y') } }, + }, + }, + }, + + vi_mode = { + NORMAL = 'green', + OP = 'magenta', + INSERT = 'blue', + VISUAL = 'magenta', + LINES = 'magenta', + BLOCK = 'magenta', + REPLACE = 'violet', + ['V-REPLACE'] = 'pink', + ENTER = 'cyan', + MORE = 'cyan', + SELECT = 'yellow', + COMMAND = 'orange', + SHELL = 'yellow', + TERM = 'orange', + NONE = 'yellow', + }, +} +``` + +_Note, that the vi mode colors are part of the theme, not the colors!_ + +### Setup statusline + +Finally, the last step is setup of our statusline: + +```lua +require('feline-theme').setup_statusline(statusline) +``` + +## Statusline's commands + +In successful case, the `FelineTheme` global lua variable become available. It provides ability +to work with the current statusline as with `FelineTheme.statusline` variable. + +### Showing the components + +The final schema is not simple, and your can easily make a mistake on describing your statusline. +For debug purpose, the statusline in `feline-theme` has few methods, which can help you to find +mistakes. The first one is `build_components`, which compose together the description of the +statusline, components, colors and theme, and returns a table with feline's components. You can +print them to looking for mistakes: + +```lua +:lua vim.pretty_print(FelineTheme.statusline:build_components()) +``` + +Or you can use the second short way: + +```lua +:lua FelineTheme.statusline:show_components() +``` + +### Showing and refresh colors + +`feline-theme` creates an `autocmd` to change colors on changing the colorscheme. To do it manually, +you can run: + +```lua +:lua FelineTheme.statusline:refresh_colors() +``` + +To see the colors, which should be used according to the current vim settings, you can print the +result of the `actual_colors`: + +```lua +:lua vim.pretty_print(FelineTheme.statusline:actual_colors()) +``` + +Or shortly: + +```lua +:lua FelineTheme.statusline:show_actual_colors() +``` + +### Show the full configuration + +Obviously, you can print the full current configuration just using the `FelineTheme.statusline`: + +```lua +:lua vim.pretty_print(FelineTheme.statusline) +``` + +But, you can do it easily: + +```lua +:lua FelineTheme.statusline:show_all() +``` + +That's all for today! See you! diff --git a/README.md b/README.md index 9bdb532..44937fa 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,12 @@ -# Components line +# Feline-theme ![light_example](light_example.png) ![dark_example](dark_example.png) This plugin is an extension for the [feline.nvim](https://github.com/feline-nvim/feline.nvim), which combines advantages of the templating similar to the -[lualine.nvim](https://github.com/nvim-lualine/lualine.nvim) with powerful syntax for description -components of the statusline from the `feline.nvim`. +[lualine.nvim](https://github.com/nvim-lualine/lualine.nvim) with powerful syntax for components +description of the statusline from the `feline.nvim`. ## Configuration example @@ -15,11 +15,11 @@ Let's see how to create a simple statusline: ```lua -- Prepare needed components -- - local components = { - mode = { - provider = require('feline.providers.vi_mode').get_vim_mode, - } + vi_mode = { + provider = 'vi_mode', + icon = '' + } file_name = { provider = function() @@ -29,88 +29,53 @@ local components = { } -- Describe how the statusline should look like -- - -local vi_mode_fg = function() - return { - fg = require('feline.providers.vi_mode').get_mode_color(), - bg = 'bg', - } -end - -local vi_mode_bg = function() - return { - fg = 'fg', - bg = require('feline.providers.vi_mode').get_mode_color(), - } -end - local theme = { active = { left = { - zone_separators = { right = { '', hl = vi_mode_fg } }, - sections_separators = { right = ' ' }, - sections = { - a = { hl = vi_mode_bg }, - b = { hl = vi_mode_fg } - }, + separators = { right = '', hl = { fg = 'blue' } }, + a = { hl = { bg = 'blue' } }, }, right = { - zone_separators = { left = { '', hl = vi_mode_fg } }, - sections_separators = { left = ' ' }, - sections = { - c = { hl = vi_mode_fg }, - d = { hl = vi_mode_bg }, - }, + separators = { left = { '', hl = { fg = 'green' } } }, + z = { hl = { bg = 'green' } }, }, }, - - dark = { - bg = '#282c34' - } } -- Create your oun statusline -- - -local statusline = require('compline.statusline'):new('example', { +require('feline-theme').setup_statusline({ active = { left = { - a = { 'mode' }, - c = { 'file_name' }, + a = { 'file_name' }, }, right = { - e = { 'file_type' }, - g = { 'position' }, + z = { 'vi_mode' }, }, }, - inactive = { - left = { - a = { 'file_name' }, - }, - }, - themes = { - default = theme, - }, + theme = theme, components = components }) ``` -More details about configuration you can find here: [Guide.md](Guide.md). +More details about configuration you can find in the [Guide.md](Guide.md). ## How to install +_This project **is under development**. API can be changed in non compatible way, so, it may be good +idea to use a tagged version in your own configuration._ + With [packer.nvim](https://github.com/wbthomason/packer.nvim/): ```lua use({ - 'dokwork/compline.nvim', + 'dokwork/feline-theme', requires = { 'kyazdani42/nvim-web-devicons', 'famiu/feline.nvim', - 'tpope/vim-fugitive', -- used for git components }, - -- optionally, you can setup preconfigured statusline: config = function() - require('compline.cosmosline'):setup() + -- setup your statusline on start: + require('feline-theme').setup_statusline(require('feline-theme.example')) end, }) ``` @@ -118,9 +83,6 @@ use({ ## Motivation I'm glad to use the [feline.nvim](https://github.com/feline-nvim/feline.nvim) plugin. This is a very -powerful and useful plugin for configuring the neovim statusline. But for my taste, the final +powerful and useful plugin for configuring the neovim statusline. But, to my taste, the final configuration usually looks a little bit cumbersome and messy. I prefer to separate an implementation of the components and their composition. - -This project is more the proof of concept, instead of the final solution, and currently **is under -develop**. diff --git a/dark_example.png b/dark_example.png index 283e14eeaebde6daa1a089826cea58546118ae4e..a0f8ae38c68e80f39350dd5a255133ee95044825 100644 GIT binary patch literal 32088 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 literal 52355 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

;q6$RZhIS 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 bn)&|&xPK@j>Z$Yw00000NkvXXu0mjfpWeV! diff --git a/light_example.png b/light_example.png index e9108ed6b4ba9d484db60c4b3d8ff8d7bc847a29..d14b559a9ed9ca86110c7ea1c436f4a0aac53c32 100644 GIT binary patch literal 31754 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

2!NU$z$W;a7rOeTNXyWHlCy^2uM$Ne|z%ry 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

LG^mKdE+~G`O1#_ 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: Highlight ----Returns highlight according to the current vi mode. -M.vi_mode = function(cmp) - local hls = cmp and cmp.hls or {} - return hls[vi_mode.get_vim_mode()] or { - fg = vi_mode.get_mode_color(), - } -end - ----@type fun(hls: table): Highlight ----Returns a highlight according to the current git status. ---- ----@param hls table # custom highlights with possible properties: ---- * `inactive: Highlight` a highlight which sould be used when git is not active; ---- * `changed: Highlight` a highlight which sould be used when at least one file is changed; ---- * `commited: Highlight` a highlight which sould be used when no one change exist. ---- ----@return Highlight # actual highlight according to the current git status. -M.git_status = function(cmp) - local hls = u.merge(cmp and cmp.hls, { - inactive = { fg = 'grey' }, - changed = { fg = 'orange' }, - commited = { fg = 'green' }, - }) - -- TODO move git utils to the separate script - if not c.is_git_workspace() then - return hls.inactive - end - if c.is_git_changed() then - return hls.changed - else - return hls.commited - end -end - ----@type fun(hls: table): Highlight ----Returns highlight according to the current state of the spellchecking. ---- ----@param hls table # custom highlights with possible properties: ---- * `active: Highlight` a highlight which sould be used when spellcheck is turned on; ---- * `inactive: Highlight` a highlight which sould be used when spellcheck is turned off; ---- ----@return function # actual highlight for spellchecking depending on its state. -M.spellcheck = function(cmp) - local hls = u.merge(cmp and cmp.hls, { - active = { fg = 'fg' }, - inactive = { fg = 'grey' }, - }) - if vim.wo.spell then - return hls.active - else - return hls.inactive - end -end - ----@type fun(hls: table): Highlight ----Returns a highlight according to the first attached lsp client. ----The color will be taken from the 'nvim-web-devicons' or 'hls.fg' will be used. If no one ----client is attached, then 'hls.client_off' will be used as foreground color. ---- ----@param hls table # custom highlights with possible properties: ---- * `unknown` a highlight which will be used if a color for the attached lsp ---- client is not found; ---- * `client_off` a highlight which will be used if no one lsp client is attached; ---- ----@return Highlight # highlight for the first attached lsp client. -M.lsp_client = function(cmp) - local hls = u.merge(cmp and cmp.hls, { - unknown = 'fg', - client_off = 'grey', - }) - local client = u.lsp_client() - local icon = u.lsp_client_icon({}, client) - return { - fg = (u.is_lsp_client_ready(client) and (icon and icon.color) or (icon and hls.unknown)) - or hls.client_off, - } -end - -M.treesitter_parser = function(cmp) - local hls = u.merge(cmp and cmp.hls, { - active = { fg = 'green' }, - inactive = { fg = 'grey' }, - }) - -- TODO move to conditions - local ok, _ = pcall(vim.treesitter.get_parser, 0) - if ok then - return hls.active - else - return hls.inactive - end -end - ----@type fun(hls: table): Highlight ---- ----@param hls table # custom highlights with possible properties: ---- * `default: Highlight` a highlight which sould be used when the file is not changed; ---- * `changed: Highlight` a highlight which sould be used when the file is changed; ---- * `read_only: Highlight` a highlight which sould be used when the file is in read only mode. ---- ----@return Highlight # actual highlight according to the current file state. -M.file_status = function(hls) - local hls = u.merge(hls, { - default = { name = 'FCFileDefault', fg = 'fg' }, - changed = { name = 'FCFileChanged', fg = 'orange' }, - read_only = { name = 'FCFileReadOnly', fg = 'red' }, - }) - if vim.bo.readonly then - return hls.read_only - end - if vim.bo.modified then - return hls.changed - else - return hls.default - end -end - -return M diff --git a/lua/compline/icons.lua b/lua/compline/icons.lua deleted file mode 100644 index b8f1f65..0000000 --- a/lua/compline/icons.lua +++ /dev/null @@ -1,85 +0,0 @@ -local h = require('compline.highlights') -local u = require('compline.utils') - -local M = {} - -M.file_status_icon = { - provider = function(c) - return (vim.bo.readonly and c.readonly_icon) or (vim.bo.modified and c.modified_icon) or '' - end, - hl = h.file_status, - readonly_icon = '  ', - modified_icon = '  ', -} - --- Returns an icon for the first lsp client attached to the current buffer. --- Icon will be taken from the `icons` field of this component or from the module --- 'nvim-web-devicons' if it's installed. If no one client will be found, --- the `icons.client_off` or 'ﮤ' will be used. --- --- `icons` an optional table with icons for possible lsp clients. Keys are names of --- the lsp clients in lowercase; Values are icons; Also, it can have two special keys: --- * `unknown` an optional string with icon for unknown lsp client. Default is '?'; --- * `client_off` an optional string with icon which means that no one client is --- attached to the current buffer. Default is 'ﮤ'; -M.lsp_client_icon = { - provider = function(cmp) - local client = u.lsp_client() - if not client then - return cmp.icons.client_off - end - local dev_icon = u.lsp_client_icon(cmp.icons, client) - return dev_icon and dev_icon.icon or cmp.icons.unknown - end, - hl = h.lsp_client, - icons = { - unknown = '?', - client_off = 'ﮤ', - }, - hls = { - unknown = 'fg', - client_off = 'grey', - }, -} - ----Returns an icon symbolizing state of the spellchecking. ----When spellchecking is on, the icon will have `hls.active` color. ----When spellchecking is off, the icon will have `hls.inactive` color. -M.spellcheck_icon = { - provider = function(cmp) - return cmp and cmp.icon_symbol - end, - hl = h.spellcheck, - icon_symbol = '暈', - hls = { - active = 'fg', - inactive = 'grey', - }, -} - -M.git_icon = { - provider = function(cmp) - return cmp and cmp.icon_symbol - end, - hl = h.git_status, - icon_symbol = ' ', - hls = { - inactive = { fg = 'grey' }, - changed = { fg = 'orange' }, - commited = { fg = 'green' }, - }, -} - -M.treesitter_parser_icon = { - provider = function(cmp) - return cmp and cmp.icon_symbol - end, - hl = h.treesitter_parser, - icon_symbol = '  ', - hls = { - active = { fg = 'green' }, - inactive = { fg = 'grey' }, - }, -} - -return M diff --git a/lua/compline/metadata.lua b/lua/compline/metadata.lua deleted file mode 100644 index c2a59d5..0000000 --- a/lua/compline/metadata.lua +++ /dev/null @@ -1,67 +0,0 @@ ------------------------------------------------------------------- --- This script contains EmmyLua Annotations for all used types. -- ------------------------------------------------------------------- - ----@alias LspClient table #an object which returns from the `vim.lsp.client()`. - ----@alias DevIcon table #an object which returns from the 'nvim-web-devicons' module. - ----@alias RGB string # RGB hex color description - ----@alias Color string # a name of the color or RGB hex color description - ----@alias Highlight string|table|function # similar to the highlight from the Feline, but a function ----can take a table as an argument. - ----@alias Provider string|table|function - ----@class Icon ----@field str string ----@field hl Highlight ----@field always_visible boolean - ----@class FelineComponent # see complete description here: |feline-components| ----@field name string ----@field provider Provider ----@field hl string|table|function # a description of the highlight according to the |feline-Component-highlight| ----@field icon Icon ----@field enabled boolean - ----@class FelineSetup # see |feline-setup-function| ----@field components table ----@field conditional_components table ----@field custom_providers table ----@field theme string|table ----@field separators table ----@field force_inactive table - ----@class Component : FelineComponent ----@field component string # a name of the existing component which will be used as a prototype. ----@field hls table # custom highlights for the component. - ----@alias Section Component[] - ----@class Line ----@field left table ----@field middle table ----@field right table - ----@class Theme ----@field colors table # key - name of a color; value - RGB hex color description ----@field vi_mode table # key - name of the vi mode; value - RGB hex color description - ----@class Library # library of reusable components. ----@field components table ----@field providers table ----@field highlights table ----@field icons table ----@field themes table - ----@class Statusline ----@field name string ----@field active Section[] list of sections with components for an active window. ----@field inactive Section[] list of sections with components for an inactive window. ----@field theme? Theme optional name of particular theme which should be used with this ---- statusline. If absent, a theme with the same name as the current ---- colorscheme will be taken (if exists) ----@field lib Library diff --git a/lua/compline/providers.lua b/lua/compline/providers.lua deleted file mode 100644 index 07e97f4..0000000 --- a/lua/compline/providers.lua +++ /dev/null @@ -1,85 +0,0 @@ -local c = require('compline.conditions') -local u = require('compline.utils') - -local M = {} - ----@type fun(): string ---- ----@return string # the name with extension of the file from the current buffer. -M.file_name = function() - return vim.fn.expand('%:t') -end - ----@type fun(): string ----Resolves the name of the current file relative to the current working directory. ----If file is not in the one of subdirectories of the working directory, then its ----path will be returned with: ---- * prefix "/.../" in case when the file is not in the one of home subdirectories; ---- * prefix "~/" in case when the file is in one of home subdirectories. ---- ----@return string # the name of the file relative to the current working directory. -M.relative_file_name = function() - local full_name = vim.fn.expand('%:p') - local name = vim.fn.expand('%:.') - if name == full_name then - name = vim.fn.expand('%:~') - end - if name == full_name then - name = '/.../' .. vim.fn.expand('%:t') - end - return name -end - ----@type fun(component: FelineComponent): string ----Cuts the current working path and gets the `opts.depth` directories from the end ----with prefix ".../". For example: inside the path `/3/2/1` this provider will return ----the string ".../2/1" for depth 2. If `opts.depth` is more then directories in the path, ----then path will be returned as is. ---- ----@param component FelineComponent the current component with properties: ----* `opts.depth: number` it will be used as a count of the last directories in the working path. Default is 2. ---- ----@return string # last `opts.depth` ac count of directories of the current working path. -M.working_path = function(component) - local full_path = vim.fn.getcwd() - local count = component.opts and component.opts.depth or 1 - local sep = '/' -- FIXME: use system separator - local dirs = vim.split(full_path, sep, { plain = true, trimempty = true }) - local result = '...' .. sep - if count > #dirs then - return full_path - end - if count <= 0 then - return result - end - local tail = vim.list_slice(dirs, #dirs - count + 1, #dirs) - for _, dir in ipairs(tail) do - result = result .. dir .. sep - end - return result -end - ----@type fun(): string ----@return string # a list of languages used to spell check or an empty string. -M.spellcheck_langs = function() - if vim.wo.spell then - return vim.bo.spelllang - else - return '' - end -end - ----@type fun(): string ----Returns the curent git branch. ----It uses `vim.fn.FugitiveHead` to take a current git branch. ---- ----@return string branch a name of the current branch or empty string; -M.fugitive_branch = function() - if c.is_git_workspace() then - return vim.fn.FugitiveHead() - else - return '' - end -end - -return M diff --git a/lua/compline/schema/feline.lua b/lua/compline/schema/feline.lua deleted file mode 100644 index 2e248f7..0000000 --- a/lua/compline/schema/feline.lua +++ /dev/null @@ -1,25 +0,0 @@ -local M = {} - -M.color = 'string' - -M.highlight = { - oneof = { - 'string', - 'function', - { - table = { - { key = 'fg', value = M.color }, - { key = 'bg', value = M.color }, - }, - }, - }, -} - -M.component = { - table = { - { key = 'provider', value = { oneof = { 'function', 'string' } } }, - { key = 'hl', value = M.highlight }, - }, -} - -return M diff --git a/lua/compline/schema/init.lua b/lua/compline/schema/init.lua deleted file mode 100644 index 4f382ba..0000000 --- a/lua/compline/schema/init.lua +++ /dev/null @@ -1,431 +0,0 @@ -local M = {} - --- const = | { const = } --- type = 'string' | 'number' | 'boolean' | 'function' | 'any' | 'nil' | const --- | { list = type } --- | { oneof = [ type ] } --- | { table = { keys = type, values = type } | [ { key = const, value = type} ] } - -M.const = { oneof = { 'string', { table = { key = 'const', value = 'string' } } } } - -M.list = function() - return { - table = { - { key = 'list', value = M.type, required = true }, - { key = 'non_empty', value = 'boolean' }, - }, - } -end - -M.oneof = function() - return { - table = { key = 'oneof', value = { list = M.type } }, - } -end - -M.table = function() - return { - table = { - key = 'table', - value = { - oneof = { - { - table = { - { key = 'key', value = M.type, required = true }, - { key = 'value', value = M.type, required = true }, - }, - }, - { - list = { - table = { - { key = 'key', value = M.type, required = true }, - { key = 'value', value = M.type, required = true }, - }, - }, - non_empty = true, - }, - }, - }, - }, - } -end - -M.primirives = { - 'boolean', - 'string', - 'number', - 'function', - 'nil', -} - -M.type = function() - local oneof = vim.tbl_extend('keep', {}, M.primirives) - table.insert(oneof, M.const) - table.insert(oneof, M.list()) - table.insert(oneof, M.table()) - table.insert(oneof, M.oneof()) - - return { - oneof = oneof, - } -end - -M.is_primitive = function(object) - return vim.tbl_contains(M.primirives, object) -end - -M.is_const = function(object) - if M.is_primitive(object) then - return false - end - if type(object) == 'table' then - return object[1] == 'const' - end - return true -end - -M.name_of_type = function(typ) - if type(typ) == 'string' then - return typ - end - if type(typ) == 'table' then - local typ = next(typ) - return typ - end - if M.is_const(typ) then - return string.format('const `%s`', typ) - end - error('Unsupported type ' .. vim.inspect(typ)) -end - -local PathToError = {} - -function PathToError:new(object, schema) - local p = {} - -- pointer to the current validated position in the object - p.current_object = self.current_object - p.current_object_key = self.current_object_key - -- pointer to the current validated position in the schema - p.current_schema = self.current_schema - p.current_schema_key = self.current_schema_key - setmetatable(p, { - __index = self, - __tostring = function(t) - return string.format( - '%s\n\nValidated value: %s\n\nValidated schema: %s', - t.error_message or '', - vim.inspect(t.object), - vim.inspect(t.schema) - ) - end, - }) - if not (object or schema) then - return p - end - - -- adding a new elements to the path -- - - if not p.current_schema then - p.object = object - p.schema = schema - p.current_object = object - p.current_schema = schema - elseif p.current_schema.list then - p.current_object[p.current_object_key] = object - p.current_object = object - p.current_object_key = nil - elseif p.current_schema.table then - local kv = p.current_schema.table[p.current_schema_key] - if not kv or kv.value then - -- key and value are already set, we should prepare a new key-value schema now - kv = {} - p.current_schema.table[p.current_schema_key] = kv - end - if not kv.key then - -- we should set a key - kv.key = schema - p.current_object[object] = '?' - p.current_schema = schema - p.current_object = object - p.current_schema_key = nil - p.current_object_key = nil - else - -- a key is already set, we should set a value now - kv.value = schema - p.current_object[p.current_object_key] = object - p.current_schema = schema - p.current_object = object - p.current_schema_key = nil - p.current_object_key = nil - end - else - p.current_object = object - p.current_schema = schema - p.current_object_key = nil - p.current_schema_key = nil - end - - return p -end - -function PathToError:wrong_type(expected_type, obj) - self.error_message = string.format( - 'Wrong type. Expected <%s>, but actual was <%s>.', - M.name_of_type(expected_type), - type(obj) - ) - return self -end - -function PathToError:wrong_type_in_schema(type_name, schema) - self.error_message = string.format( - 'Unknown type `%s` in the schema: %s', - type_name, - vim.inspect(schema) - ) - return self -end - -function PathToError:wrong_value(expected, actual) - self.error_message = string.format( - 'Wrong value "%s". Expected "%s".', - tostring(actual), - tostring(expected) - ) - return self -end - -function PathToError:wrong_oneof(value, options) - self.error_message = string.format( - 'Wrong oneof value: %s. Expected values %s.', - vim.inspect(value), - vim.inspect(options) - ) - return self -end - -function PathToError:empty_list_of(el_type) - self.error_message = string.format( - 'No one element in the none empty list of %s', - M.name_of_type(el_type) - ) - return self -end - -function PathToError:wrong_kv_types_schema(kv_types) - self.error_message = string.format( - "Wrong schema. It should have description for 'key' and 'value', but it doesn't: `%s`", - vim.inspect(kv_types) - ) - return self -end - -function PathToError:wrong_schema_of(typ, type_schema) - self.error_message = string.format( - 'Wrong schema of the %s. Expected table, but was %s.', - typ, - type(type_schema) - ) - return self -end - -function PathToError:required_key_not_found(kv_types, orig_table) - self.error_message = string.format( - 'Required key `%s` was not found.\nKeys in the original table were:\n%s', - vim.inspect(kv_types.key), - vim.inspect(vim.tbl_keys(orig_table)) - ) - return self -end - -function PathToError:required_pair_not_found(kv_types, orig_table) - self.error_message = string.format( - 'Required pair with key = `%s` and value = `%s` was not found.\nOriginal table was:\n%s', - vim.inspect(kv_types.key), - vim.inspect(kv_types.value), - vim.inspect(orig_table) - ) - return self -end - -local function validate_const(value, schema, path) - local path = path:new(value, schema) - if value ~= schema then - return false, path:wrong_value(schema, value) - end - return true -end - -local function validate_list(list, el_type, non_empty, path) - local path = path:new({}, { list = el_type, non_empty = non_empty }) - if type(list) ~= 'table' then - return false, path:wrong_type('table', list) - end - - if non_empty and #list == 0 then - return false, path:empty_list_of(el_type) - end - - for i, el in ipairs(list) do - path.current_object_key = i - local _, err = M.validate(el, el_type, path) - if err then - return false, err - end - end - return true -end - -local function validate_oneof(value, options, path) - local path = path:new(value, { oneof = options }) - if type(options) ~= 'table' then - return nil, path:wrong_schema_of('oneof', options) - end - for _, opt in ipairs(options) do - -- we do not pass any path here to avoid adding not applicable opt - if M.validate(value, opt) then - return true - end - end - return false, path:wrong_oneof(value, options) -end - -local function validate_table(orig_tbl, kvs_schema, path) - local path = path:new({}, { table = {} }) - if type(kvs_schema) ~= 'table' then - return false, path:wrong_schema_of('table', kvs_schema) - end - - if type(orig_tbl) ~= 'table' then - return false, path:wrong_type('table', orig_tbl) - end - - local function split_list(list) - local required = {} - local optional = {} - for _, v in ipairs(list) do - if type(v) == 'table' and v.required then - table.insert(required, v) - else - table.insert(optional, v) - end - end - return required, optional - end - - local function validate_key_value(unvalidated_tbl, kv_types, is_strict) - if not (kv_types.key and kv_types.value) then - return false, path:wrong_kv_types_schema(kv_types) - end - - local at_least_one_key_passed = false - local at_least_one_pair_passed = false - - for k, v in pairs(unvalidated_tbl) do - path.current_object_key = k - local _, err = M.validate(k, kv_types.key, path) - if not err then - at_least_one_key_passed = true - - _, err = M.validate(v, kv_types.value, path) - -- if key is valid, but value is not, - -- then validation must be failed regadles of is_strict - if err then - return false, err - end - - at_least_one_pair_passed = true - - -- remove validated key - unvalidated_tbl[k] = nil - - -- constant can be checked only once - if M.is_const(kv_types.key) then - return true - end - end - end - - if is_strict and not at_least_one_key_passed then - return false, path:required_key_not_found(kv_types, unvalidated_tbl) - end - - if is_strict and not at_least_one_pair_passed then - return false, path:required_pair_not_found(kv_types, unvalidated_tbl) - end - - return true - end - - local function validate_keys(unvalidated_tbl, kv_schemas, is_strict) - for i, kv_schema in ipairs(kv_schemas) do - path.current_schema_key = i - local _, err = validate_key_value(unvalidated_tbl, kv_schema, is_strict) - if err then - return false, err - end - end - return true - end - - -- this instance will be changed on validation - local unvalidated_tbl = vim.tbl_extend('error', {}, orig_tbl) - if kvs_schema.key and kvs_schema.value then - path.current_schema_key = 1 - return validate_key_value(unvalidated_tbl, kvs_schema, true) - else - local required, optional = split_list(kvs_schema) - local _, err = validate_keys(unvalidated_tbl, required, true) - if err then - return false, err - end - return validate_keys(unvalidated_tbl, optional, false) - end -end - ----@type fun(object: any, schema: table) ---- Checks that {object} sutisfied to the {schema} or raises error. ---- You can use safe version `call_validate` to avoid error and use returned status ---- instead. -M.validate = function(object, schema, path) - local path = path or PathToError:new() - - local type_name, type_schema, type_value - if type(schema) == 'function' then - return M.validate(object, schema(), path) - elseif type(schema) == 'table' then - type_name, type_schema = next(schema) - type_value = type_name == 'const' and type_schema or nil - elseif M.is_const(schema) then - type_name = 'const' - type_value = schema - else - type_name = schema - end - - if type_name == 'table' then - return validate_table(object, type_schema, path) - end - if type_name == 'oneof' then - return validate_oneof(object, type_schema, path) - end - if type_name == 'list' or type_name == 'non_empty' then - return validate_list(object, schema.list, schema.non_empty, path) - end - if type_name == 'const' then - return validate_const(object, type_value, path) - end - - if not M.is_primitive(type_name) then - return false, path:wrong_type_in_schema(type_name, schema) - end - -- flat constants or primitives - path = path:new(object, schema) - local ok = type(object) == type_name or object == type_value - if not ok then - return false, path:wrong_type(type_name, object) - end - return true -end - -return M diff --git a/lua/compline/schema/statusline.lua b/lua/compline/schema/statusline.lua deleted file mode 100644 index 45e8f20..0000000 --- a/lua/compline/schema/statusline.lua +++ /dev/null @@ -1,46 +0,0 @@ -local f = require('compline.schema.feline') -local t = require('compline.schema.theme') - -local M = {} - -M.section = { list = 'string' } - -M.zone = { - table = { - key = 'string', - value = M.section, - }, -} - -M.line = { - table = { - key = { oneof = { 'left', 'middle', 'right' } }, - value = M.zone, - }, -} - -M.statusline = { - table = { - { - key = { oneof = { 'active', 'inactive' } }, - value = M.line, - }, - { - key = 'themes', - value = { - table = { - { key = 'default', value = t.theme, required = true }, - { key = 'string', value = t.theme }, - }, - }, - required = true, - }, - { - key = 'components', - value = { table = { key = 'string', value = f.component } }, - required = true, - }, - }, -} - -return M diff --git a/lua/compline/schema/theme.lua b/lua/compline/schema/theme.lua deleted file mode 100644 index 7de3698..0000000 --- a/lua/compline/schema/theme.lua +++ /dev/null @@ -1,97 +0,0 @@ -local f = require('compline.schema.feline') - -local M = {} - -M.separator = { - oneof = { - 'string', - { - table = { - { key = 1, value = 'string', required = true }, - { key = 'hl', value = f.highlight }, - }, - }, - }, -} - -M.separators = { - table = { - { key = 'left', value = M.separator }, - { key = 'right', value = M.separator }, - }, -} - -M.sections = { - table = { - key = 'string', - value = { - table = { - { key = 'hl', value = f.highlight, required = true }, - { key = { oneof = { 'sr', 'sl' } }, value = M.separator }, - }, - }, - }, -} - -M.zone = { - table = { - { - key = 'zone_separators', - value = M.separators, - }, - { - key = 'sections_separators', - value = M.separators, - }, - { - key = 'sections', - value = M.sections, - required = true, - }, - }, -} - -M.line = { - table = { - { key = { oneof = { 'left, middle', 'right' } }, value = M.zone }, - }, -} - -M.colors = { - table = { key = 'string', value = 'string' }, -} - -M.vi_mode = { - table = { - key = { - oneof = { - 'NORMAL', - 'OP', - 'INSERT', - 'VISUAL', - 'LINES', - 'BLOCK', - 'REPLACE', - 'V-REPLACE', - 'ENTER', - 'MORE', - 'SELECT', - 'COMMAND', - 'SHELL', - 'TERM', - 'NONE', - }, - }, - value = 'string', - }, -} - -M.theme = { - table = { - { key = { oneof = { 'active', 'inactive' } }, value = M.line }, - { key = { oneof = { 'colors', 'dark', 'light' } }, value = M.colors, required = true }, - { key = 'vi_mode', value = M.vi_mode, reqired = true }, - }, -} - -return M diff --git a/lua/compline/statusline.lua b/lua/compline/statusline.lua deleted file mode 100644 index 6bd8496..0000000 --- a/lua/compline/statusline.lua +++ /dev/null @@ -1,183 +0,0 @@ -local u = require('compline.utils') -local feline = u.lazy_load('feline') - -local resolve_component = function(components, component_name) - return components[component_name] or { provider = component_name } -end - -local add_highlight = function(component, theme_hl) - component.hl = component.hl or theme_hl -end - -local add_separator = function(component, sections_seps, separator, side) - local sep = separator or sections_seps[side] - if type(sep) == 'table' then - component[side .. '_sep'] = { - str = sep[1], - hl = sep.hl, - } - elseif type(sep) == 'string' then - component[side .. '_sep'] = { - str = sep, - } - end -end - -local separator_as_component = function(sep) - if type(sep) == 'string' then - return { provider = sep } - elseif type(sep) == 'table' then - return { provider = sep[1], hl = sep.hl } - else - error('Unexpected separator: ' .. vim.inspect(sep)) - end -end - ----@param line table ----@param line_name string ----@param zone_name string ----@param theme table ----@param components table -local build_zone = function(line, line_name, zone_name, theme, components) - local result = {} - local theme_sections = vim.tbl_get(theme, line_name, zone_name, 'sections') or {} - local sections_separators = vim.tbl_get(theme, line_name, zone_name, 'sections_separators') - or {} - local zone_separators = vim.tbl_get(theme, line_name, zone_name, 'zone_separators') or {} - local sections = line[zone_name] - sections = sections ~= 'nil' and sections or {} - - local j = 0 - -- add a left separator to the zone - if zone_separators.left then - j = j + 1 - result[j] = separator_as_component(zone_separators.left) - end - -- now, resolve components in the every section a, b, c, etc... - for section_name, section in u.sorted_by_keys(sections) do - -- 'nil' is an option to remove existed section when extends existed Statusline - if section ~= 'nil' then - local theme_section = theme_sections[section_name] or {} - -- resolve components - for n, component_name in ipairs(section) do - j = j + 1 - local component = resolve_component(components, component_name) - add_highlight(component, theme_section.hl) - if n == 1 then - -- add left section's separator - add_separator(component, sections_separators, theme_section.ls, 'left') - end - if n == #section then - -- add right section's separator - add_separator(component, sections_separators, theme_section.rs, 'right') - end - result[j] = component - end - end - end - -- add a right separator to the zone - if zone_separators.right then - j = j + 1 - result[j] = separator_as_component(zone_separators.right) - end - return result -end - -local build_line = function(statusline, line_name) - local result = {} - local theme = statusline.theme or {} - local components = statusline.components or {} - local line = statusline[line_name] - local i = 0 - for _, zone_name in pairs({ 'left', 'middle', 'right' }) do - i = i + 1 - result[i] = build_zone(line, line_name, zone_name, theme, components) - end - return result -end - -local Statusline = { - -- user should be able to not specify components in some case at all - active = nil, - inactive = nil, - components = {}, - themes = {}, -} - ----@fun(name: string, customization: Statusline): Statusline -function Statusline:new(name, customization) - assert(type(name) == 'string', 'Statusline must have a name.') - - local x = vim.tbl_deep_extend('force', self, customization or {}) - x.name = name - return x -end - -function Statusline:validate() - local statusline_schema = require('compline.schema.statusline').statusline - local ok, schema = pcall(require, 'compline.schema') - if not ok then - error('To validate statusline schema, "compline.schema" module should be installed.') - end - local ok, err = schema.validate(self, statusline_schema) - - assert(ok, tostring(err)) -end - -function Statusline:build_components() - self.theme = self.themes and (self.themes[vim.g.colors_name] or self.themes.default) - - local result = {} - for _, line_name in ipairs({ 'active', 'inactive' }) do - local line = self[line_name] - if line and line ~= 'nil' then - result[line_name] = build_line(self, line_name) - end - end - return result -end - -function Statusline:select_theme() - local feline_themes = require('feline.themes') - local background = vim.o.background or 'colors' - local theme = string.format('%s_%s_%s', self.name, vim.g.colors_name, background) - local default = string.format('%s_%s_%s', self.name, 'default', background) - - theme = feline_themes[theme] or feline_themes[default] - if theme then - feline.use_theme(theme) - return - end -end - ----@return FelineSetup # table which were used to setup feline. -function Statusline:setup() - local config = {} - config.components = self:build_components() - config.vi_mode_colors = self.theme.vi_mode - - feline.setup(config) - - local feline_themes = require('feline.themes') - for theme_name, theme in pairs(self.themes) do - feline_themes[self.name .. '_' .. theme_name .. '_colors'] = theme.colors - feline_themes[self.name .. '_' .. theme_name .. '_dark'] = theme.dark - feline_themes[self.name .. '_' .. theme_name .. '_light'] = theme.light - end - - self:select_theme() - - -- change the theme on every changes colorscheme or background - local group = vim.api.nvim_create_augroup('compline_select_theme', { clear = true }) - vim.api.nvim_create_autocmd('ColorScheme', { - pattern = '*', - group = group, - callback = function() - self:select_theme() - end, - }) - - return config -end - -return Statusline diff --git a/lua/compline/test.lua b/lua/compline/test.lua deleted file mode 100644 index f5ee7d0..0000000 --- a/lua/compline/test.lua +++ /dev/null @@ -1,35 +0,0 @@ -local M = {} - ----@type fun(table: table, prop: string | number, mock: any, test: function): any --- Replaces a value in the {table} with a key {prop} by the {mock], and run the {test}. --- Then restores an original value of the {table}, when the {test} is completed --- (despite of errors), and returns thr result of the {test}. -M.use_mocked_table = function(table, prop, mock, test) - local orig = table[prop] - table[prop] = mock - local ok, result = pcall(test) - table[prop] = orig - if ok then - return result - else - error(result) - end -end - ----@type fun(module: string, prop: string | number, mock: any, test: function): any --- Replace a value in the {module} with a key {prop} by the {mock}, and run the {test}. --- Then unload {module}, when test is completed (despite errors in the {test}). -M.use_mocked_module = function(module, prop, mock, test) - package.loaded[table] = nil - local m = require(module) - m[prop] = mock - local ok, result = pcall(test) - package.loaded[table] = nil - if ok then - return result - else - error(result) - end -end - -return M diff --git a/lua/compline/utils.lua b/lua/compline/utils.lua deleted file mode 100644 index d521442..0000000 --- a/lua/compline/utils.lua +++ /dev/null @@ -1,137 +0,0 @@ -local M = {} - ----@type fun(x: any): boolean ----Checks is an argument {x} is empty. ---- ----@return boolean #true when the argument is empty. ----The argument is empty when: ----* it is the nil; ----* it has a type 'table' and doesn't have any pair; ----* it has a type 'string' and doesn't have any char; ----otherwise result is false. -M.is_empty = function(x) - if x == nil then - return true - end - if type(x) == 'table' and next(x) == nil then - return true - end - if type(x) == 'string' and string.len(x) < 1 then - return true - end - return false -end - ----@type fun(t1: table, t2: table): table ----The same as `vim.extend('keep', t1 or {}, t2 or {})` -M.merge = function(t1, t2) - return vim.tbl_extend('keep', t1 or {}, t2 or {}) -end - -M.sorted_by_keys = function(t, f) - local index = {} - for k in pairs(t) do - table.insert(index, k) - end - table.sort(index, f) - local i = 0 - return function() - i = i + 1 - local k = index[i] - return k, t[k] - end -end - ----@type fun():LspClient ---- ----@return LspClient the first attached to the current buffer lsp client. -M.lsp_client = function() - local clients = vim.lsp.buf_get_clients(0) - if M.is_empty(clients) then - return nil - end - local _, client = next(clients) - return client -end - ----@type fun(icons: table, client?: LspClient): DevIcon ----Takes a type of the file from the {client} and tries to take a corresponding icon ----from the {icons} or 'nvim-web-devicons'. {client} can be omitted. If so, result of ----the `lsp_client()` is used. ---- ----DevIcon example: ----```lua ----{ ---- icon = "", ---- color = "#51a0cf", ---- cterm_color = "74", ---- name = "Lua", ----} ----``` ---- ----@see require('nvim-web-devicons').get_icons ---- ----@param icons table # a table with icons for the lsp clients. ----If no one lsp client is attached, then nil will be returned. ----If an icon for the client is not found, then it's taken from the 'nvim-web-devicons' ----module (if such module exists) or nil will be returned. ---- ----@param client? LspClient the client to the LSP server. If absent, the first attached client to ----the current buffer is used. ---- ----@return DevIcon # icon of the LspClient or `nil` when the `client` is absent or icon not found. -M.lsp_client_icon = function(icons, client) - local c = client or M.lsp_client() - if c == nil then - return nil - end - - -- try to get icons from the 'nvim-web-devicons' module - local ok, dev_icons = pcall(require, 'nvim-web-devicons') - dev_icons = ok and dev_icons.get_icons() - - -- merge both sources with icons - local all_icons = M.merge(icons, dev_icons) - - -- get an appropriated icon - local icon - for _, ft in ipairs(c.config.filetypes) do - if all_icons[ft] then - icon = all_icons[ft] - break - end - end - return icon -end - -M.is_lsp_client_ready = function(client) - -- TODO: add support of the metals - return true -end - ----@type fun(t: table): table ----Replace all string values with 'nil' by the `nil` to remove the pair from the table. -M.remove_nil = function(t) - for k, v in pairs(t) do - if v == 'nil' then - t[k] = nil - elseif type(v) == 'table' then - t[k] = M.remove_nil(v) - end - end - return (not M.is_empty(t)) and t or nil -end - ----@type fun(module_name: string): table ----Lazy import of a module. It doesn't load a module til a first using. ----@return table # a proxy which delegates any invocation of the `__index` to the module with {module_name}. -M.lazy_load = function(module_name) - local module = {} - setmetatable(module, module) - module.__index = function(_, k) - return require(module_name)[k] - end - return module -end - -return M diff --git a/lua/feline-theme/example/colors.lua b/lua/feline-theme/example/colors.lua new file mode 100644 index 0000000..4728b03 --- /dev/null +++ b/lua/feline-theme/example/colors.lua @@ -0,0 +1,34 @@ +local u = require('feline-theme.utils') + +-- Prepare colors for sections: +-- We begin from the default background for Statusline +-- and will make it lighter/darker (depends on vim.go.background) +-- for every next section +local gradient_colors = function() + local function change(color) + if vim.go.background == 'light' then + return u.darkening_color(color, 0.4, 0.3, 0.1) + else + return u.ligthening_color(color, 0.2, 0.2, 0.3) + end + end + local colors = {} + colors.fg = vim.go.background == 'light' and 'White' or 'Black' + colors.bg = u.get_hl_bg('Statusline') + or (vim.go.background == 'light' and '#c8c8cd' or '#505050') + colors.d = change(colors.bg) + colors.c = change(colors.d) + colors.b = change(colors.c) + colors.a = change(colors.b) + + colors.z = colors.a + colors.y = colors.b + colors.x = colors.c + colors.w = colors.d + + return colors +end + +return { + default = gradient_colors, +} diff --git a/lua/feline-theme/example/components.lua b/lua/feline-theme/example/components.lua new file mode 100644 index 0000000..cdbe956 --- /dev/null +++ b/lua/feline-theme/example/components.lua @@ -0,0 +1,37 @@ +local M = {} + +M.vi_mode = { + provider = 'vi_mode', + -- turn icon off and use full name of the mode + icon = '', +} + +M.short_working_directory = { + provider = function() + return vim.fn.pathshorten(vim.fn.fnamemodify(vim.fn.getcwd(), ':p')) + end, +} + +M.file_name = { + provider = function() + return vim.fn.expand('%:t') + end, +} + +M.time = { + provider = function() + return vim.fn.strftime('%H:%M') + end, +} + +M.file_format = { + provider = { + name = 'file_type', + opts = { + filetype_icon = true, + case = 'lowercase', + }, + }, +} + +return M diff --git a/lua/feline-theme/example/init.lua b/lua/feline-theme/example/init.lua new file mode 100644 index 0000000..e5b9bfc --- /dev/null +++ b/lua/feline-theme/example/init.lua @@ -0,0 +1,19 @@ +return { + active = { + left = { + a = { 'vi_mode' }, + b = { 'short_working_directory' }, + c = { 'file_name' }, + }, + middle = { + a = { 'time' }, + }, + right = { + y = { 'file_encoding', 'file_format' }, + z = { 'position' }, + }, + }, + theme = require('feline-theme.example.theme'), + components = require('feline-theme.example.components'), + colors = require('feline-theme.example.colors'), +} diff --git a/lua/feline-theme/example/theme.lua b/lua/feline-theme/example/theme.lua new file mode 100644 index 0000000..7b41907 --- /dev/null +++ b/lua/feline-theme/example/theme.lua @@ -0,0 +1,75 @@ +local vi_mode_bg = function() + return { + bg = require('feline.providers.vi_mode').get_mode_color(), + } +end + +local vi_mode_fg = function(bg) + return function() + return { + fg = require('feline.providers.vi_mode').get_mode_color(), + bg = bg, + } + end +end + +return { + active = { + left = { + separators = { right = ' ' }, + a = { + hl = vi_mode_bg, + separators = { right = { str = '', hl = vi_mode_fg('b') } }, + }, + b = { + hl = { bg = 'b' }, + separators = { right = { str = '', hl = { fg = 'b', bg = 'c' } } }, + }, + c = { + hl = { bg = 'c' }, + separators = { right = { str = '', hl = { fg = 'c', bg = 'd' } } }, + }, + d = { + hl = { bg = 'd' }, + separators = { right = { str = '', hl = { fg = 'd', bg = 'bg' } } }, + }, + }, + right = { + separators = { left = ' ' }, + w = { + hl = { bg = 'w' }, + separators = { left = { str = '', hl = { bg = 'bg' } } }, + }, + x = { + hl = { bg = 'x' }, + separators = { left = { str = '', hl = { bg = 'w' } } }, + }, + y = { + hl = { bg = 'y' }, + separators = { left = { str = '', hl = { bg = 'x' } } }, + }, + z = { + hl = vi_mode_bg, + separators = { left = { str = '', hl = vi_mode_fg('y') } }, + }, + }, + }, + + vi_mode = { + NORMAL = 'green', + OP = 'magenta', + INSERT = 'blue', + VISUAL = 'magenta', + LINES = 'magenta', + BLOCK = 'magenta', + REPLACE = 'violet', + ['V-REPLACE'] = 'pink', + ENTER = 'cyan', + MORE = 'cyan', + SELECT = 'yellow', + COMMAND = 'orange', + SHELL = 'yellow', + TERM = 'orange', + NONE = 'yellow', + }, +} diff --git a/lua/feline-theme/init.lua b/lua/feline-theme/init.lua new file mode 100644 index 0000000..de6bcad --- /dev/null +++ b/lua/feline-theme/init.lua @@ -0,0 +1,198 @@ +local feline = require('feline') +local u = require('feline-theme.utils') + +-- global variable: +FelineTheme = {} +-- private global state: +local __state = {} +setmetatable(FelineTheme, { + __index = __state, + __newindex = function() + error('Attempt to update a read-only table') + end, +}) + +---@param statusline table a full description of the statusline +---@param line_name string active or inactive. +---@param zone_name string left or middle or right. +---@param section_name string the name of the section: a or b or c and etc. +---@param result table container for built components. +local build_section = function(statusline, line_name, zone_name, section_name, result) + local zone = vim.tbl_get(statusline, line_name, zone_name) + local section = zone and zone[section_name] + -- empty section. Skip build + if vim.tbl_isempty(section) then + return + end + + local zone_theme = vim.tbl_get(statusline, 'theme', line_name, zone_name) or {} + local section_theme = zone_theme[section_name] or {} + local section_separators = section_theme.separators or {} + + local first_component = #result + 1 + -- here we're building components stubs, which will be partially overrided later + for _, component_name in ipairs(section) do + local component = { name = component_name, hl = section_theme.hl } + table.insert(result, component) + end + local last_component = #result + -- render section separators + if #result >= first_component then + result[first_component]['left_sep'] = section_separators.left + result[last_component]['right_sep'] = section_separators.right + end +end + +---@param statusline table a full description of the statusline +---@param line_name string active or inactive. +---@param zone_name string left or middle or right. +---@return table[] # resolved components inside zone. +local build_zone = function(statusline, line_name, zone_name) + local result = {} + local zone = vim.tbl_get(statusline, line_name, zone_name) + local zone_theme = vim.tbl_get(statusline, 'theme', line_name, zone_name) or {} + local zone_separators = zone_theme.separators or {} + + -- adds `always_visible` property to the separator + local function always_visible(sep) + if type(sep) == 'table' then + sep.always_visible = true + return sep + else + return { str = sep, always_visible = true } + end + end + + -- build component stubs for every section + for section_name in u.sorted_by_keys(zone) do + build_section(statusline, line_name, zone_name, section_name, result) + end + + -- add left zone separator + if #result > 0 and zone_separators.left then + result[1].left_sep = always_visible(zone_separators.left) + end + + -- add right zone separator + if #result > 0 and zone_separators.right then + result[#result].right_sep = always_visible(zone_separators.right) + end + + -- finally resolve components + local components = statusline.components or {} + for i, stub in ipairs(result) do + local component = components[stub.name] + if component then + result[i] = vim.tbl_extend('force', stub, component) + else + stub.provider = stub.name + end + end + + return result +end + +---@param statusline table a full description of the statusline. +---@param line_name string active or inactive. +---@return table[] # description of the statusline in term of feline. +local build_line = function(statusline, line_name) + local result = {} + for i, zone_name in ipairs({ 'left', 'middle', 'right' }) do + if statusline[line_name][zone_name] then + result[i] = build_zone(statusline, line_name, zone_name) + else + result[i] = {} + end + end + return result +end + +local Statusline = { + -- user should be able to not specify components in some case at all + active = nil, + inactive = nil, + components = {}, + theme = {}, + colors = {}, +} + +function Statusline:validate() + local statusline_schema = require('feline-theme.schema.statusline').statusline + local ok, schema = pcall(require, 'lua-schema') + if ok then + local ok, err = schema.validate(self, statusline_schema) + assert(ok, tostring(err)) + else + error('To validate statusline schema module "dokwork/lua-schema.nvim" should be installed.') + end +end + +function Statusline:build_components() + local result = {} + for _, line_name in ipairs({ 'active', 'inactive' }) do + if self[line_name] then + result[line_name] = build_line(self, line_name) + end + end + return result +end + +function Statusline:show_components() + vim.pretty_print(self:build_components()) +end + +function Statusline:actual_colors() + local colors = self.colors or {} + colors = colors[vim.g.colors_name] or colors[vim.go.background] or colors['default'] + if type(colors) == 'function' then + return colors() + else + return colors + end +end + +function Statusline:show_actual_colors() + vim.pretty_print(self:actual_colors()) +end + +function Statusline:refresh_colors() + local colors = self:actual_colors() + if colors then + feline.use_theme(colors) + feline.reset_highlights() + end + return colors +end + +function Statusline:show_all() + vim.pretty_print(self) +end + +return { + setup_statusline = function(statusline) + setmetatable(statusline, { + __index = Statusline, + }) + + local config = {} + config.components = statusline:build_components() + config.theme = statusline:actual_colors() + config.vi_mode_colors = statusline.theme and statusline.theme.vi_mode + + feline.setup(config) + + -- change the theme on every changes colorscheme or background + local group = vim.api.nvim_create_augroup('feline_select_theme', { clear = true }) + vim.api.nvim_create_autocmd('ColorScheme', { + pattern = '*', + group = group, + callback = function() + statusline:refresh_colors() + end, + }) + + __state.statusline = statusline + + return statusline + end, +} diff --git a/lua/feline-theme/schema/colors.lua b/lua/feline-theme/schema/colors.lua new file mode 100644 index 0000000..17c017b --- /dev/null +++ b/lua/feline-theme/schema/colors.lua @@ -0,0 +1,23 @@ +local feline = require('feline-theme.schema.feline') + +local M = {} + +M.palette = { oneof = { 'function', { table = { key = 'string', value = feline.color } } } } + +M.colors = { + table = { + -- the palette can have a key with a name of the colorscheme for which this palette + -- should be used + { key = 'string', value = M.palette }, + -- will be used in case of `dark` background, if palette with the same name as the + -- current colorscheme was not found + { key = 'light', value = M.palette }, + -- will be used in case of `light` background, if palette with the same name as the + -- current colorscheme was not found + { key = 'dark', value = M.palette }, + -- palette with colors which will be used when no other option will be appropriate + { key = 'default', value = M.palette, required = true }, + }, +} + +return M diff --git a/lua/feline-theme/schema/feline.lua b/lua/feline-theme/schema/feline.lua new file mode 100644 index 0000000..d2c6bb8 --- /dev/null +++ b/lua/feline-theme/schema/feline.lua @@ -0,0 +1,54 @@ +local M = {} + +-- #RRBBGG +M.color = 'string' + +M.highlight = { + oneof = { + 'string', + 'function', + { + table = { + { key = 'fg', value = M.color }, + { key = 'bg', value = M.color }, + }, + }, + }, +} + +M.provider = { + oneof = { + 'string', + 'function', + { + table = { + { key = 'name', value = 'string' }, + { key = 'opts', value = { table = { key = 'string', value = 'any' } } }, + }, + }, + }, +} + +M.separator = { + oneof = { + 'string', + 'function', + { + table = { + { key = 'str', value = 'string' }, + { key = 'hl', value = M.highlight }, + { key = 'always_visible', value = 'boolean' }, + }, + }, + }, +} + +M.component = { + table = { + { key = 'provider', value = M.provider }, + { key = 'hl', value = M.highlight }, + { key = { oneof = { 'left_sep', 'right_sep' } }, value = M.separator }, + }, +} + +return M diff --git a/lua/feline-theme/schema/statusline.lua b/lua/feline-theme/schema/statusline.lua new file mode 100644 index 0000000..f28632c --- /dev/null +++ b/lua/feline-theme/schema/statusline.lua @@ -0,0 +1,38 @@ +local feline = require('feline-theme.schema.feline') + +local M = {} + +M.component = 'string' + +M.section = { list = M.component } + +M.zone = { + table = { + -- usually chars are used as name of the section + key = 'string', + value = M.section, + }, +} + +M.line = { + table = { + { key = 'left', value = M.zone }, + { key = 'middle', value = M.zone }, + { key = 'right', value = M.zone }, + }, +} + +M.statusline = { + table = { + { key = 'active', value = M.line }, + { key = 'inactive', value = M.line }, + { key = 'theme', value = require('feline-theme.schema.theme').theme }, + { key = 'colors', value = require('feline-theme.schema.colors').colors }, + { + key = 'components', + value = { table = { key = 'string', value = feline.component } }, + }, + }, +} + +return M diff --git a/lua/feline-theme/schema/theme.lua b/lua/feline-theme/schema/theme.lua new file mode 100644 index 0000000..85cd4fe --- /dev/null +++ b/lua/feline-theme/schema/theme.lua @@ -0,0 +1,68 @@ +local feline = require('feline-theme.schema.feline') + +local M = {} + +M.separator = feline.separator + +M.separators = { + table = { + { key = 'left', value = M.separator }, + { key = 'right', value = M.separator }, + }, +} + +M.section = { + table = { + { key = 'hl', value = feline.highlight }, + { key = 'separators', value = M.separators }, + }, +} + +M.zone = { + table = { + { key = 'separators', value = M.separators }, + { key = 'string', value = M.section }, + }, +} + +M.line = { + table = { + { key = 'left', value = M.zone }, + { key = 'middle', value = M.zone }, + { key = 'right', value = M.zone }, + }, +} + +M.vi_mode = { + table = { + key = { + oneof = { + 'NORMAL', + 'OP', + 'INSERT', + 'VISUAL', + 'LINES', + 'BLOCK', + 'REPLACE', + 'V-REPLACE', + 'ENTER', + 'MORE', + 'SELECT', + 'COMMAND', + 'SHELL', + 'TERM', + 'NONE', + }, + }, + value = feline.color, + }, +} + +M.theme = { + table = { + { key = { oneof = { 'active', 'inactive' } }, value = M.line }, + { key = 'vi_mode', value = M.vi_mode }, + }, +} + +return M diff --git a/lua/feline-theme/utils.lua b/lua/feline-theme/utils.lua new file mode 100644 index 0000000..41fd0cd --- /dev/null +++ b/lua/feline-theme/utils.lua @@ -0,0 +1,126 @@ +local M = {} + +---@type fun(x: any): boolean +---Checks is an argument {x} is empty. +--- +---@return boolean #true when the argument is empty. +---The argument is empty when: +---* it is the nil; +---* it has a type 'table' and doesn't have any pair; +---* it has a type 'string' and doesn't have any char; +---otherwise result is false. +M.is_empty = function(x) + if x == nil then + return true + end + if type(x) == 'table' and next(x) == nil then + return true + end + if type(x) == 'string' and string.len(x) < 1 then + return true + end + return false +end + +---@type fun(t1: table, t2: table): table +---The same as `vim.extend('keep', t1 or {}, t2 or {})` +M.merge = function(t1, t2) + return vim.tbl_extend('keep', t1 or {}, t2 or {}) +end + +M.sorted_by_keys = function(t, f) + local index = {} + for k in pairs(t) do + table.insert(index, k) + end + table.sort(index, f) + local i = 0 + return function() + i = i + 1 + local k = index[i] + return k, t[k] + end +end + +---Lazy import of a module. It doesn't load a module til a first using. +---@return table # a proxy which delegates any invocation of the `__index` to the module with {module_name}. +M.lazy_load = function(module_name) + local module = {} + setmetatable(module, module) + module.__index = function(_, k) + return require(module_name)[k] + end + return module +end + +M.get_hl_attr = function(hl, what) + local result = vim.fn.synIDattr(vim.fn.synIDtrans(vim.fn.hlID(hl)), what) + if result == '' then + return nil + else + return result + end +end + +M.get_hl_fg = function(hl) + return M.get_hl_attr(hl, 'fg#') +end + +M.get_hl_bg = function(hl) + return M.get_hl_attr(hl, 'bg#') +end + +---@type fun(color: string): number, number, number +--- Parses a color in the format '#RRGGBB', where +--- RR is a number for red part in the hex format, +--- GG is a number for green part in the hex format, +--- BB is a number for blue part in the hex format. +--- For example: '#000000' for 'black' color, or '#AAAAAA' for white color. +--- In case of wrong format of the color the error will be thrown. +M.parse_rgb_color = function(color) + if type(color) ~= 'string' then + error(string.format('Illegal color type %s. It must be string.', type(color))) + end + local _, _, r, g, b = string.find(color, '#(%x%x)(%x%x)(%x%x)') + r = tonumber(r, 16) + g = tonumber(g, 16) + b = tonumber(b, 16) + if r and g and b then + return r, g, b + else + error( + string.format( + 'Illegal color: %s. A color must follow format: #(%x%x)(%x%x)(%x%x)', + color + ) + ) + end +end + +M.create_color = function(r, g, b) + return string.format('#%02x%02x%02x', r, g, b) +end + +M.darkening_color = function(color, rf, gf, bf) + local rf = rf or 0.1 + local gf = gf or 0.1 + local bf = bf or 0.1 + local r, g, b = M.parse_rgb_color(color) + r = r * (1 - rf) + g = g * (1 - gf) + b = b * (1 - bf) + return M.create_color(r, g, b) +end + +M.ligthening_color = function(color, rf, gf, bf) + local rf = rf or 0.1 + local gf = gf or 0.1 + local bf = bf or 0.1 + local r, g, b = M.parse_rgb_color(color) + r = r + (255 - r) * rf + g = g + (255 - g) * gf + b = b + (255 - b) * bf + return M.create_color(r, g, b) +end + +return M diff --git a/test/cosmosline_spec.lua b/test/cosmosline_spec.lua deleted file mode 100644 index 3b1e543..0000000 --- a/test/cosmosline_spec.lua +++ /dev/null @@ -1,9 +0,0 @@ -describe('validating', function() - it('should be passed', function() - -- given: - local cosmosline = require('compline.cosmosline') - - -- when: - cosmosline:validate() - end) -end) diff --git a/test/init.lua b/test/init.lua index 32fb963..56d5c97 100644 --- a/test/init.lua +++ b/test/init.lua @@ -24,11 +24,11 @@ vim.cmd([[packadd packer.nvim]]) require('packer').startup(function(use) use('wbthomason/packer.nvim') use({ - 'compline', + 'feline-theme', requires = { 'kyazdani42/nvim-web-devicons', 'famiu/feline.nvim', - 'tpope/vim-fugitive', + 'dokwork/lua-schema.nvim', }, }) end) @@ -39,16 +39,5 @@ if packer_bootstrap then else -- Configuration for test: - if vim.env.COSMOSLINE then - ---@diagnostic disable-next-line: unused-local - local config = require('compline.cosmosline') - -- :new('my_line', { - -- active = { left = { a = { [1] = 'test' } } }, - -- }) - -- vim.pretty_print(config:build_components()) - config:setup() - -- vim.pretty_print(config) - else - require('compline.example'):setup() - end + require('feline-theme').setup_statusline(require('feline-theme.example')) end diff --git a/test/schema_spec.lua b/test/schema_spec.lua index 5acc9f1..7742d2c 100644 --- a/test/schema_spec.lua +++ b/test/schema_spec.lua @@ -1,317 +1,120 @@ -local s = require('compline.schema') - -describe('validation the schema', function() - it('should be passed for every type', function() - assert(s.validate(s.const, s.type()), 'Wrong schema for the const') - assert(s.validate(s.list(), s.type()), 'Wrong schema for the list') - assert(s.validate(s.oneof(), s.type()), 'Wrong schema for the oneof') - assert(s.validate(s.table(), s.type()), 'Wrong schema for the table') - assert(s.validate(s.type(), s.type()), 'Wrong schema for the type') +local s = require('lua-schema') +local c = require('feline-theme.schema.colors') +local t = require('feline-theme.schema.theme') +local st = require('feline-theme.schema.statusline') +local feline = require('feline-theme.schema.feline') + +describe('feline schema validation', function() + it('should be passed for every object', function() + -- when: + for name, schema in pairs(feline) do + local ok, err = s.validate(schema, s.type) + + -- then: + assert( + ok, + string.format( + 'Error on validation schema of the %s.\nReason:\n%s\nSchema:\n%s', + name, + err, + vim.inspect(schema) + ) + ) + end end) - it('should be failed for invalide schema', function() - assert(not s.validate({ oNNeof = { 1, 2, 3 } }, s.type())) - assert(not s.validate({ lst = 'string' }, s.type())) - assert(not s.validate({ tbl = { key = true, value = true } }, s.type())) - assert(not s.validate({ table = { ky = true, value = true } }, s.type())) - assert(not s.validate({ table = { key = true, val = true } }, s.type())) - assert(not s.validate({ table = { key = true } }, s.type())) - assert(not s.validate({ cnst = 123 }, s.type())) + it('should be passed for highlight', function() + assert(s.validate('red', feline.highlight)) + assert(s.validate({ fg = 'red', bg = 'green' }, feline.highlight)) + -- example with a function + assert(s.validate(it, feline.highlight)) end) +end) - describe('of the constants', function() - it('should be passed for both syntax of constants', function() - -- when: - assert(s.validate('123', s.const)) - assert(s.validate({ const = '123' }, s.const)) - end) - - it('should be passed for particular value by the short schema', function() - -- given: - local schema = '123' - - -- then: - assert(s.validate('123', schema)) - assert(not s.validate('12', schema)) - assert(not s.validate(123, schema)) - end) - - it('should be passed for particular value by the full schema', function() - -- given: - local schema = { const = '123' } - - -- then: - assert(s.validate('123', schema)) - assert(not s.validate('12', schema)) - assert(not s.validate(123, schema)) - end) +describe('colors schema validation', function() + it('should be passed for every object', function() + -- when: + for name, schema in pairs(c) do + local ok, err = s.validate(schema, s.type) + + -- then: + assert( + ok, + string.format( + 'Error on validation schema of the %s.\nReason:\n%s\nSchema:\n%s', + name, + err, + vim.inspect(schema) + ) + ) + end end) +end) - describe('of the oneof', function() - it('should be passed for every option', function() - -- given: - local schema = { - oneof = { '123', 456, 'function', true, { table = { key = 'a', value = 1 } } }, - } - - -- then: - assert(s.validate('123', schema)) - assert(s.validate(456, schema)) - assert(s.validate(true, schema)) - assert(s.validate({ a = 1 }, schema)) - assert(s.validate(it, schema)) - end) - - it('should be failed when value is not in the list, or has wwrong type', function() - -- given: - local schema = { oneof = { '123', 456, true, { table = { key = 'a', value = 1 } } } } - - -- then: - assert(not s.validate('!123', schema)) - assert(not s.validate('true', schema)) - end) +describe('theme schema validation', function() + it('should be passed for every object', function() + -- when: + for name, schema in pairs(t) do + local ok, err = s.validate(schema, s.type) + + -- then: + assert( + ok, + string.format( + 'Error on validation schema of the %s.\nReason:\n%s\nSchema:\n%s', + name, + err, + vim.inspect(schema) + ) + ) + end end) +end) - describe('of the list', function() - it('should be passed for list with elements with valid type', function() - -- given: - local schema = { list = 'number' } - - -- when: - local ok, err = s.validate({ 1, 2, 3 }, schema) - - -- then: - assert(ok, tostring(err)) - end) - - it('should be passed for empty list', function() - -- given: - local schema = { list = 'number' } - - -- then: - assert(s.validate({}, schema)) - end) - - it('should not be passed for empty list', function() - -- given: - local schema = { list = 'number', non_empty = true } - - -- when: - local ok, err = s.validate({}, schema) - - -- then: - assert(not ok) - assert.are.same({}, err.object) - assert.are.same(schema, err.schema) - end) - - it('should be failed for list with element with wrong type', function() - -- given: - local schema = { list = 'number' } - - -- when: - local ok, err = s.validate({ 1, 2, '3' }, schema) - - -- then: - assert(not ok) - assert.are.same({ 1, 2, '3' }, err.object) - assert.are.same(schema, err.schema) - end) +describe('statusline schema validation', function() + it('should be passed for every object', function() + -- when: + for name, schema in pairs(st) do + local ok, err = s.validate(schema, s.type) + + -- then: + assert( + ok, + string.format( + 'Error on validation schema of the %s.\nReason:\n%s\nSchema:\n%s', + name, + err, + vim.inspect(schema) + ) + ) + end end) - describe('of the table', function() - it('should be passed for a valid table', function() - -- given: - local schema = { table = { key = 'string', value = 'string' } } - - -- when: - local ok, err = s.validate({ a = 'b' }, schema) - - -- then: - assert(ok, tostring(err)) - end) - - it('should validate type of keys', function() - -- given: - local schema = { table = { key = 'string', value = 'number' } } - - -- then: - assert(not s.validate({ 1, 2 }, schema)) - end) + it('should be passed for the zone', function() + -- given: + local zone = { + a = { 'str' }, + } - it('should validate type of values', function() - -- given: - local schema = { table = { key = 'string', value = 'number' } } + -- when + local ok, err = s.validate(zone, st.zone) - -- when: - local ok, err = s.validate({ a = 'str' }, schema) - - -- then: - assert(not ok) - assert.are.same({ a = 'str' }, err.object) - assert.are.same({ table = { { key = 'string', value = 'number' } } }, err.schema) - end) - - it('should support oneof as a type of keys', function() - -- given: - local schema = { table = { key = { oneof = { 'a', 'b' } }, value = 'string' } } - - -- then: - assert(s.validate({ a = 'a' }, schema)) - assert(s.validate({ b = 'b' }, schema)) - assert(not s.validate({ c = 'c' }, schema)) - end) - - it('should check other key options if oneof failed', function() - -- given: - local schema = { - table = { - { key = { oneof = { 'a', 'b' } }, value = 'string' }, - { key = 'string', value = 'boolean' }, - }, - } - - -- when: - local ok, err = s.validate({ c = true }, schema) - - -- then: - assert(ok, tostring(err)) - end) - - it('should not be passed when required oneof was not satisfied', function() - -- given: - local schema = { - table = { - { key = { oneof = { 'a', 'b' } }, value = 'string', required = true }, - { key = 'string', value = 'boolean' }, - }, - } - - -- when: - local ok, err = s.validate({ c = true }, schema) - - -- then: - assert(not ok) - - assert.are.same({ c = '?' }, err.object) - assert.are.same({ - table = { { key = { oneof = { 'a', 'b' } } } }, - }, err.schema) - end) - - it('should support oneof as a type of values', function() - -- given: - local schema = { table = { key = 'string', value = { oneof = { 'a', 'b' } } } } - - -- then: - assert(s.validate({ a = 'a' }, schema)) - assert(s.validate({ a = 'b' }, schema)) - assert(not s.validate({ a = 'c' }, schema)) - end) - - it('should support const as a type of keys', function() - -- given: - local schema = { - table = { - { key = 'a', value = 'number' }, - { key = 'b', value = 'boolean' }, - }, - } - - -- when: - local ok, err = s.validate({ a = 1, b = true }, schema) - - -- then: - assert(ok, tostring(err)) - assert(not s.validate({ a = 'str', b = true }, schema)) - assert(not s.validate({ a = 1, b = 1 }, schema)) - end) - - it('should be passed for missed optional keys', function() - -- given: - local schema = { - table = { - { key = 'a', value = 'number' }, - { key = 'b', value = 'boolean', required = true }, - }, - } - - -- then: - assert(s.validate({ b = true }, schema)) - end) - - it('should be failed for missed required keys', function() - -- given: - local schema = { - table = { - { key = 'a', value = 'number' }, - { key = 'b', value = 'boolean', required = true }, - }, - } - - -- then: - assert(not s.validate({ a = 1 }, schema)) - end) - - it('should support mix of const and other types', function() - -- given: - local schema = { - table = { - { key = 'a', value = 'number' }, - { key = 'string', value = 'boolean' }, - }, - } - - -- when: - local ok, err = s.validate({ a = 1, str = true }, schema) - - -- then: - assert(ok, tostring(err)) - end) - - it('should support table as a value', function() - -- given: - local schema = { - table = { - { - key = 'a', - value = { - table = { key = 'b', value = 'number' }, - }, - }, - }, - } - - -- when: - local ok, err = s.validate({ a = { b = 1 } }, schema) - - -- then: - assert(ok, tostring(err)) - end) + -- then: + assert(ok, tostring(err)) + end) - it('should correctly compose error for nested tables', function() - -- given: - local schema = { - table = { - { - key = 'a', - value = { - table = { key = 'b', value = 'number' }, - }, - }, - }, - } + it('should be passed for the line', function() + -- given: + local line = { + left = { + a = { 'str' }, + }, + } - -- when: - local ok, err = s.validate({ a = { c = 1 } }, schema) + -- when + local ok, err = s.validate(line, st.line) - -- then: - assert(not ok) - assert.are.same({ a = { c = '?' } }, err.object) - assert.are.same( - { table = { { key = 'a', value = { table = { { key = 'b' } } } } } }, - err.schema - ) - end) + -- then: + assert(ok, tostring(err)) end) end) diff --git a/test/statusline_schema_spec.lua b/test/statusline_schema_spec.lua deleted file mode 100644 index 4f7ec0b..0000000 --- a/test/statusline_schema_spec.lua +++ /dev/null @@ -1,109 +0,0 @@ -local s = require('compline.schema') -local ss = require('compline.schema.statusline') -local st = require('compline.schema.theme') -local sf = require('compline.schema.feline') - -describe('feline schema validation', function() - it('should be passed for highlight', function() - assert(s.validate('red', sf.highlight)) - assert(s.validate({ fg = 'red', bg = 'green' }, sf.highlight)) - -- example with a function - assert(s.validate(it, sf.highlight)) - end) -end) - -describe('theme schema validation', function() - it('should be passed for colors', function() - -- when: - local ok, err = s.validate(st.colors, s.type) - - -- then: - assert(ok, tostring(err)) - end) - - it('should be passed for vi_mode', function() - -- when: - local ok, err = s.validate(st.vi_mode, s.type) - - -- then: - assert(ok, tostring(err)) - end) - - it('should be passed for separator', function() - -- when: - local ok, err = s.validate(st.separator, s.type) - - -- then: - assert(ok, tostring(err)) - end) - - it('should be passed for sections', function() - -- when: - local ok, err = s.validate(st.sections, s.type) - - -- then: - assert(ok, tostring(err)) - end) - - it('should be passed for zone', function() - -- when: - local ok, err = s.validate(st.zone, s.type) - - -- then: - assert(ok, tostring(err)) - end) - - it('should be passed for line', function() - -- when: - local ok, err = s.validate(st.line, s.type) - - -- then: - assert(ok, tostring(err)) - end) - - it('should be passed for whole theme', function() - -- when: - local ok, err = s.validate(st.theme, s.type) - - -- then: - assert(ok, tostring(err)) - end) -end) - -describe('statusline schema validation', function() - it('should be passed for the zone', function() - -- given: - local zone = { - a = { 'str' }, - } - - -- when - local ok, err = s.validate(zone, ss.zone) - - -- then: - assert(ok, tostring(err)) - end) - - it('should be passed for the line', function() - -- given: - local line = { - left = { - a = { 'str' }, - }, - } - - -- when - local ok, err = s.validate(line, ss.line) - - -- then: - assert(ok, tostring(err)) - end) - - it('should be passed for whole statusline', function() - -- when: - local ok, err = s.validate(ss.statusline, s.type) - - -- then: - assert(ok, tostring(err)) - end) -end) diff --git a/test/statusline_spec.lua b/test/statusline_spec.lua index 5c6e2e5..2bfaf33 100644 --- a/test/statusline_spec.lua +++ b/test/statusline_spec.lua @@ -1,14 +1,53 @@ -local Statusline = require('compline.statusline') +local FelineTheme = require('feline-theme') describe('Building componentns', function() + it('should resolve components by their names', function() + -- given: + local components = { + some_component = { provider = 'example', hl = 'ComponentHighlight' }, + } + local statusline = FelineTheme.setup_statusline({ + active = { + left = { + a = { 'some_component' }, + }, + }, + components = components, + }) + + -- when: + local result = statusline:build_components() + + -- then: + local expected = { + active = { + { + { name = 'some_component', provider = 'example', hl = 'ComponentHighlight' }, + }, + {}, + {}, + }, + } + local msg = string.format( + '\nExpected:\n%s\nActual:\n%s', + vim.inspect(expected), + vim.inspect(result) + ) + assert.are.same(expected, result, msg) + end) + it('should build components and sections in correct order', function() -- given: - local statusline = Statusline:new('test', { + local statusline = FelineTheme.setup_statusline({ active = { left = { b = { 'b', 'c' }, a = { 'a' }, }, + right = { + z = { 'z' }, + w = { 'w' }, + }, }, }) @@ -19,12 +58,15 @@ describe('Building componentns', function() local expected = { active = { { - { provider = 'a' }, - { provider = 'b' }, - { provider = 'c' }, + { name = 'a', provider = 'a' }, + { name = 'b', provider = 'b' }, + { name = 'c', provider = 'c' }, }, {}, - {}, + { + { name = 'w', provider = 'w' }, + { name = 'z', provider = 'z' }, + }, }, } local msg = string.format( @@ -34,19 +76,18 @@ describe('Building componentns', function() ) assert.are.same(expected, result, msg) end) +end) - it('should resolve components by their names', function() +describe('Resolving highlights', function() + it('should use default hl if nothing specified in the theme', function() -- given: - local components = { - some_component = { provider = 'example' }, - } - local statusline = Statusline:new('test', { + local statusline = FelineTheme.setup_statusline({ active = { left = { a = { 'some_component' }, }, }, - components = components, + theme = {}, }) -- when: @@ -56,7 +97,10 @@ describe('Building componentns', function() local expected = { active = { { - { provider = 'example' }, + { + name = 'some_component', + provider = 'some_component', + }, }, {}, {}, @@ -72,28 +116,24 @@ describe('Building componentns', function() it('should add hl to components from the theme', function() -- given: - local components = { - some_component = { provider = 'example' }, - } + local components = {} local theme = { active = { left = { - sections = { - a = { hl = { fg = 'black', bg = 'whignoree' } }, - }, + a = { hl = 'CustomHighlight' }, + b = { hl = { bg = 'white' } }, }, }, } - local statusline = Statusline:new('test', { + local statusline = FelineTheme.setup_statusline({ active = { left = { - a = { 'some_component' }, + a = { 'some_component_1' }, + b = { 'some_component_2' }, }, }, components = components, - themes = { - default = theme, - }, + theme = theme, }) -- when: @@ -103,7 +143,16 @@ describe('Building componentns', function() local expected = { active = { { - { provider = 'example', hl = { fg = 'black', bg = 'whignoree' } }, + { + name = 'some_component_1', + provider = 'some_component_1', + hl = 'CustomHighlight', + }, + { + name = 'some_component_2', + provider = 'some_component_2', + hl = { bg = 'white' }, + }, }, {}, {}, @@ -116,31 +165,26 @@ describe('Building componentns', function() ) assert.are.same(expected, result, msg) end) +end) - it("should use hl from a component when ignore's specified", function() +describe('Resolving separators', function() + it("should add always visible zone's separators for the first and last components", function() -- given: - local components = { - some_component = { provider = 'example', hl = { fg = 'red' } }, - } local theme = { active = { left = { - sections = { - a = { hl = { fg = 'black', bg = 'whignoree' } }, - }, + separators = { left = '<', right = { str = '>', hl = { fg = 'red' } } }, }, }, } - local statusline = Statusline:new('test', { + local statusline = FelineTheme.setup_statusline({ active = { left = { - a = { 'some_component' }, + a = { 'first' }, + b = { 'other', 'last' }, }, }, - components = components, - themes = { - default = theme, - }, + theme = theme, }) -- when: @@ -150,7 +194,22 @@ describe('Building componentns', function() local expected = { active = { { - { provider = 'example', hl = { fg = 'red' } }, + { + name = 'first', + provider = 'first', + + left_sep = { str = '<', always_visible = true }, + }, + { + name = 'other', + provider = 'other', + }, + { + name = 'last', + provider = 'last', + + right_sep = { str = '>', hl = { fg = 'red' }, always_visible = true }, + }, }, {}, {}, @@ -164,20 +223,24 @@ describe('Building componentns', function() assert.are.same(expected, result, msg) end) - it("should create components for zone's separators", function() + it("should add section's separators to the first and last components", function() -- given: local theme = { active = { left = { - zone_separators = { left = '<', right = { '>', hl = 'red' } }, + a = { + separators = { left = '<', right = '>' }, + }, }, }, } - local statusline = Statusline:new('test', { - active = { left = { a = { 'test' } } }, - themes = { - default = theme, + local statusline = FelineTheme.setup_statusline({ + active = { + left = { + a = { 'first', 'test', 'last' }, + }, }, + theme = theme, }) -- when: @@ -187,9 +250,20 @@ describe('Building componentns', function() local expected = { active = { { - { provider = '<' }, - { provider = 'test' }, - { provider = '>', hl = 'red' }, + { + name = 'first', + provider = 'first', + left_sep = '<', + }, + { + name = 'test', + provider = 'test', + }, + { + name = 'last', + provider = 'last', + right_sep = '>', + }, }, {}, {}, @@ -203,26 +277,25 @@ describe('Building componentns', function() assert.are.same(expected, result, msg) end) - it("should add section's separators to the outside components", function() + it("zone's separators must override sections separators", function() -- given: local theme = { active = { left = { - sections = { - a = { ls = '<', rs = { '>', hl = 'green' } }, - }, + separators = { right = '>' }, + a = { separators = { left = '[' } }, + b = { separators = { right = ']' } }, }, }, } - local statusline = Statusline:new('test', { - themes = { - default = theme, - }, + local statusline = FelineTheme.setup_statusline({ active = { left = { - a = { 'test' }, + a = { 'test 1' }, + b = { 'test 2' }, }, }, + theme = theme, }) -- when: @@ -233,9 +306,14 @@ describe('Building componentns', function() active = { { { - provider = 'test', - left_sep = { str = '<' }, - right_sep = { str = '>', hl = 'green' }, + name = 'test 1', + provider = 'test 1', + left_sep = '[', + }, + { + name = 'test 2', + provider = 'test 2', + right_sep = { str = '>', always_visible = true }, }, }, {}, @@ -249,38 +327,38 @@ describe('Building componentns', function() ) assert.are.same(expected, result, msg) end) -end) - -describe('Extending an existing statusline', function() - local existed_statusline = Statusline:new('existed', { - active = { - left = { - a = { 'component 1', 'component 2' }, - b = { 'component 3' }, - }, - }, - }) - it('should override the section', function() + it('should use separators from the components', function() -- given: - local new_statusline = existed_statusline:new('new', { + local components = { + test = { + provider = 'test', + left_sep = '<', + right_sep = { str = '>' }, + }, + } + local statusline = FelineTheme.setup_statusline({ active = { left = { - a = { 'component 1', 'new' }, + a = { 'test' }, }, }, + components = components, }) -- when: - local result = new_statusline:build_components() + local result = statusline:build_components() -- then: local expected = { active = { { - { provider = 'component 1' }, - { provider = 'new' }, - { provider = 'component 3' }, + { + name = 'test', + provider = 'test', + left_sep = '<', + right_sep = { str = '>' }, + }, }, {}, {}, @@ -294,24 +372,46 @@ describe('Extending an existing statusline', function() assert.are.same(expected, result, msg) end) - it('should remove the section', function() + it("components's separators must override section's separators", function() -- given: - local new_statusline = existed_statusline:new('new', { + local theme = { + active = { + left = { + a = { separators = { left = '[', right = ']' } }, + }, + }, + } + local components = { + test = { + provider = 'test', + left_sep = '<', + right_sep = '>', + }, + } + local statusline = FelineTheme.setup_statusline({ active = { left = { - a = 'nil', - b = 'nil', + a = { 'test' }, }, }, + theme = theme, + components = components, }) -- when: - local result = new_statusline:build_components() + local result = statusline:build_components() -- then: local expected = { active = { - {}, + { + { + name = 'test', + provider = 'test', + left_sep = '<', + right_sep = '>', + }, + }, {}, {}, }, @@ -324,28 +424,46 @@ describe('Extending an existing statusline', function() assert.are.same(expected, result, msg) end) - it('should remove active components and add inactive', function() + it("components's separators must override zone's separators", function() -- given: - local new_statusline = existed_statusline:new('new', { - active = 'nil', - inactive = { - right = { - a = { 'new' }, + local theme = { + active = { + separators = { left = '[', right = ']' }, + }, + } + local components = { + test = { + provider = 'test', + left_sep = '<', + right_sep = '>', + }, + } + local statusline = FelineTheme.setup_statusline({ + active = { + left = { + a = { 'test' }, }, }, + theme = theme, + components = components, }) -- when: - local result = new_statusline:build_components() + local result = statusline:build_components() -- then: local expected = { - inactive = { - {}, - {}, + active = { { - { provider = 'new' }, + { + name = 'test', + provider = 'test', + left_sep = '<', + right_sep = '>', + }, }, + {}, + {}, }, } local msg = string.format( diff --git a/test/try.sh b/test/try.sh index 4a06f39..ca6d2da 100755 --- a/test/try.sh +++ b/test/try.sh @@ -6,8 +6,8 @@ # got to the directory with this script (./test/): cd $(dirname ${BASH_SOURCE[0]}) -export XDG_CONFIG_HOME='/tmp/compline.nvim/conf' -export XDG_DATA_HOME='/tmp/compline.nvim/data' +export XDG_CONFIG_HOME='/tmp/feline-theme/conf' +export XDG_DATA_HOME='/tmp/feline-theme/data' ARG=$1 @@ -19,12 +19,6 @@ if [ "$ARG" == "--reset" ]; then fi -if [ "$ARG" == "--cosmosline" ]; then - - ARG='' - export COSMOSLINE="1" -fi - mkdir -p $XDG_CONFIG_HOME mkdir -p $XDG_DATA_HOME nvim -u init.lua --cmd 'set rtp='$XDG_DATA_HOME',$VIMRUNTIME,'$XDG_CONFIG_HOME $ARG diff --git a/test/utils_spec.lua b/test/utils_spec.lua index 1c83655..bb5f4a3 100644 --- a/test/utils_spec.lua +++ b/test/utils_spec.lua @@ -1,5 +1,4 @@ -local test = require('compline.test') -local u = require('compline.utils') +local u = require('feline-theme.utils') describe('is_empty', function() it('should return true for nil', function() @@ -29,65 +28,53 @@ describe('iterate with sorted keys', function() end) end) -describe('lsp_client', function() - it('should return the first attached to the current buffer client', function() - -- given: - local clients = { { name = 'first' }, { name = 'second' } } - local mock = function() - return clients - end - test.use_mocked_table(vim.lsp, 'buf_get_clients', mock, function() - -- when: - local result = u.lsp_client() +describe('colors utilities', function() + describe('create a color', function() + it('should create string with color', function() + -- given: + local r, g, b = 0, 0, 0 -- then: - assert.are.same({ name = 'first' }, result) + assert.are.equal('#000000', u.create_color(r, g, b)) end) end) -end) -describe('lsp_client_icon', function() - it('should find the icon for the client by the filetype', function() - -- given: - local client = { config = { filetypes = { 'other_type', 'test' } } } - local icon = { name = 'test', icon = '!' } + describe('parse RGB color', function() + it('should return numbers for every part of the color', function() + -- given: + local color = '#11AA4B' - -- when: - local result = u.lsp_client_icon({ test = icon }, client) + -- when: + local r, g, b = u.parse_rgb_color(color) - -- then: - assert.are.same(icon, result) + -- then: + assert.are.equal(17, r) + assert.are.equal(170, g) + assert.are.equal(75, b) + end) end) - it('should find the icon for the first attached client', function() - -- given: - local client = { config = { filetypes = { 'other_type', 'test' } } } - local icon = { name = 'test', icon = '!' } - local mock = function() - return { client } - end - test.use_mocked_table(vim.lsp, 'buf_get_clients', mock, function() + describe('changing a brightness of a color', function() + it('should make a color lighter', function() + -- given: + local color = '#9e6f11' + -- when: - local result = u.lsp_client_icon({ test = icon }) + local light_color = u.ligthening_color(color) -- then: - assert.are.same(icon, result) + assert.are.equal('#a77d28', light_color) end) - end) - it('should take an icon from the "nvim-web-devicons"', function() - -- given: - local client = { config = { filetypes = { 'other_type', 'test' } } } - local icon = { name = 'test', icon = '!' } - local mock = function() - return { test = icon } - end - test.use_mocked_module('nvim-web-devicons', 'get_icons', mock, function() + it('should make a color darker', function() + -- given: + local color = '#9e6f11' + -- when: - local result = u.lsp_client_icon({}, client) + local light_color = u.darkening_color(color) -- then: - assert.are.same(icon, result) + assert.are.equal('#8e630f', light_color) end) end) end)