Search code examples
vimgnome-terminal

Changing cursor background when highlighting text


I use vim through Ubuntu terminal. I'm wanting to change the cursor background color of the cursor when selecting test.

The text selection would be done using:

hi Visual       ctermfg=52   ctermbg=167  cterm=none

However this doesn't change the background of the cursor, that is also selected but doesn't give that impression.

Is there a command I can use to do this? I've tried

hi VisualCursor ...  
hi CursorVisual ...

But no luck.


Solution

  • As noted in comments, in a terminal, the foreground/background colors of the cursor are mostly out of vim's control. The settings for ctermfg and ctermbg apply only to the text foreground/background. See the section entitled "2. highlight arguments for color terminals" in vim documentation which describes these.

    Those settings correspond to ANSI escape sequences (ECMA-48). There is no corresponding standard for the cursor colors:

    • many terminals allow you to specify the cursor color (before starting the terminal),
    • some terminals recognize an escape sequence for setting the cursor color,
    • some terminals change the cursor color to keep it visible when on text which is the same color.

    Likewise, there is no standard for the way the cursor color changes (or does not change) when you select text with the mouse:

    • some terminals color the selection in reverse-video,
    • some use a special selection-color, and
    • the selection-color may/may not affect the cursor color.

    The actual terminal in use was not mentioned; assuming the default terminal that would be gnome-terminal. All of the relevant functionality is in the VTE library. Some of this changes with time, but in current code the place to look is in vtegtk.cc (though it helps to read vte.cc as well):

        /**
         * vte_terminal_set_color_cursor:
         * @terminal: a #VteTerminal
         * @cursor_background: (allow-none): the new color to use for the text cursor, or %NULL
         *
         * Sets the background color for text which is under the cursor.  If %NULL, text
         * under the cursor will be drawn with foreground and background colors
         * reversed.
         */
    
        /**
         * vte_terminal_set_color_cursor_foreground:
         * @terminal: a #VteTerminal
         * @cursor_foreground: (allow-none): the new color to use for the text cursor, or %NULL
         *
         * Sets the foreground color for text which is under the cursor.  If %NULL, text
         * under the cursor will be drawn with foreground and background colors
         * reversed.
         *
         * Since: 0.44
         */
    
        /**
         * vte_terminal_set_color_highlight_foreground:
         * @terminal: a #VteTerminal
         * @highlight_foreground: (allow-none): the new color to use for highlighted text, or %NULL
         *
         * Sets the foreground color for text which is highlighted.  If %NULL,
         * it is unset.  If neither highlight background nor highlight foreground are set,
         * highlighted text (which is usually highlighted because it is selected) will
         * be drawn with foreground and background colors reversed.
         */
    

    The VTE documentation, such as it is, is generated from the comments (imitating JavaDoc, in this case). So reading the source code is the only way to understand what the program does. The comments agree with OP's additional question asked:

    How comes the cursor background color changes when selecting text then? Thing is, the bg color changes to the color of the text the cursor is on.

    The individual functions in VTE imitate features of xterm, which provides more control over the way colors are managed. For instance, VTE recognizes the control sequence which lets xtermcontrol change the cursor color from a shell command. The control sequence is documented in XTerm Control Sequences:

            Ps = 1 2  -> Change text cursor color to Pt.
    

    Doing that overrides the reverse-video scheme alluded to in the comments. Quoting from the xterm manual gives some idea of what alternatives could be implemented in VTE:

       highlightColor (class HighlightColor)
               Specifies  the  color  to  use  for  the background of selected
               (highlighted) text.   If  not  specified  (i.e.,  matching  the
               default  foreground),  reverse  video  is used.  The default is
               "XtDefaultForeground".
    
       highlightColorMode (class HighlightColorMode)
               Specifies whether xterm should use highlightTextColor and high-
               lightColor  to override the reversed foreground/background col-
               ors in a selection.  The default is  unspecified:  at  startup,
               xterm checks if those resources are set to something other than
               the default foreground and  background  colors.   Setting  this
               resource disables the check.