From 682732e4c82d50f533961ff36a8fbeea4e22aadf Mon Sep 17 00:00:00 2001 From: Gaetan Lepage Date: Sat, 20 Jan 2024 16:19:25 +0100 Subject: [PATCH] plugins/airline: switch to mkPlugin + refactoring --- plugins/statuslines/airline.nix | 454 +++++++++++++++--- .../plugins/statuslines/airline.nix | 82 ++++ 2 files changed, 458 insertions(+), 78 deletions(-) create mode 100644 tests/test-sources/plugins/statuslines/airline.nix diff --git a/plugins/statuslines/airline.nix b/plugins/statuslines/airline.nix index ecfccf87..3778c566 100644 --- a/plugins/statuslines/airline.nix +++ b/plugins/statuslines/airline.nix @@ -1,86 +1,384 @@ { lib, - helpers, - config, pkgs, ... -}: -with lib; let - cfg = config.plugins.airline; +} @ args: +with lib; +with import ../helpers.nix {inherit lib;}; + mkPlugin args { + name = "airline"; + description = "vim-airline"; + package = pkgs.vimPlugins.vim-airline; + globalPrefix = "airline_"; - sectionType = with types; nullOr (oneOf [str (listOf str)]); - sectionOption = mkOption { - default = null; - type = sectionType; - description = "Configuration for this section. Can be either a statusline-format string or a list of modules to be passed to airline#section#create_*."; - }; -in { - options = { - plugins.airline = { - enable = mkEnableOption "airline"; + options = + ( + listToAttrs ( + map + ( + name: + nameValuePair + "section${toUpper name}" + (mkDefaultOpt { + global = "section_${name}"; + type = with types; + oneOf + [ + str + (listOf str) + (attrsOf anything) + ]; + description = "Configuration for this section."; + }) + ) + ["a" "b" "c" "x" "y" "z"] + ) + ) + // { + experimental = mkDefaultOpt { + description = '' + Enable experimental features. + Currently: Enable Vim9 Script implementation. - package = helpers.mkPackageOption "airline" pkgs.vimPlugins.vim-airline; + Default: `true` + ''; + type = types.bool; + }; - extensions = mkOption { - default = null; - type = with types; nullOr attrs; - description = "A list of extensions and their configuration"; + leftSep = mkDefaultOpt { + global = "left_sep"; + description = '' + The separator used on the left side. + + Default: ">" + ''; + type = types.str; + }; + + rightSep = mkDefaultOpt { + global = "right_sep"; + description = '' + The separator used on the right side. + + Default: "<" + ''; + type = types.str; + }; + + detectModified = mkDefaultOpt { + global = "detect_modified"; + description = '' + Enable modified detection. + + Default: `true` + ''; + type = types.bool; + }; + + detectPaste = mkDefaultOpt { + global = "detect_paste"; + description = '' + Enable paste detection. + + Default: `true` + ''; + type = types.bool; + }; + + detectCrypt = mkDefaultOpt { + global = "detect_crypt"; + description = '' + Enable crypt detection. + + Default: `true` + ''; + type = types.bool; + }; + + detectSpell = mkDefaultOpt { + global = "detect_spell"; + description = '' + Enable spell detection. + + Default: `true` + ''; + type = types.bool; + }; + + detectSpelllang = mkDefaultOpt { + global = "detect_spelllang"; + description = '' + Display spelling language when spell detection is enabled (if enough space is available). + + Set to 'flag' to get a unicode icon of the relevant country flag instead of the + 'spelllang' itself. + + Default: `true` + ''; + type = with types; either bool (enum ["flag"]); + }; + + detectIminsert = mkDefaultOpt { + global = "detect_iminsert"; + description = '' + Enable iminsert detection. + + Default: `false` + ''; + type = types.bool; + }; + + inactiveCollapse = mkDefaultOpt { + global = "inactive_collapse"; + description = '' + Determine whether inactive windows should have the left section collapsed to only the + filename of that buffer. + + Default: `true` + ''; + type = types.bool; + }; + + inactiveAltSep = mkDefaultOpt { + global = "inactive_alt_sep"; + description = '' + Use alternative separators for the statusline of inactive windows. + + Default: `true` + ''; + type = types.bool; + }; + + theme = mkDefaultOpt { + description = '' + Themes are automatically selected based on the matching colorscheme. + This can be overridden by defining a value. + + Note: Only the dark theme is distributed with vim-airline. + For more themes, checkout the vim-airline-themes repository + (https://github.com/vim-airline/vim-airline-themes) + + Default: "dark" + ''; + type = types.str; + }; + + themePatchFunc = mkDefaultOpt { + global = "theme_patch_func"; + description = '' + If you want to patch the airline theme before it gets applied, you can supply the name of + a function where you can modify the palette. + + Example: "AirlineThemePatch" + + Then, define this function using `extraConfigVim`: + ```nix + extraConfigVim = \'\' + function! AirlineThemePatch(palette) + if g:airline_theme == 'badwolf' + for colors in values(a:palette.inactive) + let colors[3] = 245 + endfor + endif + endfunction + \'\'; + ``` + ''; + type = types.str; + }; + + powerlineFonts = mkDefaultOpt { + global = "powerline_fonts"; + description = '' + By default, airline will use unicode symbols if your encoding matches utf-8. + If you want the powerline symbols set this variable to `true`. + + Default: `false` + ''; + type = types.bool; + }; + + symbolsAscii = mkDefaultOpt { + global = "symbols_ascii"; + description = '' + By default, airline will use unicode symbols if your encoding matches utf-8. + If you want to use plain ascii symbols, set this variable: > + + Default: `false` + ''; + type = types.bool; + }; + + modeMap = mkDefaultOpt { + global = "mode_map"; + description = '' + Define the set of text to display for each mode. + + Default: see source + ''; + type = with types; attrsOf str; + }; + + excludeFilenames = mkDefaultOpt { + global = "exclude_filenames"; + description = '' + Define the set of filename match queries which excludes a window from having its + statusline modified. + + Default: see source for current list + ''; + type = with types; listOf str; + }; + + excludeFiletypes = mkDefaultOpt { + global = "exclude_filetypes"; + description = '' + Define the set of filetypes which are excluded from having its window statusline modified. + + Default: see source for current list + ''; + type = with types; listOf str; + }; + + filetypeOverrides = mkDefaultOpt { + global = "filetype_overrides"; + description = '' + Define the set of names to be displayed instead of a specific filetypes. + + Example: + ```nix + { + coc-explorer = ["CoC Explorer" ""]; + defx = ["defx" "%{b:defx.paths[0]}"]; + fugitive = ["fugitive" "%{airline#util#wrap(airline#extensions#branch#get_head(),80)}"]; + gundo = ["Gundo" "" ]; + help = ["Help" "%f"]; + minibufexpl = ["MiniBufExplorer" ""]; + startify = ["startify" ""]; + vim-plug = ["Plugins" ""]; + vimfiler = ["vimfiler" "%{vimfiler#get_status_string()}"]; + vimshell = ["vimshell" "%{vimshell#get_status_string()}"]; + vaffle = ["Vaffle" "%{b:vaffle.dir}"]; + } + ``` + ''; + type = with types; attrsOf (listOf str); + }; + + excludePreview = mkDefaultOpt { + global = "exclude_filenames"; + description = '' + Defines whether the preview window should be excluded from having its window statusline + modified (may help with plugins which use the preview window heavily). + + Default: `false` + ''; + type = types.bool; + }; + + disableStatusline = mkDefaultOpt { + global = "disable_statusline"; + description = '' + Disable the Airline statusline customization globally. + + This setting disables setting the 'statusline' option. + This allows to use e.g. the tabline extension (`|airline-tabline|`) but keep the + 'statusline' option totally configurable by a custom configuration. + + Default: `false` + ''; + type = types.bool; + }; + + skipEmptySections = mkDefaultOpt { + global = "skip_empty_sections"; + description = '' + Do not draw separators for empty sections (only for the active window). + + Default: `true` + ''; + type = types.bool; + }; + + highlightingCache = mkDefaultOpt { + global = "highlighting_cache"; + description = '' + Caches the changes to the highlighting groups, should therefore be faster. + Set this to one, if you experience a sluggish Vim. + + Default: `false` + ''; + type = types.bool; + }; + + focuslostInactive = mkDefaultOpt { + global = "focuslost_inactive"; + description = '' + Disable airline on FocusLost autocommand (e.g. when Vim loses focus). + + Default: `false` + ''; + type = types.bool; + }; + + statuslineOntop = mkDefaultOpt { + global = "statusline_ontop"; + description = '' + Display the statusline in the tabline (first top line). + + Setting this option, allows to use the statusline option to be used by a custom function + or another plugin, since airline won't change it. + + Note: This setting is experimental and works on a best effort approach. + Updating the statusline might not always happen as fast as needed, but that is a + limitation, that comes from Vim. + airline tries to force an update if needed, but it might not always work as expected. + To force updating the tabline on mode changes, call `airline#check_mode()` in your custom + statusline setting: `:set stl=%!airline#check_mode(winnr())` will correctly update the + tabline on mode changes. + + Default: `false` + ''; + type = types.bool; + }; + + stlPathStyle = mkDefaultOpt { + global = "stl_path_style"; + description = '' + Display a short path in statusline. + + Default: "short" + ''; + type = types.str; + }; + + sectionCOnlyFilename = mkDefaultOpt { + global = "section_c_only_filename"; + description = '' + Display a only file name in statusline. + + Default: `true` + ''; + type = types.bool; + }; + + symbols = mkDefaultOpt { + description = '' + Customize airline symbols. + + Example: + ```nix + { + branch = ""; + colnr = " ℅:"; + readonly = ""; + linenr = " :"; + maxlinenr = "☰ "; + dirty= "⚡"; + } + ``` + ''; + type = with types; attrsOf str; + }; }; - - onTop = mkOption { - default = false; - type = types.bool; - description = "Whether to show the statusline on the top instead of the bottom"; - }; - - sections = mkOption { - description = "Statusbar sections"; - default = null; - type = with types; - nullOr (submodule { - options = { - a = sectionOption; - b = sectionOption; - c = sectionOption; - x = sectionOption; - y = sectionOption; - z = sectionOption; - }; - }); - }; - - powerline = mkOption { - default = false; - type = types.bool; - description = "Whether to use powerline symbols"; - }; - - theme = mkOption { - default = config.colorscheme; - type = with types; nullOr str; - description = "The theme to use for vim-airline. If set, vim-airline-themes will be installed."; - }; - }; - }; - - config = let - sections = {}; - in - mkIf cfg.enable { - extraPlugins = with pkgs.vimPlugins; - [ - cfg.package - ] - ++ optional (cfg.theme != null) vim-airline-themes; - globals = - { - airline.extensions = cfg.extensions; - - airline_statusline_ontop = mkIf cfg.onTop 1; - airline_powerline_fonts = mkIf cfg.powerline 1; - - airline_theme = mkIf (cfg.theme != null) cfg.theme; - } - // sections; - }; -} + } diff --git a/tests/test-sources/plugins/statuslines/airline.nix b/tests/test-sources/plugins/statuslines/airline.nix new file mode 100644 index 00000000..3f89c883 --- /dev/null +++ b/tests/test-sources/plugins/statuslines/airline.nix @@ -0,0 +1,82 @@ +{ + empty = { + plugins.airline.enable = true; + }; + + example = { + plugins.airline = { + enable = true; + + sectionA = "foo"; + sectionB = "foo"; + sectionC = "foo"; + sectionX = "foo"; + sectionY = "foo"; + sectionZ = "foo"; + experimental = true; + leftSep = ">"; + rightSep = "<"; + detectModified = true; + detectPaste = true; + detectCrypt = true; + detectSpell = true; + detectSpelllang = true; + detectIminsert = false; + inactiveCollapse = true; + inactiveAltSep = true; + theme = "dark"; + themePatchFunc = null; + powerlineFonts = false; + symbolsAscii = false; + modeMap = { + __ = "-"; + c = "C"; + i = "I"; + ic = "I"; + ix = "I"; + n = "N"; + multi = "M"; + ni = "N"; + no = "N"; + R = "R"; + Rv = "R"; + s = "S"; + S = "S"; + t = "T"; + v = "V"; + V = "V"; + }; + excludeFilenames = []; + excludeFiletypes = []; + filetypeOverrides = { + coc-explorer = ["CoC Explorer" ""]; + defx = ["defx" "%{b:defx.paths[0]}"]; + fugitive = ["fugitive" "%{airline#util#wrap(airline#extensions#branch#get_head(),80)}"]; + gundo = ["Gundo" ""]; + help = ["Help" "%f"]; + minibufexpl = ["MiniBufExplorer" ""]; + startify = ["startify" ""]; + vim-plug = ["Plugins" ""]; + vimfiler = ["vimfiler" "%{vimfiler#get_status_string()}"]; + vimshell = ["vimshell" "%{vimshell#get_status_string()}"]; + vaffle = ["Vaffle" "%{b:vaffle.dir}"]; + }; + excludePreview = false; + disableStatusline = false; + skipEmptySections = true; + highlightingCache = false; + focuslostInactive = false; + statuslineOntop = false; + stlPathStyle = "short"; + sectionCOnlyFilename = true; + symbols = { + branch = ""; + colnr = " ℅:"; + readonly = ""; + linenr = " :"; + maxlinenr = "☰ "; + dirty = "⚡"; + }; + }; + }; +}