Changing the cursor colour in Insert mode

Inspired by a recent GitHub issue, I figured I’d try changing the cursor colour scheme between insert and normal mode. It was trickier than I expected, because I prefer to stick to the basic 16 terminal colours. It’s difficult to come up with a set of faces that distinguishes primary vs. secondary and cursor vs. selection in a logical way with only the basic 16 colours, and adding the normal vs. insert distinction on top makes it even harder.

Here’s what I came up with:

set-face global PrimarySelection white,blue+F
set-face global SecondarySelection black,blue+F
set-face global PrimaryCursor black,bright-cyan+F
set-face global SecondaryCursor black,bright-blue+F
set-face global PrimaryCursorEol black,bright-cyan
set-face global SecondaryCursorEol black,bright-blue
                                                                          
hook global ModeChange .*:insert %{
    set-face window PrimarySelection white,green+F
    set-face window SecondarySelection black,green+F
    set-face window PrimaryCursor black,bright-yellow+F
    set-face window SecondaryCursor black,bright-green+F
    set-face window PrimaryCursorEol black,bright-yellow
    set-face window SecondaryCursorEol black,bright-green
}

hook global ModeChange insert:.* %{
    unset-face window PrimarySelection
    unset-face window SecondarySelection
    unset-face window PrimaryCursor
    unset-face window SecondaryCursor
    unset-face window PrimaryCursorEol
    unset-face window SecondaryCursorEol
}

Basically:

  • White text on colour for primary selections, black text on colour for secondary
  • Black text on very bright colour for primary cursors, black text on slightly brighter colour for secondary cursors
  • Normal mode uses blue, bright-blue, and bright-cyan as its dark, bright and very-bright colours, while insert mode uses green, bright-green, and bright-yellow
  • No special colors for the Eol cursor variants, because I have a show-whitespace highlighter to make them visible instead.

It’s awkward that this scheme needs three shades of colour; if it were two, the standard 16-colour palette has plenty, and if it were four, I could maybe use a pair of two-shade cool colours and a pair of two-shade warm colours. Ah, well. I’ll use this scheme for a bit and see how I feel about it.

3 Likes

Can you show us a GIF or asciicast?

Hilariously, the asciicast website doesn’t seem to support the bright-blue or bright-green colours that I use for secondary cursors (it works when played back in the terminal), but you can still get the general idea: https://asciinema.org/a/1zeMpIvVEvvRF46tqQqZWNkO8

1 Like

Since I made this post years ago, Kakoune has changed the syntax of the ModeChange hook parameter, and the example I gave above no longer works. Here’s a fixed version:

# Shades of blue/cyan for normal mode
set-face global PrimarySelection white,blue+F
set-face global SecondarySelection black,blue+F
set-face global PrimaryCursor black,bright-cyan+F
set-face global SecondaryCursor black,bright-blue+F
set-face global PrimaryCursorEol black,bright-cyan
set-face global SecondaryCursorEol black,bright-blue

# Shades of green/yellow for insert mode.
hook global ModeChange (push|pop):.*:insert %{
    set-face window PrimarySelection white,green+F
    set-face window SecondarySelection black,green+F
    set-face window PrimaryCursor black,bright-yellow+F
    set-face window SecondaryCursor black,bright-green+F
    set-face window PrimaryCursorEol black,bright-yellow
    set-face window SecondaryCursorEol black,bright-green
}

# Undo colour changes when we leave insert mode.
hook global ModeChange (push|pop):insert:.* %{
    unset-face window PrimarySelection
    unset-face window SecondarySelection
    unset-face window PrimaryCursor
    unset-face window SecondaryCursor
    unset-face window PrimaryCursorEol
    unset-face window SecondaryCursorEol
}