pax_global_header 0000666 0000000 0000000 00000000064 14650122720 0014511 g ustar 00root root 0000000 0000000 52 comment=77b6635b2ae7664a00c043d0d7ce955f3188e4f6
golang-github-atomicgo-keyboard-0.2.9/ 0000775 0000000 0000000 00000000000 14650122720 0017646 5 ustar 00root root 0000000 0000000 golang-github-atomicgo-keyboard-0.2.9/.github/ 0000775 0000000 0000000 00000000000 14650122720 0021206 5 ustar 00root root 0000000 0000000 golang-github-atomicgo-keyboard-0.2.9/.github/custom_readme 0000664 0000000 0000000 00000000001 14650122720 0023747 0 ustar 00root root 0000000 0000000
golang-github-atomicgo-keyboard-0.2.9/.github/settings.yml 0000664 0000000 0000000 00000001624 14650122720 0023574 0 ustar 00root root 0000000 0000000 _extends: .github
repository:
# See https://developer.github.com/v3/repos/#edit for all available settings.
# A short description of the repository that will show up on GitHub
description: ⌨️ Read keyboard events in your terminal applications! (Arrow keys, Home, End, etc.)
# A comma-separated list of topics to set on the repository
topics: atomicgo, go, golang, keyboard, terminal, cli
# Either `true` to make the repository private, or `false` to make it public.
# private: false
# Either `true` to enable issues for this repository, `false` to disable them.
# has_issues: true
# Either `true` to enable projects for this repository, or `false` to disable them.
# If projects are disabled for the organization, passing `true` will cause an API error.
# has_projects: false
# Either `true` to enable the wiki for this repository, `false` to disable it.
# has_wiki: false
golang-github-atomicgo-keyboard-0.2.9/.github/workflows/ 0000775 0000000 0000000 00000000000 14650122720 0023243 5 ustar 00root root 0000000 0000000 golang-github-atomicgo-keyboard-0.2.9/.github/workflows/atomicgo.yml 0000664 0000000 0000000 00000000452 14650122720 0025571 0 ustar 00root root 0000000 0000000 on: push
name: AtomicGo
jobs:
docs:
if: "!contains(github.event.head_commit.message, 'autoupdate')"
runs-on: ubuntu-latest
steps:
- name: Update Docs
uses: atomicgo/ci@main
env:
ACCESS_TOKEN: ${{ secrets.ACCESS_TOKEN }}
TERM: xterm-256color
golang-github-atomicgo-keyboard-0.2.9/.github/workflows/go.yml 0000664 0000000 0000000 00000001355 14650122720 0024377 0 ustar 00root root 0000000 0000000 name: Go
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
jobs:
build:
name: Build
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ ubuntu-latest, windows-latest, macos-latest ]
steps:
- name: Set up Go 1.x
uses: actions/setup-go@v2
with:
go-version: ^1
id: go
- name: Check out code into the Go module directory
uses: actions/checkout@v2
- name: Get dependencies
run: go get -v -t -d ./...
- name: Build
run: go build -v .
- name: Test
run: go test -coverprofile="coverage.txt" -covermode=atomic -v -p 1 .
- name: Upload coverage to Codecov
uses: codecov/codecov-action@v1
golang-github-atomicgo-keyboard-0.2.9/.github/workflows/golangci.yml 0000664 0000000 0000000 00000000501 14650122720 0025545 0 ustar 00root root 0000000 0000000 name: golangci-lint
on: [ pull_request ]
jobs:
golangci:
name: lint
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Set up Go
uses: actions/setup-go@v2
- name: golangci-lint
uses: golangci/golangci-lint-action@v3
with:
version: latest
golang-github-atomicgo-keyboard-0.2.9/.github/workflows/tweet-release.yml 0000664 0000000 0000000 00000001616 14650122720 0026540 0 ustar 00root root 0000000 0000000 name: tweet-release
# Listen to the `release` event
on:
release:
types: [published]
jobs:
tweet:
runs-on: ubuntu-latest
steps:
- uses: Eomm/why-don-t-you-tweet@v1
# We don't want to tweet if the repository is not a public one
if: ${{ !github.event.repository.private }}
with:
tweet-message: "New ${{ github.event.repository.name }} release: ${{ github.event.release.tag_name }}! 🎉
Try it out: ${{ github.event.release.html_url }}
#go #golang #opensource #library #release #atomicgo"
env:
TWITTER_CONSUMER_API_KEY: ${{ secrets.TWITTER_CONSUMER_API_KEY }}
TWITTER_CONSUMER_API_SECRET: ${{ secrets.TWITTER_CONSUMER_API_SECRET }}
TWITTER_ACCESS_TOKEN: ${{ secrets.TWITTER_ACCESS_TOKEN }}
TWITTER_ACCESS_TOKEN_SECRET: ${{ secrets.TWITTER_ACCESS_TOKEN_SECRET }}
golang-github-atomicgo-keyboard-0.2.9/.gitignore 0000664 0000000 0000000 00000000661 14650122720 0021641 0 ustar 00root root 0000000 0000000 ### Go template
# Binaries for programs and plugins
*.exe
*.exe~
*.dll
*.so
*.dylib
# Test binary, built with `go test -c`
*.test
# Output of the go coverage tool, specifically when used with LiteIDE
*.out
# Dependency directories (remove the comment below to include it)
vendor/
### IntelliJ
.idea
*.iml
out
gen
### VisualStudioCode
.vscode
*.code-workspace
### macOS
# General
.DS_Store
# Experimenting folder
experimenting
golang-github-atomicgo-keyboard-0.2.9/.golangci.yml 0000664 0000000 0000000 00000002525 14650122720 0022236 0 ustar 00root root 0000000 0000000 linters-settings:
gocritic:
enabled-tags:
- diagnostic
- experimental
- opinionated
- performance
- style
disabled-checks:
- dupImport
- ifElseChain
- octalLiteral
- whyNoLint
- wrapperFunc
- exitAfterDefer
- hugeParam
- ptrToRefParam
- paramTypeCombine
- unnamedResult
misspell:
locale: US
linters:
disable-all: true
enable:
- errcheck
- gosimple
- govet
- ineffassign
- staticcheck
- asciicheck
- bodyclose
- dupl
- durationcheck
- errorlint
- exhaustive
- gci
- gocognit
- gocritic
- godot
- godox
- goerr113
- gofmt
- goimports
- goprintffuncname
- misspell
- nilerr
- nlreturn
- noctx
- prealloc
- predeclared
- thelper
- unconvert
- unparam
- wastedassign
- wrapcheck
issues:
# Excluding configuration per-path, per-linter, per-text and per-source
exclude-rules:
- path: _test\.go
linters:
- errcheck
- dupl
- gocritic
- wrapcheck
- goerr113
# https://github.com/go-critic/go-critic/issues/926
- linters:
- gocritic
text: "unnecessaryDefer:"
service:
golangci-lint-version: 1.39.x # use the fixed version to not introduce new linters unexpectedly
golang-github-atomicgo-keyboard-0.2.9/LICENSE 0000664 0000000 0000000 00000002074 14650122720 0020656 0 ustar 00root root 0000000 0000000 MIT License
Copyright (c) 2020 Marvin Wendt (MarvinJWendt)
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.
golang-github-atomicgo-keyboard-0.2.9/README.md 0000664 0000000 0000000 00000013634 14650122720 0021134 0 ustar 00root root 0000000 0000000
AtomicGo | keyboard
---
Get The Module
|
Documentation
|
Contributing
|
Code of Conduct
---
![]()
-----------------------------------------------------------------------------------------------------
|
go get atomicgo.dev/keyboard
![]()
-----------------------------------------------------------------------------------------------------
|
## Description
Package keyboard can be used to read key presses from the keyboard, while in a
terminal application. It's crossplatform and keypresses can be combined to check
for ctrl+c, alt+4, ctrl-shift, alt+ctrl+right, etc. It can also be used to
simulate (mock) keypresses for CI testing.
Works nicely with https://atomicgo.dev/cursor
## Simple Usage
```go
keyboard.Listen(func(key keys.Key) (stop bool, err error) {
if key.Code == keys.CtrlC {
return true, nil // Stop listener by returning true on Ctrl+C
}
fmt.Println("\r" + key.String()) // Print every key press
return false, nil // Return false to continue listening
})
```
## Advanced Usage
```go
// Stop keyboard listener on Escape key press or CTRL+C.
// Exit application on "q" key press.
// Print every rune key press.
// Print every other key press.
keyboard.Listen(func(key keys.Key) (stop bool, err error) {
switch key.Code {
case keys.CtrlC, keys.Escape:
return true, nil // Return true to stop listener
case keys.RuneKey: // Check if key is a rune key (a, b, c, 1, 2, 3, ...)
if key.String() == "q" { // Check if key is "q"
fmt.Println("\rQuitting application")
os.Exit(0) // Exit application
}
fmt.Printf("\rYou pressed the rune key: %s\n", key)
default:
fmt.Printf("\rYou pressed: %s\n", key)
}
return false, nil // Return false to continue listening
})
```
## Simulate Key Presses (for mocking in tests)
```go
go func() {
keyboard.SimulateKeyPress("Hello") // Simulate key press for every letter in string
keyboard.SimulateKeyPress(keys.Enter) // Simulate key press for Enter
keyboard.SimulateKeyPress(keys.CtrlShiftRight) // Simulate key press for Ctrl+Shift+Right
keyboard.SimulateKeyPress('x') // Simulate key press for a single rune
keyboard.SimulateKeyPress('x', keys.Down, 'a') // Simulate key presses for multiple inputs
keyboard.SimulateKeyPress(keys.Escape) // Simulate key press for Escape, which quits the program
}()
keyboard.Listen(func(key keys.Key) (stop bool, err error) {
if key.Code == keys.Escape || key.Code == keys.CtrlC {
os.Exit(0) // Exit program on Escape
}
fmt.Println("\r" + key.String()) // Print every key press
return false, nil // Return false to continue listening
})
```
## Usage
#### func Listen
```go
func Listen(onKeyPress func(key keys.Key) (stop bool, err error)) error
```
Listen calls a callback function when a key is pressed.
Simple example:
keyboard.Listen(func(key keys.Key) (stop bool, err error) {
if key.Code == keys.CtrlC {
return true, nil // Stop listener by returning true on Ctrl+C
}
fmt.Println("\r" + key.String()) // Print every key press
return false, nil // Return false to continue listening
})
#### func SimulateKeyPress
```go
func SimulateKeyPress(input ...interface{}) error
```
SimulateKeyPress simulate a key press. It can be used to mock user input and
test your application.
Example:
go func() {
keyboard.SimulateKeyPress("Hello") // Simulate key press for every letter in string
keyboard.SimulateKeyPress(keys.Enter) // Simulate key press for Enter
keyboard.SimulateKeyPress(keys.CtrlShiftRight) // Simulate key press for Ctrl+Shift+Right
keyboard.SimulateKeyPress('x') // Simulate key press for a single rune
keyboard.SimulateKeyPress('x', keys.Down, 'a') // Simulate key presses for multiple inputs
}()
---
> [AtomicGo.dev](https://atomicgo.dev) ·
> with ❤️ by [@MarvinJWendt](https://github.com/MarvinJWendt) |
> [MarvinJWendt.com](https://marvinjwendt.com)
golang-github-atomicgo-keyboard-0.2.9/codecov.yml 0000664 0000000 0000000 00000000202 14650122720 0022005 0 ustar 00root root 0000000 0000000 coverage:
status:
project:
default:
informational: true
patch:
default:
informational: true
golang-github-atomicgo-keyboard-0.2.9/doc.go 0000664 0000000 0000000 00000004421 14650122720 0020743 0 ustar 00root root 0000000 0000000 /*
Package keyboard can be used to read key presses from the keyboard, while in a terminal application. It's crossplatform and keypresses can be combined to check for ctrl+c, alt+4, ctrl-shift, alt+ctrl+right, etc.
It can also be used to simulate (mock) keypresses for CI testing.
Works nicely with https://atomicgo.dev/cursor
## Simple Usage
keyboard.Listen(func(key keys.Key) (stop bool, err error) {
if key.Code == keys.CtrlC {
return true, nil // Stop listener by returning true on Ctrl+C
}
fmt.Println("\r" + key.String()) // Print every key press
return false, nil // Return false to continue listening
})
## Advanced Usage
// Stop keyboard listener on Escape key press or CTRL+C.
// Exit application on "q" key press.
// Print every rune key press.
// Print every other key press.
keyboard.Listen(func(key keys.Key) (stop bool, err error) {
switch key.Code {
case keys.CtrlC, keys.Escape:
return true, nil // Return true to stop listener
case keys.RuneKey: // Check if key is a rune key (a, b, c, 1, 2, 3, ...)
if key.String() == "q" { // Check if key is "q"
fmt.Println("\rQuitting application")
os.Exit(0) // Exit application
}
fmt.Printf("\rYou pressed the rune key: %s\n", key)
default:
fmt.Printf("\rYou pressed: %s\n", key)
}
return false, nil // Return false to continue listening
})
## Simulate Key Presses (for mocking in tests)
go func() {
keyboard.SimulateKeyPress("Hello") // Simulate key press for every letter in string
keyboard.SimulateKeyPress(keys.Enter) // Simulate key press for Enter
keyboard.SimulateKeyPress(keys.CtrlShiftRight) // Simulate key press for Ctrl+Shift+Right
keyboard.SimulateKeyPress('x') // Simulate key press for a single rune
keyboard.SimulateKeyPress('x', keys.Down, 'a') // Simulate key presses for multiple inputs
keyboard.SimulateKeyPress(keys.Escape) // Simulate key press for Escape, which quits the program
}()
keyboard.Listen(func(key keys.Key) (stop bool, err error) {
if key.Code == keys.Escape || key.Code == keys.CtrlC {
os.Exit(0) // Exit program on Escape
}
fmt.Println("\r" + key.String()) // Print every key press
return false, nil // Return false to continue listening
})
*/
package keyboard
golang-github-atomicgo-keyboard-0.2.9/doc_test.go 0000664 0000000 0000000 00000003670 14650122720 0022007 0 ustar 00root root 0000000 0000000 package keyboard
import (
"fmt"
"os"
"atomicgo.dev/keyboard/keys"
)
func ExampleListen_simple() {
Listen(func(key keys.Key) (stop bool, err error) {
if key.Code == keys.CtrlC {
return true, nil // Stop listener by returning true on Ctrl+C
}
fmt.Println("\r" + key.String()) // Print every key press
return false, nil // Return false to continue listening
})
}
func ExampleListen_advanced() {
// Stop keyboard listener on Escape key press or CTRL+C.
// Exit application on "q" key press.
// Print every rune key press.
// Print every other key press.
Listen(func(key keys.Key) (stop bool, err error) {
switch key.Code {
case keys.CtrlC, keys.Escape:
return true, nil // Return true to stop listener
case keys.RuneKey: // Check if key is a rune key (a, b, c, 1, 2, 3, ...)
if key.String() == "q" { // Check if key is "q"
fmt.Println("\rQuitting application")
os.Exit(0) // Exit application
}
fmt.Printf("\rYou pressed the rune key: %s\n", key)
default:
fmt.Printf("\rYou pressed: %s\n", key)
}
return false, nil // Return false to continue listening
})
}
func ExampleSimulateKeyPress() {
go func() {
SimulateKeyPress("Hello") // Simulate key press for every letter in string
SimulateKeyPress(keys.Enter) // Simulate key press for Enter
SimulateKeyPress(keys.CtrlShiftRight) // Simulate key press for Ctrl+Shift+Right
SimulateKeyPress('x') // Simulate key press for a single rune
SimulateKeyPress('x', keys.Down, 'a') // Simulate key presses for multiple inputs
SimulateKeyPress(keys.Escape) // Simulate key press for Escape, which quits the program
}()
Listen(func(key keys.Key) (stop bool, err error) {
if key.Code == keys.Escape || key.Code == keys.CtrlC {
os.Exit(0) // Exit program on Escape
}
fmt.Println("\r" + key.String()) // Print every key press
return false, nil // Return false to continue listening
})
}
golang-github-atomicgo-keyboard-0.2.9/go.mod 0000664 0000000 0000000 00000000200 14650122720 0020744 0 ustar 00root root 0000000 0000000 module atomicgo.dev/keyboard
go 1.15
require (
github.com/MarvinJWendt/testza v0.4.2
github.com/containerd/console v1.0.3
)
golang-github-atomicgo-keyboard-0.2.9/go.sum 0000664 0000000 0000000 00000014312 14650122720 0021002 0 ustar 00root root 0000000 0000000 github.com/MarvinJWendt/testza v0.1.0/go.mod h1:7AxNvlfeHP7Z/hDQ5JtE3OKYT3XFUeLCDE2DQninSqs=
github.com/MarvinJWendt/testza v0.2.1/go.mod h1:God7bhG8n6uQxwdScay+gjm9/LnO4D3kkcZX4hv9Rp8=
github.com/MarvinJWendt/testza v0.2.8/go.mod h1:nwIcjmr0Zz+Rcwfh3/4UhBp7ePKVhuBExvZqnKYWlII=
github.com/MarvinJWendt/testza v0.2.10/go.mod h1:pd+VWsoGUiFtq+hRKSU1Bktnn+DMCSrDrXDpX2bG66k=
github.com/MarvinJWendt/testza v0.2.12/go.mod h1:JOIegYyV7rX+7VZ9r77L/eH6CfJHHzXjB69adAhzZkI=
github.com/MarvinJWendt/testza v0.3.0/go.mod h1:eFcL4I0idjtIx8P9C6KkAuLgATNKpX4/2oUqKc6bF2c=
github.com/MarvinJWendt/testza v0.4.2 h1:Vbw9GkSB5erJI2BPnBL9SVGV9myE+XmUSFahBGUhW2Q=
github.com/MarvinJWendt/testza v0.4.2/go.mod h1:mSdhXiKH8sg/gQehJ63bINcCKp7RtYewEjXsvsVUPbE=
github.com/atomicgo/cursor v0.0.1 h1:xdogsqa6YYlLfM+GyClC/Lchf7aiMerFiZQn7soTOoU=
github.com/atomicgo/cursor v0.0.1/go.mod h1:cBON2QmmrysudxNBFthvMtN32r3jxVRIvzkUiF/RuIk=
github.com/containerd/console v1.0.3 h1:lIr7SlA5PxZyMV30bDW0MGbiOPXwc63yRuCP0ARubLw=
github.com/containerd/console v1.0.3/go.mod h1:7LqA/THxQ86k76b8c/EMSiaJ3h1eZkMkXar0TQ1gf3U=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/gookit/color v1.4.2/go.mod h1:fqRyamkC1W8uxl+lxCQxOT09l/vYfZ+QeiX3rKQHCoQ=
github.com/gookit/color v1.5.0 h1:1Opow3+BWDwqor78DcJkJCIwnkviFi+rrOANki9BUFw=
github.com/gookit/color v1.5.0/go.mod h1:43aQb+Zerm/BWh2GnrgOQm7ffz7tvQXEKV6BFMl7wAo=
github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
github.com/klauspost/cpuid/v2 v2.0.10/go.mod h1:g2LTdtYhdyuGPqyWyv7qRAmj1WBqxuObKfj5c0PQa7c=
github.com/klauspost/cpuid/v2 v2.0.12 h1:p9dKCg8i4gmOxtv35DvrYoWqYzQrvEVdjQ762Y0OqZE=
github.com/klauspost/cpuid/v2 v2.0.12/go.mod h1:g2LTdtYhdyuGPqyWyv7qRAmj1WBqxuObKfj5c0PQa7c=
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4OSgU=
github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/pterm/pterm v0.12.27/go.mod h1:PhQ89w4i95rhgE+xedAoqous6K9X+r6aSOI2eFF7DZI=
github.com/pterm/pterm v0.12.29/go.mod h1:WI3qxgvoQFFGKGjGnJR849gU0TsEOvKn5Q8LlY1U7lg=
github.com/pterm/pterm v0.12.30/go.mod h1:MOqLIyMOgmTDz9yorcYbcw+HsgoZo3BQfg2wtl3HEFE=
github.com/pterm/pterm v0.12.31/go.mod h1:32ZAWZVXD7ZfG0s8qqHXePte42kdz8ECtRyEejaWgXU=
github.com/pterm/pterm v0.12.33/go.mod h1:x+h2uL+n7CP/rel9+bImHD5lF3nM9vJj80k9ybiiTTE=
github.com/pterm/pterm v0.12.36/go.mod h1:NjiL09hFhT/vWjQHSj1athJpx6H8cjpHXNAK5bUw8T8=
github.com/pterm/pterm v0.12.40 h1:LvQE43RYegVH+y5sCDcqjlbsRu0DlAecEn9FDfs9ePs=
github.com/pterm/pterm v0.12.40/go.mod h1:ffwPLwlbXxP+rxT0GsgDTzS3y3rmpAO1NMjUkGTYf8s=
github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY=
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
github.com/sergi/go-diff v1.2.0 h1:XU+rvMAioB0UC3q1MFrIQy4Vo5/4VsRDQQXHsEya6xQ=
github.com/sergi/go-diff v1.2.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778 h1:QldyIu/L63oPpyvQmHgvgickp1Yw510KJOqX7H24mg8=
github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778/go.mod h1:2MuV+tbUrU1zIOPMxZ5EncGwgmMJsa+9ucAQZXxsObs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211013075003-97ac67df715c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220319134239-a9b59b0215f8 h1:OH54vjqzRWmbJ62fjuhxy7AxFFgoHN0/DPc/UrL8cAs=
golang.org/x/sys v0.0.0-20220319134239-a9b59b0215f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 h1:JGgROgKl9N8DuW20oFS5gxc+lE67/N3FcwmBPMe7ArY=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo=
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
golang-github-atomicgo-keyboard-0.2.9/input.go 0000664 0000000 0000000 00000017614 14650122720 0021345 0 ustar 00root root 0000000 0000000 package keyboard
import (
"errors"
"fmt"
"os"
"unicode/utf8"
"atomicgo.dev/keyboard/internal"
"atomicgo.dev/keyboard/keys"
)
// Sequence mappings.
var sequences = map[string]keys.Key{
// Arrow keys
"\x1b[A": {Code: keys.Up},
"\x1b[B": {Code: keys.Down},
"\x1b[C": {Code: keys.Right},
"\x1b[D": {Code: keys.Left},
"\x1b[1;2A": {Code: keys.ShiftUp},
"\x1b[1;2B": {Code: keys.ShiftDown},
"\x1b[1;2C": {Code: keys.ShiftRight},
"\x1b[1;2D": {Code: keys.ShiftLeft},
"\x1b[OA": {Code: keys.ShiftUp},
"\x1b[OB": {Code: keys.ShiftDown},
"\x1b[OC": {Code: keys.ShiftRight},
"\x1b[OD": {Code: keys.ShiftLeft},
"\x1b[a": {Code: keys.ShiftUp},
"\x1b[b": {Code: keys.ShiftDown},
"\x1b[c": {Code: keys.ShiftRight},
"\x1b[d": {Code: keys.ShiftLeft},
"\x1b[1;3A": {Code: keys.Up, AltPressed: true},
"\x1b[1;3B": {Code: keys.Down, AltPressed: true},
"\x1b[1;3C": {Code: keys.Right, AltPressed: true},
"\x1b[1;3D": {Code: keys.Left, AltPressed: true},
"\x1b\x1b[A": {Code: keys.Up, AltPressed: true},
"\x1b\x1b[B": {Code: keys.Down, AltPressed: true},
"\x1b\x1b[C": {Code: keys.Right, AltPressed: true},
"\x1b\x1b[D": {Code: keys.Left, AltPressed: true},
"\x1b[1;4A": {Code: keys.ShiftUp, AltPressed: true},
"\x1b[1;4B": {Code: keys.ShiftDown, AltPressed: true},
"\x1b[1;4C": {Code: keys.ShiftRight, AltPressed: true},
"\x1b[1;4D": {Code: keys.ShiftLeft, AltPressed: true},
"\x1b\x1b[a": {Code: keys.ShiftUp, AltPressed: true},
"\x1b\x1b[b": {Code: keys.ShiftDown, AltPressed: true},
"\x1b\x1b[c": {Code: keys.ShiftRight, AltPressed: true},
"\x1b\x1b[d": {Code: keys.ShiftLeft, AltPressed: true},
"\x1b[1;5A": {Code: keys.CtrlUp},
"\x1b[1;5B": {Code: keys.CtrlDown},
"\x1b[1;5C": {Code: keys.CtrlRight},
"\x1b[1;5D": {Code: keys.CtrlLeft},
"\x1b[Oa": {Code: keys.CtrlUp, AltPressed: true},
"\x1b[Ob": {Code: keys.CtrlDown, AltPressed: true},
"\x1b[Oc": {Code: keys.CtrlRight, AltPressed: true},
"\x1b[Od": {Code: keys.CtrlLeft, AltPressed: true},
"\x1b[1;6A": {Code: keys.CtrlShiftUp},
"\x1b[1;6B": {Code: keys.CtrlShiftDown},
"\x1b[1;6C": {Code: keys.CtrlShiftRight},
"\x1b[1;6D": {Code: keys.CtrlShiftLeft},
"\x1b[1;7A": {Code: keys.CtrlUp, AltPressed: true},
"\x1b[1;7B": {Code: keys.CtrlDown, AltPressed: true},
"\x1b[1;7C": {Code: keys.CtrlRight, AltPressed: true},
"\x1b[1;7D": {Code: keys.CtrlLeft, AltPressed: true},
"\x1b[1;8A": {Code: keys.CtrlShiftUp, AltPressed: true},
"\x1b[1;8B": {Code: keys.CtrlShiftDown, AltPressed: true},
"\x1b[1;8C": {Code: keys.CtrlShiftRight, AltPressed: true},
"\x1b[1;8D": {Code: keys.CtrlShiftLeft, AltPressed: true},
// Miscellaneous keys
"\x1b[Z": {Code: keys.ShiftTab},
"\x1b[3~": {Code: keys.Delete},
"\x1b[3;3~": {Code: keys.Delete, AltPressed: true},
"\x1b[1~": {Code: keys.Home},
"\x1b[1;3H~": {Code: keys.Home, AltPressed: true},
"\x1b[4~": {Code: keys.End},
"\x1b[1;3F~": {Code: keys.End, AltPressed: true},
"\x1b[5~": {Code: keys.PgUp},
"\x1b[5;3~": {Code: keys.PgUp, AltPressed: true},
"\x1b[6~": {Code: keys.PgDown},
"\x1b[6;3~": {Code: keys.PgDown, AltPressed: true},
"\x1b[7~": {Code: keys.Home},
"\x1b[8~": {Code: keys.End},
"\x1b\x1b[3~": {Code: keys.Delete, AltPressed: true},
"\x1b\x1b[5~": {Code: keys.PgUp, AltPressed: true},
"\x1b\x1b[6~": {Code: keys.PgDown, AltPressed: true},
"\x1b\x1b[7~": {Code: keys.Home, AltPressed: true},
"\x1b\x1b[8~": {Code: keys.End, AltPressed: true},
// Function keys
"\x1bOP": {Code: keys.F1},
"\x1bOQ": {Code: keys.F2},
"\x1bOR": {Code: keys.F3},
"\x1bOS": {Code: keys.F4},
"\x1b[15~": {Code: keys.F5},
"\x1b[17~": {Code: keys.F6},
"\x1b[18~": {Code: keys.F7},
"\x1b[19~": {Code: keys.F8},
"\x1b[20~": {Code: keys.F9},
"\x1b[21~": {Code: keys.F10},
"\x1b[23~": {Code: keys.F11},
"\x1b[24~": {Code: keys.F12},
"\x1b[1;2P": {Code: keys.F13},
"\x1b[1;2Q": {Code: keys.F14},
"\x1b[1;2R": {Code: keys.F15},
"\x1b[1;2S": {Code: keys.F16},
"\x1b[15;2~": {Code: keys.F17},
"\x1b[17;2~": {Code: keys.F18},
"\x1b[18;2~": {Code: keys.F19},
"\x1b[19;2~": {Code: keys.F20},
// Function keys with the alt modifier
"\x1b[1;3P": {Code: keys.F1, AltPressed: true},
"\x1b[1;3Q": {Code: keys.F2, AltPressed: true},
"\x1b[1;3R": {Code: keys.F3, AltPressed: true},
"\x1b[1;3S": {Code: keys.F4, AltPressed: true},
"\x1b[15;3~": {Code: keys.F5, AltPressed: true},
"\x1b[17;3~": {Code: keys.F6, AltPressed: true},
"\x1b[18;3~": {Code: keys.F7, AltPressed: true},
"\x1b[19;3~": {Code: keys.F8, AltPressed: true},
"\x1b[20;3~": {Code: keys.F9, AltPressed: true},
"\x1b[21;3~": {Code: keys.F10, AltPressed: true},
"\x1b[23;3~": {Code: keys.F11, AltPressed: true},
"\x1b[24;3~": {Code: keys.F12, AltPressed: true},
// Function keys, urxvt
"\x1b[11~": {Code: keys.F1},
"\x1b[12~": {Code: keys.F2},
"\x1b[13~": {Code: keys.F3},
"\x1b[14~": {Code: keys.F4},
"\x1b[25~": {Code: keys.F13},
"\x1b[26~": {Code: keys.F14},
"\x1b[28~": {Code: keys.F15},
"\x1b[29~": {Code: keys.F16},
"\x1b[31~": {Code: keys.F17},
"\x1b[32~": {Code: keys.F18},
"\x1b[33~": {Code: keys.F19},
"\x1b[34~": {Code: keys.F20},
// Function keys with the alt modifier, urxvt
"\x1b\x1b[11~": {Code: keys.F1, AltPressed: true},
"\x1b\x1b[12~": {Code: keys.F2, AltPressed: true},
"\x1b\x1b[13~": {Code: keys.F3, AltPressed: true},
"\x1b\x1b[14~": {Code: keys.F4, AltPressed: true},
"\x1b\x1b[25~": {Code: keys.F13, AltPressed: true},
"\x1b\x1b[26~": {Code: keys.F14, AltPressed: true},
"\x1b\x1b[28~": {Code: keys.F15, AltPressed: true},
"\x1b\x1b[29~": {Code: keys.F16, AltPressed: true},
"\x1b\x1b[31~": {Code: keys.F17, AltPressed: true},
"\x1b\x1b[32~": {Code: keys.F18, AltPressed: true},
"\x1b\x1b[33~": {Code: keys.F19, AltPressed: true},
"\x1b\x1b[34~": {Code: keys.F20, AltPressed: true},
}
var hexCodes = map[string]keys.Key{
"1b0d": {Code: keys.Enter, AltPressed: true},
"1b7f": {Code: keys.Backspace, AltPressed: true},
// support other backspace variants
"1b08": {Code: keys.Backspace, AltPressed: true},
"08": {Code: keys.Backspace},
// Powershell
"1b4f41": {Code: keys.Up, AltPressed: false},
"1b4f42": {Code: keys.Down, AltPressed: false},
"1b4f43": {Code: keys.Right, AltPressed: false},
"1b4f44": {Code: keys.Left, AltPressed: false},
}
func getKeyPress() (keys.Key, error) {
var buf [256]byte
// Read
numBytes, err := inputTTY.Read(buf[:])
if err != nil {
if errors.Is(err, os.ErrClosed) {
return keys.Key{}, nil
}
if err.Error() == "EOF" {
return keys.Key{}, nil
} else if err.Error() == "invalid argument" {
return keys.Key{}, nil
}
return keys.Key{}, nil
}
// Check if it's a sequence
if k, ok := sequences[string(buf[:numBytes])]; ok {
return k, nil
}
hex := fmt.Sprintf("%x", buf[:numBytes])
if k, ok := hexCodes[hex]; ok {
return k, nil
}
// Check if the alt key is pressed.
if numBytes > 1 && buf[0] == 0x1b {
// Remove the initial escape sequence
c, _ := utf8.DecodeRune(buf[1:])
if c == utf8.RuneError {
return keys.Key{}, fmt.Errorf("could not decode rune after removing initial escape sequence")
}
return keys.Key{AltPressed: true, Code: keys.RuneKey, Runes: []rune{c}}, nil
}
var runes []rune
b := buf[:numBytes]
// Translate stdin into runes.
for i, w := 0, 0; i < len(b); i += w { //nolint:wastedassign
r, width := utf8.DecodeRune(b[i:])
if r == utf8.RuneError {
return keys.Key{}, fmt.Errorf("could not decode rune: %w", err)
}
runes = append(runes, r)
w = width
}
if len(runes) == 0 {
return keys.Key{}, fmt.Errorf("received 0 runes from stdin")
} else if len(runes) > 1 {
return keys.Key{Code: keys.RuneKey, Runes: runes}, nil
}
r := keys.KeyCode(runes[0])
if numBytes == 1 && r <= internal.KeyUnitSeparator || r == internal.KeyDelete {
return keys.Key{Code: r}, nil
}
if runes[0] == ' ' {
return keys.Key{Code: keys.Space, Runes: runes}, nil
}
return keys.Key{Code: keys.RuneKey, Runes: runes}, nil
}
golang-github-atomicgo-keyboard-0.2.9/internal/ 0000775 0000000 0000000 00000000000 14650122720 0021462 5 ustar 00root root 0000000 0000000 golang-github-atomicgo-keyboard-0.2.9/internal/keys.go 0000664 0000000 0000000 00000002173 14650122720 0022767 0 ustar 00root root 0000000 0000000 package internal
// See: https://en.wikipedia.org/wiki/C0_and_C1_control_codes
const (
KeyNull = 0
KeyStartOfHeading = 1
KeyStartOfText = 2
KeyExit = 3 // ctrl-c
KeyEndOfTransimission = 4
KeyEnquiry = 5
KeyAcknowledge = 6
KeyBELL = 7
KeyBackspace = 8
KeyHorizontalTabulation = 9
KeyLineFeed = 10
KeyVerticalTabulation = 11
KeyFormFeed = 12
KeyCarriageReturn = 13
KeyShiftOut = 14
KeyShiftIn = 15
KeyDataLinkEscape = 16
KeyDeviceControl1 = 17
KeyDeviceControl2 = 18
KeyDeviceControl3 = 19
KeyDeviceControl4 = 20
KeyNegativeAcknowledge = 21
KeySynchronousIdle = 22
KeyEndOfTransmissionBlock = 23
KeyCancel = 24
KeyEndOfMedium = 25
KeySubstitution = 26
KeyEscape = 27
KeyFileSeparator = 28
KeyGroupSeparator = 29
KeyRecordSeparator = 30
KeyUnitSeparator = 31
KeyDelete = 127
)
golang-github-atomicgo-keyboard-0.2.9/keyboard.go 0000664 0000000 0000000 00000006423 14650122720 0022002 0 ustar 00root root 0000000 0000000 package keyboard
import (
"fmt"
"os"
"github.com/containerd/console"
"atomicgo.dev/keyboard/keys"
)
var windowsStdin *os.File
var con console.Console
var stdin = os.Stdin
var inputTTY *os.File
var mockChannel = make(chan keys.Key)
var mocking = false
func startListener() error {
err := initInput()
if err != nil {
return err
}
if mocking {
return nil
}
if con != nil {
err := con.SetRaw()
if err != nil {
return fmt.Errorf("failed to set raw mode: %w", err)
}
}
inputTTY, err = openInputTTY()
if err != nil {
return err
}
return nil
}
func stopListener() error {
if con != nil {
err := con.Reset()
if err != nil {
return fmt.Errorf("failed to reset console: %w", err)
}
}
return restoreInput()
}
// Listen calls a callback function when a key is pressed.
//
// Simple example:
//
// keyboard.Listen(func(key keys.Key) (stop bool, err error) {
// if key.Code == keys.CtrlC {
// return true, nil // Stop listener by returning true on Ctrl+C
// }
//
// fmt.Println("\r" + key.String()) // Print every key press
// return false, nil // Return false to continue listening
// })
func Listen(onKeyPress func(key keys.Key) (stop bool, err error)) error {
cancel := make(chan bool)
stopRoutine := false
go func() {
for {
select {
case c := <-cancel:
if c {
return
}
case keyInfo := <-mockChannel:
stopRoutine, _ = onKeyPress(keyInfo)
if stopRoutine {
closeInput()
inputTTY.Close()
}
}
}
}()
err := startListener()
if err != nil {
if err.Error() != "provided file is not a console" {
return err
}
}
for !stopRoutine {
key, err := getKeyPress()
if err != nil {
return err
}
// check if returned key is empty
// if reflect.DeepEqual(key, keys.Key{}) {
// return nil
// }
stop, err := onKeyPress(key)
if err != nil {
return err
}
if stop {
closeInput()
inputTTY.Close()
break
}
}
err = stopListener()
if err != nil {
return err
}
cancel <- true
return nil
}
// SimulateKeyPress simulate a key press. It can be used to mock user stdin and test your application.
//
// Example:
//
// go func() {
// keyboard.SimulateKeyPress("Hello") // Simulate key press for every letter in string
// keyboard.SimulateKeyPress(keys.Enter) // Simulate key press for Enter
// keyboard.SimulateKeyPress(keys.CtrlShiftRight) // Simulate key press for Ctrl+Shift+Right
// keyboard.SimulateKeyPress('x') // Simulate key press for a single rune
// keyboard.SimulateKeyPress('x', keys.Down, 'a') // Simulate key presses for multiple inputs
// }()
func SimulateKeyPress(input ...interface{}) error {
for _, key := range input {
// Check if key is a keys.Key
if key, ok := key.(keys.Key); ok {
mockChannel <- key
return nil
}
// Check if key is a rune
if key, ok := key.(rune); ok {
mockChannel <- keys.Key{
Code: keys.RuneKey,
Runes: []rune{key},
}
return nil
}
// Check if key is a string
if key, ok := key.(string); ok {
for _, r := range key {
mockChannel <- keys.Key{
Code: keys.RuneKey,
Runes: []rune{r},
}
}
return nil
}
// Check if key is a KeyCode
if key, ok := key.(keys.KeyCode); ok {
mockChannel <- keys.Key{
Code: key,
}
return nil
}
}
return nil
}
golang-github-atomicgo-keyboard-0.2.9/keyboard_test.go 0000664 0000000 0000000 00000002236 14650122720 0023037 0 ustar 00root root 0000000 0000000 package keyboard_test
import (
"testing"
"atomicgo.dev/keyboard"
"atomicgo.dev/keyboard/keys"
"github.com/MarvinJWendt/testza"
)
func TestMocking(t *testing.T) {
go func() {
keyboard.SimulateKeyPress('a')
keyboard.SimulateKeyPress("b")
keyboard.SimulateKeyPress("c")
keyboard.SimulateKeyPress(keys.Enter)
}()
var aPressed, bPressed, cPressed, enterPressed bool
var keyList []keys.Key
err := keyboard.Listen(func(key keys.Key) (stop bool, err error) {
keyList = append(keyList, key)
switch key.Code {
case keys.RuneKey:
switch key.String() {
case "a":
println("a pressed")
aPressed = true
return false, nil
case "b":
println("b pressed")
bPressed = true
return false, nil
case "c":
println("c pressed")
cPressed = true
return false, nil
}
case keys.Enter:
println("enter pressed")
enterPressed = true
return true, nil
}
return false, nil
})
testza.AssertNoError(t, err)
testza.AssertTrue(t, aPressed, "A | %s", keyList)
testza.AssertTrue(t, bPressed, "B | %s", keyList)
testza.AssertTrue(t, cPressed, "C | %s", keyList)
testza.AssertTrue(t, enterPressed, "Enter | %s", keyList)
}
golang-github-atomicgo-keyboard-0.2.9/keys/ 0000775 0000000 0000000 00000000000 14650122720 0020621 5 ustar 00root root 0000000 0000000 golang-github-atomicgo-keyboard-0.2.9/keys/keys.go 0000664 0000000 0000000 00000014125 14650122720 0022126 0 ustar 00root root 0000000 0000000 package keys
import "atomicgo.dev/keyboard/internal"
// Key contains information about a keypress.
type Key struct {
Code KeyCode
Runes []rune // Runes that the key produced. Most key pressed produce one single rune.
AltPressed bool // True when alt is pressed while the key is typed.
}
// String returns a string representation of the key.
// (e.g. "a", "B", "alt+a", "enter", "ctrl+c", "shift-down", etc.)
//
// Example:
//
// k := keys.Key{Code: keys.Enter}
// fmt.Println(k)
// // Output: enter
func (k Key) String() (str string) {
if k.AltPressed {
str += "alt+"
}
if k.Code == RuneKey {
str += string(k.Runes)
return str
} else if s, ok := keyNames[k.Code]; ok {
str += s
return str
}
return ""
}
// KeyCode is an integer representation of a non-rune key, such as Escape, Enter, etc.
// All other keys are represented by a rune and have the KeyCode: RuneKey.
//
// Example:
//
// k := Key{Code: RuneKey, Runes: []rune{'x'}, AltPressed: true}
// if k.Code == RuneKey {
// fmt.Println(k.Runes)
// // Output: x
//
// fmt.Println(k.String())
// // Output: alt+x
// }
type KeyCode int
func (k KeyCode) String() (str string) {
if s, ok := keyNames[k]; ok {
return s
}
return ""
}
// All control keys.
const (
Null KeyCode = internal.KeyNull
Break KeyCode = internal.KeyExit
Enter KeyCode = internal.KeyCarriageReturn
Backspace KeyCode = internal.KeyDelete
Tab KeyCode = internal.KeyHorizontalTabulation
Esc KeyCode = internal.KeyEscape
Escape KeyCode = internal.KeyEscape
CtrlAt KeyCode = internal.KeyNull
CtrlA KeyCode = internal.KeyStartOfHeading
CtrlB KeyCode = internal.KeyStartOfText
CtrlC KeyCode = internal.KeyExit
CtrlD KeyCode = internal.KeyEndOfTransimission
CtrlE KeyCode = internal.KeyEnquiry
CtrlF KeyCode = internal.KeyAcknowledge
CtrlG KeyCode = internal.KeyBELL
CtrlH KeyCode = internal.KeyBackspace
CtrlI KeyCode = internal.KeyHorizontalTabulation
CtrlJ KeyCode = internal.KeyLineFeed
CtrlK KeyCode = internal.KeyVerticalTabulation
CtrlL KeyCode = internal.KeyFormFeed
CtrlM KeyCode = internal.KeyCarriageReturn
CtrlN KeyCode = internal.KeyShiftOut
CtrlO KeyCode = internal.KeyShiftIn
CtrlP KeyCode = internal.KeyDataLinkEscape
CtrlQ KeyCode = internal.KeyDeviceControl1
CtrlR KeyCode = internal.KeyDeviceControl2
CtrlS KeyCode = internal.KeyDeviceControl3
CtrlT KeyCode = internal.KeyDeviceControl4
CtrlU KeyCode = internal.KeyNegativeAcknowledge
CtrlV KeyCode = internal.KeySynchronousIdle
CtrlW KeyCode = internal.KeyEndOfTransmissionBlock
CtrlX KeyCode = internal.KeyCancel
CtrlY KeyCode = internal.KeyEndOfMedium
CtrlZ KeyCode = internal.KeySubstitution
CtrlOpenBracket KeyCode = internal.KeyEscape
CtrlBackslash KeyCode = internal.KeyFileSeparator
CtrlCloseBracket KeyCode = internal.KeyGroupSeparator
CtrlCaret KeyCode = internal.KeyRecordSeparator
CtrlUnderscore KeyCode = internal.KeyUnitSeparator
CtrlQuestionMark KeyCode = internal.KeyDelete
)
// Other keys.
const (
RuneKey KeyCode = -(iota + 1)
Up
Down
Right
Left
ShiftTab
Home
End
PgUp
PgDown
Delete
Space
CtrlUp
CtrlDown
CtrlRight
CtrlLeft
ShiftUp
ShiftDown
ShiftRight
ShiftLeft
CtrlShiftUp
CtrlShiftDown
CtrlShiftLeft
CtrlShiftRight
F1
F2
F3
F4
F5
F6
F7
F8
F9
F10
F11
F12
F13
F14
F15
F16
F17
F18
F19
F20
)
var keyNames = map[KeyCode]string{
// Control keys.
internal.KeyNull: "ctrl+@", // also ctrl+backtick
internal.KeyStartOfHeading: "ctrl+a",
internal.KeyStartOfText: "ctrl+b",
internal.KeyExit: "ctrl+c",
internal.KeyEndOfTransimission: "ctrl+d",
internal.KeyEnquiry: "ctrl+e",
internal.KeyAcknowledge: "ctrl+f",
internal.KeyBELL: "ctrl+g",
internal.KeyBackspace: "ctrl+h",
internal.KeyHorizontalTabulation: "tab", // also ctrl+i
internal.KeyLineFeed: "ctrl+j",
internal.KeyVerticalTabulation: "ctrl+k",
internal.KeyFormFeed: "ctrl+l",
internal.KeyCarriageReturn: "enter",
internal.KeyShiftOut: "ctrl+n",
internal.KeyShiftIn: "ctrl+o",
internal.KeyDataLinkEscape: "ctrl+p",
internal.KeyDeviceControl1: "ctrl+q",
internal.KeyDeviceControl2: "ctrl+r",
internal.KeyDeviceControl3: "ctrl+s",
internal.KeyDeviceControl4: "ctrl+t",
internal.KeyNegativeAcknowledge: "ctrl+u",
internal.KeySynchronousIdle: "ctrl+v",
internal.KeyEndOfTransmissionBlock: "ctrl+w",
internal.KeyCancel: "ctrl+x",
internal.KeyEndOfMedium: "ctrl+y",
internal.KeySubstitution: "ctrl+z",
internal.KeyEscape: "esc",
internal.KeyFileSeparator: "ctrl+\\",
internal.KeyGroupSeparator: "ctrl+]",
internal.KeyRecordSeparator: "ctrl+^",
internal.KeyUnitSeparator: "ctrl+_",
internal.KeyDelete: "backspace",
// Other keys.
RuneKey: "runes",
Up: "up",
Down: "down",
Right: "right",
Space: "space",
Left: "left",
ShiftTab: "shift+tab",
Home: "home",
End: "end",
PgUp: "pgup",
PgDown: "pgdown",
Delete: "delete",
CtrlUp: "ctrl+up",
CtrlDown: "ctrl+down",
CtrlRight: "ctrl+right",
CtrlLeft: "ctrl+left",
ShiftUp: "shift+up",
ShiftDown: "shift+down",
ShiftRight: "shift+right",
ShiftLeft: "shift+left",
CtrlShiftUp: "ctrl+shift+up",
CtrlShiftDown: "ctrl+shift+down",
CtrlShiftLeft: "ctrl+shift+left",
CtrlShiftRight: "ctrl+shift+right",
F1: "f1",
F2: "f2",
F3: "f3",
F4: "f4",
F5: "f5",
F6: "f6",
F7: "f7",
F8: "f8",
F9: "f9",
F10: "f10",
F11: "f11",
F12: "f12",
F13: "f13",
F14: "f14",
F15: "f15",
F16: "f16",
F17: "f17",
F18: "f18",
F19: "f19",
F20: "f20",
}
golang-github-atomicgo-keyboard-0.2.9/tty_unix.go 0000664 0000000 0000000 00000001051 14650122720 0022055 0 ustar 00root root 0000000 0000000 //go:build darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris
// +build darwin dragonfly freebsd linux netbsd openbsd solaris
package keyboard
import (
"os"
"github.com/containerd/console"
)
func restoreInput() error {
if con != nil {
return con.Reset()
}
return nil
}
func initInput() error {
c, err := console.ConsoleFromFile(stdin)
if err != nil {
return err
}
con = c
return nil
}
func openInputTTY() (*os.File, error) {
f, err := os.Open("/dev/tty")
if err != nil {
return nil, err
}
return f, nil
}
golang-github-atomicgo-keyboard-0.2.9/tty_windows.go 0000664 0000000 0000000 00000001210 14650122720 0022561 0 ustar 00root root 0000000 0000000 //go:build windows
// +build windows
package keyboard
import (
"fmt"
"os"
"syscall"
"github.com/containerd/console"
)
func restoreInput() error {
if windowsStdin != nil {
os.Stdin = windowsStdin
}
return nil
}
func initInput() error {
windowsStdin = os.Stdin
os.Stdin = stdin
var mode uint32
err := syscall.GetConsoleMode(syscall.Stdin, &mode)
if err != nil {
mocking = true
return nil
}
con = console.Current()
return nil
}
func openInputTTY() (*os.File, error) {
f, err := os.OpenFile("CONIN$", os.O_RDWR, 0644)
if err != nil {
return nil, fmt.Errorf("failed to open stdin TTY: %w", err)
}
return f, nil
}
golang-github-atomicgo-keyboard-0.2.9/utils.go 0000664 0000000 0000000 00000000275 14650122720 0021341 0 ustar 00root root 0000000 0000000 //go:build darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris
// +build darwin dragonfly freebsd linux netbsd openbsd solaris
package keyboard
func closeInput() {
}
golang-github-atomicgo-keyboard-0.2.9/utils_windows.go 0000664 0000000 0000000 00000000162 14650122720 0023106 0 ustar 00root root 0000000 0000000 package keyboard
import "syscall"
func closeInput() {
syscall.CancelIoEx(syscall.Handle(inputTTY.Fd()), nil)
}