user
Create a routine to obtain data entry using a specific place on the terminal screen.

Data entry fields should be restricted to a specific length,   and the cursor should not move beyond the input length.

The routine should accept parameters for row number,   column number,   and input length,   and should obtain a string value entered by the user.

For the purpose of this task,   obtain input from the user,   showing data entry at   row   **3**,   column   **5**,   with input width restricted to a maximum of   **8**   characters.

Note:   in this task input wrapping is allowed.   If the length of input exceeds the maximum width, the left hand side of the field should disappear, allowing additional input to be obtained.   However, the cursor must not move beyond the designated input length.

It is permissible to use navigation keys to see input field length.

(See Terminal control/Restricted width positional input/No wrapping for similar input routine with no wrapping).

For a similar task using a graphical user interface,   see   Graphical User Interface/Restricted width positional input/With wrapping.
assistant
(formerly Perl 6)

**Works with**: Rakudo version 2018.10

Should work with any termios compatible terminal.

All printable character keys (except Tab) work, as does backspace and enter. Ctrl-c to exit. All other keys / key-combos are ignored.

```
use Term::termios;

constant $saved   = Term::termios.new(fd => 1).getattr;
constant $termios = Term::termios.new(fd => 1).getattr;
# raw mode interferes with carriage returns, so
# set flags needed to emulate it manually
$termios.unset_iflags(<BRKINT ICRNL ISTRIP IXON>);
$termios.unset_lflags(<ECHO ICANON IEXTEN ISIG>);
$termios.setattr(:DRAIN);

END {
    $saved.setattr(:NOW); # reset terminal to original settings
    print "\e[?25h \e[H\e[J"; # clear and reset screen
}

my $row     = 3;
my $column  = 5;
my $field   = '';
my $spacer  = ' ' x 8;
my $pointer = 0;

my ($rows,$cols) = qx/stty size/.words; # get screen size

my @screen = "\e[41m{' ' x $cols}\e[0m" xx $rows;

update($spacer);

loop {
    my $key = $*IN.read(4).decode;
    given $key {
        when ' '..'~' {
            if $pointer < 8 {
                $field ~= $_;
                $spacer = ' ' x 8 - $field.chars;
                $pointer +=1;
                update($field~$spacer)
            } elsif $pointer >= 8 {
                $field ~= $_;
                $spacer = '';
                update($field.substr(*-8))
            }
        }
        when "\c[127]" { # backspace
            if $pointer > 0 {
                $field.=substr(0,*-1);
                $spacer = ' ' x (8 - $field.chars max 0);
                $pointer -= 1 if $field.chars < 8;
                my $display = $field.chars < 8 ?? $field !! $field.substr(*-8);
                update($display~$spacer)
            }
        }
        when "\c[13]" {
            update('        ');
            print "\e[10;6H\e[1;33;41mYou entered: $field\e[0m\e[$row;{$column}H";
            $field = '';
            $pointer = 0;
        }
        when "\c[0003]" { exit } # Ctrl-c
        default { }
    }
}

sub update ($str) {
    ($rows,$cols) = qx/stty size/.words;
    @screen = "\e[41m{' ' x $cols}\e[0m" xx $rows;
    print "\e[H\e[J{@screen.join: "\n"}\e[$row;{$column}H$str\e[$row;{$column + $pointer}H";
}

```