如何更改当前光标位置指示器的颜色?

Posted

技术标签:

【中文标题】如何更改当前光标位置指示器的颜色?【英文标题】:How do I change the color of current cursor position indicator? 【发布时间】:2012-07-14 16:39:16 【问题描述】:

当我打开终端时,我有一个黑色背景和白色字符。我还有一个绿色占位符,它向我指示当前光标在哪里。

在终端中运行的任何 perl 脚本中,此行为都是相同的。

如何在脚本中更改光标指示器的颜色(具体来说,我希望它消失一段时间然后回来)?

我正在使用 Linux 和 bash。

【问题讨论】:

这在很大程度上取决于您使用的操作系统和终端软件。 Mac / Linux / Windows? 【参考方案1】:

没有什么可移植的,但某些终端接受转义序列来改变光标颜色。

例如xterm 接受OSC 12 设置颜色

$ echo -e "\e]12;red\a"

【讨论】:

【参考方案2】:

简答

echo -n -e '\e[?0c'       #DISAPPEAR
echo -n -e '\e[?16;0;64c' #REAPPEAR
echo -n -e '\e[?16;0;80c' #REAPPEAR w/highlighting

长答案

截至今天,agetty 的当前版本(包含在 util-linux 2.27.1 [util-linux 是提供大多数核心命令的 linux 软件包,例如 @987654324 @、sumountmorekill - 仅举几例] - 如果你的 linux 内核版本 >=4.4,你应该拥有它)具有与尚未描述的行为不同的行为-更新 kernel.org 文档 (Software cursor for VGA)。

考虑

echo -n -e '\e[?byte1;byte2;byte3c'

字节1:

+---------------+---------------+
|  high nibble  |   low nibble  |
+---+-----------+-----------+---+
|msb|           |           |lsb|
+---+---+---+---+---+---+---+---+
| 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
+---+---+---+---+---+---+---+---+
                  |   |   |   |
                  |   |   |   +-+
                  |   |   |     |   These bits specify the 8
                  |   |   +-----+-> possible blinking HW carets
                  |   |         |   
                  |   +---------+
                  |
                  +---------------> When set, this bit enables SW
                                    caret instead of HW caret

byte2(SW 插入符号):

                +-----------------> A pretty useless mask applied
                |                   to bits in byte3
+---------------+---------------+
|  high nibble  |   low nibble  |
+---+-----------+-----------+---+
|msb|           |           |lsb|
+---+---+---+---+---+---+---+---+
| 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
+---+---+---+---+---+---+---+---+

byte3(SW 插入符号):

+---------------+---------------+
|  high nibble  |   low nibble  |
+---+-----------+-----------+---+
|msb|           |           |lsb|
+---+---+---+---+---+---+---+---+
| 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
+---+---+---+---+---+---+---+---+
  |   |   |   |
  |   |   |   +-------------------> Highlighting
  |   |   |
  |   |   +---------------------+
  |   |                         |
  |   +-------------------------+-> Color
  |                             |
  +-----------------------------+

突出显示:突出显示插入符号下方的字符(例如,将其更改为白色 [真正闪亮的白色] 而不是深白色 [通常是 TTY 的默认浅灰色])。

颜色:插入符号的颜色。请注意,与我们都知道和喜爱的 ANSI 颜色代码的通常顺序相比,位是相反的,所以 - 对于这个三元组 - 第 7 个是 Lsb 而第 5 个是 M 某人。

因此,虽然 ANSI 在 70 年代定义了以下颜色代码,但为 TTY、各种 linux 终端、控制台等设置了一个普遍采用的de-facto标准

000 (0) black
001 (1) red
010 (2) green
011 (3) yellow or dark yellow
100 (4) blue or dark blue
101 (5) magenta, purple or violet
110 (6) cyan or light blue
111 (7) white or dark white (light gray)

在这种情况下,我们有相反的情况

000 (0) black
100 (4) red
010 (2) green
110 (6) yellow or dark yellow
001 (1) blue or dark blue
101 (5) magenta, purple or violet
011 (3) cyan or light blue
111 (7) white or dark white (light gray)

