andreyorst / powerline.kak

Kakoune modeline, but with passion
MIT License
50 stars 8 forks source link

Add a base to separators' colours, to fix transparency #23

Closed Qeole closed 2 years ago

Qeole commented 2 years ago

Breaking change

no

The new face has no attributes or underline colour set, therefore it should not change the appearance of any opaque colour applied on top of it. For transparent colours, it should harmonise the colours of the separators with the colours of the rest of the segments.

Description

Define a new powerline_base face with the default background colour as both background and foreground, and use it as a base when passing the faces for the separators between the different segments of the Powerline.

Kakoune supports transparent colours in faces. If:

1) the background colour used for this base (through %opt{powerline_base_bg}, usually alined on %opt{powerline_color08}) is an RGB colour defined as rgb:RRGGBB or rgba::RRGGBBAA 2) colours applied on top of it, for example powerline_color03 for the bufname background, have an alpha value set

... Then transparency can be applied even to the background colour for the segment, resulting in the blending of powerline_color03 with the buffer background colour.

One use case, for example, is to build a colour theme for the modeline with different shades from a single colour, playing on the values of the alpha channel. Such a scheme presents two advantages: first, we do not have to pick individual colours for each segment background. Finding a single hexadecimal code is enough (and we can even reuse some colours from Kakoune's current colour scheme). Secondly, this theme is trivial to adapt when we switch to a different Kakoune colour scheme.

Let's consider the following example, relying on a colour scheme for Kakoune that defines a colour named black and uses it as a background colour for the buffer, and a white colour for its foreground. This is the case, for example, of several themes available here (although black is commented by default so that users can keep their terminal's background colour). We can define the following Powerline theme:

hook global ModuleLoaded powerline %{ require-module powerline_test }
provide-module powerline_test %§
set-option -add global powerline_themes "test"
define-command -hidden powerline-theme-test %{
    define-command -hidden powerline-theme-recolor %{

        # Extract the hexadecimal code for "black" and "white"
        declare-option -hidden str whitergb %sh{ color=$kak_opt_white; printf "%s" "${color#rgb:}" }
        declare-option -hidden str blackrgb %sh{ color=$kak_opt_black; printf "%s" "${color#rgb:}" }
        declare-option -hidden str powerline_color02 "rgba:%opt{blackrgb}ff" # fg: git
        declare-option -hidden str powerline_color04 "rgba:%opt{whitergb}ff" # bg: git
        declare-option -hidden str powerline_color00 "rgba:%opt{blackrgb}ff" # fg: bufname
        declare-option -hidden str powerline_color03 "rgba:%opt{whitergb}a0" # bg: bufname
        declare-option -hidden str powerline_color06 "rgba:%opt{whitergb}ff" # fg: line-column, lsp
        declare-option -hidden str powerline_color09 "rgba:%opt{whitergb}40" # bg: line-column, lsp
        declare-option -hidden str powerline_color07 "rgba:%opt{blackrgb}ff" # fg: mode-info
        declare-option -hidden str powerline_color08 "rgba:%opt{blackrgb}ff" # base background, bg: mode-info
        declare-option -hidden str powerline_color10 "rgba:%opt{blackrgb}ff" # fg: filetype
        declare-option -hidden str powerline_color11 "rgba:%opt{whitergb}aa" # bg: filetype
        declare-option -hidden str powerline_color13 "rgba:%opt{whitergb}ff" # fg: client
        declare-option -hidden str powerline_color12 "rgba:%opt{whitergb}40" # bg: client
        declare-option -hidden str powerline_color15 "rgba:%opt{blackrgb}ff" # fg: session
        declare-option -hidden str powerline_color14 "rgba:%opt{whitergb}a0" # bg: session
        declare-option -hidden str powerline_color05 "rgba:%opt{blackrgb}ff" # fg: position
        declare-option -hidden str powerline_color01 "rgba:%opt{whitergb}ff" # bg: position

        declare-option -hidden str powerline_next_bg %opt{powerline_color08}
        declare-option -hidden str powerline_base_bg %opt{powerline_color08}
    }
    powerline-theme-recolor
}
§

This way, we create a Powerline theme that is automatically adjusted to the colour scheme that Kakoune uses on startup. We can replace the call to "powerline-theme-recolor" with the following:

    hook global BufSetOption ^black=.* %{
        powerline-theme-recolor
        powerline-rebuild-buffer
    }

This time, we even recompute the colours when the main colour scheme changes (in practice, when the black option changes): switching from ayu-dark to pastel and then to monokai makes the Powerline theme adjust automatically!

Most of this is already possible with the existing code, provided the colour theme for Kakoune uses RGB colours for foreground and background. However, the base for the separators needs to be adjusted, because their foreground is in fact a background value (the one of the coming segment), thus necessiting base with the buffer background colour as foreground instead of Default.

Screenshots

Ayu-dark with black colour uncommented, before the patch. Note the inconsistent appearance of the separators (no foreground transparency, or rather, blending in of white with white, resulting in an opaque colour): ayu-broken

Ayu-dark (same), with the Powerline patch applied: ayu

After typing :colorscheme monokai (also edited to set the black colour): monokai

After typing :colorscheme mygruvbox (idem): mygruvbox

After typing :colorscheme pastel (idem): pastel

andreyorst commented 2 years ago

Thanks! This looks super good!