::selection with themes and linters

I have a hard time figuring out how to make a selection well recognizable.

I mainly use the cobalt theme, with the current line slightly darker, thus it’s almost impossible to see the current selection in the current line. The co-appearing words in the document are visually selected fine, and they are recognizable - a very nice feature.

import { createTheme } from "thememirror";
import { cobalt } from "thememirror";
extensions.push(cobalt);

let highlightTheme = EditorView.theme(
    {
        ".cm-selectionMatch": {
            backgroundColor: "#511",
        },
        "&.cm-focused .cm-selectionBackground, ::selection": {
            backgroundColor: "#A22",
        },
    },
    { dark: true }
);

extensions.push(highlightTheme);

Tried to modify the sourcode for the cobalt theme, but no luck. I can only underline with CSS which is a bit odd and unusual annoying workaround. …

Could anyone suggest a proper solution?

Thank you very much.

Which Cobalt theme are you using?

Hello Marijn,

The cobalt theme:

import { tags as t } from '@lezer/highlight';
import createTheme from '../create-theme.js';
// Author: Jacob Rus
export const cobalt = createTheme({
    variant: 'dark',
    settings: {
        background: '#00254b',
        foreground: '#FFFFFF',
        caret: '#FFFFFF',
        selection: '#B36539BF',
        gutterBackground: '#00254b',
        gutterForeground: '#FFFFFF70',
        lineHighlight: '#00000059',
    },
    styles: [
        {
            tag: t.comment,
            color: '#0088FF',
        },
        {
            tag: t.string,
            color: '#3AD900',
        },
        {
            tag: t.regexp,
            color: '#80FFC2',
        },
        {
            tag: [t.number, t.bool, t.null],
            color: '#FF628C',
        },
        {
            tag: [t.definitionKeyword, t.modifier],
            color: '#FFEE80',
        },
        {
            tag: t.variableName,
            color: '#CCCCCC',
        },
        {
            tag: t.self,
            color: '#FF80E1',
        },
        {
            tag: [
                t.className,
                t.definition(t.propertyName),
                t.function(t.variableName),
                t.definition(t.typeName),
                t.labelName,
            ],
            color: '#FFDD00',
        },
        {
            tag: [t.keyword, t.operator],
            color: '#FF9D00',
        },
        {
            tag: [t.propertyName, t.typeName],
            color: '#80FFBB',
        },
        {
            tag: t.special(t.brace),
            color: '#EDEF7D',
        },
        {
            tag: t.attributeName,
            color: '#9EFFFF',
        },
        {
            tag: t.derefOperator,
            color: '#fff',
        },
    ],
});


Okay, and what does createTheme look like? Specifically, what selector does it use for the selection? And are you using drawSelection (possibly via basicSetup) or not?

Yes, I’m using drawSelection() in basicSetup.

The trick to find the matching css class is to inspect a selection, open the div in the inspector for the selection - here the focus is lost, and only the cm-selectionBackground is active, and then click back on the code selection context menu - focus. This makes the active selection’s div visible.

This is the result:

const customSelectionStyle = EditorView.baseTheme({
    "&.cm-focused > .cm-scroller > .cm-selectionLayer .cm-selectionBackground": {
        backgroundColor: "purple",
    },
    ".cm-selectionBackground": {
        backgroundColor: "yellow",
    },
});

With this extension, the selection is purple when the window is in focus, and yellow if it is out of focus.

I think this changed recently, with some update.

Thank you @marijn, greetings.