Search code examples
perlterminalcursor-positionlibtermkey

Is it somehow possible to catch with Term::TermKey the cursor position?


Is it possible to get hold of the cursor position with Term::TermKey in a similar way Term::ReadKey can do it:

#!/usr/bin/env perl
use warnings;
use 5.12.0;
use Term::ReadKey;

ReadMode 4;

system( 'clear' ) == 0 or die $?;
print "Hello world\n" x 4;
print "go to column 21 -> |";

print "\e[6n";
my ( $x, $y ) = getch();
say "Col: $x  -  Row: $y";

ReadMode 0;

sub getch {
    my $c = ReadKey 0;
    if ( $c eq "\e" ) {
        my $c = ReadKey 0.10;
        if ( $c eq '[' ) {
            my $c = ReadKey 0;
            if ( $c =~ /\A\d/ ) { 
                my $c1 = ReadKey 0;
                if ( $c1 ne '~' ) {
                    my $y = 0 + $c;
                    while ( 1 ) {
                        last if $c1 eq ';';
                        $y = 10 * $y + $c1;
                        $c1 = ReadKey 0;
                    }
                    my $x = 0;
                    while ( 1 ) {
                        $c1 = ReadKey 0;
                        last if $c1 eq 'R';
                        $x = 10 * $x + $c1;
                    }
                    return $x, $y;
                }
            }
        }
    } 
}

Solution

  • Not yet, but I'm working on a plan for it. It will likely be reported as a new event type, looking something like:

    use Term::TermKey;
    
    my $tk = Term::TermKey->new;
    
    syswrite STDOUT, "\e[6n";
    
    while( $tk->waitkey( my $key ) ) {
      if( $key->type_is_position ) {
        printf "The cursor is at %d, %d\n", $key->line, $key->col;
      }
    }
    

    Requires some extra support in the underlying C library first, including the ability to hook other CSI sequences. Once that's in though it ought to be much easier to support more in the future, such as the many other status reports that come through CSIs.


    Edit 2012/04/26: I've now released libtermkey 0.15 and Term::TermKey 0.14, which has this API as described above.