windows keybindings

added uniterm based on nimline
This commit is contained in:
Productive2 2021-02-19 13:27:09 +01:00
parent 5d56d59c7f
commit 0390de150a
6 changed files with 124 additions and 41 deletions

2
.gitignore vendored
View File

@ -1,7 +1,7 @@
examples/editor examples/editor
examples/interactive_basic examples/interactive_basic
examples/interactive_history examples/interactive_history
getkey examples/getkey
# Ignore all # Ignore all
tests/* tests/*

25
NOTICE.md Normal file
View File

@ -0,0 +1,25 @@
# Sources of inspiration
https://github.com/h3rald/nimline
MIT License
Copyright (c) 2017 Fabio Cevasco
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

28
examples/getkey.nim Normal file
View File

@ -0,0 +1,28 @@
# handy tool that prints out char codes when pressed
import jale/uniterm
import jale/keycodes
import strutils
import terminal
import os
import tables
echo "Press 'ctrl+c' to quit"
echo "Press 'ctrl+a' to print a horizontal bar"
var escape = false
if paramCount() > 0 and paramStr(1) == "esc":
escape = true
while true:
let key = if escape: getKey() else: int(uniGetchr())
if key == 3:
break
if key == 1:
echo "=".repeat(terminalWidth())
else:
if keysById.hasKey(key):
echo keysById[key]
else:
echo key

View File

@ -1,15 +0,0 @@
# handy tool that prints out char codes when pressed
import terminal
import strutils
echo "Press 'ctrl+c' to quit"
echo "Press 'ctrl+a' to print a horizontal bar"
while true:
let key = int(getch())
if key == 3:
break
if key == 1:
echo "=".repeat(terminalWidth())
else:
echo key

View File

@ -2,18 +2,19 @@
import tables import tables
import strutils import strutils
import terminal import uniterm
type type
JaleKeycode* = enum JaleKeycode* = enum
jkStart = 255 # jale keycodes exported start one above jkStart jkStart = 255 # jale keycodes exported start one above jkStart
# arrow keys
jkLeft = 256, jkRight, jkUp, jkDown, jkLeft = 256, jkRight, jkUp, jkDown,
jkHome, jkEnd, jkPageUp, jkPageDown,
jkShiftLeft, jkShiftRight, jkShiftUp, jkShiftDown,
jkCtrlLeft, jkCtrlRight, jkCtrlUp, jkCtrlDown, jkCtrlLeft, jkCtrlRight, jkCtrlUp, jkCtrlDown,
# other 4 move keys
jkHome, jkEnd, jkPageUp, jkPageDown,
jkCtrlHome, jkCtrlEnd, jkCtrlPageUp, jkCtrlPageDown, jkCtrlHome, jkCtrlEnd, jkCtrlPageUp, jkCtrlPageDown,
jkDelete, jkBackspace, # special keys
jkInsert, jkEnter jkDelete, jkBackspace, jkInsert, jkEnter,
jkFinish, # jale keycodes exported end one below jkFinish jkFinish, # jale keycodes exported end one below jkFinish
# non-exported jale keycodes come here: # non-exported jale keycodes come here:
@ -28,6 +29,12 @@ block:
keysById[i] = "ctrl+" & $char(i + 96) keysById[i] = "ctrl+" & $char(i + 96)
keysById[9] = "tab" keysById[9] = "tab"
# keysById[8] will never get triggered because it's an escape seq
keysById[28] = r"ctrl+\"
keysById[29] = "ctrl+]"
keysByName[r"ctrl+\"] = 28
keysByName["ctrl+]"] = 29
for i in countup(1, 26): for i in countup(1, 26):
keysByName[keysById[i]] = i keysByName[keysById[i]] = i
@ -51,15 +58,33 @@ proc defEscSeq(keys: seq[int], id: JaleKeycode) =
block: block:
when defined(windows): when defined(windows):
defEscSeq(@[224], jkContinue) defEscSeq(@[224], jkContinue)
# arrow keys
defEscSeq(@[224, 72], jkUp) defEscSeq(@[224, 72], jkUp)
defEscSeq(@[224, 80], jkDown) defEscSeq(@[224, 80], jkDown)
defEscSeq(@[224, 77], jkRight) defEscSeq(@[224, 77], jkRight)
defEscSeq(@[224, 75], jkLeft) defEscSeq(@[224, 75], jkLeft)
# ctrl+arrow keys
defEscSeq(@[224, 141], jkCtrlUp)
defEscSeq(@[224, 145], jkCtrlDown)
defEscSeq(@[224, 116], jkCtrlRight)
defEscSeq(@[224, 115], jkCtrlLeft)
# moves
defEscSeq(@[224, 71], jkHome) defEscSeq(@[224, 71], jkHome)
defEscSeq(@[224, 79], jkEnd) defEscSeq(@[224, 79], jkEnd)
defEscSeq(@[224, 73], jkPageUp)
defEscSeq(@[224, 81], jkPageDown)
# ctrl+moves
defEscSeq(@[224, 134], jkCtrlPageUp)
defEscSeq(@[224, 118], jkCtrlPageDown)
defEscSeq(@[224, 115], jkCtrlHome)
defEscSeq(@[224, 116], jkCtrlEnd)
# special keys
defEscSeq(@[8], jkBackspace)
defEscSeq(@[13], jkEnter)
defEscSeq(@[224, 82], jkInsert) defEscSeq(@[224, 82], jkInsert)
defEscSeq(@[224, 83], jkDelete) defEscSeq(@[224, 83], jkDelete)
# TODO: finish defining escape sequences
else: else:
# arrow keys # arrow keys
defEscSeq(@[27], jkContinue) defEscSeq(@[27], jkContinue)
@ -73,33 +98,19 @@ block:
defEscSeq(@[27, 91, 49], jkContinue) defEscSeq(@[27, 91, 49], jkContinue)
defEscSeq(@[27, 91, 49, 59], jkContinue) defEscSeq(@[27, 91, 49, 59], jkContinue)
defEscSeq(@[27, 91, 49, 59, 53], jkContinue) # ctrl defEscSeq(@[27, 91, 49, 59, 53], jkContinue) # ctrl
defEscSeq(@[27, 91, 49, 59, 50], jkContinue) # shift
defEscSeq(@[27, 91, 49, 59, 50, 65], jkShiftUp) defEscSeq(@[27, 91, 49, 59, 50], jkContinue) # shift
defEscSeq(@[27, 91, 49, 59, 50, 66], jkShiftDown)
defEscSeq(@[27, 91, 49, 59, 50, 67], jkShiftRight)
defEscSeq(@[27, 91, 49, 59, 50, 68], jkShiftLeft)
defEscSeq(@[27, 91, 49, 59, 53, 65], jkCtrlUp) # ctrl defEscSeq(@[27, 91, 49, 59, 53, 65], jkCtrlUp) # ctrl
defEscSeq(@[27, 91, 49, 59, 53, 66], jkCtrlDown) # ctrl defEscSeq(@[27, 91, 49, 59, 53, 66], jkCtrlDown) # ctrl
defEscSeq(@[27, 91, 49, 59, 53, 67], jkCtrlRight) # ctrl defEscSeq(@[27, 91, 49, 59, 53, 67], jkCtrlRight) # ctrl
defEscSeq(@[27, 91, 49, 59, 53, 68], jkCtrlLeft) # ctrl defEscSeq(@[27, 91, 49, 59, 53, 68], jkCtrlLeft) # ctrl
# home, end # other 4 move keys
defEscSeq(@[27, 91, 72], jkHome) defEscSeq(@[27, 91, 72], jkHome)
defEscSeq(@[27, 91, 70], jkEnd) defEscSeq(@[27, 91, 70], jkEnd)
# ctrl+ home, end
defEscSeq(@[27, 91, 49, 59, 53, 72], jkCtrlHome)
defEscSeq(@[27, 91, 49, 59, 53, 70], jkCtrlEnd)
# fancy keys like delete, insert, pgup, pgdown
defEscSeq(@[27, 91, 51], jkContinue)
defEscSeq(@[27, 91, 50], jkContinue)
defEscSeq(@[27, 91, 54], jkContinue) defEscSeq(@[27, 91, 54], jkContinue)
defEscSeq(@[27, 91, 53], jkContinue) defEscSeq(@[27, 91, 53], jkContinue)
defEscSeq(@[27, 91, 51, 126], jkDelete)
defEscSeq(@[27, 91, 50, 126], jkInsert)
defEscSeq(@[27, 91, 53, 126], jkPageUp) defEscSeq(@[27, 91, 53, 126], jkPageUp)
defEscSeq(@[27, 91, 54, 126], jkPageDown) defEscSeq(@[27, 91, 54, 126], jkPageDown)
@ -111,16 +122,24 @@ block:
defEscSeq(@[27, 91, 54, 59, 53], jkContinue) defEscSeq(@[27, 91, 54, 59, 53], jkContinue)
defEscSeq(@[27, 91, 54, 59, 53, 126], jkCtrlPageDown) defEscSeq(@[27, 91, 54, 59, 53, 126], jkCtrlPageDown)
# other keys # ctrl+ home, end
defEscSeq(@[27, 91, 49, 59, 53, 72], jkCtrlHome)
defEscSeq(@[27, 91, 49, 59, 53, 70], jkCtrlEnd)
# other keys
defEscSeq(@[27, 91, 51], jkContinue)
defEscSeq(@[27, 91, 50], jkContinue)
defEscSeq(@[27, 91, 51, 126], jkDelete)
defEscSeq(@[27, 91, 50, 126], jkInsert)
defEscSeq(@[13], jkEnter) defEscSeq(@[13], jkEnter)
defEscSeq(@[127], jkBackspace) defEscSeq(@[127], jkBackspace)
# TODO ctrl+h as backspace? test more terminals defEscSeq(@[8], jkBackspace)
proc getKey*: int = proc getKey*: int =
var key: int = 0 var key: int = 0
while true: while true:
key *= 256 key *= 256
key += int(getch()) key += int(uniGetChr())
if escapeSeqs.hasKey(key): if escapeSeqs.hasKey(key):
if escapeSeqs[key] != jkContinue: if escapeSeqs[key] != jkContinue:
key = int(escapeSeqs[key]) key = int(escapeSeqs[key])

26
src/jale/uniterm.nim Normal file
View File

@ -0,0 +1,26 @@
## Universal (cross platform) terminal abstractions
# source: https://github.com/h3rald/nimline/blob/master/nimline.nim
# lines 42-56 (modified)
when defined(windows):
proc putchr(c: cint): cint {.discardable, header: "<conio.h>", importc: "_putch".}
proc getchr(): cint {.header: "<conio.h>", importc: "_getch".}
proc uniPutChr*(c: char) =
## Prints an ASCII character to stdout.
putchr(c.cint)
proc uniGetChr*: int =
## Retrieves an ASCII character from stdin.
getchr().int
else:
import terminal
proc uniPutChr*(c: char) =
## Prints an ASCII character to stdout.
stdout.write(c)
proc uniGetChr*: int =
## Retrieves an ASCII character from stdin.
return getch().int