Just as an excuse to play around with single line ANSI control sequences, I came up with this.
It runs in an xterm on ArchLinux ( mostly because that's all I have to play with ).
#!/usr/bin/perl
use strict; # https://perlmonks.org/?node_id=11115029
use warnings;
my $newline = promptandreviseline( "Previous Value : ", 'previous line
+' );
print "The New Line is: $newline\n";
######################################################################
use Term::ReadKey;
use Data::Dump qw( pp );
sub promptandreviseline
{
my ($prompt, $line) = @_;
$line //= '';
$line =~ tr/\t\n/ /;
local $| = 1;
my $startcolumn = 1 + length $prompt;
print "\e[1G$prompt";
my $cursor = length $line;
my $pos = $startcolumn + $cursor;
print "\e[${startcolumn}G\e[K$line\e[${pos}G";
my $more = 1;
ReadMode 'raw';
while( $more )
{
sysread STDIN, my $input, 4096 or last;
for my $key ( $input =~ /\e[^\e]+|./gs )
{
if( $key =~ /^[\cc\e]\z/ ) { $more = 0 } # ^c escape
elsif( $key =~ /^[\n\r]\z/ )
{
print "\n";
$line .= "\n";
$more = 0
}
elsif( $key =~ /^[ -~]$/ ) { substr $line, $cursor++, 0, $key }
+# char
elsif( $key eq "\b" ) # backspace
{
$cursor > 0 and substr $line, --$cursor, 1, '';
}
elsif( $key eq "\e[3~" ) # Delete
{
$cursor < length($line) and substr $line, $cursor, 1, '';
}
elsif( $key eq "\e[D" ) { $cursor > 0 and $cursor-- } # left arr
+ow
elsif( $key eq "\e[C" ) { $cursor < length($line) and ++$cursor
+} # right
elsif( $key eq "\e[F" ) { $cursor = length($line) } # End
elsif( $key eq "\e[H" ) { $cursor = 0 } # Home
else # invalid, show sequence
{
my $seq = pp $key;
substr $line, $cursor, 0, $seq;
$cursor += length $seq;
}
$pos = $startcolumn + $cursor;
$more and print "\e[${startcolumn}G$line\e[K\e[${pos}G";
}
}
ReadMode 'restore';
return $line;
}