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> |