(带括号的八进制值)

所以,列表来了:

#Hardware carets (blinking and [dark ]white)
echo -n -e '\e[?0c' #default caret
echo -n -e '\e[?1c' #invisible caret
echo -n -e '\e[?2c' #underscore caret
echo -n -e '\e[?3c' #thicker underscore caret
echo -n -e '\e[?4c' #smaller block caret
echo -n -e '\e[?5c' #small block caret
echo -n -e '\e[?6c' #big block caret
echo -n -e '\e[?7c' #biggest block caret
#On my Linux machine, both 6 and 7 are the big rectangular full-size block caret

#Software carets (non-blinking and colored)
echo -n -e '\e[?16;0;0c'  #00001000 0 00000000 black (thus invisible on black background)
echo -n -e '\e[?16;0;128c'#00001000 0 10000000 red
echo -n -e '\e[?16;0;64c' #00001000 0 01000000 green
echo -n -e '\e[?16;0;192c'#00001000 0 11000000 yellow
echo -n -e '\e[?16;0;32c' #00001000 0 00100000 blue
echo -n -e '\e[?16;0;160c'#00001000 0 10100000 magenta
echo -n -e '\e[?16;0;96c' #00001000 0 01100000 cyan
echo -n -e '\e[?16;0;224c'#00001000 0 11100000 dim white
echo -n -e '\e[?16;0;16c' #00001000 0 00010000 black     + highlighting
echo -n -e '\e[?16;0;144c'#00001000 0 10010000 red       + highlighting
echo -n -e '\e[?16;0;80c' #00001000 0 01010000 green     + highlighting
echo -n -e '\e[?16;0;208c'#00001000 0 11010000 yellow    + highlighting
echo -n -e '\e[?16;0;48c' #00001000 0 00110000 blue      + highlighting
echo -n -e '\e[?16;0;176c'#00001000 0 10110000 magenta   + highlighting
echo -n -e '\e[?16;0;112c'#00001000 0 01110000 cyan      + highlighting
echo -n -e '\e[?16;0;240c'#00001000 0 11110000 dim white + highlighting

【讨论】:

我喜欢你的回答。这是我在网上看到的最全面的答案。但是基于这个答案,我只有 3 位颜色,但在我的 ubuntu 中,我可以设置我喜欢的任何 RGB 颜色,那是怎么回事?这是我为此找到的方法: echo -ne '\e]12;#'$1'\a' 其中 $1 是 6 个字符的十六进制颜色。我不知道这是怎么回事 @godzsa,这个回复是关于linux终端的,你说的转义码在xterm/vte/etc上工作。【参考方案3】:

如果您更改打印文本的颜色,您可以更改光标的颜色。 所以你不能简单地改变光标的颜色而不改变你正在打印的文本的颜色。

但是你可以让光标不可见:

system("tput cinvis"); # make cursor invisible
system("tput cnorm");  # make cursor visible

【讨论】:

它们为什么相关?实际上我有一个绿色光标,我打印白色文本,在我程序的其他部分我打印红色或绿色文本,光标仍然是绿色的。但是,感谢您提供的 shell 解决方案,但可能存在拼写错误:tput civis 适用于我的系统,而 cinvis(如您所说)抱怨未知的 terminfo 功能。 这取决于终端(所有终端都不是这个答案)。【参考方案4】:

你尝试过这样的事情吗?

use Term::ANSIColor qw(:constants);

print RED, "Danger, Will Robinson!\n", RESET;

【讨论】:

这会将其打印为红色。但不会影响当前光标指示器的颜色。我试过了。

以上是关于如何更改当前光标位置指示器的颜色?的主要内容,如果未能解决你的问题,请参考以下文章

如何从 RichTextBox 中的光标位置选择前一个字符

code::blocks 编辑代码是的光标颜色如何更改?

在 Entry 小部件中更改光标的位置

Richedit更改选择的颜色

Delphi中如何判断当前光标的位置

c# 动态获取当前屏幕中光标所在位置