我想更改程序以自动检测终端是否具有颜色功能,所以当我从一个不支持颜色的终端(比如(X)Emacs中的Mx shell)中运行所述程序时,颜色会自动关闭.
我不想硬编码程序来检测TERM = {emacs,dumb}.
我认为termcap/terminfo应该可以帮助解决这个问题,但到目前为止,我只是设法将这个(n)curses - 使用代码片段拼凑在一起,当它无法找到终端时会严重失败:
#include <stdlib.h>
#include <curses.h>
int main(void) {
int colors=0;
initscr();
start_color();
colors=has_colors() ? 1 : 0;
endwin();
printf(colors ? "YES\n" : "NO\n");
exit(0);
}
Run Code Online (Sandbox Code Playgroud)
即我明白了:
$ gcc -Wall -lncurses -o hep hep.c
$ echo $TERM
xterm
$ ./hep
YES
$ export TERM=dumb
$ ./hep
NO
$ export TERM=emacs
$ ./hep
Error opening terminal: emacs.
$
Run Code Online (Sandbox Code Playgroud)
这是......次优的.
我通过我的Mac上的ssh连接在NetBSD系统上工作,我想使用该screen
实用程序,以便我可以启动进程并在终端连接中断后返回它们.当我输入时,screen
我收到错误消息:
Cannot find termcap entry for 'xterm-256color'
Run Code Online (Sandbox Code Playgroud)
浏览论坛帖子后,我认为它与远程机器上的termcap有关,但似乎并非如此; 我可以从另一台计算机的ssh会话中启动屏幕而没有任何错误,我通常无法访问该计算机.这表明我需要在本地计算机上配置一些东西,但我无法弄清楚是什么或如何.虽然这篇文章被标记为"gnu-screen"但我怀疑我正在使用Berkeley屏幕,尽管我不知道这是否是一个重要的区别.
这是我第二次想要这样做,而且我的google-fu再次失败了.
在运行shell脚本(在我的情况下是一个bash脚本)的过程中是否有一个程序/脚本来测试当前shell是否支持颜色?
或者有没有办法采取终端类型,并轻松确定它是否支持颜色?
无论哪种方式,它都会有所帮助.
ISO/IEC 2022定义了C0和C1控制代码.在C0组之间是熟悉的代码0x00
和0x1f
在ASCII,ISO-8859-1和UTF-8(例如ESC,CR,LF).
一些VT100终端仿真器(例如screen(1)
,PuTTY)也支持C1集.这些值之间0x80
和0x9f
(因此,例如,0x84
向下移动光标的线).
我正在显示用户提供的输入.我不希望用户输入能够改变终端状态(例如移动光标).我目前正在过滤出C0集中的字符代码; 但是我想有条件地过滤出C1集,如果终端将它们解释为控制码.
有没有办法从数据库中获取此信息termcap
?
据我所知terminfo(5)
,kcuu1 应该是按下向上箭头时终端发送的序列。我从来没有见过除了^[[A
(现在谈论cat
,搞乱终端设置等)以外的任何东西。那么,鉴于我使用的终端(rxvt、gnome-terminal、iTerm)都默认为 TERM=xterm,为什么不是 kcuu1 \E[A
?
我看到 cuu1是 \E[A
,但是(再次从手册页),这是我应该发送到终端以移动光标的字符串,而不是终端发送给我的字符串。
顺便说一句,这是 OS X 的情况。
在我的特殊情况下,我正在使用MinGW/MSys
.它不包含termios.h
.原来它不是一个可以下载和安装的库(谷歌没有找到任何).Termcap
也不包括在内termios.h
.
从哪里获取此文件?
XTerm控制序列指定以下键序列:
CSI ? 1 h ? Application Cursor Keys (DECCKM)
CSI ? 1 l ? Normal Cursor Mode (DECOM)
CSI ? 66 h ? Application keypad (DECNKM)
CSI ? 66 l ? Numeric keypad (DECNKM)
Run Code Online (Sandbox Code Playgroud)
和TERMINFO源格式有如下条目:
Variable: keypad_xmit
Capname: smkx
Termcap: ks
Description: Put terminal in "keypad-transmit" mode
Run Code Online (Sandbox Code Playgroud)
但是xterm的terminfo实际上是说smkx=\E[?1h\E=
,这似乎让我感到困惑(smkx应该影响键盘,而不是光标键,对吗?)。我在这里想念什么?
码
while (1)
{
keycode = key_hook();
if (keycode == SPACE || keycode == BKSPACE)
{
render_again = 1;
}
if (keycode == ESC)
break;
if (render_again)
{
render_again = 0;
render(all);
}
dprintf(1, ""); //I have no idea why this prevents the program from freezing
}
int key_hook()
{
char buffer[4];
read(0, buffer, 4);
return (*(unsigned int *)buffer);
}
Run Code Online (Sandbox Code Playgroud)
好吧,所以这段代码处理重绘屏幕上的文本.某些文本行使用下划线或突出显示termcaps (tputs(tgetstr("us, NULL")......)
.一切都打印得很好,但在第一次重新绘制文本后,显然会冻结,除非dprintf/printf
存在.该key_hook
函数只是读取4 bytes
距离stdin
,并将其转换为int
.
我想知道如何在我的程序中获取光标位置 (x, y),而不在屏幕上写任何东西,也不会一直跟踪它。
我找到了一种使用此函数获取其位置的方法(我在这里不检查读取、写入等的返回来编写有关此主题的较小代码,但我在我的程序中执行此操作):
void get_cursor_position(int *col, int *rows)
{
int a = 0;
int i = 0;
char buf[4];
write(1, "\033[6n", 4); // string asking for the cursor position
read(1, buf, 4);
while (buf[i])
{
if (buf[i] >= 48 && buf[i] <= 57)
{
if (a == 0)
*rows = atoi(&buf[i]) - 1;
else
*col = atoi(&buf[i]) - 1;
a++;
}
i++;
}
}
Run Code Online (Sandbox Code Playgroud)
这个函数给了我准确的光标位置(*rows = y,*col = x),但它写在屏幕上。
如何在不在屏幕上写任何东西的情况下获得光标位置?
(如果光标位于打印的字符之一上,它将覆盖它。)
应该在发送转义序列之前和之后切换 echo 吗?
这是一个学校项目,所以我只能使用termcap,我不能使用ncurses函数,唯一允许的函数是tputs、tgoto、tgetstr、tgetnum、tgetflag。
我正在尝试将嵌入式Pod作为ANSI文本输出到终端。在Perl 5中,我可以使用Pod::Text::Termcap
:
use strict;
use warnings;
use Pod::Text::Termcap;
my $str = do {local $/; <DATA>};
my $parser = Pod::Text::Termcap->new();
$parser->parse_string_document( $str, \*STDERR );
__DATA__
=head1 SYNOPSIS
my_test_command I<filename> [OPTIONS]
=head1 ARGUMENTS
=over 4
=item I<filename>
File name to test
=back
=head1 OPTIONS
=over 4
=item B<--help>
Prints help
=back
=head1 DESCRIPTION
A sample test command with embedded Pod
Run Code Online (Sandbox Code Playgroud)
输出:
我试图在Perl 6中实现相同的目标:
use v6;
%*ENV<POD_TO_TEXT_ANSI> = 1;
my @lines;
for $=pod -> $pod-block {
for $pod-block.contents -> $pod-item …
Run Code Online (Sandbox Code Playgroud)