Perl 航站楼:我在哪里?

Perl 航站楼:我在哪里?,perl,terminal,cursor-position,termcap,Perl,Terminal,Cursor Position,Termcap,是否有一个变量或函数可以告诉我光标的实际位置 #!/usr/bin/env perl use warnings; use 5.012; use Term::ReadKey; use Term::Cap; use POSIX; my( $col, $row ) = GetTerminalSize(); my $termios = new POSIX::Termios; $termios->getattr; my $ospeed = $termios->getospeed; my

是否有一个变量或函数可以告诉我光标的实际位置

#!/usr/bin/env perl
use warnings;
use 5.012;

use Term::ReadKey;
use Term::Cap;
use POSIX;

my( $col, $row ) = GetTerminalSize();

my $termios = new POSIX::Termios;
$termios->getattr;
my $ospeed = $termios->getospeed;

my $terminal = Tgetent Term::Cap { TERM => undef, OSPEED => $ospeed };

# some movement ...

# at which position (x/y) is the cursor now?

我认为您无法使用
termcap
确定光标位置

说:

如果计划在应用程序中使用相对光标运动命令,则必须知道光标的起始位置。为此,必须跟踪光标位置,并在每次向终端输出任何内容(包括图形字符)时更新记录


你可以用诅咒代替。它有
getcurx()
getcurx()
。它有一个定位程序(Debian或Ubuntu中的
libcurses perl
包)。

一些终端可能支持查询位置,如
CSI 6 n
。如果支持,该位置将报告为
CSI Pl;Pc R
。比如说

$ echo -e "\e[6n"; xxd

^[[4;1R
0000000: 1b5b 343b 3152 0a                      .[4;1R.
这将报告光标位于第4行的第1列(从1开始计数)


但是,这可能不应该依赖,因为实际上没有多少终端支持这一点。

在ANSI兼容的终端上打印ESC[6n将为您提供当前光标位置为ESC[n;mR,其中n是行,m是列

所以试着用终端转义字符来读它。类似于:

perl -e '$/ = "R";' -e 'print "\033[6n";my $x=<STDIN>;my($n, $m)=$x=~m/(\d+)\;(\d+)/;print "Current position: $m, $n\n";'
perl-e'$/=“R”;“-e”print“\033[6n”;my$x=;my$n,$m)=$x=~m/(\d+);(\d+)/;print“当前位置:$m,$n\n”;”

但这是一个很大的“如果”-如果您不打算限制自己使用相对光标移动命令(对于旧终端或打印机可能需要这样做),那么还有其他可用选项,特别是在现代终端上-例如序列。(“现代”在这里的意思是“大约从1980年开始生产的任何东西”:-)@psmears同意。确实有办法做到这一点。不过,sid_com将其标记为termcap。使用它,这是不可能的。实际上(使用随某些Linux版本分发的
termcap
,至少是由Eric Raymond维护的版本),“u7”字符串是“查询光标位置”序列,而“u8”string是一种描述响应的格式字符串(请参见
/etc/termcap
),OP将其标记为termcap.+1作为替代。
getcurx()
getcury()
只需返回
curses
光标位置的概念。他们实际上并不询问真正的终端。