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

Content added Content deleted
mNo edit summary
(Added Kotlin)
Line 13: Line 13:


[[Category:Terminal control]]
[[Category:Terminal control]]

=={{header|Kotlin}}==
{{works with|Windows 10}}
This assumes an 80 x 25 Windows console and uses the Win32 function _getwch() to get character input without (immediately) echoing it to the console. Only ASCII characters in the range 32 to 126 are then printed if the maximum width would not be exceeded.

Apart from these, only the backspace key (8), return key (13) and Ctrl-C (3) are handled, all other keys being ignored. Some keys (such as the function and arrow keys) return a two character sequence starting with either 0 or 224 and so, after the first character is trapped, the second character needs to be removed from the buffer.

It would also be possible to allow for printable Unicode characters (>= 160) to be entered by adding an extra clause to the 'when' statement. However, for this to work properly, you will need to be using a suitable code page (65001, say) and a suitable font (Lucida Console, say).
<lang scala>// 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)" }
memScoped {
val coord = alloc<COORD>().apply { X = col; Y = row }
setCursor(coord)
}
val sb = StringBuilder(width)
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 -> if (sb.length > 0) { print("\b \b"); sb.length-- } // mimic backspace
0, 224 -> _getwch() // consume extra character
in ascii -> if (!full) { _putwch(ch); sb.append(ch.toChar()) } // echo ascii character
else -> {} // igore other characters
}
full = sb.length == width // can't exceed width
}
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'")
}</lang>