Terminal control/Restricted width positional input/With wrapping: Difference between revisions

From Rosetta Code
Content added Content deleted
(Terminal control/Restricted width positional input/With wrapping in FreeBASIC)
m (→‎{{header|Wren}}: Changed to Wren S/H)
 
(2 intermediate revisions by 2 users not shown)
Line 23: Line 23:
==={{header|ncurses}}===
==={{header|ncurses}}===
To interface ncurses from Lisp, the ''[https://www.cliki.net/croatoan croatoan]'' library is used.
To interface ncurses from Lisp, the ''[https://www.cliki.net/croatoan croatoan]'' library is used.
<lang lisp>;; Load the library from the quicklisp repository
<syntaxhighlight lang="lisp">;; Load the library from the quicklisp repository
(ql:quickload "croatoan")
(ql:quickload "croatoan")
(in-package :croatoan)
(in-package :croatoan)
Line 40: Line 40:


;; call the routine
;; call the routine
(field-input-with-wrapping 2 4 8)</lang>
(field-input-with-wrapping 2 4 8)</syntaxhighlight>




=={{header|FreeBASIC}}==
=={{header|FreeBASIC}}==
<lang freebasic>Function getInput(fila As Integer, columna As Integer, ancho As Integer) As String
<syntaxhighlight lang="freebasic">Function getInput(fila As Integer, columna As Integer, ancho As Integer) As String
Locate fila, columna, 0
Locate fila, columna, 0
Dim As String KBD, cadena = ""
Dim As String KBD, cadena = ""
Line 67: Line 67:
Dim As String s = getInput(3, 5, 8)
Dim As String s = getInput(3, 5, 8)
Locate 23,1 : Print "You entered: "; s
Locate 23,1 : Print "You entered: "; s
Sleep</lang>
Sleep</syntaxhighlight>




Line 75: Line 75:
<br>
<br>
This uses _getch() rather than _getwch() as only ASCII is supported.
This uses _getch() rather than _getwch() as only ASCII is supported.
<lang go>package main
<syntaxhighlight lang="go">package main


/*
/*
Line 155: Line 155:
setCursor(coord)
setCursor(coord)
fmt.Printf("You entered '%s'\n", s)
fmt.Printf("You entered '%s'\n", s)
}</lang>
}</syntaxhighlight>




=={{header|Julia}}==
=={{header|Julia}}==
Requires an ANSI compatible terminal and a system C library implementing _getch() for unbuffered keyboard input.
Requires an ANSI compatible terminal and a system C library implementing _getch() for unbuffered keyboard input.
<lang julia>getch() = UInt8(ccall(:_getch, Cint, ()))
<syntaxhighlight lang="julia">getch() = UInt8(ccall(:_getch, Cint, ()))
cls() = print("\33[2J")
cls() = print("\33[2J")
reposition(row, col) = print("\u001b[$row;$(col)H")
reposition(row, col) = print("\u001b[$row;$(col)H")
Line 184: Line 184:
s = input_y_x_upto(3, 5, 80, 8)
s = input_y_x_upto(3, 5, 80, 8)
println("\n\n\nResult: You entered <<$s>>")
println("\n\n\nResult: You entered <<$s>>")
</syntaxhighlight>
</lang>


=={{header|Kotlin}}==
=={{header|Kotlin}}==
{{works with|Windows 10}}
{{works with|Windows 10}}
This follows a similar approach to the Kotlin entry for the [[Terminal control/Restricted width positional input/No wrapping]] task except, of course, that the code now allows for wrapping.
This follows a similar approach to the Kotlin entry for the [[Terminal control/Restricted width positional input/No wrapping]] task except, of course, that the code now allows for wrapping.
<lang scala>// Kotlin Native v0.5
<syntaxhighlight lang="scala">// Kotlin Native v0.5


import kotlinx.cinterop.*
import kotlinx.cinterop.*
Line 257: Line 257:
}
}
println("You entered '$s'")
println("You entered '$s'")
}</lang>
}</syntaxhighlight>


=={{header|Nim}}==
=={{header|Nim}}==
Line 265: Line 265:
We had also to check for backspace character and for character <code>'\x7f'</code> as the backspace key gives this last value (but Control+H gives <code>'\x08'</code> i.e. ASCII backspace character).
We had also to check for backspace character and for character <code>'\x7f'</code> as the backspace key gives this last value (but Control+H gives <code>'\x08'</code> i.e. ASCII backspace character).


<lang Nim>import strformat, terminal
<syntaxhighlight lang="nim">import strformat, terminal


proc eraseLineEnd() = stdout.write("\e[K")
proc eraseLineEnd() = stdout.write("\e[K")
Line 282: Line 282:
setCursorPos(3, 5)
setCursorPos(3, 5)
let s = inputXYUpto(3, 5, 80, 8)
let s = inputXYUpto(3, 5, 80, 8)
echo &"\n\n\nResult: You entered <<{s}>>"</lang>
echo &"\n\n\nResult: You entered <<{s}>>"</syntaxhighlight>

=={{header|Perl}}==
<syntaxhighlight lang="perl">#!/usr/bin/perl

use strict; # https://rosettacode.org/wiki/Terminal_control/Restricted_width_positional_input/With_wrapping
use warnings;
use Term::ReadKey;

sub input
{
my ($row, $column, $length) = @_;
my ($input, $done, $start) = ( '', 0,
"\e[$row;${column}H" . ' ' x $length . "\e[$row;${column}H");
local $| = 1;
ReadMode 'raw';
until( $done )
{
print $start, substr $input, -$length;
local $_ = ReadKey 0;
if( tr/ -~// ) { $input .= $_ } # add char
elsif( tr/\cu// ) { $input = '' } # clear all
elsif( tr/\b\x7f// ) { chop $input } # delete last char
elsif( tr/\n\r\e\cc// ) { $done++ } # guess!
}
ReadMode 'restore';
return $input;
}

print "\e[H\e[Jinput at row 3 column 5 length 8\n";
my $in = input( 3, 5, 8 );
print "\n\n\ninput is $in\n\n";</syntaxhighlight>


=={{header|Phix}}==
=={{header|Phix}}==
<!--<lang Phix>(notonline)-->
<!--<syntaxhighlight lang="phix">(notonline)-->
<span style="color: #008080;">without</span> <span style="color: #008080;">js</span> <span style="color: #000080;font-style:italic;">-- (position, wait_key)</span>
<span style="color: #008080;">without</span> <span style="color: #008080;">js</span> <span style="color: #000080;font-style:italic;">-- (position, wait_key)</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">getInput</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">row</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">col</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">width</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">getInput</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">row</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">col</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">width</span><span style="color: #0000FF;">)</span>
Line 319: Line 350:
<span style="color: #7060A8;">position</span><span style="color: #0000FF;">(</span><span style="color: #000000;">23</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">position</span><span style="color: #0000FF;">(</span><span style="color: #000000;">23</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"You entered '%s'\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">s</span><span style="color: #0000FF;">})</span>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"You entered '%s'\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">s</span><span style="color: #0000FF;">})</span>
<!--</lang>-->
<!--</syntaxhighlight>-->


=={{header|Raku}}==
=={{header|Raku}}==
Line 328: Line 359:
All printable character keys (except Tab) work, as does backspace and enter. Ctrl-c to exit. All other keys / key-combos are ignored.
All printable character keys (except Tab) work, as does backspace and enter. Ctrl-c to exit. All other keys / key-combos are ignored.


<lang perl6>use Term::termios;
<syntaxhighlight lang="raku" line>use Term::termios;


constant $saved = Term::termios.new(fd => 1).getattr;
constant $saved = Term::termios.new(fd => 1).getattr;
Line 394: Line 425:
@screen = "\e[41m{' ' x $cols}\e[0m" xx $rows;
@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";
print "\e[H\e[J{@screen.join: "\n"}\e[$row;{$column}H$str\e[$row;{$column + $pointer}H";
}</lang>
}</syntaxhighlight>


=={{header|REXX}}==
=={{header|REXX}}==
(Only works with: &nbsp; REXX/Personal)
(Only works with: &nbsp; REXX/Personal)
<lang rexx>/*REXX pgm reads text from the terminal screen from a certain row, column, and length.*/
<syntaxhighlight lang="rexx">/*REXX pgm reads text from the terminal screen from a certain row, column, and length.*/
parse arg row col len . /*obtain optional arguments from the CL*/
parse arg row col len . /*obtain optional arguments from the CL*/
if row=='' | row=="," then row= 3 /*Not specified? Then use the default.*/
if row=='' | row=="," then row= 3 /*Not specified? Then use the default.*/
Line 414: Line 445:
say 'data read from terminal row ' row " col " col ' length ' len " is:"
say 'data read from terminal row ' row " col " col ' length ' len " is:"
say $
say $
exit 0 /*stick a fork in it, we're all done. */</lang>
exit 0 /*stick a fork in it, we're all done. */</syntaxhighlight>


=={{header|Wren}}==
=={{header|Wren}}==
Due to a bug the ''Stdin.readByte()'' method can currently process only the first byte of a multi-byte character. The others are skipped.
Due to a bug the ''Stdin.readByte()'' method can currently process only the first byte of a multi-byte character. The others are skipped.
<lang ecmascript>import "io" for Stdin, Stdout
<syntaxhighlight lang="wren">import "io" for Stdin, Stdout


var textAtPos = Fn.new { |text, r, c|
var textAtPos = Fn.new { |text, r, c|
Line 463: Line 494:


var res = input.call(3, 5, 8)
var res = input.call(3, 5, 8)
System.print(res)</lang>
System.print(res)</syntaxhighlight>


=={{header|Yabasic}}==
=={{header|Yabasic}}==
<lang Yabasic>// Rosetta Code problem: http://rosettacode.org/wiki/Restricted_width_positional_input/With_wrapping
<syntaxhighlight lang="yabasic">// Rosetta Code problem: http://rosettacode.org/wiki/Restricted_width_positional_input/With_wrapping
// by Galileo, 04/2022
// by Galileo, 04/2022


Line 496: Line 527:
text$ = getInput$(3, 5, 8)
text$ = getInput$(3, 5, 8)
print at(1, 23) "You entered: ", text$</lang>
print at(1, 23) "You entered: ", text$</syntaxhighlight>

Latest revision as of 12:18, 13 February 2024

Terminal control/Restricted width positional input/With wrapping is a draft programming task. It is not yet considered ready to be promoted as a complete task, for reasons that should be found in its talk page.

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.

Common Lisp

ncurses

To interface ncurses from Lisp, the croatoan library is used.

;; Load the library from the quicklisp repository
(ql:quickload "croatoan")
(in-package :croatoan)

(defun field-input-with-wrapping (row column input-length)
  (with-screen (scr :input-echoing nil :cursor-visible t :enable-colors t :enable-function-keys t :input-blocking t)
    (let ((field (make-instance 'field :position (list row column) :width input-length :max-buffer-length 30 :window scr)))
      (setf (style field)
            (list :background (list :simple-char #\.)))
      (bind field #\newline 'accept)
      (edit field)
      (clear scr)
      (refresh scr)
      ;; return the value of the field as a string
      (value field))))

;; call the routine
(field-input-with-wrapping 2 4 8)


FreeBASIC

Function getInput(fila As Integer, columna As Integer, ancho As Integer) As String
    Locate fila, columna, 0
    Dim As String KBD, cadena = ""
    Dim As Integer ini
    
    Do
        Do: KBD = Inkey: Loop Until KBD <> ""
        If KBD = Chr(8) Then  'backspace
            cadena = Left(cadena, Len(cadena) - 1)
            Print !"\b ";
        Else
            cadena &= KBD
        End If
        ini = Iif(Len(cadena) > ancho, Len(cadena) - ancho + 1, 1)
        
        Locate fila, columna : Print Mid(cadena, ini, ancho);
    Loop Until KBD = Chr(13)
    
    Return cadena
End Function 

Dim As String s = getInput(3, 5, 8)
Locate 23,1 : Print "You entered: "; s
Sleep


Go

Works with: Windows 10
Translation of: Kotlin


This uses _getch() rather than _getwch() as only ASCII is supported.

package main

/*
#include <windows.h>
#include <conio.h>
*/
import "C"
import (
    "fmt"
    "os"
    "os/exec"
)

var conOut = C.GetStdHandle(C.STD_OUTPUT_HANDLE)

func setCursor(p C.COORD) {
    C.SetConsoleCursorPosition(conOut, p)
}

func cls() {
    cmd := exec.Command("cmd", "/c", "cls")
    cmd.Stdout = os.Stdout
    cmd.Run()
}

func getInput(row, col, width int) string {
    if row < 0 || row > 20 || col < 0 || width < 1 || width > 78 || col > (79 - width) {
        panic("Invalid parameter(s) to getInput. Terminating program")
    }
    coord := C.COORD{C.short(col), C.short(row)}
    setCursor(coord)
    var sb []byte
    wlen := 0                                    // length of text in editing window
    full := false
    loop:
    for {
        ch := C._getch()                         // gets next character, no echo
        switch c := byte(ch); c {
        case 3, 13:
            break loop                           // break on Ctrl-C or enter key
        case 8:
            if wlen > 0 {                        // mimic backspace
		fmt.Print("\b \b")
                sb = sb[:len(sb) - 1]
                wlen--
            }
            if len(sb) > wlen {
		coord.X = C.short(col)
                coord.Y = C.short(row)
                setCursor(coord)
                fmt.Print(string(sb)[len(sb) - width:])
                wlen = width
            }
        case 0, 224:
            C._getch()                           // consume extra character
        default:
            if c >= 32 && c <= 126 {             // echo ascii character, ignore others
                sb = append(sb, c)
                if !full {
                    C._putch(ch)
                    wlen++
                } else if len(sb) > wlen {
		    coord.X = C.short(col)
                    coord.Y = C.short(row)
                    setCursor(coord)
                    fmt.Print(string(sb)[len(sb) - width:])
                }
            }
        }
        full = wlen == width                     // wlen can't exceed width
    }
    return string(sb)
}

func main() {
    cls() // clear the console
    s := getInput(2, 4, 8) // Windows console row/col numbering starts at 0
    coord := C.COORD{0, 22}
    setCursor(coord)
    fmt.Printf("You entered '%s'\n", s)
}


Julia

Requires an ANSI compatible terminal and a system C library implementing _getch() for unbuffered keyboard input.

getch() = UInt8(ccall(:_getch, Cint, ()))
cls() = print("\33[2J")
reposition(row, col) = print("\u001b[$row;$(col)H")
clearfromcursor() = print("\u001b[K")

function input_y_x_upto(row, col, cmax, width=cmax)
    buf = ""
    while (buflen = length(buf)) < cmax && !((c = getch()) in [0xff, 0x0d, 0x0a])
        reposition(row, col)
        clearfromcursor()
        if c == '\b' && buflen > 0
            buf = buf[1:end-1]
        else
            buf = buf * Char(c)
        end
        print(buf[(buflen > width ? buflen - width + 1 : 1):end])
    end
    return buf
end

cls()
reposition(3, 5)
s = input_y_x_upto(3, 5, 80, 8)
println("\n\n\nResult:  You entered <<$s>>")

Kotlin

Works with: Windows 10

This follows a similar approach to the Kotlin entry for the Terminal control/Restricted width positional input/No wrapping task except, of course, that the code now allows for wrapping.

// Kotlin Native v0.5

import kotlinx.cinterop.*
import platform.windows.*
import platform.posix.*

val ascii = 32..126
val conOut = GetStdHandle(STD_OUTPUT_HANDLE)!!

fun setCursor(p: COORD) = SetConsoleCursorPosition(conOut, p.readValue())

fun getInput(row: Short, col: Short, width: Int): String {
    require(row in 0..20 && col in 0..(79 - width) && width in 1..78) { "Invalid parameter(s)" }
    val coord = nativeHeap.alloc<COORD>().apply { X = col; Y = row }
    setCursor(coord)
    val sb = StringBuilder(width)
    var wlen = 0                                          // length of text in editing window
    var full = false
    loop@ while (true) {
        val ch = _getwch()                                // gets next character, no echo
        when (ch.toInt()) {
            3, 13 -> break@loop                           // break on Ctrl-C or enter key

            8 -> {                                        // mimic backspace
                if (wlen > 0) {
                    print("\b \b")
                    sb.length--
                    wlen--
                }
                if (sb.length > wlen) {
                    coord.apply { X = col; Y = row }
                    setCursor(coord)
                    print(sb.toString().takeLast(width))
                    wlen = width
                }
            }

            0, 224 -> _getwch()                           // consume extra character

            in ascii -> {                                 // echo ascii character
                sb.append(ch.toChar())
                if (!full) {
                    _putwch(ch)
                    wlen++
                }
                else if (sb.length > wlen) {
                    coord.apply { X = col; Y = row }
                    setCursor(coord)
                    print(sb.toString().takeLast(width))
                }
            }

            else -> {}                                    // igore other characters
        }
        full = wlen == width                              // wlen can't exceed width
    }
    nativeHeap.free(coord)
    return sb.toString()
}

fun main(args: Array<String>) {
    system("cls")  // clear the console
    val s = getInput(2, 4, 8)  // Windows console row/col numbering starts at 0
    memScoped {
        val coord = alloc<COORD>().apply { X = 0 ; Y = 22 }
        setCursor(coord)
    }
    println("You entered '$s'")
}

Nim

Translation of: Julia

Rather than using directly escape codes, we use the standard module terminal which works on Posix systems and on Windows. Unfortunately, there is no function to clear from cursor to end of line, so we had to provide one, but it works only on Posix systems.

We had also to check for backspace character and for character '\x7f' as the backspace key gives this last value (but Control+H gives '\x08' i.e. ASCII backspace character).

import strformat, terminal

proc eraseLineEnd() = stdout.write("\e[K")

proc inputXYUpto(row, col, cmax: int; width = cmax): string =
  while result.len < cmax and not ((let c = getch(); c) in ['\xff', '\f', '\r']):
    setCursorPos(row, col)
    eraseLineEnd()
    if c in ['\b', '\x7f'] and result.len > 0:
      result.setLen(result.len - 1)
    else:
      result.add c
    stdout.write result[(if result.len > width: result.len - width else: 0)..result.high]

eraseScreen()
setCursorPos(3, 5)
let s = inputXYUpto(3, 5, 80, 8)
echo &"\n\n\nResult:  You entered <<{s}>>"

Perl

#!/usr/bin/perl

use strict; # https://rosettacode.org/wiki/Terminal_control/Restricted_width_positional_input/With_wrapping
use warnings;
use Term::ReadKey;

sub input
  {
  my ($row, $column, $length) = @_;
  my ($input, $done, $start) = ( '', 0,
    "\e[$row;${column}H" . ' ' x $length . "\e[$row;${column}H");
  local $| = 1;
  ReadMode 'raw';
  until( $done )
    {
    print $start, substr $input, -$length;
    local $_ = ReadKey 0;
    if( tr/ -~// ) { $input .= $_ } # add char
    elsif( tr/\cu// ) { $input = '' } # clear all
    elsif( tr/\b\x7f// ) { chop $input } # delete last char
    elsif( tr/\n\r\e\cc// ) { $done++ } # guess!
    }
  ReadMode 'restore';
  return $input;
  }

print "\e[H\e[Jinput at row 3 column 5 length 8\n";
my $in = input( 3, 5, 8 );
print "\n\n\ninput is $in\n\n";

Phix

without js -- (position, wait_key)
function getInput(integer row, col, width)
    position(row,col)
    string s = ""
    while 1 do
        integer ch = wait_key()
        if ch='\r' then exit end if
        if ch='\b' then
            if length(s)>0 then
                puts(1,"\b \b")
                s = s[1..$-1]
            end if
            if length(s)>=width then
                position(row,col)
                puts(1,s[-width..-1])
            end if
        elsif ch>=' ' and ch<='~' then
            s &= ch
            if length(s)<=width then
                puts(1,ch)
            else
                position(row,col)
                puts(1,s[-width..-1])
            end if
        end if
    end while
    return s
end function 
 
clear_screen() -- clear the console
string s = getInput(3, 5, 8)
position(23,1)
printf(1,"You entered '%s'\n",{s})

Raku

(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";
}

REXX

(Only works with:   REXX/Personal)

/*REXX pgm reads text from the terminal screen from a certain  row,  column, and length.*/
parse arg row col len .                          /*obtain optional arguments from the CL*/
if row=='' | row==","  then row= 3               /*Not specified?  Then use the default.*/
if col=='' | col==","  then col= 5               /* "      "         "   "   "     "    */
if len=='' | len==","  then len= 8               /* "      "         "   "   "     "    */
parse upper version v .                          /*obtain the version of REXX being used*/

if v\=='REXX/PERSONAL'  then do;  say            /*Not correct version?   Tell err msg. */
                                  say '***error***:'
                                  say 'This REXX program requires Personal REXX version.'
                                  say
                                  exit 13
                             end
$= scrread(row, col, len)
say 'data read from terminal row '  row  "    col "  col  '    length '  len  "   is:"
say $
exit 0                                           /*stick a fork in it,  we're all done. */

Wren

Due to a bug the Stdin.readByte() method can currently process only the first byte of a multi-byte character. The others are skipped.

import "io" for Stdin, Stdout

var textAtPos = Fn.new { |text, r, c|
    System.write("\e[%(r);%(c)H%(text)")
    Stdout.flush()
}

var input = Fn.new { |r, c, maxWidth|
    System.write("\e[2J")
    textAtPos.call("", r, c)
    Stdin.isRaw = true
    var res = ""
    var blank = " " * (maxWidth-1)
    while (true) {
        var byte = Stdin.readByte()
        if (byte >= 32 && byte < 127) {        // All printable ASCII characters
            var char = String.fromByte(byte)
            res = res + char
            var count = res.count
            if (count <= maxWidth-1) {
                textAtPos.call(res, r, c)
            } else {
                textAtPos.call(res[-maxWidth+1..-1], r, c)
            }
        } else if (byte == 127 && res.count > 0) {     // Backspace/delete (127 used rather than 8)
            res = res[0...-1]
            var count = res.count
            if (count <= maxWidth-1) {
                textAtPos.call(blank, r, c)
                textAtPos.call(res, r, c)
            } else {
                textAtPos.call(res[-maxWidth+1..-1], r, c)
            }
        } else if (byte == 13 || byte == 10) { // Carriage return or line feed
            System.print()
            break
        } else if (byte == 3 || byte == 4) {   // Ctrl-C or Ctrl-D
            Fiber.abort("\nScript aborted")
        }
    }
    Stdin.isRaw = false
    return res
}

var res = input.call(3, 5, 8)
System.print(res)

Yabasic

// Rosetta Code problem: http://rosettacode.org/wiki/Restricted_width_positional_input/With_wrapping
// by Galileo, 04/2022

clear screen

sub getInput$(r, c, long)
    local text$, c$, ini, lt
    
    c = c - 1
    r = r - 1
    print at(c, r);
    do
        c$ = inkey$
        if c$ = "enter" break
        if c$ = "backspace" then
            text$ = left$(text$, len(text$) - 1)
            print "\b ";
        else
            text$ = text$ + c$
        end if
        lt = len(text$)
        if lt > long then ini = lt - long + 1 else ini = 1 end if
        print at(c, r) mid$(text$, ini, long);
    loop
    
    return text$
end sub

text$ = getInput$(3, 5, 8)
 
print at(1, 23) "You entered: ", text$