diff --git a/go.mod b/go.mod index 58aefd19..d9ca34fe 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,7 @@ go 1.22 require ( github.com/adrg/xdg v0.4.0 github.com/charmbracelet/bubbles v0.18.0 - github.com/charmbracelet/bubbletea v0.25.0 + github.com/charmbracelet/bubbletea v0.26.6 github.com/charmbracelet/glamour v0.6.0 github.com/charmbracelet/lipgloss v0.10.0 github.com/getkin/kin-openapi v0.124.0 @@ -40,9 +40,13 @@ require ( github.com/atotto/clipboard v0.1.4 // indirect github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect github.com/aymerick/douceur v0.2.0 // indirect - github.com/containerd/console v1.0.4-0.20230313162750-1ae8d489ac81 // indirect + github.com/charmbracelet/x/ansi v0.1.2 // indirect + github.com/charmbracelet/x/input v0.1.0 // indirect + github.com/charmbracelet/x/term v0.1.1 // indirect + github.com/charmbracelet/x/windows v0.1.0 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/dlclark/regexp2 v1.4.0 // indirect + github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f // indirect github.com/felixge/httpsnoop v1.0.3 // indirect github.com/fsnotify/fsnotify v1.7.0 // indirect github.com/go-openapi/jsonpointer v0.20.2 // indirect @@ -69,7 +73,7 @@ require ( github.com/microcosm-cc/bluemonday v1.0.25 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect - github.com/muesli/ansi v0.0.0-20211018074035-2e021307bc4b // indirect + github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 // indirect github.com/muesli/cancelreader v0.2.2 // indirect github.com/muesli/termenv v0.15.2 // indirect github.com/olekukonko/tablewriter v0.0.5 // indirect @@ -86,6 +90,7 @@ require ( github.com/spf13/cast v1.6.0 // indirect github.com/stretchr/objx v0.5.2 // indirect github.com/subosito/gotenv v1.6.0 // indirect + github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect github.com/yuin/goldmark v1.5.2 // indirect github.com/yuin/goldmark-emoji v1.0.1 // indirect go.uber.org/atomic v1.9.0 // indirect diff --git a/go.sum b/go.sum index cada5711..8e0e95ec 100644 --- a/go.sum +++ b/go.sum @@ -51,19 +51,25 @@ github.com/bmatcuk/doublestar v1.1.1/go.mod h1:UD6OnuiIn0yFxxA2le/rnRU1G4RaI4UvF github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/charmbracelet/bubbles v0.18.0 h1:PYv1A036luoBGroX6VWjQIE9Syf2Wby2oOl/39KLfy0= github.com/charmbracelet/bubbles v0.18.0/go.mod h1:08qhZhtIwzgrtBjAcJnij1t1H0ZRjwHyGsy6AL11PSw= -github.com/charmbracelet/bubbletea v0.25.0 h1:bAfwk7jRz7FKFl9RzlIULPkStffg5k6pNt5dywy4TcM= -github.com/charmbracelet/bubbletea v0.25.0/go.mod h1:EN3QDR1T5ZdWmdfDzYcqOCAps45+QIJbLOBxmVNWNNg= +github.com/charmbracelet/bubbletea v0.26.6 h1:zTCWSuST+3yZYZnVSvbXwKOPRSNZceVeqpzOLN2zq1s= +github.com/charmbracelet/bubbletea v0.26.6/go.mod h1:dz8CWPlfCCGLFbBlTY4N7bjLiyOGDJEnd2Muu7pOWhk= github.com/charmbracelet/glamour v0.6.0 h1:wi8fse3Y7nfcabbbDuwolqTqMQPMnVPeZhDM273bISc= github.com/charmbracelet/glamour v0.6.0/go.mod h1:taqWV4swIMMbWALc0m7AfE9JkPSU8om2538k9ITBxOc= github.com/charmbracelet/lipgloss v0.10.0 h1:KWeXFSexGcfahHX+54URiZGkBFazf70JNMtwg/AFW3s= github.com/charmbracelet/lipgloss v0.10.0/go.mod h1:Wig9DSfvANsxqkRsqj6x87irdy123SR4dOXlKa91ciE= +github.com/charmbracelet/x/ansi v0.1.2 h1:6+LR39uG8DE6zAmbu023YlqjJHkYXDF1z36ZwzO4xZY= +github.com/charmbracelet/x/ansi v0.1.2/go.mod h1:dk73KoMTT5AX5BsX0KrqhsTqAnhZZoCBjs7dGWp4Ktw= +github.com/charmbracelet/x/input v0.1.0 h1:TEsGSfZYQyOtp+STIjyBq6tpRaorH0qpwZUj8DavAhQ= +github.com/charmbracelet/x/input v0.1.0/go.mod h1:ZZwaBxPF7IG8gWWzPUVqHEtWhc1+HXJPNuerJGRGZ28= +github.com/charmbracelet/x/term v0.1.1 h1:3cosVAiPOig+EV4X9U+3LDgtwwAoEzJjNdwbXDjF6yI= +github.com/charmbracelet/x/term v0.1.1/go.mod h1:wB1fHt5ECsu3mXYusyzcngVWWlu1KKUmmLhfgr/Flxw= +github.com/charmbracelet/x/windows v0.1.0 h1:gTaxdvzDM5oMa/I2ZNF7wN78X/atWemG9Wph7Ika2k4= +github.com/charmbracelet/x/windows v0.1.0/go.mod h1:GLEO/l+lizvFDBPLIOk+49gdX49L9YWMB5t+DZd0jkQ= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= -github.com/containerd/console v1.0.4-0.20230313162750-1ae8d489ac81 h1:q2hJAaP1k2wIvVRd/hEHD7lacgqrCPS+k8g1MndzfWY= -github.com/containerd/console v1.0.4-0.20230313162750-1ae8d489ac81/go.mod h1:YynlIjWYF8myEu6sdkwKIvGQq+cOckRm6So2avqoYAk= github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -75,6 +81,8 @@ github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymF github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f h1:Y/CXytFA4m6baUTXGLOoWe4PQhGxaX0KpnayAqC48p4= +github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f/go.mod h1:vw97MGsxSvLiUE2X8qFplwetxpGLQrlU1Q9AUEIzCaM= github.com/felixge/httpsnoop v1.0.3 h1:s/nj+GCswXYzN5v2DpNMuMQYe+0DDwt5WVCU6CWBdXk= github.com/felixge/httpsnoop v1.0.3/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= @@ -232,8 +240,8 @@ github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyua github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9M+97sNutRR1RKhG96O6jWumTTnw= github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8= -github.com/muesli/ansi v0.0.0-20211018074035-2e021307bc4b h1:1XF24mVaiu7u+CFywTdcDo2ie1pzzhwjt6RHqzpMU34= -github.com/muesli/ansi v0.0.0-20211018074035-2e021307bc4b/go.mod h1:fQuZ0gauxyBcmsdE3ZT4NasjaRdxmbCS0jRHsrWu3Ho= +github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 h1:ZK8zHtRHOkbHy6Mmr5D264iyp3TiX5OmNcI5cIARiQI= +github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6/go.mod h1:CJlz5H+gyd6CUWT45Oy4q24RdLyn7Md9Vj2/ldJBSIo= github.com/muesli/cancelreader v0.2.2 h1:3I4Kt4BQjOR54NavqnDogx/MIoWBFa0StPA8ELUXHmA= github.com/muesli/cancelreader v0.2.2/go.mod h1:3XuTXfFS2VjM+HTLZY9Ak0l6eUKfijIfMUZ4EgX0QYo= github.com/muesli/reflow v0.3.0 h1:IFsN6K9NfGtjeggFP+68I4chLZV2yIKsXJFNZ+eWh6s= @@ -310,6 +318,8 @@ github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4d github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= github.com/wsxiaoys/terminal v0.0.0-20160513160801-0940f3fc43a0 h1:3UeQBvD0TFrlVjOeLOBz+CPAI8dnbqNSVwUwRrkp7vQ= github.com/wsxiaoys/terminal v0.0.0-20160513160801-0940f3fc43a0/go.mod h1:IXCdmsXIht47RaVFLEdVnh1t+pgYtTAhQGj73kz+2DM= +github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e h1:JVG44RsyaB9T2KIHavMF/ppJZNG9ZpyihvCd0w101no= +github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e/go.mod h1:RbqR21r5mrJuqunuUZ/Dhy/avygyECGrLceyNeo4LiM= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= @@ -441,6 +451,7 @@ golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/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-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= diff --git a/vendor/github.com/charmbracelet/bubbletea/.golangci-soft.yml b/vendor/github.com/charmbracelet/bubbletea/.golangci-soft.yml index ef456e06..1b6824bb 100644 --- a/vendor/github.com/charmbracelet/bubbletea/.golangci-soft.yml +++ b/vendor/github.com/charmbracelet/bubbletea/.golangci-soft.yml @@ -23,7 +23,6 @@ linters: - gomnd - gomoddirectives - goprintffuncname - - ifshort # - lll - misspell - nakedret diff --git a/vendor/github.com/charmbracelet/bubbletea/.golangci.yml b/vendor/github.com/charmbracelet/bubbletea/.golangci.yml index a5a91d0d..3affce91 100644 --- a/vendor/github.com/charmbracelet/bubbletea/.golangci.yml +++ b/vendor/github.com/charmbracelet/bubbletea/.golangci.yml @@ -16,6 +16,7 @@ linters: enable: - bodyclose - exportloopref + - gofumpt - goimports - gosec - nilerr diff --git a/vendor/github.com/charmbracelet/bubbletea/.goreleaser.yml b/vendor/github.com/charmbracelet/bubbletea/.goreleaser.yml new file mode 100644 index 00000000..40d9f298 --- /dev/null +++ b/vendor/github.com/charmbracelet/bubbletea/.goreleaser.yml @@ -0,0 +1,6 @@ +includes: + - from_url: + url: charmbracelet/meta/main/goreleaser-lib.yaml + +# yaml-language-server: $schema=https://goreleaser.com/static/schema-pro.json + diff --git a/vendor/github.com/charmbracelet/bubbletea/README.md b/vendor/github.com/charmbracelet/bubbletea/README.md index 0834246c..9a8d93e2 100644 --- a/vendor/github.com/charmbracelet/bubbletea/README.md +++ b/vendor/github.com/charmbracelet/bubbletea/README.md @@ -1,10 +1,11 @@ # Bubble Tea
The fun, functional and stateful way to build terminal apps. A Go framework @@ -266,15 +267,21 @@ delve in headless mode and then connect to it: ```bash # Start the debugger -$ dlv debug --headless . -API server listening at: 127.0.0.1:34241 +$ dlv debug --headless --api-version=2 --listen=127.0.0.1:43000 . +API server listening at: 127.0.0.1:43000 # Connect to it from another terminal -$ dlv connect 127.0.0.1:34241 +$ dlv connect 127.0.0.1:43000 ``` -Note that the default port used will vary on your system and per run, so -actually watch out what address the first `dlv` run tells you to connect to. +If you do not explicitly supply the `--listen` flag, the port used will vary +per run, so passing this in makes the debugger easier to use from a script +or your IDE of choice. + +Additionally, we pass in `--api-version=2` because delve defaults to version 1 +for backwards compatibility reasons. However, delve recommends using version 2 +for all new development and some clients may no longer work with version 1. +For more information, see the [Delve documentation](https://github.com/go-delve/delve/tree/master/Documentation/api). ### Logging Stuff @@ -302,6 +309,7 @@ your program in another window. * [Lip Gloss][lipgloss]: Style, format and layout tools for terminal applications * [Harmonica][harmonica]: A spring animation library for smooth, natural motion * [BubbleZone][bubblezone]: Easy mouse event tracking for Bubble Tea components +* [ntcharts][ntcharts]: A terminal charting library built for Bubble Tea and [Lip Gloss][lipgloss] * [Termenv][termenv]: Advanced ANSI styling for terminal applications * [Reflow][reflow]: Advanced ANSI-aware methods for working with text @@ -309,6 +317,7 @@ your program in another window. [lipgloss]: https://github.com/charmbracelet/lipgloss [harmonica]: https://github.com/charmbracelet/harmonica [bubblezone]: https://github.com/lrstanley/bubblezone +[ntcharts]: https://github.com/NimbleMarkets/ntcharts [termenv]: https://github.com/muesli/termenv [reflow]: https://github.com/muesli/reflow @@ -316,25 +325,36 @@ your program in another window. For some Bubble Tea programs in production, see: +* [ASCII Movie](https://github.com/gabe565/ascii-movie): a Star Wars ASCII art movie player * [AT CLI](https://github.com/daskycodes/at_cli): execute AT Commands via serial port connections * [Aztify](https://github.com/Azure/aztfy): bring Microsoft Azure resources under Terraform * [brows](https://github.com/rubysolo/brows): a GitHub release browser * [Canard](https://github.com/mrusme/canard): an RSS client * [charm](https://github.com/charmbracelet/charm): the official Charm user account manager +* [chatgpt-cli](https://github.com/j178/chatgpt): a CLI for ChatGPT +* [chatgpt-tui](https://github.com/tearingItUp786/chatgpt-tui): a TUI for ChatGPT with SQLite sessions +* [ChatGPTUI](https://github.com/dwisiswant0/chatgptui): a TUI for ChatGPT * [chezmoi](https://github.com/twpayne/chezmoi): securely manage your dotfiles across multiple machines -* [chtop](https://github.com/chhetripradeep/chtop): monitor your ClickHouse node without leaving terminal +* [chip-8](https://github.com/braheezy/chip-8): a CHIP-8 interpreter +* [chtop](https://github.com/chhetripradeep/chtop): monitor your ClickHouse node without leaving the terminal * [circumflex](https://github.com/bensadeh/circumflex): read Hacker News in the terminal * [clidle](https://github.com/ajeetdsouza/clidle): a Wordle clone * [cLive](https://github.com/koki-develop/clive): automate terminal operations and view them live in a browser * [container-canary](https://github.com/NVIDIA/container-canary): a container validator * [countdown](https://github.com/aldernero/countdown): a multi-event countdown timer -* [dns53](https://github.com/purpleclay/dns53): dynamic DNS with Amazon Route53. Expose your EC2 quickly, securely and privately -* [eks-node-viewer](https://github.com/awslabs/eks-node-viewer): a tool for visualizing dynamic node usage within an eks cluster -* [enola](https://github.com/sherlock-project/enola): hunt down social media accounts by username across social networks +* [CRT](https://github.com/BigJk/crt): a simple terminal emulator for running Bubble Tea in a dedicated window, with optional shaders +* [cueitup](https://github.com/dhth/cueitup): inspect messages in an AWS SQS queue in a simple and deliberate manner +* [Daytona](https://github.com/daytonaio/daytona): an development environment manager +* [dns53](https://github.com/purpleclay/dns53): dynamic DNS with Amazon Route53; expose your EC2 quickly, securely and privately +* [eks-node-viewer](https://github.com/awslabs/eks-node-viewer): a tool for visualizing dynamic node usage within an EKS cluster +* [End Of Eden](https://github.com/BigJk/end_of_eden): a "Slay the Spire"-like, roguelike deck-builder game +* [enola](https://github.com/sherlock-project/enola): find social media accounts by username across social networks * [flapioca](https://github.com/kbrgl/flapioca): Flappy Bird on the CLI! * [fm](https://github.com/knipferrc/fm): a terminal-based file manager * [fork-cleaner](https://github.com/caarlos0/fork-cleaner): clean up old and inactive forks in your GitHub account +* [fractals-cli](https://github.com/MicheleFiladelfia/fractals-cli): a multiplatform terminal fractal explorer * [fztea](https://github.com/jon4hz/fztea): a Flipper Zero TUI +* [gama](https://github.com/termkit/gama): manage GitHub Actions from the terminal * [gambit](https://github.com/maaslalani/gambit): chess in the terminal * [gembro](https://git.sr.ht/~rafael/gembro): a mouse-driven Gemini browser * [gh-b](https://github.com/joaom00/gh-b): a GitHub CLI extension for managing branches @@ -343,37 +363,56 @@ For some Bubble Tea programs in production, see: * [Glow](https://github.com/charmbracelet/glow): a markdown reader, browser, and online markdown stash * [go-sweep](https://github.com/maxpaulus43/go-sweep): Minesweeper in the terminal * [gocovsh](https://github.com/orlangure/gocovsh): explore Go coverage reports from the CLI -* [got](https://github.com/fedeztk/got): a simple translator and text-to-speech app build on top of simplytranslate's APIs -* [hiSHtory](https://github.com/ddworken/hishtory): your shell history in context, synced, and queryable +* [got](https://github.com/fedeztk/got): a simple translator and text-to-speech app built on simplytranslate's APIs +* [gum](https://github.com/charmbracelet/gum): interactivity and styling for shells and shell scripts +* [hiSHtory](https://github.com/ddworken/hishtory): your shell history in context: synced, and queryable * [httpit](https://github.com/gonetx/httpit): a rapid http(s) benchmark tool +* [Huh?](https://github.com/charmbracelet/huh): an interactive prompt and form toolkit * [IDNT](https://github.com/r-darwish/idnt): a batch software uninstaller +* [json-log-viewer](https://github.com/hedhyw/json-log-viewer): an interactive JSON log viewer * [kboard](https://github.com/CamiloGarciaLaRotta/kboard): a typing game -* [mandelbrot-cli](https://github.com/MicheleFiladelfia/mandelbrot-cli): a multiplatform terminal mandelbrot set explorer +* [kplay](https://github.com/dhth/kplay): inspect messages in a Kafka topic +* [laboon](https://github.com/arisnacg/laboon): a Docker-desktop-style container manager * [mc](https://github.com/minio/mc): the official [MinIO](https://min.io) client * [mergestat](https://github.com/mergestat/mergestat): run SQL queries on git repositories +* [meteor](https://github.com/stefanlogue/meteor): a highly customizable conventional commit message tool +* [mods](https://github.com/charmbracelet/mods): AI on the CLI, built for pipelines +* [nachrichten](https://github.com/zMoooooritz/nachrichten): access up-to-date news in German provided by the [Tagesschau](https://www.tagesschau.de/) * [Neon Modem Overdrive](https://github.com/mrusme/neonmodem): a BBS-style TUI client for Discourse, Lemmy, Lobste.rs and Hacker News +* [nom](https://github.com/guyfedwards/nom): an RSS reader and manager * [Noted](https://github.com/torbratsberg/noted): a note viewer and manager -* [nom](https://github.com/guyfedwards/nom): RSS reader and manager -* [pathos](https://github.com/chip/pathos): a PATH env variable editor +* [outtasync](https://github.com/dhth/outtasync): identify CloudFormation stacks that are out of sync with their template files +* [pathos](https://github.com/chip/pathos): a PATH environment variable editor +* [Plandex](https://github.com/plandex-ai/plandex): a terminal-based AI coding engine for complex tasks * [portal](https://github.com/ZinoKader/portal): secure transfers between computers -* [redis-viewer](https://github.com/SaltFishPr/redis-viewer): a Redis databases browser -* [scrabbler](https://github.com/wI2L/scrabbler): Automatic draw TUI for your duplicate Scrabble games +* [prs](https://github.com/dhth/prs): stay up to date with your PRs +* [puffin](https://github.com/siddhantac/puffin): a TUI for hledger to manage your finances +* [pug](https://github.com/leg100/pug): terraform task manager +* [punchout](https://github.com/dhth/punchout): takes the suck out of logging time on JIRA +* [redis-viewer](https://github.com/SaltFishPr/redis-viewer): a Redis database browser +* [redis_tui](https://github.com/mat2cc/redis_tui): a Redis database browser +* [schemas](https://github.com/dhth/schemas): lets you inspect postgres schemas in the terminal +* [scrabbler](https://github.com/wI2L/scrabbler): an automatic draw tool for your duplicate Scrabble games * [sku](https://github.com/fedeztk/sku): Sudoku on the CLI * [Slides](https://github.com/maaslalani/slides): a markdown-based presentation tool -* [SlurmCommander](https://github.com/CLIP-HPC/SlurmCommander): a Slurm workload manager TUI +* [SlurmCommander](https://github.com/CLIP-HPC/SlurmCommander): a Slurm workload manager * [Soft Serve](https://github.com/charmbracelet/soft-serve): a command-line-first Git server that runs a TUI over SSH * [solitaire-tui](https://github.com/brianstrauch/solitaire-tui): Klondike Solitaire for the terminal * [StormForge Optimize Controller](https://github.com/thestormforge/optimize-controller): a tool for experimenting with application configurations in Kubernetes -* [Storydb](https://github.com/grrlopes/storydb): a bash/zsh ctrl+r improved command history finder. +* [Storydb](https://github.com/grrlopes/storydb): an improved bash/zsh-style ctrl+r command history finder * [STTG](https://github.com/wille1101/sttg): a teletext client for SVT, Sweden’s national public television station * [sttr](https://github.com/abhimanyu003/sttr): a general-purpose text transformer +* [superfile](https://github.com/MHNightCat/superfile) a fancy, modern terminal-based file manager * [tasktimer](https://github.com/caarlos0/tasktimer): a dead-simple task timer * [termdbms](https://github.com/mathaou/termdbms): a keyboard and mouse driven database browser +* [tgpt](https://github.com/aandrew-me/tgpt): conversational AI for the CLI; no API keys necessary * [ticker](https://github.com/achannarasappa/ticker): a terminal stock viewer and stock position tracker +* [trainer](https://github.com/rusinikita/trainer): a Go concurrency coding interview simulator with learning materials * [tran](https://github.com/abdfnx/tran): securely transfer stuff between computers (based on [portal](https://github.com/ZinoKader/portal)) +* [Trufflehog](https://github.com/trufflesecurity/trufflehog): find leaked credentials * [Typer](https://github.com/maaslalani/typer): a typing test -* [typioca](https://github.com/bloznelis/typioca): Cozy typing speed tester in terminal -* [tz](https://github.com/oz/tz): an aid for scheduling across multiple time zones +* [typioca](https://github.com/bloznelis/typioca): a typing test +* [tz](https://github.com/oz/tz): a scheduling aid for people in multiple time zones * [ugm](https://github.com/ariasmn/ugm): a unix user and group browser * [walk](https://github.com/antonmedv/walk): a terminal navigator * [wander](https://github.com/robinovitch61/wander): a HashiCorp Nomad terminal client diff --git a/vendor/github.com/charmbracelet/bubbletea/commands.go b/vendor/github.com/charmbracelet/bubbletea/commands.go index 7b139b88..2541bea0 100644 --- a/vendor/github.com/charmbracelet/bubbletea/commands.go +++ b/vendor/github.com/charmbracelet/bubbletea/commands.go @@ -20,11 +20,15 @@ func Batch(cmds ...Cmd) Cmd { } validCmds = append(validCmds, c) } - if len(validCmds) == 0 { + switch len(validCmds) { + case 0: return nil - } - return func() Msg { - return BatchMsg(validCmds) + case 1: + return validCmds[0] + default: + return func() Msg { + return BatchMsg(validCmds) + } } } @@ -90,11 +94,16 @@ type sequenceMsg []Cmd // // Every is analogous to Tick in the Elm Architecture. func Every(duration time.Duration, fn func(time.Time) Msg) Cmd { + n := time.Now() + d := n.Truncate(duration).Add(duration).Sub(n) + t := time.NewTimer(d) return func() Msg { - n := time.Now() - d := n.Truncate(duration).Add(duration).Sub(n) - t := time.NewTimer(d) - return fn(<-t.C) + ts := <-t.C + t.Stop() + for len(t.C) > 0 { + <-t.C + } + return fn(ts) } } @@ -137,9 +146,14 @@ func Every(duration time.Duration, fn func(time.Time) Msg) Cmd { // return m, nil // } func Tick(d time.Duration, fn func(time.Time) Msg) Cmd { + t := time.NewTimer(d) return func() Msg { - t := time.NewTimer(d) - return fn(<-t.C) + ts := <-t.C + t.Stop() + for len(t.C) > 0 { + <-t.C + } + return fn(ts) } } diff --git a/vendor/github.com/charmbracelet/bubbletea/exec.go b/vendor/github.com/charmbracelet/bubbletea/exec.go index fb6d91ed..7a14d2a7 100644 --- a/vendor/github.com/charmbracelet/bubbletea/exec.go +++ b/vendor/github.com/charmbracelet/bubbletea/exec.go @@ -109,7 +109,7 @@ func (p *Program) exec(c ExecCommand, fn ExecCallback) { } c.SetStdin(p.input) - c.SetStdout(p.output.TTY()) + c.SetStdout(p.output) c.SetStderr(os.Stderr) // Execute system command. diff --git a/vendor/github.com/charmbracelet/bubbletea/inputreader_other.go b/vendor/github.com/charmbracelet/bubbletea/inputreader_other.go new file mode 100644 index 00000000..8e63a87d --- /dev/null +++ b/vendor/github.com/charmbracelet/bubbletea/inputreader_other.go @@ -0,0 +1,14 @@ +//go:build !windows +// +build !windows + +package tea + +import ( + "io" + + "github.com/muesli/cancelreader" +) + +func newInputReader(r io.Reader) (cancelreader.CancelReader, error) { + return cancelreader.NewReader(r) +} diff --git a/vendor/github.com/charmbracelet/bubbletea/inputreader_windows.go b/vendor/github.com/charmbracelet/bubbletea/inputreader_windows.go new file mode 100644 index 00000000..449df479 --- /dev/null +++ b/vendor/github.com/charmbracelet/bubbletea/inputreader_windows.go @@ -0,0 +1,107 @@ +//go:build windows +// +build windows + +package tea + +import ( + "fmt" + "io" + "os" + "sync" + + "github.com/charmbracelet/x/term" + "github.com/erikgeiser/coninput" + "github.com/muesli/cancelreader" + "golang.org/x/sys/windows" +) + +type conInputReader struct { + cancelMixin + + conin windows.Handle + + originalMode uint32 +} + +var _ cancelreader.CancelReader = &conInputReader{} + +func newInputReader(r io.Reader) (cancelreader.CancelReader, error) { + fallback := func(io.Reader) (cancelreader.CancelReader, error) { + return cancelreader.NewReader(r) + } + if f, ok := r.(term.File); !ok || f.Fd() != os.Stdin.Fd() { + return fallback(r) + } + + conin, err := coninput.NewStdinHandle() + if err != nil { + return fallback(r) + } + + originalMode, err := prepareConsole(conin, + windows.ENABLE_MOUSE_INPUT, + windows.ENABLE_WINDOW_INPUT, + windows.ENABLE_EXTENDED_FLAGS, + ) + if err != nil { + return nil, fmt.Errorf("failed to prepare console input: %w", err) + } + + return &conInputReader{ + conin: conin, + originalMode: originalMode, + }, nil +} + +// Cancel implements cancelreader.CancelReader. +func (r *conInputReader) Cancel() bool { + r.setCanceled() + + return windows.CancelIo(r.conin) == nil +} + +// Close implements cancelreader.CancelReader. +func (r *conInputReader) Close() error { + if r.originalMode != 0 { + err := windows.SetConsoleMode(r.conin, r.originalMode) + if err != nil { + return fmt.Errorf("reset console mode: %w", err) + } + } + + return nil +} + +// Read implements cancelreader.CancelReader. +func (*conInputReader) Read(_ []byte) (n int, err error) { + return 0, nil +} + +func prepareConsole(input windows.Handle, modes ...uint32) (originalMode uint32, err error) { + err = windows.GetConsoleMode(input, &originalMode) + if err != nil { + return 0, fmt.Errorf("get console mode: %w", err) + } + + newMode := coninput.AddInputModes(0, modes...) + + err = windows.SetConsoleMode(input, newMode) + if err != nil { + return 0, fmt.Errorf("set console mode: %w", err) + } + + return originalMode, nil +} + +// cancelMixin represents a goroutine-safe cancelation status. +type cancelMixin struct { + unsafeCanceled bool + lock sync.Mutex +} + +func (c *cancelMixin) setCanceled() { + c.lock.Lock() + defer c.lock.Unlock() + + c.unsafeCanceled = true +} diff --git a/vendor/github.com/charmbracelet/bubbletea/key.go b/vendor/github.com/charmbracelet/bubbletea/key.go index f851490a..89a588ae 100644 --- a/vendor/github.com/charmbracelet/bubbletea/key.go +++ b/vendor/github.com/charmbracelet/bubbletea/key.go @@ -5,6 +5,7 @@ import ( "fmt" "io" "regexp" + "strings" "unicode/utf8" ) @@ -54,6 +55,7 @@ type Key struct { Type KeyType Runes []rune Alt bool + Paste bool } // String returns a friendly string representation for a key. It's safe (and @@ -63,15 +65,28 @@ type Key struct { // fmt.Println(k) // // Output: enter func (k Key) String() (str string) { + var buf strings.Builder if k.Alt { - str += "alt+" + buf.WriteString("alt+") } if k.Type == KeyRunes { - str += string(k.Runes) - return str + if k.Paste { + // Note: bubbles/keys bindings currently do string compares to + // recognize shortcuts. Since pasted text should never activate + // shortcuts, we need to ensure that the binding code doesn't + // match Key events that result from pastes. We achieve this + // here by enclosing pastes in '[...]' so that the string + // comparison in Matches() fails in that case. + buf.WriteByte('[') + } + buf.WriteString(string(k.Runes)) + if k.Paste { + buf.WriteByte(']') + } + return buf.String() } else if s, ok := keyNames[k.Type]; ok { - str += s - return str + buf.WriteString(s) + return buf.String() } return "" } @@ -538,9 +553,9 @@ func (u unknownCSISequenceMsg) String() string { var spaceRunes = []rune{' '} -// readInputs reads keypress and mouse inputs from a TTY and produces messages +// readAnsiInputs reads keypress and mouse inputs from a TTY and produces messages // containing information about the key or mouse events accordingly. -func readInputs(ctx context.Context, msgs chan<- Msg, input io.Reader) error { +func readAnsiInputs(ctx context.Context, msgs chan<- Msg, input io.Reader) error { var buf [256]byte var leftOverFromPrevIteration []byte @@ -566,7 +581,7 @@ loop: canHaveMoreData := numBytes == len(buf) var i, w int - for i, w = 0, 07; i < len(b); i += w { + for i, w = 0, 0; i < len(b); i += w { var msg Msg w, msg = detectOneMsg(b[i:], canHaveMoreData) if w == 0 { @@ -607,19 +622,26 @@ func detectOneMsg(b []byte, canHaveMoreData bool) (w int, msg Msg) { case '<': if matchIndices := mouseSGRRegex.FindSubmatchIndex(b[3:]); matchIndices != nil { // SGR mouse events length is the length of the match plus the length of the escape sequence - mouseEventSGRLen := matchIndices[1] + 3 + mouseEventSGRLen := matchIndices[1] + 3 //nolint:gomnd return mouseEventSGRLen, MouseMsg(parseSGRMouseEvent(b)) } } } + // Detect bracketed paste. + var foundbp bool + foundbp, w, msg = detectBracketedPaste(b) + if foundbp { + return w, msg + } + // Detect escape sequence and control characters other than NUL, // possibly with an escape character in front to mark the Alt // modifier. var foundSeq bool foundSeq, w, msg = detectSequence(b) if foundSeq { - return + return w, msg } // No non-NUL control character or escape sequence. diff --git a/vendor/github.com/charmbracelet/bubbletea/key_other.go b/vendor/github.com/charmbracelet/bubbletea/key_other.go new file mode 100644 index 00000000..b8c46082 --- /dev/null +++ b/vendor/github.com/charmbracelet/bubbletea/key_other.go @@ -0,0 +1,13 @@ +//go:build !windows +// +build !windows + +package tea + +import ( + "context" + "io" +) + +func readInputs(ctx context.Context, msgs chan<- Msg, input io.Reader) error { + return readAnsiInputs(ctx, msgs, input) +} diff --git a/vendor/github.com/charmbracelet/bubbletea/key_sequences.go b/vendor/github.com/charmbracelet/bubbletea/key_sequences.go index cc200f8d..4ba0f79e 100644 --- a/vendor/github.com/charmbracelet/bubbletea/key_sequences.go +++ b/vendor/github.com/charmbracelet/bubbletea/key_sequences.go @@ -1,6 +1,10 @@ package tea -import "sort" +import ( + "bytes" + "sort" + "unicode/utf8" +) // extSequences is used by the map-based algorithm below. It contains // the sequences plus their alternatives with an escape character @@ -69,3 +73,47 @@ func detectSequence(input []byte) (hasSeq bool, width int, msg Msg) { return false, 0, nil } + +// detectBracketedPaste detects an input pasted while bracketed +// paste mode was enabled. +// +// Note: this function is a no-op if bracketed paste was not enabled +// on the terminal, since in that case we'd never see this +// particular escape sequence. +func detectBracketedPaste(input []byte) (hasBp bool, width int, msg Msg) { + // Detect the start sequence. + const bpStart = "\x1b[200~" + if len(input) < len(bpStart) || string(input[:len(bpStart)]) != bpStart { + return false, 0, nil + } + + // Skip over the start sequence. + input = input[len(bpStart):] + + // If we saw the start sequence, then we must have an end sequence + // as well. Find it. + const bpEnd = "\x1b[201~" + idx := bytes.Index(input, []byte(bpEnd)) + inputLen := len(bpStart) + idx + len(bpEnd) + if idx == -1 { + // We have encountered the end of the input buffer without seeing + // the marker for the end of the bracketed paste. + // Tell the outer loop we have done a short read and we want more. + return true, 0, nil + } + + // The paste is everything in-between. + paste := input[:idx] + + // All there is in-between is runes, not to be interpreted further. + k := Key{Type: KeyRunes, Paste: true} + for len(paste) > 0 { + r, w := utf8.DecodeRune(paste) + if r != utf8.RuneError { + k.Runes = append(k.Runes, r) + } + paste = paste[w:] + } + + return true, inputLen, KeyMsg(k) +} diff --git a/vendor/github.com/charmbracelet/bubbletea/key_windows.go b/vendor/github.com/charmbracelet/bubbletea/key_windows.go new file mode 100644 index 00000000..b693efd6 --- /dev/null +++ b/vendor/github.com/charmbracelet/bubbletea/key_windows.go @@ -0,0 +1,351 @@ +//go:build windows +// +build windows + +package tea + +import ( + "context" + "fmt" + "io" + + "github.com/erikgeiser/coninput" + localereader "github.com/mattn/go-localereader" + "golang.org/x/sys/windows" +) + +func readInputs(ctx context.Context, msgs chan<- Msg, input io.Reader) error { + if coninReader, ok := input.(*conInputReader); ok { + return readConInputs(ctx, msgs, coninReader.conin) + } + + return readAnsiInputs(ctx, msgs, localereader.NewReader(input)) +} + +func readConInputs(ctx context.Context, msgsch chan<- Msg, con windows.Handle) error { + var ps coninput.ButtonState // keep track of previous mouse state + var ws coninput.WindowBufferSizeEventRecord // keep track of the last window size event + for { + events, err := coninput.ReadNConsoleInputs(con, 16) + if err != nil { + return fmt.Errorf("read coninput events: %w", err) + } + + for _, event := range events { + var msgs []Msg + switch e := event.Unwrap().(type) { + case coninput.KeyEventRecord: + if !e.KeyDown || e.VirtualKeyCode == coninput.VK_SHIFT { + continue + } + + for i := 0; i < int(e.RepeatCount); i++ { + eventKeyType := keyType(e) + var runes []rune + + // Add the character only if the key type is an actual character and not a control sequence. + // This mimics the behavior in readAnsiInputs where the character is also removed. + // We don't need to handle KeySpace here. See the comment in keyType(). + if eventKeyType == KeyRunes { + runes = []rune{e.Char} + } + + msgs = append(msgs, KeyMsg{ + Type: eventKeyType, + Runes: runes, + Alt: e.ControlKeyState.Contains(coninput.LEFT_ALT_PRESSED | coninput.RIGHT_ALT_PRESSED), + }) + } + case coninput.WindowBufferSizeEventRecord: + if e != ws { + ws = e + msgs = append(msgs, WindowSizeMsg{ + Width: int(e.Size.X), + Height: int(e.Size.Y), + }) + } + case coninput.MouseEventRecord: + event := mouseEvent(ps, e) + if event.Type != MouseUnknown { + msgs = append(msgs, event) + } + ps = e.ButtonState + case coninput.FocusEventRecord, coninput.MenuEventRecord: + // ignore + default: // unknown event + continue + } + + // Send all messages to the channel + for _, msg := range msgs { + select { + case msgsch <- msg: + case <-ctx.Done(): + err := ctx.Err() + if err != nil { + return fmt.Errorf("coninput context error: %w", err) + } + return err + } + } + } + } +} + +func mouseEventButton(p, s coninput.ButtonState) (button MouseButton, action MouseAction) { + btn := p ^ s + action = MouseActionPress + if btn&s == 0 { + action = MouseActionRelease + } + + if btn == 0 { + switch { + case s&coninput.FROM_LEFT_1ST_BUTTON_PRESSED > 0: + button = MouseButtonLeft + case s&coninput.FROM_LEFT_2ND_BUTTON_PRESSED > 0: + button = MouseButtonMiddle + case s&coninput.RIGHTMOST_BUTTON_PRESSED > 0: + button = MouseButtonRight + case s&coninput.FROM_LEFT_3RD_BUTTON_PRESSED > 0: + button = MouseButtonBackward + case s&coninput.FROM_LEFT_4TH_BUTTON_PRESSED > 0: + button = MouseButtonForward + } + return + } + + switch { + case btn == coninput.FROM_LEFT_1ST_BUTTON_PRESSED: // left button + button = MouseButtonLeft + case btn == coninput.RIGHTMOST_BUTTON_PRESSED: // right button + button = MouseButtonRight + case btn == coninput.FROM_LEFT_2ND_BUTTON_PRESSED: // middle button + button = MouseButtonMiddle + case btn == coninput.FROM_LEFT_3RD_BUTTON_PRESSED: // unknown (possibly mouse backward) + button = MouseButtonBackward + case btn == coninput.FROM_LEFT_4TH_BUTTON_PRESSED: // unknown (possibly mouse forward) + button = MouseButtonForward + } + + return button, action +} + +func mouseEvent(p coninput.ButtonState, e coninput.MouseEventRecord) MouseMsg { + ev := MouseMsg{ + X: int(e.MousePositon.X), + Y: int(e.MousePositon.Y), + Alt: e.ControlKeyState.Contains(coninput.LEFT_ALT_PRESSED | coninput.RIGHT_ALT_PRESSED), + Ctrl: e.ControlKeyState.Contains(coninput.LEFT_CTRL_PRESSED | coninput.RIGHT_CTRL_PRESSED), + Shift: e.ControlKeyState.Contains(coninput.SHIFT_PRESSED), + } + switch e.EventFlags { + case coninput.CLICK, coninput.DOUBLE_CLICK: + ev.Button, ev.Action = mouseEventButton(p, e.ButtonState) + if ev.Action == MouseActionRelease { + ev.Type = MouseRelease + } + switch ev.Button { + case MouseButtonLeft: + ev.Type = MouseLeft + case MouseButtonMiddle: + ev.Type = MouseMiddle + case MouseButtonRight: + ev.Type = MouseRight + case MouseButtonBackward: + ev.Type = MouseBackward + case MouseButtonForward: + ev.Type = MouseForward + } + case coninput.MOUSE_WHEELED: + if e.WheelDirection > 0 { + ev.Button = MouseButtonWheelUp + ev.Type = MouseWheelUp + } else { + ev.Button = MouseButtonWheelDown + ev.Type = MouseWheelDown + } + case coninput.MOUSE_HWHEELED: + if e.WheelDirection > 0 { + ev.Button = MouseButtonWheelRight + ev.Type = MouseWheelRight + } else { + ev.Button = MouseButtonWheelLeft + ev.Type = MouseWheelLeft + } + case coninput.MOUSE_MOVED: + ev.Button, _ = mouseEventButton(p, e.ButtonState) + ev.Action = MouseActionMotion + ev.Type = MouseMotion + } + + return ev +} + +func keyType(e coninput.KeyEventRecord) KeyType { + code := e.VirtualKeyCode + + shiftPressed := e.ControlKeyState.Contains(coninput.SHIFT_PRESSED) + ctrlPressed := e.ControlKeyState.Contains(coninput.LEFT_CTRL_PRESSED | coninput.RIGHT_CTRL_PRESSED) + + switch code { + case coninput.VK_RETURN: + return KeyEnter + case coninput.VK_BACK: + return KeyBackspace + case coninput.VK_TAB: + if shiftPressed { + return KeyShiftTab + } + return KeyTab + case coninput.VK_SPACE: + return KeyRunes // this could be KeySpace but on unix space also produces KeyRunes + case coninput.VK_ESCAPE: + return KeyEscape + case coninput.VK_UP: + switch { + case shiftPressed && ctrlPressed: + return KeyCtrlShiftUp + case shiftPressed: + return KeyShiftUp + case ctrlPressed: + return KeyCtrlUp + default: + return KeyUp + } + case coninput.VK_DOWN: + switch { + case shiftPressed && ctrlPressed: + return KeyCtrlShiftDown + case shiftPressed: + return KeyShiftDown + case ctrlPressed: + return KeyCtrlDown + default: + return KeyDown + } + case coninput.VK_RIGHT: + switch { + case shiftPressed && ctrlPressed: + return KeyCtrlShiftRight + case shiftPressed: + return KeyShiftRight + case ctrlPressed: + return KeyCtrlRight + default: + return KeyRight + } + case coninput.VK_LEFT: + switch { + case shiftPressed && ctrlPressed: + return KeyCtrlShiftLeft + case shiftPressed: + return KeyShiftLeft + case ctrlPressed: + return KeyCtrlLeft + default: + return KeyLeft + } + case coninput.VK_HOME: + switch { + case shiftPressed && ctrlPressed: + return KeyCtrlShiftHome + case shiftPressed: + return KeyShiftHome + case ctrlPressed: + return KeyCtrlHome + default: + return KeyHome + } + case coninput.VK_END: + switch { + case shiftPressed && ctrlPressed: + return KeyCtrlShiftEnd + case shiftPressed: + return KeyShiftEnd + case ctrlPressed: + return KeyCtrlEnd + default: + return KeyEnd + } + case coninput.VK_PRIOR: + return KeyPgUp + case coninput.VK_NEXT: + return KeyPgDown + case coninput.VK_DELETE: + return KeyDelete + default: + if e.ControlKeyState&(coninput.LEFT_CTRL_PRESSED|coninput.RIGHT_CTRL_PRESSED) == 0 { + return KeyRunes + } + + switch e.Char { + case '@': + return KeyCtrlAt + case '\x01': + return KeyCtrlA + case '\x02': + return KeyCtrlB + case '\x03': + return KeyCtrlC + case '\x04': + return KeyCtrlD + case '\x05': + return KeyCtrlE + case '\x06': + return KeyCtrlF + case '\a': + return KeyCtrlG + case '\b': + return KeyCtrlH + case '\t': + return KeyCtrlI + case '\n': + return KeyCtrlJ + case '\v': + return KeyCtrlK + case '\f': + return KeyCtrlL + case '\r': + return KeyCtrlM + case '\x0e': + return KeyCtrlN + case '\x0f': + return KeyCtrlO + case '\x10': + return KeyCtrlP + case '\x11': + return KeyCtrlQ + case '\x12': + return KeyCtrlR + case '\x13': + return KeyCtrlS + case '\x14': + return KeyCtrlT + case '\x15': + return KeyCtrlU + case '\x16': + return KeyCtrlV + case '\x17': + return KeyCtrlW + case '\x18': + return KeyCtrlX + case '\x19': + return KeyCtrlY + case '\x1a': + return KeyCtrlZ + case '\x1b': + return KeyCtrlCloseBracket + case '\x1c': + return KeyCtrlBackslash + case '\x1f': + return KeyCtrlUnderscore + } + + switch code { + case coninput.VK_OEM_4: + return KeyCtrlOpenBracket + } + + return KeyRunes + } +} diff --git a/vendor/github.com/charmbracelet/bubbletea/mouse.go b/vendor/github.com/charmbracelet/bubbletea/mouse.go index add8d029..6ec51cc0 100644 --- a/vendor/github.com/charmbracelet/bubbletea/mouse.go +++ b/vendor/github.com/charmbracelet/bubbletea/mouse.go @@ -45,7 +45,7 @@ func (m MouseEvent) String() (s string) { s += "shift+" } - if m.Button == MouseButtonNone { + if m.Button == MouseButtonNone { //nolint:nestif if m.Action == MouseActionMotion || m.Action == MouseActionRelease { s += mouseActions[m.Action] } else { @@ -172,7 +172,7 @@ const ( func parseSGRMouseEvent(buf []byte) MouseEvent { str := string(buf[3:]) matches := mouseSGRRegex.FindStringSubmatch(str) - if len(matches) != 5 { + if len(matches) != 5 { //nolint:gomnd // Unreachable, we already checked the regex in `detectOneMsg`. panic("invalid mouse event") } @@ -288,7 +288,7 @@ func parseMouseButton(b int, isSGR bool) MouseEvent { m.Type = MouseForward case m.Action == MouseActionMotion: m.Type = MouseMotion - switch m.Button { + switch m.Button { //nolint:exhaustive case MouseButtonLeft: m.Type = MouseLeft case MouseButtonMiddle: diff --git a/vendor/github.com/charmbracelet/bubbletea/nil_renderer.go b/vendor/github.com/charmbracelet/bubbletea/nil_renderer.go index 1b1d4409..f4a83b6b 100644 --- a/vendor/github.com/charmbracelet/bubbletea/nil_renderer.go +++ b/vendor/github.com/charmbracelet/bubbletea/nil_renderer.go @@ -2,20 +2,24 @@ package tea type nilRenderer struct{} -func (n nilRenderer) start() {} -func (n nilRenderer) stop() {} -func (n nilRenderer) kill() {} -func (n nilRenderer) write(_ string) {} -func (n nilRenderer) repaint() {} -func (n nilRenderer) clearScreen() {} -func (n nilRenderer) altScreen() bool { return false } -func (n nilRenderer) enterAltScreen() {} -func (n nilRenderer) exitAltScreen() {} -func (n nilRenderer) showCursor() {} -func (n nilRenderer) hideCursor() {} -func (n nilRenderer) enableMouseCellMotion() {} -func (n nilRenderer) disableMouseCellMotion() {} -func (n nilRenderer) enableMouseAllMotion() {} -func (n nilRenderer) disableMouseAllMotion() {} -func (n nilRenderer) enableMouseSGRMode() {} -func (n nilRenderer) disableMouseSGRMode() {} +func (n nilRenderer) start() {} +func (n nilRenderer) stop() {} +func (n nilRenderer) kill() {} +func (n nilRenderer) write(_ string) {} +func (n nilRenderer) repaint() {} +func (n nilRenderer) clearScreen() {} +func (n nilRenderer) altScreen() bool { return false } +func (n nilRenderer) enterAltScreen() {} +func (n nilRenderer) exitAltScreen() {} +func (n nilRenderer) showCursor() {} +func (n nilRenderer) hideCursor() {} +func (n nilRenderer) enableMouseCellMotion() {} +func (n nilRenderer) disableMouseCellMotion() {} +func (n nilRenderer) enableMouseAllMotion() {} +func (n nilRenderer) disableMouseAllMotion() {} +func (n nilRenderer) enableBracketedPaste() {} +func (n nilRenderer) disableBracketedPaste() {} +func (n nilRenderer) enableMouseSGRMode() {} +func (n nilRenderer) disableMouseSGRMode() {} +func (n nilRenderer) bracketedPasteActive() bool { return false } +func (n nilRenderer) setWindowTitle(_ string) {} diff --git a/vendor/github.com/charmbracelet/bubbletea/options.go b/vendor/github.com/charmbracelet/bubbletea/options.go index 71e94493..8aee6da6 100644 --- a/vendor/github.com/charmbracelet/bubbletea/options.go +++ b/vendor/github.com/charmbracelet/bubbletea/options.go @@ -4,8 +4,6 @@ import ( "context" "io" "sync/atomic" - - "github.com/muesli/termenv" ) // ProgramOption is used to set options when initializing a Program. Program can @@ -29,11 +27,7 @@ func WithContext(ctx context.Context) ProgramOption { // won't need to use this. func WithOutput(output io.Writer) ProgramOption { return func(p *Program) { - if o, ok := output.(*termenv.Output); ok { - p.output = o - } else { - p.output = termenv.NewOutput(output, termenv.WithColorCache(true)) - } + p.output = output } } @@ -101,6 +95,13 @@ func WithAltScreen() ProgramOption { } } +// WithoutBracketedPaste starts the program with bracketed paste disabled. +func WithoutBracketedPaste() ProgramOption { + return func(p *Program) { + p.startupOptions |= withoutBracketedPaste + } +} + // WithMouseCellMotion starts the program with the mouse enabled in "cell // motion" mode. // diff --git a/vendor/github.com/charmbracelet/bubbletea/renderer.go b/vendor/github.com/charmbracelet/bubbletea/renderer.go index 5a3ee3c4..de3936e7 100644 --- a/vendor/github.com/charmbracelet/bubbletea/renderer.go +++ b/vendor/github.com/charmbracelet/bubbletea/renderer.go @@ -56,6 +56,20 @@ type renderer interface { // disableMouseSGRMode disables mouse extended mode (SGR). disableMouseSGRMode() + + // enableBracketedPaste enables bracketed paste, where characters + // inside the input are not interpreted when pasted as a whole. + enableBracketedPaste() + + // disableBracketedPaste disables bracketed paste. + disableBracketedPaste() + + // bracketedPasteActive reports whether bracketed paste mode is + // currently enabled. + bracketedPasteActive() bool + + // setWindowTitle sets the terminal window title. + setWindowTitle(string) } // repaintMsg forces a full repaint. diff --git a/vendor/github.com/charmbracelet/bubbletea/screen.go b/vendor/github.com/charmbracelet/bubbletea/screen.go index d064222f..6256c159 100644 --- a/vendor/github.com/charmbracelet/bubbletea/screen.go +++ b/vendor/github.com/charmbracelet/bubbletea/screen.go @@ -116,6 +116,34 @@ func ShowCursor() Msg { // this message with ShowCursor. type showCursorMsg struct{} +// EnableBracketedPaste is a special command that tells the Bubble Tea program +// to accept bracketed paste input. +// +// Note that bracketed paste will be automatically disabled when the +// program quits. +func EnableBracketedPaste() Msg { + return enableBracketedPasteMsg{} +} + +// enableBracketedPasteMsg in an internal message signals that +// bracketed paste should be enabled. You can send an +// enableBracketedPasteMsg with EnableBracketedPaste. +type enableBracketedPasteMsg struct{} + +// DisableBracketedPaste is a special command that tells the Bubble Tea program +// to accept bracketed paste input. +// +// Note that bracketed paste will be automatically disabled when the +// program quits. +func DisableBracketedPaste() Msg { + return disableBracketedPasteMsg{} +} + +// disableBracketedPasteMsg in an internal message signals that +// bracketed paste should be disabled. You can send an +// disableBracketedPasteMsg with DisableBracketedPaste. +type disableBracketedPasteMsg struct{} + // EnterAltScreen enters the alternate screen buffer, which consumes the entire // terminal window. ExitAltScreen will return the terminal to its former state. // @@ -123,6 +151,8 @@ type showCursorMsg struct{} func (p *Program) EnterAltScreen() { if p.renderer != nil { p.renderer.enterAltScreen() + } else { + p.startupOptions |= withAltScreen } } @@ -132,6 +162,8 @@ func (p *Program) EnterAltScreen() { func (p *Program) ExitAltScreen() { if p.renderer != nil { p.renderer.exitAltScreen() + } else { + p.startupOptions &^= withAltScreen } } @@ -140,7 +172,11 @@ func (p *Program) ExitAltScreen() { // // Deprecated: Use the WithMouseCellMotion ProgramOption instead. func (p *Program) EnableMouseCellMotion() { - p.renderer.enableMouseCellMotion() + if p.renderer != nil { + p.renderer.enableMouseCellMotion() + } else { + p.startupOptions |= withMouseCellMotion + } } // DisableMouseCellMotion disables Mouse Cell Motion tracking. This will be @@ -148,7 +184,11 @@ func (p *Program) EnableMouseCellMotion() { // // Deprecated: The mouse will automatically be disabled when the program exits. func (p *Program) DisableMouseCellMotion() { - p.renderer.disableMouseCellMotion() + if p.renderer != nil { + p.renderer.disableMouseCellMotion() + } else { + p.startupOptions &^= withMouseCellMotion + } } // EnableMouseAllMotion enables mouse click, release, wheel and motion events, @@ -157,7 +197,11 @@ func (p *Program) DisableMouseCellMotion() { // // Deprecated: Use the WithMouseAllMotion ProgramOption instead. func (p *Program) EnableMouseAllMotion() { - p.renderer.enableMouseAllMotion() + if p.renderer != nil { + p.renderer.enableMouseAllMotion() + } else { + p.startupOptions |= withMouseAllMotion + } } // DisableMouseAllMotion disables All Motion mouse tracking. This will be @@ -165,10 +209,20 @@ func (p *Program) EnableMouseAllMotion() { // // Deprecated: The mouse will automatically be disabled when the program exits. func (p *Program) DisableMouseAllMotion() { - p.renderer.disableMouseAllMotion() + if p.renderer != nil { + p.renderer.disableMouseAllMotion() + } else { + p.startupOptions &^= withMouseAllMotion + } } // SetWindowTitle sets the terminal window title. +// +// Deprecated: Use the SetWindowTitle command instead. func (p *Program) SetWindowTitle(title string) { - p.output.SetWindowTitle(title) + if p.renderer != nil { + p.renderer.setWindowTitle(title) + } else { + p.startupTitle = title + } } diff --git a/vendor/github.com/charmbracelet/bubbletea/signals_unix.go b/vendor/github.com/charmbracelet/bubbletea/signals_unix.go index 826f58b9..40954038 100644 --- a/vendor/github.com/charmbracelet/bubbletea/signals_unix.go +++ b/vendor/github.com/charmbracelet/bubbletea/signals_unix.go @@ -1,5 +1,5 @@ -//go:build darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || aix -// +build darwin dragonfly freebsd linux netbsd openbsd solaris aix +//go:build darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || aix || zos +// +build darwin dragonfly freebsd linux netbsd openbsd solaris aix zos package tea diff --git a/vendor/github.com/charmbracelet/bubbletea/standard_renderer.go b/vendor/github.com/charmbracelet/bubbletea/standard_renderer.go index 1573a1c2..1b7f4b9b 100644 --- a/vendor/github.com/charmbracelet/bubbletea/standard_renderer.go +++ b/vendor/github.com/charmbracelet/bubbletea/standard_renderer.go @@ -8,9 +8,8 @@ import ( "sync" "time" + "github.com/charmbracelet/x/ansi" "github.com/muesli/ansi/compressor" - "github.com/muesli/reflow/truncate" - "github.com/muesli/termenv" ) const ( @@ -27,7 +26,7 @@ const ( // to exclude ranges of lines, allowing them to be written to directly. type standardRenderer struct { mtx *sync.Mutex - out *termenv.Output + out io.Writer buf bytes.Buffer queuedMessageLines []string @@ -45,6 +44,9 @@ type standardRenderer struct { // essentially whether or not we're using the full size of the terminal altScreenActive bool + // whether or not we're currently using bracketed paste + bpActive bool + // renderer dimensions; usually the size of the window width int height int @@ -55,7 +57,7 @@ type standardRenderer struct { // newRenderer creates a new renderer. Normally you'll want to initialize it // with os.Stdout as the first argument. -func newRenderer(out *termenv.Output, useANSICompressor bool, fps int) renderer { +func newRenderer(out io.Writer, useANSICompressor bool, fps int) renderer { if fps < 1 { fps = defaultFPS } else if fps > maxFPS { @@ -70,7 +72,7 @@ func newRenderer(out *termenv.Output, useANSICompressor bool, fps int) renderer queuedMessageLines: []string{}, } if r.useANSICompressor { - r.out = termenv.NewOutput(&compressor.Writer{Forward: out}) + r.out = &compressor.Writer{Forward: out} } return r } @@ -105,15 +107,20 @@ func (r *standardRenderer) stop() { r.mtx.Lock() defer r.mtx.Unlock() - r.out.ClearLine() + r.execute(ansi.EraseEntireLine) if r.useANSICompressor { - if w, ok := r.out.TTY().(io.WriteCloser); ok { + if w, ok := r.out.(io.WriteCloser); ok { _ = w.Close() } } } +// execute writes a sequence to the terminal. +func (r *standardRenderer) execute(seq string) { + _, _ = io.WriteString(r.out, seq) +} + // kill halts the renderer. The final frame will not be rendered. func (r *standardRenderer) kill() { // Stop the renderer before acquiring the mutex to avoid a deadlock. @@ -124,7 +131,7 @@ func (r *standardRenderer) kill() { r.mtx.Lock() defer r.mtx.Unlock() - r.out.ClearLine() + r.execute(ansi.EraseEntireLine) } // listen waits for ticks on the ticker, or a signal to stop the renderer. @@ -153,7 +160,6 @@ func (r *standardRenderer) flush() { // Output buffer buf := &bytes.Buffer{} - out := termenv.NewOutput(buf) newLines := strings.Split(r.buf.String(), "\n") @@ -170,25 +176,24 @@ func (r *standardRenderer) flush() { skipLines := make(map[int]struct{}) flushQueuedMessages := len(r.queuedMessageLines) > 0 && !r.altScreenActive - // Add any queued messages to this render - if flushQueuedMessages { - newLines = append(r.queuedMessageLines, newLines...) - r.queuedMessageLines = []string{} - } - // Clear any lines we painted in the last render. if r.linesRendered > 0 { for i := r.linesRendered - 1; i > 0; i-- { - // If the number of lines we want to render hasn't increased and - // new line is the same as the old line we can skip rendering for - // this line as a performance optimization. - if (len(newLines) <= len(oldLines)) && (len(newLines) > i && len(oldLines) > i) && (newLines[i] == oldLines[i]) { + // if we are clearing queued messages, we want to clear all lines, since + // printing messages allows for native terminal word-wrap, we + // don't have control over the queued lines + if flushQueuedMessages { + buf.WriteString(ansi.EraseEntireLine) + } else if (len(newLines) <= len(oldLines)) && (len(newLines) > i && len(oldLines) > i) && (newLines[i] == oldLines[i]) { + // If the number of lines we want to render hasn't increased and + // new line is the same as the old line we can skip rendering for + // this line as a performance optimization. skipLines[i] = struct{}{} } else if _, exists := r.ignoreLines[i]; !exists { - out.ClearLine() + buf.WriteString(ansi.EraseEntireLine) } - out.CursorUp(1) + buf.WriteString(ansi.CursorUp1) } if _, exists := r.ignoreLines[0]; !exists { @@ -201,8 +206,8 @@ func (r *standardRenderer) flush() { // standard (whereas others are proprietary to, say, VT100/VT52). // If cursor previous line (ESC[ +
+ return 1, KeyDownEvent{Rune: rune(b) - 0x40, Mod: Ctrl | Alt}
+ }
+ return parseUtf8(buf)
+ }
+}
+
+func parseCsi(b []byte) (int, Event) {
+ if len(b) == 2 && b[0] == ansi.ESC {
+ // short cut if this is an alt+[ key
+ return 2, KeyDownEvent{Rune: rune(b[1]), Mod: Alt}
+ }
+
+ var csi ansi.CsiSequence
+ var params [parser.MaxParamsSize]int
+ var paramsLen int
+
+ var i int
+ if b[i] == ansi.CSI || b[i] == ansi.ESC {
+ i++
+ }
+ if i < len(b) && b[i-1] == ansi.ESC && b[i] == '[' {
+ i++
+ }
+
+ // Initial CSI byte
+ if i < len(b) && b[i] >= '<' && b[i] <= '?' {
+ csi.Cmd |= int(b[i]) << parser.MarkerShift
+ }
+
+ // Scan parameter bytes in the range 0x30-0x3F
+ var j int
+ for j = 0; i < len(b) && paramsLen < len(params) && b[i] >= 0x30 && b[i] <= 0x3F; i, j = i+1, j+1 {
+ if b[i] >= '0' && b[i] <= '9' {
+ if params[paramsLen] == parser.MissingParam {
+ params[paramsLen] = 0
+ }
+ params[paramsLen] *= 10
+ params[paramsLen] += int(b[i]) - '0'
+ }
+ if b[i] == ':' {
+ params[paramsLen] |= parser.HasMoreFlag
+ }
+ if b[i] == ';' || b[i] == ':' {
+ paramsLen++
+ if paramsLen < len(params) {
+ // Don't overflow the params slice
+ params[paramsLen] = parser.MissingParam
+ }
+ }
+ }
+
+ if j > 0 && paramsLen < len(params) {
+ // has parameters
+ paramsLen++
+ }
+
+ // Scan intermediate bytes in the range 0x20-0x2F
+ var intermed byte
+ for ; i < len(b) && b[i] >= 0x20 && b[i] <= 0x2F; i++ {
+ intermed = b[i]
+ }
+
+ // Set the intermediate byte
+ csi.Cmd |= int(intermed) << parser.IntermedShift
+
+ // Scan final byte in the range 0x40-0x7E
+ if i >= len(b) || b[i] < 0x40 || b[i] > 0x7E {
+ // Special case for URxvt keys
+ // CSI $ is an invalid sequence, but URxvt uses it for
+ // shift modified keys.
+ if b[i-1] == '$' {
+ n, ev := parseCsi(append(b[:i-1], '~'))
+ if k, ok := ev.(KeyDownEvent); ok {
+ k.Mod |= Shift
+ return n, k
+ }
+ }
+ return i, UnknownEvent(b[:i-1])
+ }
+
+ // Add the final byte
+ csi.Cmd |= int(b[i])
+ i++
+
+ csi.Params = params[:paramsLen]
+ marker, cmd := csi.Marker(), csi.Command()
+ switch marker {
+ case '?':
+ switch cmd {
+ case 'y':
+ switch intermed {
+ case '$':
+ // Report Mode (DECRPM)
+ if paramsLen != 2 {
+ return i, UnknownCsiEvent(b[:i])
+ }
+ return i, ReportModeEvent{Mode: csi.Param(0), Value: csi.Param(1)}
+ }
+ case 'c':
+ // Primary Device Attributes
+ return i, parsePrimaryDevAttrs(&csi)
+ case 'u':
+ // Kitty keyboard flags
+ if param := csi.Param(0); param != -1 {
+ return i, KittyKeyboardEvent(param)
+ }
+ case 'R':
+ // This report may return a third parameter representing the page
+ // number, but we don't really need it.
+ if paramsLen >= 2 {
+ return i, CursorPositionEvent{Row: csi.Param(0), Column: csi.Param(1)}
+ }
+ }
+ return i, UnknownCsiEvent(b[:i])
+ case '<':
+ switch cmd {
+ case 'm', 'M':
+ // Handle SGR mouse
+ if paramsLen != 3 {
+ return i, UnknownCsiEvent(b[:i])
+ }
+ return i, parseSGRMouseEvent(&csi)
+ default:
+ return i, UnknownCsiEvent(b[:i])
+ }
+ case '>':
+ switch cmd {
+ case 'm':
+ // XTerm modifyOtherKeys
+ if paramsLen != 2 || csi.Param(0) != 4 {
+ return i, UnknownCsiEvent(b[:i])
+ }
+
+ return i, ModifyOtherKeysEvent(csi.Param(1))
+ default:
+ return i, UnknownCsiEvent(b[:i])
+ }
+ case '=':
+ // We don't support any of these yet
+ return i, UnknownCsiEvent(b[:i])
+ }
+
+ switch cmd := csi.Command(); cmd {
+ case 'R':
+ // Cursor position report OR modified F3
+ if paramsLen == 0 {
+ return i, KeyDownEvent{Sym: KeyF3}
+ } else if paramsLen != 2 {
+ break
+ }
+
+ // XXX: We cannot differentiate between cursor position report and
+ // CSI 1 ; R (which is modified F3) when the cursor is at the
+ // row 1. In this case, we report a modified F3 event since it's more
+ // likely to be the case than the cursor being at the first row.
+ //
+ // For a non ambiguous cursor position report, use
+ // [ansi.RequestExtendedCursorPosition] (DECXCPR) instead.
+ if csi.Param(0) != 1 {
+ return i, CursorPositionEvent{Row: csi.Param(0), Column: csi.Param(1)}
+ }
+
+ fallthrough
+ case 'a', 'b', 'c', 'd', 'A', 'B', 'C', 'D', 'E', 'F', 'H', 'P', 'Q', 'S', 'Z':
+ var k KeyDownEvent
+ switch cmd {
+ case 'a', 'b', 'c', 'd':
+ k = KeyDownEvent{Sym: KeyUp + KeySym(cmd-'a'), Mod: Shift}
+ case 'A', 'B', 'C', 'D':
+ k = KeyDownEvent{Sym: KeyUp + KeySym(cmd-'A')}
+ case 'E':
+ k = KeyDownEvent{Sym: KeyBegin}
+ case 'F':
+ k = KeyDownEvent{Sym: KeyEnd}
+ case 'H':
+ k = KeyDownEvent{Sym: KeyHome}
+ case 'P', 'Q', 'R', 'S':
+ k = KeyDownEvent{Sym: KeyF1 + KeySym(cmd-'P')}
+ case 'Z':
+ k = KeyDownEvent{Sym: KeyTab, Mod: Shift}
+ }
+ if paramsLen > 1 && csi.Param(0) == 1 {
+ // CSI 1 ; A
+ if paramsLen > 1 {
+ k.Mod |= KeyMod(csi.Param(1) - 1)
+ }
+ }
+ return i, k
+ case 'M':
+ // Handle X10 mouse
+ if i+3 > len(b) {
+ return i, UnknownCsiEvent(b[:i])
+ }
+ return i + 3, parseX10MouseEvent(append(b[:i], b[i:i+3]...))
+ case 'y':
+ // Report Mode (DECRPM)
+ if paramsLen != 2 {
+ return i, UnknownCsiEvent(b[:i])
+ }
+ return i, ReportModeEvent{Mode: csi.Param(0), Value: csi.Param(1)}
+ case 'u':
+ // Kitty keyboard protocol & CSI u (fixterms)
+ if paramsLen == 0 {
+ return i, UnknownCsiEvent(b[:i])
+ }
+ return i, parseKittyKeyboard(&csi)
+ case '_':
+ // Win32 Input Mode
+ if paramsLen != 6 {
+ return i, UnknownCsiEvent(b[:i])
+ }
+
+ rc := uint16(csi.Param(5))
+ if rc == 0 {
+ rc = 1
+ }
+
+ event := parseWin32InputKeyEvent(
+ coninput.VirtualKeyCode(csi.Param(0)), // Vk wVirtualKeyCode
+ coninput.VirtualKeyCode(csi.Param(1)), // Sc wVirtualScanCode
+ rune(csi.Param(2)), // Uc UnicodeChar
+ csi.Param(3) == 1, // Kd bKeyDown
+ coninput.ControlKeyState(csi.Param(4)), // Cs dwControlKeyState
+ rc, // Rc wRepeatCount
+ )
+
+ if event == nil {
+ return i, UnknownCsiEvent(b[:])
+ }
+
+ return i, event
+ case '@', '^', '~':
+ if paramsLen == 0 {
+ return i, UnknownCsiEvent(b[:i])
+ }
+
+ param := csi.Param(0)
+ switch cmd {
+ case '~':
+ switch param {
+ case 27:
+ // XTerm modifyOtherKeys 2
+ if paramsLen != 3 {
+ return i, UnknownCsiEvent(b[:i])
+ }
+ return i, parseXTermModifyOtherKeys(&csi)
+ case 200:
+ // bracketed-paste start
+ return i, PasteStartEvent{}
+ case 201:
+ // bracketed-paste end
+ return i, PasteEndEvent{}
+ }
+ }
+
+ switch param {
+ case 1, 2, 3, 4, 5, 6, 7, 8:
+ fallthrough
+ case 11, 12, 13, 14, 15:
+ fallthrough
+ case 17, 18, 19, 20, 21, 23, 24, 25, 26:
+ fallthrough
+ case 28, 29, 31, 32, 33, 34:
+ var k KeyDownEvent
+ switch param {
+ case 1:
+ if flags&FlagFind != 0 {
+ k = KeyDownEvent{Sym: KeyFind}
+ } else {
+ k = KeyDownEvent{Sym: KeyHome}
+ }
+ case 2:
+ k = KeyDownEvent{Sym: KeyInsert}
+ case 3:
+ k = KeyDownEvent{Sym: KeyDelete}
+ case 4:
+ if flags&FlagSelect != 0 {
+ k = KeyDownEvent{Sym: KeySelect}
+ } else {
+ k = KeyDownEvent{Sym: KeyEnd}
+ }
+ case 5:
+ k = KeyDownEvent{Sym: KeyPgUp}
+ case 6:
+ k = KeyDownEvent{Sym: KeyPgDown}
+ case 7:
+ k = KeyDownEvent{Sym: KeyHome}
+ case 8:
+ k = KeyDownEvent{Sym: KeyEnd}
+ case 11, 12, 13, 14, 15:
+ k = KeyDownEvent{Sym: KeyF1 + KeySym(param-11)}
+ case 17, 18, 19, 20, 21:
+ k = KeyDownEvent{Sym: KeyF6 + KeySym(param-17)}
+ case 23, 24, 25, 26:
+ k = KeyDownEvent{Sym: KeyF11 + KeySym(param-23)}
+ case 28, 29:
+ k = KeyDownEvent{Sym: KeyF15 + KeySym(param-28)}
+ case 31, 32, 33, 34:
+ k = KeyDownEvent{Sym: KeyF17 + KeySym(param-31)}
+ }
+
+ // modifiers
+ if paramsLen > 1 {
+ k.Mod |= KeyMod(csi.Param(1) - 1)
+ }
+
+ // Handle URxvt weird keys
+ switch cmd {
+ case '^':
+ k.Mod |= Ctrl
+ case '@':
+ k.Mod |= Ctrl | Shift
+ }
+
+ return i, k
+ }
+ }
+ return i, UnknownCsiEvent(b[:i])
+}
+
+// parseSs3 parses a SS3 sequence.
+// See https://vt100.net/docs/vt220-rm/chapter4.html#S4.4.4.2
+func parseSs3(b []byte) (int, Event) {
+ if len(b) == 2 && b[0] == ansi.ESC {
+ // short cut if this is an alt+O key
+ return 2, KeyDownEvent{Rune: rune(b[1]), Mod: Alt}
+ }
+
+ var i int
+ if b[i] == ansi.SS3 || b[i] == ansi.ESC {
+ i++
+ }
+ if i < len(b) && b[i-1] == ansi.ESC && b[i] == 'O' {
+ i++
+ }
+
+ // Scan numbers from 0-9
+ var mod int
+ for ; i < len(b) && b[i] >= '0' && b[i] <= '9'; i++ {
+ mod *= 10
+ mod += int(b[i]) - '0'
+ }
+
+ // Scan a GL character
+ // A GL character is a single byte in the range 0x21-0x7E
+ // See https://vt100.net/docs/vt220-rm/chapter2.html#S2.3.2
+ if i >= len(b) || b[i] < 0x21 || b[i] > 0x7E {
+ return i, UnknownEvent(b[:i])
+ }
+
+ // GL character(s)
+ gl := b[i]
+ i++
+
+ var k KeyDownEvent
+ switch gl {
+ case 'a', 'b', 'c', 'd':
+ k = KeyDownEvent{Sym: KeyUp + KeySym(gl-'a'), Mod: Ctrl}
+ case 'A', 'B', 'C', 'D':
+ k = KeyDownEvent{Sym: KeyUp + KeySym(gl-'A')}
+ case 'E':
+ k = KeyDownEvent{Sym: KeyBegin}
+ case 'F':
+ k = KeyDownEvent{Sym: KeyEnd}
+ case 'H':
+ k = KeyDownEvent{Sym: KeyHome}
+ case 'P', 'Q', 'R', 'S':
+ k = KeyDownEvent{Sym: KeyF1 + KeySym(gl-'P')}
+ case 'M':
+ k = KeyDownEvent{Sym: KeyKpEnter}
+ case 'X':
+ k = KeyDownEvent{Sym: KeyKpEqual}
+ case 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y':
+ k = KeyDownEvent{Sym: KeyKpMultiply + KeySym(gl-'j')}
+ default:
+ return i, UnknownSs3Event(b[:i])
+ }
+
+ // Handle weird SS3 Func
+ if mod > 0 {
+ k.Mod |= KeyMod(mod - 1)
+ }
+
+ return i, k
+}
+
+func parseOsc(b []byte) (int, Event) {
+ if len(b) == 2 && b[0] == ansi.ESC {
+ // short cut if this is an alt+] key
+ return 2, KeyDownEvent{Rune: rune(b[1]), Mod: Alt}
+ }
+
+ var i int
+ if b[i] == ansi.OSC || b[i] == ansi.ESC {
+ i++
+ }
+ if i < len(b) && b[i-1] == ansi.ESC && b[i] == ']' {
+ i++
+ }
+
+ // Parse OSC command
+ // An OSC sequence is terminated by a BEL, ESC, or ST character
+ var start, end int
+ cmd := -1
+ for ; i < len(b) && b[i] >= '0' && b[i] <= '9'; i++ {
+ if cmd == -1 {
+ cmd = 0
+ } else {
+ cmd *= 10
+ }
+ cmd += int(b[i]) - '0'
+ }
+
+ if i < len(b) && b[i] == ';' {
+ // mark the start of the sequence data
+ i++
+ start = i
+ }
+
+ for ; i < len(b); i++ {
+ // advance to the end of the sequence
+ if b[i] == ansi.BEL || b[i] == ansi.ESC || b[i] == ansi.ST {
+ break
+ }
+ }
+
+ if i >= len(b) {
+ return i, UnknownEvent(b[:i])
+ }
+
+ end = i // end of the sequence data
+ i++
+
+ // Check 7-bit ST (string terminator) character
+ if i < len(b) && b[i-1] == ansi.ESC && b[i] == '\\' {
+ i++
+ }
+
+ if end <= start {
+ return i, UnknownOscEvent(b[:i])
+ }
+
+ data := string(b[start:end])
+ switch cmd {
+ case 10:
+ return i, ForegroundColorEvent{xParseColor(data)}
+ case 11:
+ return i, BackgroundColorEvent{xParseColor(data)}
+ case 12:
+ return i, CursorColorEvent{xParseColor(data)}
+ case 52:
+ parts := strings.Split(data, ";")
+ if len(parts) == 0 {
+ return i, ClipboardEvent("")
+ }
+ b64 := parts[len(parts)-1]
+ bts, err := base64.StdEncoding.DecodeString(b64)
+ if err != nil {
+ return i, ClipboardEvent("")
+ }
+ return i, ClipboardEvent(bts)
+ default:
+ return i, UnknownOscEvent(b[:i])
+ }
+}
+
+// parseStTerminated parses a control sequence that gets terminated by a ST character.
+func parseStTerminated(intro8, intro7 byte) func([]byte) (int, Event) {
+ return func(b []byte) (int, Event) {
+ var i int
+ if b[i] == intro8 || b[i] == ansi.ESC {
+ i++
+ }
+ if i < len(b) && b[i-1] == ansi.ESC && b[i] == intro7 {
+ i++
+ }
+
+ // Scan control sequence
+ // Most common control sequence is terminated by a ST character
+ // ST is a 7-bit string terminator character is (ESC \)
+ // nolint: revive
+ for ; i < len(b) && b[i] != ansi.ST && b[i] != ansi.ESC; i++ {
+ }
+
+ if i >= len(b) {
+ switch intro8 {
+ case ansi.DCS:
+ return i, UnknownDcsEvent(b[:i])
+ case ansi.APC:
+ return i, UnknownApcEvent(b[:i])
+ default:
+ return i, UnknownEvent(b[:i])
+ }
+ }
+ i++
+
+ // Check 7-bit ST (string terminator) character
+ if i < len(b) && b[i-1] == ansi.ESC && b[i] == '\\' {
+ i++
+ }
+
+ switch intro8 {
+ case ansi.DCS:
+ return i, UnknownDcsEvent(b[:i])
+ case ansi.APC:
+ return i, UnknownApcEvent(b[:i])
+ default:
+ return i, UnknownEvent(b[:i])
+ }
+ }
+}
+
+func parseDcs(b []byte) (int, Event) {
+ if len(b) == 2 && b[0] == ansi.ESC {
+ // short cut if this is an alt+P key
+ return 2, KeyDownEvent{Rune: rune(b[1]), Mod: Alt}
+ }
+
+ var params [16]int
+ var paramsLen int
+ var dcs ansi.DcsSequence
+
+ // DCS sequences are introduced by DCS (0x90) or ESC P (0x1b 0x50)
+ var i int
+ if b[i] == ansi.DCS || b[i] == ansi.ESC {
+ i++
+ }
+ if i < len(b) && b[i-1] == ansi.ESC && b[i] == 'P' {
+ i++
+ }
+
+ // initial DCS byte
+ if i < len(b) && b[i] >= '<' && b[i] <= '?' {
+ dcs.Cmd |= int(b[i]) << parser.MarkerShift
+ }
+
+ // Scan parameter bytes in the range 0x30-0x3F
+ var j int
+ for j = 0; i < len(b) && paramsLen < len(params) && b[i] >= 0x30 && b[i] <= 0x3F; i, j = i+1, j+1 {
+ if b[i] >= '0' && b[i] <= '9' {
+ if params[paramsLen] == parser.MissingParam {
+ params[paramsLen] = 0
+ }
+ params[paramsLen] *= 10
+ params[paramsLen] += int(b[i]) - '0'
+ }
+ if b[i] == ':' {
+ params[paramsLen] |= parser.HasMoreFlag
+ }
+ if b[i] == ';' || b[i] == ':' {
+ paramsLen++
+ if paramsLen < len(params) {
+ // Don't overflow the params slice
+ params[paramsLen] = parser.MissingParam
+ }
+ }
+ }
+
+ if j > 0 && paramsLen < len(params) {
+ // has parameters
+ paramsLen++
+ }
+
+ // Scan intermediate bytes in the range 0x20-0x2F
+ var intermed byte
+ for j := 0; i < len(b) && b[i] >= 0x20 && b[i] <= 0x2F; i, j = i+1, j+1 {
+ intermed = b[i]
+ }
+
+ // set intermediate byte
+ dcs.Cmd |= int(intermed) << parser.IntermedShift
+
+ // Scan final byte in the range 0x40-0x7E
+ if i >= len(b) || b[i] < 0x40 || b[i] > 0x7E {
+ return i, UnknownEvent(b[:i])
+ }
+
+ // Add the final byte
+ dcs.Cmd |= int(b[i])
+ i++
+
+ start := i // start of the sequence data
+ for ; i < len(b); i++ {
+ if b[i] == ansi.ST || b[i] == ansi.ESC {
+ break
+ }
+ }
+
+ if i >= len(b) {
+ return i, UnknownEvent(b[:i])
+ }
+
+ end := i // end of the sequence data
+ i++
+
+ // Check 7-bit ST (string terminator) character
+ if i < len(b) && b[i-1] == ansi.ESC && b[i] == '\\' {
+ i++
+ }
+
+ dcs.Params = params[:paramsLen]
+ switch cmd := dcs.Command(); cmd {
+ case 'r':
+ switch dcs.Intermediate() {
+ case '+':
+ // XTGETTCAP responses
+ switch param := dcs.Param(0); param {
+ case 0, 1:
+ tc := parseTermcap(b[start:end])
+ // XXX: some terminals like KiTTY report invalid responses with
+ // their queries i.e. sending a query for "Tc" using "\x1bP+q5463\x1b\\"
+ // returns "\x1bP0+r5463\x1b\\".
+ // The specs says that invalid responses should be in the form of
+ // DCS 0 + r ST "\x1bP0+r\x1b\\"
+ //
+ // See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h3-Operating-System-Commands
+ tc.IsValid = param == 1
+ return i, tc
+ }
+ }
+ }
+
+ return i, UnknownDcsEvent(b[:i])
+}
+
+func parseApc(b []byte) (int, Event) {
+ if len(b) == 2 && b[0] == ansi.ESC {
+ // short cut if this is an alt+_ key
+ return 2, KeyDownEvent{Rune: rune(b[1]), Mod: Alt}
+ }
+
+ // APC sequences are introduced by APC (0x9f) or ESC _ (0x1b 0x5f)
+ return parseStTerminated(ansi.APC, '_')(b)
+}
+
+func parseUtf8(b []byte) (int, Event) {
+ r, rw := utf8.DecodeRune(b)
+ if r <= ansi.US || r == ansi.DEL || r == ansi.SP {
+ // Control codes get handled by parseControl
+ return 1, parseControl(byte(r))
+ } else if r == utf8.RuneError {
+ return 1, UnknownEvent(b[0])
+ }
+ return rw, KeyDownEvent{Rune: r}
+}
+
+func parseControl(b byte) Event {
+ switch b {
+ case ansi.NUL:
+ if flags&FlagCtrlAt != 0 {
+ return KeyDownEvent{Rune: '@', Mod: Ctrl}
+ }
+ return KeyDownEvent{Rune: ' ', Sym: KeySpace, Mod: Ctrl}
+ case ansi.BS:
+ return KeyDownEvent{Rune: 'h', Mod: Ctrl}
+ case ansi.HT:
+ if flags&FlagCtrlI != 0 {
+ return KeyDownEvent{Rune: 'i', Mod: Ctrl}
+ }
+ return KeyDownEvent{Sym: KeyTab}
+ case ansi.CR:
+ if flags&FlagCtrlM != 0 {
+ return KeyDownEvent{Rune: 'm', Mod: Ctrl}
+ }
+ return KeyDownEvent{Sym: KeyEnter}
+ case ansi.ESC:
+ if flags&FlagCtrlOpenBracket != 0 {
+ return KeyDownEvent{Rune: '[', Mod: Ctrl}
+ }
+ return KeyDownEvent{Sym: KeyEscape}
+ case ansi.DEL:
+ if flags&FlagBackspace != 0 {
+ return KeyDownEvent{Sym: KeyDelete}
+ }
+ return KeyDownEvent{Sym: KeyBackspace}
+ case ansi.SP:
+ return KeyDownEvent{Sym: KeySpace, Rune: ' '}
+ default:
+ if b >= ansi.SOH && b <= ansi.SUB {
+ // Use lower case letters for control codes
+ return KeyDownEvent{Rune: rune(b + 0x60), Mod: Ctrl}
+ } else if b >= ansi.FS && b <= ansi.US {
+ return KeyDownEvent{Rune: rune(b + 0x40), Mod: Ctrl}
+ }
+ return UnknownEvent(b)
+ }
+}
diff --git a/vendor/github.com/charmbracelet/x/input/paste.go b/vendor/github.com/charmbracelet/x/input/paste.go
new file mode 100644
index 00000000..079d3cb2
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/input/paste.go
@@ -0,0 +1,12 @@
+package input
+
+// PasteEvent is an event that is emitted when a terminal receives pasted text
+// using bracketed-paste.
+type PasteEvent string
+
+// PasteStartEvent is an event that is emitted when a terminal enters
+// bracketed-paste mode.
+type PasteStartEvent struct{}
+
+// PasteEvent is an event that is emitted when a terminal receives pasted text.
+type PasteEndEvent struct{}
diff --git a/vendor/github.com/charmbracelet/x/input/seq.go b/vendor/github.com/charmbracelet/x/input/seq.go
new file mode 100644
index 00000000..460e12b8
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/input/seq.go
@@ -0,0 +1,45 @@
+package input
+
+import (
+ "fmt"
+)
+
+// UnknownCsiEvent represents an unknown CSI sequence event.
+type UnknownCsiEvent string
+
+// String implements fmt.Stringer.
+func (e UnknownCsiEvent) String() string {
+ return fmt.Sprintf("%q", string(e))
+}
+
+// UnknownOscEvent represents an unknown OSC sequence event.
+type UnknownOscEvent string
+
+// String implements fmt.Stringer.
+func (e UnknownOscEvent) String() string {
+ return fmt.Sprintf("%q", string(e))
+}
+
+// UnknownDcsEvent represents an unknown DCS sequence event.
+type UnknownDcsEvent string
+
+// String implements fmt.Stringer.
+func (e UnknownDcsEvent) String() string {
+ return fmt.Sprintf("%q", string(e))
+}
+
+// UnknownApcEvent represents an unknown APC sequence event.
+type UnknownApcEvent string
+
+// String implements fmt.Stringer.
+func (e UnknownApcEvent) String() string {
+ return fmt.Sprintf("%q", string(e))
+}
+
+// UnknownSs3Event represents an unknown SS3 sequence event.
+type UnknownSs3Event string
+
+// String implements fmt.Stringer.
+func (e UnknownSs3Event) String() string {
+ return fmt.Sprintf("%q", string(e))
+}
diff --git a/vendor/github.com/charmbracelet/x/input/table.go b/vendor/github.com/charmbracelet/x/input/table.go
new file mode 100644
index 00000000..5ce20307
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/input/table.go
@@ -0,0 +1,388 @@
+package input
+
+import (
+ "strconv"
+
+ "github.com/charmbracelet/x/ansi"
+)
+
+func buildKeysTable(flags int, term string) map[string]Key {
+ nul := Key{Rune: ' ', Sym: KeySpace, Mod: Ctrl} // ctrl+@ or ctrl+space
+ if flags&FlagCtrlAt != 0 {
+ nul = Key{Rune: '@', Mod: Ctrl}
+ }
+
+ tab := Key{Sym: KeyTab} // ctrl+i or tab
+ if flags&FlagCtrlI != 0 {
+ tab = Key{Rune: 'i', Mod: Ctrl}
+ }
+
+ enter := Key{Sym: KeyEnter} // ctrl+m or enter
+ if flags&FlagCtrlM != 0 {
+ enter = Key{Rune: 'm', Mod: Ctrl}
+ }
+
+ esc := Key{Sym: KeyEscape} // ctrl+[ or escape
+ if flags&FlagCtrlOpenBracket != 0 {
+ esc = Key{Rune: '[', Mod: Ctrl} // ctrl+[ or escape
+ }
+
+ del := Key{Sym: KeyBackspace}
+ if flags&FlagBackspace != 0 {
+ del.Sym = KeyDelete
+ }
+
+ find := Key{Sym: KeyHome}
+ if flags&FlagFind != 0 {
+ find.Sym = KeyFind
+ }
+
+ sel := Key{Sym: KeyEnd}
+ if flags&FlagSelect != 0 {
+ sel.Sym = KeySelect
+ }
+
+ // The following is a table of key sequences and their corresponding key
+ // events based on the VT100/VT200 terminal specs.
+ //
+ // See: https://vt100.net/docs/vt100-ug/chapter3.html#S3.2
+ // See: https://vt100.net/docs/vt220-rm/chapter3.html
+ //
+ // XXX: These keys may be overwritten by other options like XTerm or
+ // Terminfo.
+ table := map[string]Key{
+ // C0 control characters
+ string(byte(ansi.NUL)): nul,
+ string(byte(ansi.SOH)): {Rune: 'a', Mod: Ctrl},
+ string(byte(ansi.STX)): {Rune: 'b', Mod: Ctrl},
+ string(byte(ansi.ETX)): {Rune: 'c', Mod: Ctrl},
+ string(byte(ansi.EOT)): {Rune: 'd', Mod: Ctrl},
+ string(byte(ansi.ENQ)): {Rune: 'e', Mod: Ctrl},
+ string(byte(ansi.ACK)): {Rune: 'f', Mod: Ctrl},
+ string(byte(ansi.BEL)): {Rune: 'g', Mod: Ctrl},
+ string(byte(ansi.BS)): {Rune: 'h', Mod: Ctrl},
+ string(byte(ansi.HT)): tab,
+ string(byte(ansi.LF)): {Rune: 'j', Mod: Ctrl},
+ string(byte(ansi.VT)): {Rune: 'k', Mod: Ctrl},
+ string(byte(ansi.FF)): {Rune: 'l', Mod: Ctrl},
+ string(byte(ansi.CR)): enter,
+ string(byte(ansi.SO)): {Rune: 'n', Mod: Ctrl},
+ string(byte(ansi.SI)): {Rune: 'o', Mod: Ctrl},
+ string(byte(ansi.DLE)): {Rune: 'p', Mod: Ctrl},
+ string(byte(ansi.DC1)): {Rune: 'q', Mod: Ctrl},
+ string(byte(ansi.DC2)): {Rune: 'r', Mod: Ctrl},
+ string(byte(ansi.DC3)): {Rune: 's', Mod: Ctrl},
+ string(byte(ansi.DC4)): {Rune: 't', Mod: Ctrl},
+ string(byte(ansi.NAK)): {Rune: 'u', Mod: Ctrl},
+ string(byte(ansi.SYN)): {Rune: 'v', Mod: Ctrl},
+ string(byte(ansi.ETB)): {Rune: 'w', Mod: Ctrl},
+ string(byte(ansi.CAN)): {Rune: 'x', Mod: Ctrl},
+ string(byte(ansi.EM)): {Rune: 'y', Mod: Ctrl},
+ string(byte(ansi.SUB)): {Rune: 'z', Mod: Ctrl},
+ string(byte(ansi.ESC)): esc,
+ string(byte(ansi.FS)): {Rune: '\\', Mod: Ctrl},
+ string(byte(ansi.GS)): {Rune: ']', Mod: Ctrl},
+ string(byte(ansi.RS)): {Rune: '^', Mod: Ctrl},
+ string(byte(ansi.US)): {Rune: '_', Mod: Ctrl},
+
+ // Special keys in G0
+ string(byte(ansi.SP)): {Sym: KeySpace, Rune: ' '},
+ string(byte(ansi.DEL)): del,
+
+ // Special keys
+
+ "\x1b[Z": {Sym: KeyTab, Mod: Shift},
+
+ "\x1b[1~": find,
+ "\x1b[2~": {Sym: KeyInsert},
+ "\x1b[3~": {Sym: KeyDelete},
+ "\x1b[4~": sel,
+ "\x1b[5~": {Sym: KeyPgUp},
+ "\x1b[6~": {Sym: KeyPgDown},
+ "\x1b[7~": {Sym: KeyHome},
+ "\x1b[8~": {Sym: KeyEnd},
+
+ // Normal mode
+ "\x1b[A": {Sym: KeyUp},
+ "\x1b[B": {Sym: KeyDown},
+ "\x1b[C": {Sym: KeyRight},
+ "\x1b[D": {Sym: KeyLeft},
+ "\x1b[E": {Sym: KeyBegin},
+ "\x1b[F": {Sym: KeyEnd},
+ "\x1b[H": {Sym: KeyHome},
+ "\x1b[P": {Sym: KeyF1},
+ "\x1b[Q": {Sym: KeyF2},
+ "\x1b[R": {Sym: KeyF3},
+ "\x1b[S": {Sym: KeyF4},
+
+ // Application Cursor Key Mode (DECCKM)
+ "\x1bOA": {Sym: KeyUp},
+ "\x1bOB": {Sym: KeyDown},
+ "\x1bOC": {Sym: KeyRight},
+ "\x1bOD": {Sym: KeyLeft},
+ "\x1bOE": {Sym: KeyBegin},
+ "\x1bOF": {Sym: KeyEnd},
+ "\x1bOH": {Sym: KeyHome},
+ "\x1bOP": {Sym: KeyF1},
+ "\x1bOQ": {Sym: KeyF2},
+ "\x1bOR": {Sym: KeyF3},
+ "\x1bOS": {Sym: KeyF4},
+
+ // Keypad Application Mode (DECKPAM)
+
+ "\x1bOM": {Sym: KeyKpEnter},
+ "\x1bOX": {Sym: KeyKpEqual},
+ "\x1bOj": {Sym: KeyKpMultiply},
+ "\x1bOk": {Sym: KeyKpPlus},
+ "\x1bOl": {Sym: KeyKpComma},
+ "\x1bOm": {Sym: KeyKpMinus},
+ "\x1bOn": {Sym: KeyKpDecimal},
+ "\x1bOo": {Sym: KeyKpDivide},
+ "\x1bOp": {Sym: KeyKp0},
+ "\x1bOq": {Sym: KeyKp1},
+ "\x1bOr": {Sym: KeyKp2},
+ "\x1bOs": {Sym: KeyKp3},
+ "\x1bOt": {Sym: KeyKp4},
+ "\x1bOu": {Sym: KeyKp5},
+ "\x1bOv": {Sym: KeyKp6},
+ "\x1bOw": {Sym: KeyKp7},
+ "\x1bOx": {Sym: KeyKp8},
+ "\x1bOy": {Sym: KeyKp9},
+
+ // Function keys
+
+ "\x1b[11~": {Sym: KeyF1},
+ "\x1b[12~": {Sym: KeyF2},
+ "\x1b[13~": {Sym: KeyF3},
+ "\x1b[14~": {Sym: KeyF4},
+ "\x1b[15~": {Sym: KeyF5},
+ "\x1b[17~": {Sym: KeyF6},
+ "\x1b[18~": {Sym: KeyF7},
+ "\x1b[19~": {Sym: KeyF8},
+ "\x1b[20~": {Sym: KeyF9},
+ "\x1b[21~": {Sym: KeyF10},
+ "\x1b[23~": {Sym: KeyF11},
+ "\x1b[24~": {Sym: KeyF12},
+ "\x1b[25~": {Sym: KeyF13},
+ "\x1b[26~": {Sym: KeyF14},
+ "\x1b[28~": {Sym: KeyF15},
+ "\x1b[29~": {Sym: KeyF16},
+ "\x1b[31~": {Sym: KeyF17},
+ "\x1b[32~": {Sym: KeyF18},
+ "\x1b[33~": {Sym: KeyF19},
+ "\x1b[34~": {Sym: KeyF20},
+ }
+
+ // CSI ~ sequence keys
+ csiTildeKeys := map[string]Key{
+ "1": find, "2": {Sym: KeyInsert},
+ "3": {Sym: KeyDelete}, "4": sel,
+ "5": {Sym: KeyPgUp}, "6": {Sym: KeyPgDown},
+ "7": {Sym: KeyHome}, "8": {Sym: KeyEnd},
+ // There are no 9 and 10 keys
+ "11": {Sym: KeyF1}, "12": {Sym: KeyF2},
+ "13": {Sym: KeyF3}, "14": {Sym: KeyF4},
+ "15": {Sym: KeyF5}, "17": {Sym: KeyF6},
+ "18": {Sym: KeyF7}, "19": {Sym: KeyF8},
+ "20": {Sym: KeyF9}, "21": {Sym: KeyF10},
+ "23": {Sym: KeyF11}, "24": {Sym: KeyF12},
+ "25": {Sym: KeyF13}, "26": {Sym: KeyF14},
+ "28": {Sym: KeyF15}, "29": {Sym: KeyF16},
+ "31": {Sym: KeyF17}, "32": {Sym: KeyF18},
+ "33": {Sym: KeyF19}, "34": {Sym: KeyF20},
+ }
+
+ // URxvt keys
+ // See https://manpages.ubuntu.com/manpages/trusty/man7/urxvt.7.html#key%20codes
+ table["\x1b[a"] = Key{Sym: KeyUp, Mod: Shift}
+ table["\x1b[b"] = Key{Sym: KeyDown, Mod: Shift}
+ table["\x1b[c"] = Key{Sym: KeyRight, Mod: Shift}
+ table["\x1b[d"] = Key{Sym: KeyLeft, Mod: Shift}
+ table["\x1bOa"] = Key{Sym: KeyUp, Mod: Ctrl}
+ table["\x1bOb"] = Key{Sym: KeyDown, Mod: Ctrl}
+ table["\x1bOc"] = Key{Sym: KeyRight, Mod: Ctrl}
+ table["\x1bOd"] = Key{Sym: KeyLeft, Mod: Ctrl}
+ // TODO: invistigate if shift-ctrl arrow keys collide with DECCKM keys i.e.
+ // "\x1bOA", "\x1bOB", "\x1bOC", "\x1bOD"
+
+ // URxvt modifier CSI ~ keys
+ for k, v := range csiTildeKeys {
+ key := v
+ // Normal (no modifier) already defined part of VT100/VT200
+ // Shift modifier
+ key.Mod = Shift
+ table["\x1b["+k+"$"] = key
+ // Ctrl modifier
+ key.Mod = Ctrl
+ table["\x1b["+k+"^"] = key
+ // Shift-Ctrl modifier
+ key.Mod = Shift | Ctrl
+ table["\x1b["+k+"@"] = key
+ }
+
+ // URxvt F keys
+ // Note: Shift + F1-F10 generates F11-F20.
+ // This means Shift + F1 and Shift + F2 will generate F11 and F12, the same
+ // applies to Ctrl + Shift F1 & F2.
+ //
+ // P.S. Don't like this? Blame URxvt, configure your terminal to use
+ // different escapes like XTerm, or switch to a better terminal ¯\_(ツ)_/¯
+ //
+ // See https://manpages.ubuntu.com/manpages/trusty/man7/urxvt.7.html#key%20codes
+ table["\x1b[23$"] = Key{Sym: KeyF11, Mod: Shift}
+ table["\x1b[24$"] = Key{Sym: KeyF12, Mod: Shift}
+ table["\x1b[25$"] = Key{Sym: KeyF13, Mod: Shift}
+ table["\x1b[26$"] = Key{Sym: KeyF14, Mod: Shift}
+ table["\x1b[28$"] = Key{Sym: KeyF15, Mod: Shift}
+ table["\x1b[29$"] = Key{Sym: KeyF16, Mod: Shift}
+ table["\x1b[31$"] = Key{Sym: KeyF17, Mod: Shift}
+ table["\x1b[32$"] = Key{Sym: KeyF18, Mod: Shift}
+ table["\x1b[33$"] = Key{Sym: KeyF19, Mod: Shift}
+ table["\x1b[34$"] = Key{Sym: KeyF20, Mod: Shift}
+ table["\x1b[11^"] = Key{Sym: KeyF1, Mod: Ctrl}
+ table["\x1b[12^"] = Key{Sym: KeyF2, Mod: Ctrl}
+ table["\x1b[13^"] = Key{Sym: KeyF3, Mod: Ctrl}
+ table["\x1b[14^"] = Key{Sym: KeyF4, Mod: Ctrl}
+ table["\x1b[15^"] = Key{Sym: KeyF5, Mod: Ctrl}
+ table["\x1b[17^"] = Key{Sym: KeyF6, Mod: Ctrl}
+ table["\x1b[18^"] = Key{Sym: KeyF7, Mod: Ctrl}
+ table["\x1b[19^"] = Key{Sym: KeyF8, Mod: Ctrl}
+ table["\x1b[20^"] = Key{Sym: KeyF9, Mod: Ctrl}
+ table["\x1b[21^"] = Key{Sym: KeyF10, Mod: Ctrl}
+ table["\x1b[23^"] = Key{Sym: KeyF11, Mod: Ctrl}
+ table["\x1b[24^"] = Key{Sym: KeyF12, Mod: Ctrl}
+ table["\x1b[25^"] = Key{Sym: KeyF13, Mod: Ctrl}
+ table["\x1b[26^"] = Key{Sym: KeyF14, Mod: Ctrl}
+ table["\x1b[28^"] = Key{Sym: KeyF15, Mod: Ctrl}
+ table["\x1b[29^"] = Key{Sym: KeyF16, Mod: Ctrl}
+ table["\x1b[31^"] = Key{Sym: KeyF17, Mod: Ctrl}
+ table["\x1b[32^"] = Key{Sym: KeyF18, Mod: Ctrl}
+ table["\x1b[33^"] = Key{Sym: KeyF19, Mod: Ctrl}
+ table["\x1b[34^"] = Key{Sym: KeyF20, Mod: Ctrl}
+ table["\x1b[23@"] = Key{Sym: KeyF11, Mod: Shift | Ctrl}
+ table["\x1b[24@"] = Key{Sym: KeyF12, Mod: Shift | Ctrl}
+ table["\x1b[25@"] = Key{Sym: KeyF13, Mod: Shift | Ctrl}
+ table["\x1b[26@"] = Key{Sym: KeyF14, Mod: Shift | Ctrl}
+ table["\x1b[28@"] = Key{Sym: KeyF15, Mod: Shift | Ctrl}
+ table["\x1b[29@"] = Key{Sym: KeyF16, Mod: Shift | Ctrl}
+ table["\x1b[31@"] = Key{Sym: KeyF17, Mod: Shift | Ctrl}
+ table["\x1b[32@"] = Key{Sym: KeyF18, Mod: Shift | Ctrl}
+ table["\x1b[33@"] = Key{Sym: KeyF19, Mod: Shift | Ctrl}
+ table["\x1b[34@"] = Key{Sym: KeyF20, Mod: Shift | Ctrl}
+
+ // Register Alt + combinations
+ // XXX: this must come after URxvt but before XTerm keys to register URxvt
+ // keys with alt modifier
+ tmap := map[string]Key{}
+ for seq, key := range table {
+ key := key
+ key.Mod |= Alt
+ tmap["\x1b"+seq] = key
+ }
+ for seq, key := range tmap {
+ table[seq] = key
+ }
+
+ // XTerm modifiers
+ // These are offset by 1 to be compatible with our Mod type.
+ // See https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h3-PC-Style-Function-Keys
+ modifiers := []KeyMod{
+ Shift, // 1
+ Alt, // 2
+ Shift | Alt, // 3
+ Ctrl, // 4
+ Shift | Ctrl, // 5
+ Alt | Ctrl, // 6
+ Shift | Alt | Ctrl, // 7
+ Meta, // 8
+ Meta | Shift, // 9
+ Meta | Alt, // 10
+ Meta | Shift | Alt, // 11
+ Meta | Ctrl, // 12
+ Meta | Shift | Ctrl, // 13
+ Meta | Alt | Ctrl, // 14
+ Meta | Shift | Alt | Ctrl, // 15
+ }
+
+ // SS3 keypad function keys
+ ss3FuncKeys := map[string]Key{
+ // These are defined in XTerm
+ // Taken from Foot keymap.h and XTerm modifyOtherKeys
+ // https://codeberg.org/dnkl/foot/src/branch/master/keymap.h
+ "M": {Sym: KeyKpEnter}, "X": {Sym: KeyKpEqual},
+ "j": {Sym: KeyKpMultiply}, "k": {Sym: KeyKpPlus},
+ "l": {Sym: KeyKpComma}, "m": {Sym: KeyKpMinus},
+ "n": {Sym: KeyKpDecimal}, "o": {Sym: KeyKpDivide},
+ "p": {Sym: KeyKp0}, "q": {Sym: KeyKp1},
+ "r": {Sym: KeyKp2}, "s": {Sym: KeyKp3},
+ "t": {Sym: KeyKp4}, "u": {Sym: KeyKp5},
+ "v": {Sym: KeyKp6}, "w": {Sym: KeyKp7},
+ "x": {Sym: KeyKp8}, "y": {Sym: KeyKp9},
+ }
+
+ // XTerm keys
+ csiFuncKeys := map[string]Key{
+ "A": {Sym: KeyUp}, "B": {Sym: KeyDown},
+ "C": {Sym: KeyRight}, "D": {Sym: KeyLeft},
+ "E": {Sym: KeyBegin}, "F": {Sym: KeyEnd},
+ "H": {Sym: KeyHome}, "P": {Sym: KeyF1},
+ "Q": {Sym: KeyF2}, "R": {Sym: KeyF3},
+ "S": {Sym: KeyF4},
+ }
+
+ // CSI 27 ; ; ~ keys defined in XTerm modifyOtherKeys
+ modifyOtherKeys := map[int]Key{
+ ansi.BS: {Sym: KeyBackspace},
+ ansi.HT: {Sym: KeyTab},
+ ansi.CR: {Sym: KeyEnter},
+ ansi.ESC: {Sym: KeyEscape},
+ ansi.DEL: {Sym: KeyBackspace},
+ }
+
+ for _, m := range modifiers {
+ // XTerm modifier offset +1
+ xtermMod := strconv.Itoa(int(m) + 1)
+
+ // CSI 1 ;
+ for k, v := range csiFuncKeys {
+ // Functions always have a leading 1 param
+ seq := "\x1b[1;" + xtermMod + k
+ key := v
+ key.Mod = m
+ table[seq] = key
+ }
+ // SS3
+ for k, v := range ss3FuncKeys {
+ seq := "\x1bO" + xtermMod + k
+ key := v
+ key.Mod = m
+ table[seq] = key
+ }
+ // CSI ; ~
+ for k, v := range csiTildeKeys {
+ seq := "\x1b[" + k + ";" + xtermMod + "~"
+ key := v
+ key.Mod = m
+ table[seq] = key
+ }
+ // CSI 27 ; ; ~
+ for k, v := range modifyOtherKeys {
+ code := strconv.Itoa(k)
+ seq := "\x1b[27;" + xtermMod + ";" + code + "~"
+ key := v
+ key.Mod = m
+ table[seq] = key
+ }
+ }
+
+ // Register terminfo keys
+ // XXX: this might override keys already registered in table
+ if flags&FlagTerminfo != 0 {
+ titable := buildTerminfoKeys(flags, term)
+ for seq, key := range titable {
+ table[seq] = key
+ }
+ }
+
+ return table
+}
diff --git a/vendor/github.com/charmbracelet/x/input/termcap.go b/vendor/github.com/charmbracelet/x/input/termcap.go
new file mode 100644
index 00000000..82045b1d
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/input/termcap.go
@@ -0,0 +1,49 @@
+package input
+
+import (
+ "bytes"
+ "encoding/hex"
+)
+
+// TermcapEvent represents a Termcap response event. Termcap responses are
+// generated by the terminal in response to RequestTermcap (XTGETTCAP)
+// requests.
+//
+// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h3-Operating-System-Commands
+type TermcapEvent struct {
+ Values map[string]string
+ IsValid bool
+}
+
+func parseTermcap(data []byte) TermcapEvent {
+ // XTGETTCAP
+ if len(data) == 0 {
+ return TermcapEvent{}
+ }
+
+ tc := TermcapEvent{Values: make(map[string]string)}
+ split := bytes.Split(data, []byte{';'})
+ for _, s := range split {
+ parts := bytes.SplitN(s, []byte{'='}, 2)
+ if len(parts) == 0 {
+ return TermcapEvent{}
+ }
+
+ name, err := hex.DecodeString(string(parts[0]))
+ if err != nil || len(name) == 0 {
+ continue
+ }
+
+ var value []byte
+ if len(parts) > 1 {
+ value, err = hex.DecodeString(string(parts[1]))
+ if err != nil {
+ continue
+ }
+ }
+
+ tc.Values[string(name)] = string(value)
+ }
+
+ return tc
+}
diff --git a/vendor/github.com/charmbracelet/x/input/terminfo.go b/vendor/github.com/charmbracelet/x/input/terminfo.go
new file mode 100644
index 00000000..debf8511
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/input/terminfo.go
@@ -0,0 +1,277 @@
+package input
+
+import (
+ "strings"
+
+ "github.com/xo/terminfo"
+)
+
+func buildTerminfoKeys(flags int, term string) map[string]Key {
+ table := make(map[string]Key)
+ ti, _ := terminfo.Load(term)
+ if ti == nil {
+ return table
+ }
+
+ tiTable := defaultTerminfoKeys(flags)
+
+ // Default keys
+ for name, seq := range ti.StringCapsShort() {
+ if !strings.HasPrefix(name, "k") || len(seq) == 0 {
+ continue
+ }
+
+ if k, ok := tiTable[name]; ok {
+ table[string(seq)] = k
+ }
+ }
+
+ // Extended keys
+ for name, seq := range ti.ExtStringCapsShort() {
+ if !strings.HasPrefix(name, "k") || len(seq) == 0 {
+ continue
+ }
+
+ if k, ok := tiTable[name]; ok {
+ table[string(seq)] = k
+ }
+ }
+
+ return table
+}
+
+// This returns a map of terminfo keys to key events. It's a mix of ncurses
+// terminfo default and user-defined key capabilities.
+// Upper-case caps that are defined in the default terminfo database are
+// - kNXT
+// - kPRV
+// - kHOM
+// - kEND
+// - kDC
+// - kIC
+// - kLFT
+// - kRIT
+//
+// See https://man7.org/linux/man-pages/man5/terminfo.5.html
+// See https://github.com/mirror/ncurses/blob/master/include/Caps-ncurses
+func defaultTerminfoKeys(flags int) map[string]Key {
+ keys := map[string]Key{
+ "kcuu1": {Sym: KeyUp},
+ "kUP": {Sym: KeyUp, Mod: Shift},
+ "kUP3": {Sym: KeyUp, Mod: Alt},
+ "kUP4": {Sym: KeyUp, Mod: Shift | Alt},
+ "kUP5": {Sym: KeyUp, Mod: Ctrl},
+ "kUP6": {Sym: KeyUp, Mod: Shift | Ctrl},
+ "kUP7": {Sym: KeyUp, Mod: Alt | Ctrl},
+ "kUP8": {Sym: KeyUp, Mod: Shift | Alt | Ctrl},
+ "kcud1": {Sym: KeyDown},
+ "kDN": {Sym: KeyDown, Mod: Shift},
+ "kDN3": {Sym: KeyDown, Mod: Alt},
+ "kDN4": {Sym: KeyDown, Mod: Shift | Alt},
+ "kDN5": {Sym: KeyDown, Mod: Ctrl},
+ "kDN7": {Sym: KeyDown, Mod: Alt | Ctrl},
+ "kDN6": {Sym: KeyDown, Mod: Shift | Ctrl},
+ "kDN8": {Sym: KeyDown, Mod: Shift | Alt | Ctrl},
+ "kcub1": {Sym: KeyLeft},
+ "kLFT": {Sym: KeyLeft, Mod: Shift},
+ "kLFT3": {Sym: KeyLeft, Mod: Alt},
+ "kLFT4": {Sym: KeyLeft, Mod: Shift | Alt},
+ "kLFT5": {Sym: KeyLeft, Mod: Ctrl},
+ "kLFT6": {Sym: KeyLeft, Mod: Shift | Ctrl},
+ "kLFT7": {Sym: KeyLeft, Mod: Alt | Ctrl},
+ "kLFT8": {Sym: KeyLeft, Mod: Shift | Alt | Ctrl},
+ "kcuf1": {Sym: KeyRight},
+ "kRIT": {Sym: KeyRight, Mod: Shift},
+ "kRIT3": {Sym: KeyRight, Mod: Alt},
+ "kRIT4": {Sym: KeyRight, Mod: Shift | Alt},
+ "kRIT5": {Sym: KeyRight, Mod: Ctrl},
+ "kRIT6": {Sym: KeyRight, Mod: Shift | Ctrl},
+ "kRIT7": {Sym: KeyRight, Mod: Alt | Ctrl},
+ "kRIT8": {Sym: KeyRight, Mod: Shift | Alt | Ctrl},
+ "kich1": {Sym: KeyInsert},
+ "kIC": {Sym: KeyInsert, Mod: Shift},
+ "kIC3": {Sym: KeyInsert, Mod: Alt},
+ "kIC4": {Sym: KeyInsert, Mod: Shift | Alt},
+ "kIC5": {Sym: KeyInsert, Mod: Ctrl},
+ "kIC6": {Sym: KeyInsert, Mod: Shift | Ctrl},
+ "kIC7": {Sym: KeyInsert, Mod: Alt | Ctrl},
+ "kIC8": {Sym: KeyInsert, Mod: Shift | Alt | Ctrl},
+ "kdch1": {Sym: KeyDelete},
+ "kDC": {Sym: KeyDelete, Mod: Shift},
+ "kDC3": {Sym: KeyDelete, Mod: Alt},
+ "kDC4": {Sym: KeyDelete, Mod: Shift | Alt},
+ "kDC5": {Sym: KeyDelete, Mod: Ctrl},
+ "kDC6": {Sym: KeyDelete, Mod: Shift | Ctrl},
+ "kDC7": {Sym: KeyDelete, Mod: Alt | Ctrl},
+ "kDC8": {Sym: KeyDelete, Mod: Shift | Alt | Ctrl},
+ "khome": {Sym: KeyHome},
+ "kHOM": {Sym: KeyHome, Mod: Shift},
+ "kHOM3": {Sym: KeyHome, Mod: Alt},
+ "kHOM4": {Sym: KeyHome, Mod: Shift | Alt},
+ "kHOM5": {Sym: KeyHome, Mod: Ctrl},
+ "kHOM6": {Sym: KeyHome, Mod: Shift | Ctrl},
+ "kHOM7": {Sym: KeyHome, Mod: Alt | Ctrl},
+ "kHOM8": {Sym: KeyHome, Mod: Shift | Alt | Ctrl},
+ "kend": {Sym: KeyEnd},
+ "kEND": {Sym: KeyEnd, Mod: Shift},
+ "kEND3": {Sym: KeyEnd, Mod: Alt},
+ "kEND4": {Sym: KeyEnd, Mod: Shift | Alt},
+ "kEND5": {Sym: KeyEnd, Mod: Ctrl},
+ "kEND6": {Sym: KeyEnd, Mod: Shift | Ctrl},
+ "kEND7": {Sym: KeyEnd, Mod: Alt | Ctrl},
+ "kEND8": {Sym: KeyEnd, Mod: Shift | Alt | Ctrl},
+ "kpp": {Sym: KeyPgUp},
+ "kprv": {Sym: KeyPgUp},
+ "kPRV": {Sym: KeyPgUp, Mod: Shift},
+ "kPRV3": {Sym: KeyPgUp, Mod: Alt},
+ "kPRV4": {Sym: KeyPgUp, Mod: Shift | Alt},
+ "kPRV5": {Sym: KeyPgUp, Mod: Ctrl},
+ "kPRV6": {Sym: KeyPgUp, Mod: Shift | Ctrl},
+ "kPRV7": {Sym: KeyPgUp, Mod: Alt | Ctrl},
+ "kPRV8": {Sym: KeyPgUp, Mod: Shift | Alt | Ctrl},
+ "knp": {Sym: KeyPgDown},
+ "knxt": {Sym: KeyPgDown},
+ "kNXT": {Sym: KeyPgDown, Mod: Shift},
+ "kNXT3": {Sym: KeyPgDown, Mod: Alt},
+ "kNXT4": {Sym: KeyPgDown, Mod: Shift | Alt},
+ "kNXT5": {Sym: KeyPgDown, Mod: Ctrl},
+ "kNXT6": {Sym: KeyPgDown, Mod: Shift | Ctrl},
+ "kNXT7": {Sym: KeyPgDown, Mod: Alt | Ctrl},
+ "kNXT8": {Sym: KeyPgDown, Mod: Shift | Alt | Ctrl},
+
+ "kbs": {Sym: KeyBackspace},
+ "kcbt": {Sym: KeyTab, Mod: Shift},
+
+ // Function keys
+ // This only includes the first 12 function keys. The rest are treated
+ // as modifiers of the first 12.
+ // Take a look at XTerm modifyFunctionKeys
+ //
+ // XXX: To use unambiguous function keys, use fixterms or kitty clipboard.
+ //
+ // See https://invisible-island.net/xterm/manpage/xterm.html#VT100-Widget-Resources:modifyFunctionKeys
+ // See https://invisible-island.net/xterm/terminfo.html
+
+ "kf1": {Sym: KeyF1},
+ "kf2": {Sym: KeyF2},
+ "kf3": {Sym: KeyF3},
+ "kf4": {Sym: KeyF4},
+ "kf5": {Sym: KeyF5},
+ "kf6": {Sym: KeyF6},
+ "kf7": {Sym: KeyF7},
+ "kf8": {Sym: KeyF8},
+ "kf9": {Sym: KeyF9},
+ "kf10": {Sym: KeyF10},
+ "kf11": {Sym: KeyF11},
+ "kf12": {Sym: KeyF12},
+ "kf13": {Sym: KeyF1, Mod: Shift},
+ "kf14": {Sym: KeyF2, Mod: Shift},
+ "kf15": {Sym: KeyF3, Mod: Shift},
+ "kf16": {Sym: KeyF4, Mod: Shift},
+ "kf17": {Sym: KeyF5, Mod: Shift},
+ "kf18": {Sym: KeyF6, Mod: Shift},
+ "kf19": {Sym: KeyF7, Mod: Shift},
+ "kf20": {Sym: KeyF8, Mod: Shift},
+ "kf21": {Sym: KeyF9, Mod: Shift},
+ "kf22": {Sym: KeyF10, Mod: Shift},
+ "kf23": {Sym: KeyF11, Mod: Shift},
+ "kf24": {Sym: KeyF12, Mod: Shift},
+ "kf25": {Sym: KeyF1, Mod: Ctrl},
+ "kf26": {Sym: KeyF2, Mod: Ctrl},
+ "kf27": {Sym: KeyF3, Mod: Ctrl},
+ "kf28": {Sym: KeyF4, Mod: Ctrl},
+ "kf29": {Sym: KeyF5, Mod: Ctrl},
+ "kf30": {Sym: KeyF6, Mod: Ctrl},
+ "kf31": {Sym: KeyF7, Mod: Ctrl},
+ "kf32": {Sym: KeyF8, Mod: Ctrl},
+ "kf33": {Sym: KeyF9, Mod: Ctrl},
+ "kf34": {Sym: KeyF10, Mod: Ctrl},
+ "kf35": {Sym: KeyF11, Mod: Ctrl},
+ "kf36": {Sym: KeyF12, Mod: Ctrl},
+ "kf37": {Sym: KeyF1, Mod: Shift | Ctrl},
+ "kf38": {Sym: KeyF2, Mod: Shift | Ctrl},
+ "kf39": {Sym: KeyF3, Mod: Shift | Ctrl},
+ "kf40": {Sym: KeyF4, Mod: Shift | Ctrl},
+ "kf41": {Sym: KeyF5, Mod: Shift | Ctrl},
+ "kf42": {Sym: KeyF6, Mod: Shift | Ctrl},
+ "kf43": {Sym: KeyF7, Mod: Shift | Ctrl},
+ "kf44": {Sym: KeyF8, Mod: Shift | Ctrl},
+ "kf45": {Sym: KeyF9, Mod: Shift | Ctrl},
+ "kf46": {Sym: KeyF10, Mod: Shift | Ctrl},
+ "kf47": {Sym: KeyF11, Mod: Shift | Ctrl},
+ "kf48": {Sym: KeyF12, Mod: Shift | Ctrl},
+ "kf49": {Sym: KeyF1, Mod: Alt},
+ "kf50": {Sym: KeyF2, Mod: Alt},
+ "kf51": {Sym: KeyF3, Mod: Alt},
+ "kf52": {Sym: KeyF4, Mod: Alt},
+ "kf53": {Sym: KeyF5, Mod: Alt},
+ "kf54": {Sym: KeyF6, Mod: Alt},
+ "kf55": {Sym: KeyF7, Mod: Alt},
+ "kf56": {Sym: KeyF8, Mod: Alt},
+ "kf57": {Sym: KeyF9, Mod: Alt},
+ "kf58": {Sym: KeyF10, Mod: Alt},
+ "kf59": {Sym: KeyF11, Mod: Alt},
+ "kf60": {Sym: KeyF12, Mod: Alt},
+ "kf61": {Sym: KeyF1, Mod: Shift | Alt},
+ "kf62": {Sym: KeyF2, Mod: Shift | Alt},
+ "kf63": {Sym: KeyF3, Mod: Shift | Alt},
+ }
+
+ // Preserve F keys from F13 to F63 instead of using them for F-keys
+ // modifiers.
+ if flags&FlagFKeys != 0 {
+ keys["kf13"] = Key{Sym: KeyF13}
+ keys["kf14"] = Key{Sym: KeyF14}
+ keys["kf15"] = Key{Sym: KeyF15}
+ keys["kf16"] = Key{Sym: KeyF16}
+ keys["kf17"] = Key{Sym: KeyF17}
+ keys["kf18"] = Key{Sym: KeyF18}
+ keys["kf19"] = Key{Sym: KeyF19}
+ keys["kf20"] = Key{Sym: KeyF20}
+ keys["kf21"] = Key{Sym: KeyF21}
+ keys["kf22"] = Key{Sym: KeyF22}
+ keys["kf23"] = Key{Sym: KeyF23}
+ keys["kf24"] = Key{Sym: KeyF24}
+ keys["kf25"] = Key{Sym: KeyF25}
+ keys["kf26"] = Key{Sym: KeyF26}
+ keys["kf27"] = Key{Sym: KeyF27}
+ keys["kf28"] = Key{Sym: KeyF28}
+ keys["kf29"] = Key{Sym: KeyF29}
+ keys["kf30"] = Key{Sym: KeyF30}
+ keys["kf31"] = Key{Sym: KeyF31}
+ keys["kf32"] = Key{Sym: KeyF32}
+ keys["kf33"] = Key{Sym: KeyF33}
+ keys["kf34"] = Key{Sym: KeyF34}
+ keys["kf35"] = Key{Sym: KeyF35}
+ keys["kf36"] = Key{Sym: KeyF36}
+ keys["kf37"] = Key{Sym: KeyF37}
+ keys["kf38"] = Key{Sym: KeyF38}
+ keys["kf39"] = Key{Sym: KeyF39}
+ keys["kf40"] = Key{Sym: KeyF40}
+ keys["kf41"] = Key{Sym: KeyF41}
+ keys["kf42"] = Key{Sym: KeyF42}
+ keys["kf43"] = Key{Sym: KeyF43}
+ keys["kf44"] = Key{Sym: KeyF44}
+ keys["kf45"] = Key{Sym: KeyF45}
+ keys["kf46"] = Key{Sym: KeyF46}
+ keys["kf47"] = Key{Sym: KeyF47}
+ keys["kf48"] = Key{Sym: KeyF48}
+ keys["kf49"] = Key{Sym: KeyF49}
+ keys["kf50"] = Key{Sym: KeyF50}
+ keys["kf51"] = Key{Sym: KeyF51}
+ keys["kf52"] = Key{Sym: KeyF52}
+ keys["kf53"] = Key{Sym: KeyF53}
+ keys["kf54"] = Key{Sym: KeyF54}
+ keys["kf55"] = Key{Sym: KeyF55}
+ keys["kf56"] = Key{Sym: KeyF56}
+ keys["kf57"] = Key{Sym: KeyF57}
+ keys["kf58"] = Key{Sym: KeyF58}
+ keys["kf59"] = Key{Sym: KeyF59}
+ keys["kf60"] = Key{Sym: KeyF60}
+ keys["kf61"] = Key{Sym: KeyF61}
+ keys["kf62"] = Key{Sym: KeyF62}
+ keys["kf63"] = Key{Sym: KeyF63}
+ }
+
+ return keys
+}
diff --git a/vendor/github.com/charmbracelet/x/input/win32input.go b/vendor/github.com/charmbracelet/x/input/win32input.go
new file mode 100644
index 00000000..6fb55acb
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/input/win32input.go
@@ -0,0 +1,240 @@
+package input
+
+import (
+ "unicode"
+
+ "github.com/erikgeiser/coninput"
+)
+
+func parseWin32InputKeyEvent(vkc coninput.VirtualKeyCode, _ coninput.VirtualKeyCode, r rune, keyDown bool, cks coninput.ControlKeyState, repeatCount uint16) Event {
+ var key Key
+ isCtrl := cks.Contains(coninput.LEFT_CTRL_PRESSED | coninput.RIGHT_CTRL_PRESSED)
+ switch vkc {
+ case coninput.VK_SHIFT:
+ // We currently ignore these keys when they are pressed alone.
+ return nil
+ case coninput.VK_MENU:
+ if cks.Contains(coninput.LEFT_ALT_PRESSED) {
+ key = Key{Sym: KeyLeftAlt}
+ } else if cks.Contains(coninput.RIGHT_ALT_PRESSED) {
+ key = Key{Sym: KeyRightAlt}
+ } else if !keyDown {
+ return nil
+ }
+ case coninput.VK_CONTROL:
+ if cks.Contains(coninput.LEFT_CTRL_PRESSED) {
+ key = Key{Sym: KeyLeftCtrl}
+ } else if cks.Contains(coninput.RIGHT_CTRL_PRESSED) {
+ key = Key{Sym: KeyRightCtrl}
+ } else if !keyDown {
+ return nil
+ }
+ case coninput.VK_CAPITAL:
+ key = Key{Sym: KeyCapsLock}
+ default:
+ var ok bool
+ key, ok = vkKeyEvent[vkc]
+ if !ok {
+ if isCtrl {
+ key = vkCtrlRune(key, r, vkc)
+ } else {
+ key = Key{Rune: r}
+ }
+ }
+ }
+
+ if isCtrl {
+ key.Mod |= Ctrl
+ }
+ if cks.Contains(coninput.LEFT_ALT_PRESSED | coninput.RIGHT_ALT_PRESSED) {
+ key.Mod |= Alt
+ }
+ if cks.Contains(coninput.SHIFT_PRESSED) {
+ key.Mod |= Shift
+ }
+ if cks.Contains(coninput.CAPSLOCK_ON) {
+ key.Mod |= CapsLock
+ }
+ if cks.Contains(coninput.NUMLOCK_ON) {
+ key.Mod |= NumLock
+ }
+ if cks.Contains(coninput.SCROLLLOCK_ON) {
+ key.Mod |= ScrollLock
+ }
+
+ // Use the unshifted key
+ if cks.Contains(coninput.SHIFT_PRESSED ^ coninput.CAPSLOCK_ON) {
+ key.AltRune = unicode.ToUpper(key.Rune)
+ } else {
+ key.AltRune = unicode.ToLower(key.Rune)
+ }
+
+ var e Event = KeyDownEvent(key)
+ key.IsRepeat = repeatCount > 1
+ if !keyDown {
+ e = KeyUpEvent(key)
+ }
+
+ if repeatCount <= 1 {
+ return e
+ }
+
+ var kevents []Event
+ for i := 0; i < int(repeatCount); i++ {
+ kevents = append(kevents, e)
+ }
+
+ return MultiEvent(kevents)
+}
+
+var vkKeyEvent = map[coninput.VirtualKeyCode]Key{
+ coninput.VK_RETURN: {Sym: KeyEnter},
+ coninput.VK_BACK: {Sym: KeyBackspace},
+ coninput.VK_TAB: {Sym: KeyTab},
+ coninput.VK_ESCAPE: {Sym: KeyEscape},
+ coninput.VK_SPACE: {Sym: KeySpace, Rune: ' '},
+ coninput.VK_UP: {Sym: KeyUp},
+ coninput.VK_DOWN: {Sym: KeyDown},
+ coninput.VK_RIGHT: {Sym: KeyRight},
+ coninput.VK_LEFT: {Sym: KeyLeft},
+ coninput.VK_HOME: {Sym: KeyHome},
+ coninput.VK_END: {Sym: KeyEnd},
+ coninput.VK_PRIOR: {Sym: KeyPgUp},
+ coninput.VK_NEXT: {Sym: KeyPgDown},
+ coninput.VK_DELETE: {Sym: KeyDelete},
+ coninput.VK_SELECT: {Sym: KeySelect},
+ coninput.VK_SNAPSHOT: {Sym: KeyPrintScreen},
+ coninput.VK_INSERT: {Sym: KeyInsert},
+ coninput.VK_LWIN: {Sym: KeyLeftSuper},
+ coninput.VK_RWIN: {Sym: KeyRightSuper},
+ coninput.VK_APPS: {Sym: KeyMenu},
+ coninput.VK_NUMPAD0: {Sym: KeyKp0},
+ coninput.VK_NUMPAD1: {Sym: KeyKp1},
+ coninput.VK_NUMPAD2: {Sym: KeyKp2},
+ coninput.VK_NUMPAD3: {Sym: KeyKp3},
+ coninput.VK_NUMPAD4: {Sym: KeyKp4},
+ coninput.VK_NUMPAD5: {Sym: KeyKp5},
+ coninput.VK_NUMPAD6: {Sym: KeyKp6},
+ coninput.VK_NUMPAD7: {Sym: KeyKp7},
+ coninput.VK_NUMPAD8: {Sym: KeyKp8},
+ coninput.VK_NUMPAD9: {Sym: KeyKp9},
+ coninput.VK_MULTIPLY: {Sym: KeyKpMultiply},
+ coninput.VK_ADD: {Sym: KeyKpPlus},
+ coninput.VK_SEPARATOR: {Sym: KeyKpComma},
+ coninput.VK_SUBTRACT: {Sym: KeyKpMinus},
+ coninput.VK_DECIMAL: {Sym: KeyKpDecimal},
+ coninput.VK_DIVIDE: {Sym: KeyKpDivide},
+ coninput.VK_F1: {Sym: KeyF1},
+ coninput.VK_F2: {Sym: KeyF2},
+ coninput.VK_F3: {Sym: KeyF3},
+ coninput.VK_F4: {Sym: KeyF4},
+ coninput.VK_F5: {Sym: KeyF5},
+ coninput.VK_F6: {Sym: KeyF6},
+ coninput.VK_F7: {Sym: KeyF7},
+ coninput.VK_F8: {Sym: KeyF8},
+ coninput.VK_F9: {Sym: KeyF9},
+ coninput.VK_F10: {Sym: KeyF10},
+ coninput.VK_F11: {Sym: KeyF11},
+ coninput.VK_F12: {Sym: KeyF12},
+ coninput.VK_F13: {Sym: KeyF13},
+ coninput.VK_F14: {Sym: KeyF14},
+ coninput.VK_F15: {Sym: KeyF15},
+ coninput.VK_F16: {Sym: KeyF16},
+ coninput.VK_F17: {Sym: KeyF17},
+ coninput.VK_F18: {Sym: KeyF18},
+ coninput.VK_F19: {Sym: KeyF19},
+ coninput.VK_F20: {Sym: KeyF20},
+ coninput.VK_F21: {Sym: KeyF21},
+ coninput.VK_F22: {Sym: KeyF22},
+ coninput.VK_F23: {Sym: KeyF23},
+ coninput.VK_F24: {Sym: KeyF24},
+ coninput.VK_NUMLOCK: {Sym: KeyNumLock},
+ coninput.VK_SCROLL: {Sym: KeyScrollLock},
+ coninput.VK_LSHIFT: {Sym: KeyLeftShift},
+ coninput.VK_RSHIFT: {Sym: KeyRightShift},
+ coninput.VK_LCONTROL: {Sym: KeyLeftCtrl},
+ coninput.VK_RCONTROL: {Sym: KeyRightCtrl},
+ coninput.VK_LMENU: {Sym: KeyLeftAlt},
+ coninput.VK_RMENU: {Sym: KeyRightAlt},
+ coninput.VK_OEM_4: {Rune: '['},
+ // TODO: add more keys
+}
+
+func vkCtrlRune(k Key, r rune, kc coninput.VirtualKeyCode) Key {
+ switch r {
+ case '@':
+ k.Rune = '@'
+ case '\x01':
+ k.Rune = 'a'
+ case '\x02':
+ k.Rune = 'b'
+ case '\x03':
+ k.Rune = 'c'
+ case '\x04':
+ k.Rune = 'd'
+ case '\x05':
+ k.Rune = 'e'
+ case '\x06':
+ k.Rune = 'f'
+ case '\a':
+ k.Rune = 'g'
+ case '\b':
+ k.Rune = 'h'
+ case '\t':
+ k.Rune = 'i'
+ case '\n':
+ k.Rune = 'j'
+ case '\v':
+ k.Rune = 'k'
+ case '\f':
+ k.Rune = 'l'
+ case '\r':
+ k.Rune = 'm'
+ case '\x0e':
+ k.Rune = 'n'
+ case '\x0f':
+ k.Rune = 'o'
+ case '\x10':
+ k.Rune = 'p'
+ case '\x11':
+ k.Rune = 'q'
+ case '\x12':
+ k.Rune = 'r'
+ case '\x13':
+ k.Rune = 's'
+ case '\x14':
+ k.Rune = 't'
+ case '\x15':
+ k.Rune = 'u'
+ case '\x16':
+ k.Rune = 'v'
+ case '\x17':
+ k.Rune = 'w'
+ case '\x18':
+ k.Rune = 'x'
+ case '\x19':
+ k.Rune = 'y'
+ case '\x1a':
+ k.Rune = 'z'
+ case '\x1b':
+ k.Rune = ']'
+ case '\x1c':
+ k.Rune = '\\'
+ case '\x1f':
+ k.Rune = '_'
+ }
+
+ switch kc {
+ case coninput.VK_OEM_4:
+ k.Rune = '['
+ }
+
+ // https://learn.microsoft.com/en-us/windows/win32/inputdev/virtual-key-codes
+ if k.Rune == 0 &&
+ (kc >= 0x30 && kc <= 0x39) ||
+ (kc >= 0x41 && kc <= 0x5a) {
+ k.Rune = rune(kc)
+ }
+
+ return k
+}
diff --git a/vendor/github.com/charmbracelet/x/input/xterm.go b/vendor/github.com/charmbracelet/x/input/xterm.go
new file mode 100644
index 00000000..f80ecf4b
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/input/xterm.go
@@ -0,0 +1,40 @@
+package input
+
+import (
+ "github.com/charmbracelet/x/ansi"
+)
+
+func parseXTermModifyOtherKeys(csi *ansi.CsiSequence) Event {
+ // XTerm modify other keys starts with ESC [ 27 ; ; ~
+ mod := KeyMod(csi.Param(1) - 1)
+ r := rune(csi.Param(2))
+
+ switch r {
+ case ansi.BS:
+ return KeyDownEvent{Mod: mod, Sym: KeyBackspace}
+ case ansi.HT:
+ return KeyDownEvent{Mod: mod, Sym: KeyTab}
+ case ansi.CR:
+ return KeyDownEvent{Mod: mod, Sym: KeyEnter}
+ case ansi.ESC:
+ return KeyDownEvent{Mod: mod, Sym: KeyEscape}
+ case ansi.DEL:
+ return KeyDownEvent{Mod: mod, Sym: KeyBackspace}
+ }
+
+ // CSI 27 ; ; ~ keys defined in XTerm modifyOtherKeys
+ return KeyDownEvent{
+ Mod: mod,
+ Rune: r,
+ }
+}
+
+// ModifyOtherKeysEvent represents a modifyOtherKeys event.
+//
+// 0: disable
+// 1: enable mode 1
+// 2: enable mode 2
+//
+// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h3-Functions-using-CSI-_-ordered-by-the-final-character_s_
+// See: https://invisible-island.net/xterm/manpage/xterm.html#VT100-Widget-Resources:modifyOtherKeys
+type ModifyOtherKeysEvent uint8
diff --git a/vendor/github.com/charmbracelet/x/term/LICENSE b/vendor/github.com/charmbracelet/x/term/LICENSE
new file mode 100644
index 00000000..65a5654e
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/term/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2023 Charmbracelet, Inc.
+
+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.
diff --git a/vendor/github.com/charmbracelet/x/term/term.go b/vendor/github.com/charmbracelet/x/term/term.go
new file mode 100644
index 00000000..58d6522c
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/term/term.go
@@ -0,0 +1,49 @@
+package term
+
+// State contains platform-specific state of a terminal.
+type State struct {
+ state
+}
+
+// IsTerminal returns whether the given file descriptor is a terminal.
+func IsTerminal(fd uintptr) bool {
+ return isTerminal(fd)
+}
+
+// MakeRaw puts the terminal connected to the given file descriptor into raw
+// mode and returns the previous state of the terminal so that it can be
+// restored.
+func MakeRaw(fd uintptr) (*State, error) {
+ return makeRaw(fd)
+}
+
+// GetState returns the current state of a terminal which may be useful to
+// restore the terminal after a signal.
+func GetState(fd uintptr) (*State, error) {
+ return getState(fd)
+}
+
+// SetState sets the given state of the terminal.
+func SetState(fd uintptr, state *State) error {
+ return setState(fd, state)
+}
+
+// Restore restores the terminal connected to the given file descriptor to a
+// previous state.
+func Restore(fd uintptr, oldState *State) error {
+ return restore(fd, oldState)
+}
+
+// GetSize returns the visible dimensions of the given terminal.
+//
+// These dimensions don't include any scrollback buffer height.
+func GetSize(fd uintptr) (width, height int, err error) {
+ return getSize(fd)
+}
+
+// ReadPassword reads a line of input from a terminal without local echo. This
+// is commonly used for inputting passwords and other sensitive data. The slice
+// returned does not include the \n.
+func ReadPassword(fd uintptr) ([]byte, error) {
+ return readPassword(fd)
+}
diff --git a/vendor/github.com/charmbracelet/x/term/term_other.go b/vendor/github.com/charmbracelet/x/term/term_other.go
new file mode 100644
index 00000000..092c7e9d
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/term/term_other.go
@@ -0,0 +1,39 @@
+//go:build !aix && !darwin && !dragonfly && !freebsd && !linux && !netbsd && !openbsd && !zos && !windows && !solaris && !plan9
+// +build !aix,!darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!zos,!windows,!solaris,!plan9
+
+package term
+
+import (
+ "fmt"
+ "runtime"
+)
+
+type state struct{}
+
+func isTerminal(fd uintptr) bool {
+ return false
+}
+
+func makeRaw(fd uintptr) (*State, error) {
+ return nil, fmt.Errorf("terminal: MakeRaw not implemented on %s/%s", runtime.GOOS, runtime.GOARCH)
+}
+
+func getState(fd uintptr) (*State, error) {
+ return nil, fmt.Errorf("terminal: GetState not implemented on %s/%s", runtime.GOOS, runtime.GOARCH)
+}
+
+func restore(fd uintptr, state *State) error {
+ return fmt.Errorf("terminal: Restore not implemented on %s/%s", runtime.GOOS, runtime.GOARCH)
+}
+
+func getSize(fd uintptr) (width, height int, err error) {
+ return 0, 0, fmt.Errorf("terminal: GetSize not implemented on %s/%s", runtime.GOOS, runtime.GOARCH)
+}
+
+func setState(fd uintptr, state *State) error {
+ return fmt.Errorf("terminal: SetState not implemented on %s/%s", runtime.GOOS, runtime.GOARCH)
+}
+
+func readPassword(fd uintptr) ([]byte, error) {
+ return nil, fmt.Errorf("terminal: ReadPassword not implemented on %s/%s", runtime.GOOS, runtime.GOARCH)
+}
diff --git a/vendor/github.com/charmbracelet/x/term/term_unix.go b/vendor/github.com/charmbracelet/x/term/term_unix.go
new file mode 100644
index 00000000..1459cb1b
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/term/term_unix.go
@@ -0,0 +1,96 @@
+//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || zos
+// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris zos
+
+package term
+
+import (
+ "golang.org/x/sys/unix"
+)
+
+type state struct {
+ unix.Termios
+}
+
+func isTerminal(fd uintptr) bool {
+ _, err := unix.IoctlGetTermios(int(fd), ioctlReadTermios)
+ return err == nil
+}
+
+func makeRaw(fd uintptr) (*State, error) {
+ termios, err := unix.IoctlGetTermios(int(fd), ioctlReadTermios)
+ if err != nil {
+ return nil, err
+ }
+
+ oldState := State{state{Termios: *termios}}
+
+ // This attempts to replicate the behaviour documented for cfmakeraw in
+ // the termios(3) manpage.
+ termios.Iflag &^= unix.IGNBRK | unix.BRKINT | unix.PARMRK | unix.ISTRIP | unix.INLCR | unix.IGNCR | unix.ICRNL | unix.IXON
+ termios.Oflag &^= unix.OPOST
+ termios.Lflag &^= unix.ECHO | unix.ECHONL | unix.ICANON | unix.ISIG | unix.IEXTEN
+ termios.Cflag &^= unix.CSIZE | unix.PARENB
+ termios.Cflag |= unix.CS8
+ termios.Cc[unix.VMIN] = 1
+ termios.Cc[unix.VTIME] = 0
+ if err := unix.IoctlSetTermios(int(fd), ioctlWriteTermios, termios); err != nil {
+ return nil, err
+ }
+
+ return &oldState, nil
+}
+
+func setState(fd uintptr, state *State) error {
+ var termios *unix.Termios
+ if state != nil {
+ termios = &state.Termios
+ }
+ return unix.IoctlSetTermios(int(fd), ioctlWriteTermios, termios)
+}
+
+func getState(fd uintptr) (*State, error) {
+ termios, err := unix.IoctlGetTermios(int(fd), ioctlReadTermios)
+ if err != nil {
+ return nil, err
+ }
+
+ return &State{state{Termios: *termios}}, nil
+}
+
+func restore(fd uintptr, state *State) error {
+ return unix.IoctlSetTermios(int(fd), ioctlWriteTermios, &state.Termios)
+}
+
+func getSize(fd uintptr) (width, height int, err error) {
+ ws, err := unix.IoctlGetWinsize(int(fd), unix.TIOCGWINSZ)
+ if err != nil {
+ return 0, 0, err
+ }
+ return int(ws.Col), int(ws.Row), nil
+}
+
+// passwordReader is an io.Reader that reads from a specific file descriptor.
+type passwordReader int
+
+func (r passwordReader) Read(buf []byte) (int, error) {
+ return unix.Read(int(r), buf)
+}
+
+func readPassword(fd uintptr) ([]byte, error) {
+ termios, err := unix.IoctlGetTermios(int(fd), ioctlReadTermios)
+ if err != nil {
+ return nil, err
+ }
+
+ newState := *termios
+ newState.Lflag &^= unix.ECHO
+ newState.Lflag |= unix.ICANON | unix.ISIG
+ newState.Iflag |= unix.ICRNL
+ if err := unix.IoctlSetTermios(int(fd), ioctlWriteTermios, &newState); err != nil {
+ return nil, err
+ }
+
+ defer unix.IoctlSetTermios(int(fd), ioctlWriteTermios, termios)
+
+ return readPasswordLine(passwordReader(fd))
+}
diff --git a/vendor/github.com/charmbracelet/x/term/term_unix_bsd.go b/vendor/github.com/charmbracelet/x/term/term_unix_bsd.go
new file mode 100644
index 00000000..b435031a
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/term/term_unix_bsd.go
@@ -0,0 +1,11 @@
+//go:build darwin || dragonfly || freebsd || netbsd || openbsd
+// +build darwin dragonfly freebsd netbsd openbsd
+
+package term
+
+import "golang.org/x/sys/unix"
+
+const (
+ ioctlReadTermios = unix.TIOCGETA
+ ioctlWriteTermios = unix.TIOCSETA
+)
diff --git a/vendor/github.com/charmbracelet/x/term/term_unix_other.go b/vendor/github.com/charmbracelet/x/term/term_unix_other.go
new file mode 100644
index 00000000..ee2a29eb
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/term/term_unix_other.go
@@ -0,0 +1,11 @@
+//go:build aix || linux || solaris || zos
+// +build aix linux solaris zos
+
+package term
+
+import "golang.org/x/sys/unix"
+
+const (
+ ioctlReadTermios = unix.TCGETS
+ ioctlWriteTermios = unix.TCSETS
+)
diff --git a/vendor/github.com/charmbracelet/x/term/term_windows.go b/vendor/github.com/charmbracelet/x/term/term_windows.go
new file mode 100644
index 00000000..9e1c4740
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/term/term_windows.go
@@ -0,0 +1,86 @@
+//go:build windows
+// +build windows
+
+package term
+
+import (
+ "os"
+
+ "golang.org/x/sys/windows"
+)
+
+type state struct {
+ Mode uint32
+}
+
+func isTerminal(fd uintptr) bool {
+ var st uint32
+ err := windows.GetConsoleMode(windows.Handle(fd), &st)
+ return err == nil
+}
+
+func makeRaw(fd uintptr) (*State, error) {
+ var st uint32
+ if err := windows.GetConsoleMode(windows.Handle(fd), &st); err != nil {
+ return nil, err
+ }
+ raw := st &^ (windows.ENABLE_ECHO_INPUT | windows.ENABLE_PROCESSED_INPUT | windows.ENABLE_LINE_INPUT | windows.ENABLE_PROCESSED_OUTPUT)
+ if err := windows.SetConsoleMode(windows.Handle(fd), raw); err != nil {
+ return nil, err
+ }
+ return &State{state{st}}, nil
+}
+
+func setState(fd uintptr, state *State) error {
+ var mode uint32
+ if state != nil {
+ mode = state.Mode
+ }
+ return windows.SetConsoleMode(windows.Handle(fd), mode)
+}
+
+func getState(fd uintptr) (*State, error) {
+ var st uint32
+ if err := windows.GetConsoleMode(windows.Handle(fd), &st); err != nil {
+ return nil, err
+ }
+ return &State{state{st}}, nil
+}
+
+func restore(fd uintptr, state *State) error {
+ return windows.SetConsoleMode(windows.Handle(fd), state.Mode)
+}
+
+func getSize(fd uintptr) (width, height int, err error) {
+ var info windows.ConsoleScreenBufferInfo
+ if err := windows.GetConsoleScreenBufferInfo(windows.Handle(fd), &info); err != nil {
+ return 0, 0, err
+ }
+ return int(info.Window.Right - info.Window.Left + 1), int(info.Window.Bottom - info.Window.Top + 1), nil
+}
+
+func readPassword(fd uintptr) ([]byte, error) {
+ var st uint32
+ if err := windows.GetConsoleMode(windows.Handle(fd), &st); err != nil {
+ return nil, err
+ }
+ old := st
+
+ st &^= (windows.ENABLE_ECHO_INPUT | windows.ENABLE_LINE_INPUT)
+ st |= (windows.ENABLE_PROCESSED_OUTPUT | windows.ENABLE_PROCESSED_INPUT)
+ if err := windows.SetConsoleMode(windows.Handle(fd), st); err != nil {
+ return nil, err
+ }
+
+ defer windows.SetConsoleMode(windows.Handle(fd), old)
+
+ var h windows.Handle
+ p, _ := windows.GetCurrentProcess()
+ if err := windows.DuplicateHandle(p, windows.Handle(fd), p, &h, 0, false, windows.DUPLICATE_SAME_ACCESS); err != nil {
+ return nil, err
+ }
+
+ f := os.NewFile(uintptr(h), "stdin")
+ defer f.Close()
+ return readPasswordLine(f)
+}
diff --git a/vendor/github.com/charmbracelet/x/term/terminal.go b/vendor/github.com/charmbracelet/x/term/terminal.go
new file mode 100644
index 00000000..09d83f9a
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/term/terminal.go
@@ -0,0 +1,126 @@
+package term
+
+import (
+ "image/color"
+ "io"
+ "time"
+
+ "github.com/charmbracelet/x/ansi"
+ "github.com/charmbracelet/x/input"
+)
+
+// File represents a file that has a file descriptor and can be read from,
+// written to, and closed.
+type File interface {
+ io.ReadWriteCloser
+ Fd() uintptr
+}
+
+// QueryBackgroundColor queries the terminal for the background color.
+// If the terminal does not support querying the background color, nil is
+// returned.
+//
+// Note: you will need to set the input to raw mode before calling this
+// function.
+//
+// state, _ := term.MakeRaw(in.Fd())
+// defer term.Restore(in.Fd(), state)
+func QueryBackgroundColor(in io.Reader, out io.Writer) (c color.Color, err error) {
+ // nolint: errcheck
+ err = QueryTerminal(in, out, defaultQueryTimeout,
+ func(events []input.Event) bool {
+ for _, e := range events {
+ switch e := e.(type) {
+ case input.BackgroundColorEvent:
+ c = e.Color
+ continue // we need to consume the next DA1 event
+ case input.PrimaryDeviceAttributesEvent:
+ return false
+ }
+ }
+ return true
+ }, ansi.RequestBackgroundColor+ansi.RequestPrimaryDeviceAttributes)
+ return
+}
+
+// QueryKittyKeyboard returns the enabled Kitty keyboard protocol options.
+// -1 means the terminal does not support the feature.
+//
+// Note: you will need to set the input to raw mode before calling this
+// function.
+//
+// state, _ := term.MakeRaw(in.Fd())
+// defer term.Restore(in.Fd(), state)
+func QueryKittyKeyboard(in io.Reader, out io.Writer) (flags int, err error) {
+ flags = -1
+ // nolint: errcheck
+ err = QueryTerminal(in, out, defaultQueryTimeout,
+ func(events []input.Event) bool {
+ for _, e := range events {
+ switch event := e.(type) {
+ case input.KittyKeyboardEvent:
+ flags = int(event)
+ continue // we need to consume the next DA1 event
+ case input.PrimaryDeviceAttributesEvent:
+ return false
+ }
+ }
+ return true
+ }, ansi.RequestKittyKeyboard+ansi.RequestPrimaryDeviceAttributes)
+ return
+}
+
+const defaultQueryTimeout = time.Second * 2
+
+// QueryTerminalFilter is a function that filters input events using a type
+// switch. If false is returned, the QueryTerminal function will stop reading
+// input.
+type QueryTerminalFilter func(events []input.Event) bool
+
+// QueryTerminal queries the terminal for support of various features and
+// returns a list of response events.
+// Most of the time, you will need to set stdin to raw mode before calling this
+// function.
+// Note: This function will block until the terminal responds or the timeout
+// is reached.
+func QueryTerminal(
+ in io.Reader,
+ out io.Writer,
+ timeout time.Duration,
+ filter QueryTerminalFilter,
+ query string,
+) error {
+ rd, err := input.NewDriver(in, "", 0)
+ if err != nil {
+ return err
+ }
+
+ defer rd.Close() // nolint: errcheck
+
+ done := make(chan struct{}, 1)
+ defer close(done)
+ go func() {
+ select {
+ case <-done:
+ case <-time.After(timeout):
+ rd.Cancel()
+ }
+ }()
+
+ if _, err := io.WriteString(out, query); err != nil {
+ return err
+ }
+
+ for {
+ events, err := rd.ReadEvents()
+ if err != nil {
+ return err
+ }
+
+ if !filter(events) {
+ break
+ }
+ }
+
+ return nil
+}
diff --git a/vendor/github.com/charmbracelet/x/term/util.go b/vendor/github.com/charmbracelet/x/term/util.go
new file mode 100644
index 00000000..b7313418
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/term/util.go
@@ -0,0 +1,47 @@
+package term
+
+import (
+ "io"
+ "runtime"
+)
+
+// readPasswordLine reads from reader until it finds \n or io.EOF.
+// The slice returned does not include the \n.
+// readPasswordLine also ignores any \r it finds.
+// Windows uses \r as end of line. So, on Windows, readPasswordLine
+// reads until it finds \r and ignores any \n it finds during processing.
+func readPasswordLine(reader io.Reader) ([]byte, error) {
+ var buf [1]byte
+ var ret []byte
+
+ for {
+ n, err := reader.Read(buf[:])
+ if n > 0 {
+ switch buf[0] {
+ case '\b':
+ if len(ret) > 0 {
+ ret = ret[:len(ret)-1]
+ }
+ case '\n':
+ if runtime.GOOS != "windows" {
+ return ret, nil
+ }
+ // otherwise ignore \n
+ case '\r':
+ if runtime.GOOS == "windows" {
+ return ret, nil
+ }
+ // otherwise ignore \r
+ default:
+ ret = append(ret, buf[0])
+ }
+ continue
+ }
+ if err != nil {
+ if err == io.EOF && len(ret) > 0 {
+ return ret, nil
+ }
+ return ret, err
+ }
+ }
+}
diff --git a/vendor/github.com/charmbracelet/x/windows/LICENSE b/vendor/github.com/charmbracelet/x/windows/LICENSE
new file mode 100644
index 00000000..65a5654e
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/windows/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2023 Charmbracelet, Inc.
+
+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.
diff --git a/vendor/github.com/charmbracelet/x/windows/doc.go b/vendor/github.com/charmbracelet/x/windows/doc.go
new file mode 100644
index 00000000..15fc9ee9
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/windows/doc.go
@@ -0,0 +1,3 @@
+package windows
+
+//go generate go run golang.org/x/sys/windows/mkwinsyscall -output zsyscall_windows.go syscall_windows.go
diff --git a/vendor/github.com/charmbracelet/x/windows/syscall_windows.go b/vendor/github.com/charmbracelet/x/windows/syscall_windows.go
new file mode 100644
index 00000000..dd49431f
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/windows/syscall_windows.go
@@ -0,0 +1,10 @@
+package windows
+
+import "golang.org/x/sys/windows"
+
+var NewLazySystemDLL = windows.NewLazySystemDLL
+
+type Handle = windows.Handle
+
+//sys GetKeyboardLayout(threadId uint32) (hkl Handle, err error) = user32.GetKeyboardLayout
+//sys ToUnicodeEx(vkey uint32, scancode uint32, keystate *byte, pwszBuff *uint16, cchBuff int32, flags uint32, hkl Handle) (ret int32, err error) = user32.ToUnicodeEx
diff --git a/vendor/github.com/charmbracelet/x/windows/zsyscall_windows.go b/vendor/github.com/charmbracelet/x/windows/zsyscall_windows.go
new file mode 100644
index 00000000..97096a42
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/windows/zsyscall_windows.go
@@ -0,0 +1,61 @@
+// Code generated by 'go generate'; DO NOT EDIT.
+
+package windows
+
+import (
+ "syscall"
+ "unsafe"
+)
+
+var _ unsafe.Pointer
+
+// Do the interface allocations only once for common
+// Errno values.
+const (
+ errnoERROR_IO_PENDING = 997
+)
+
+var (
+ errERROR_IO_PENDING error = syscall.Errno(errnoERROR_IO_PENDING)
+ errERROR_EINVAL error = syscall.EINVAL
+)
+
+// errnoErr returns common boxed Errno values, to prevent
+// allocations at runtime.
+func errnoErr(e syscall.Errno) error {
+ switch e {
+ case 0:
+ return errERROR_EINVAL
+ case errnoERROR_IO_PENDING:
+ return errERROR_IO_PENDING
+ }
+ // TODO: add more here, after collecting data on the common
+ // error values see on Windows. (perhaps when running
+ // all.bat?)
+ return e
+}
+
+var (
+ moduser32 = NewLazySystemDLL("user32.dll")
+
+ procGetKeyboardLayout = moduser32.NewProc("GetKeyboardLayout")
+ procToUnicodeEx = moduser32.NewProc("ToUnicodeEx")
+)
+
+func GetKeyboardLayout(threadId uint32) (hkl Handle, err error) {
+ r0, _, e1 := syscall.Syscall(procGetKeyboardLayout.Addr(), 1, uintptr(threadId), 0, 0)
+ hkl = Handle(r0)
+ if hkl == 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func ToUnicodeEx(vkey uint32, scancode uint32, keystate *byte, pwszBuff *uint16, cchBuff int32, flags uint32, hkl Handle) (ret int32, err error) {
+ r0, _, e1 := syscall.Syscall9(procToUnicodeEx.Addr(), 7, uintptr(vkey), uintptr(scancode), uintptr(unsafe.Pointer(keystate)), uintptr(unsafe.Pointer(pwszBuff)), uintptr(cchBuff), uintptr(flags), uintptr(hkl), 0, 0)
+ ret = int32(r0)
+ if ret == 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
diff --git a/vendor/github.com/containerd/console/.golangci.yml b/vendor/github.com/containerd/console/.golangci.yml
deleted file mode 100644
index abe3d84b..00000000
--- a/vendor/github.com/containerd/console/.golangci.yml
+++ /dev/null
@@ -1,20 +0,0 @@
-linters:
- enable:
- - gofmt
- - goimports
- - ineffassign
- - misspell
- - revive
- - staticcheck
- - structcheck
- - unconvert
- - unused
- - varcheck
- - vet
- disable:
- - errcheck
-
-run:
- timeout: 3m
- skip-dirs:
- - vendor
diff --git a/vendor/github.com/containerd/console/LICENSE b/vendor/github.com/containerd/console/LICENSE
deleted file mode 100644
index 584149b6..00000000
--- a/vendor/github.com/containerd/console/LICENSE
+++ /dev/null
@@ -1,191 +0,0 @@
-
- Apache License
- Version 2.0, January 2004
- https://www.apache.org/licenses/
-
- TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
- 1. Definitions.
-
- "License" shall mean the terms and conditions for use, reproduction,
- and distribution as defined by Sections 1 through 9 of this document.
-
- "Licensor" shall mean the copyright owner or entity authorized by
- the copyright owner that is granting the License.
-
- "Legal Entity" shall mean the union of the acting entity and all
- other entities that control, are controlled by, or are under common
- control with that entity. For the purposes of this definition,
- "control" means (i) the power, direct or indirect, to cause the
- direction or management of such entity, whether by contract or
- otherwise, or (ii) ownership of fifty percent (50%) or more of the
- outstanding shares, or (iii) beneficial ownership of such entity.
-
- "You" (or "Your") shall mean an individual or Legal Entity
- exercising permissions granted by this License.
-
- "Source" form shall mean the preferred form for making modifications,
- including but not limited to software source code, documentation
- source, and configuration files.
-
- "Object" form shall mean any form resulting from mechanical
- transformation or translation of a Source form, including but
- not limited to compiled object code, generated documentation,
- and conversions to other media types.
-
- "Work" shall mean the work of authorship, whether in Source or
- Object form, made available under the License, as indicated by a
- copyright notice that is included in or attached to the work
- (an example is provided in the Appendix below).
-
- "Derivative Works" shall mean any work, whether in Source or Object
- form, that is based on (or derived from) the Work and for which the
- editorial revisions, annotations, elaborations, or other modifications
- represent, as a whole, an original work of authorship. For the purposes
- of this License, Derivative Works shall not include works that remain
- separable from, or merely link (or bind by name) to the interfaces of,
- the Work and Derivative Works thereof.
-
- "Contribution" shall mean any work of authorship, including
- the original version of the Work and any modifications or additions
- to that Work or Derivative Works thereof, that is intentionally
- submitted to Licensor for inclusion in the Work by the copyright owner
- or by an individual or Legal Entity authorized to submit on behalf of
- the copyright owner. For the purposes of this definition, "submitted"
- means any form of electronic, verbal, or written communication sent
- to the Licensor or its representatives, including but not limited to
- communication on electronic mailing lists, source code control systems,
- and issue tracking systems that are managed by, or on behalf of, the
- Licensor for the purpose of discussing and improving the Work, but
- excluding communication that is conspicuously marked or otherwise
- designated in writing by the copyright owner as "Not a Contribution."
-
- "Contributor" shall mean Licensor and any individual or Legal Entity
- on behalf of whom a Contribution has been received by Licensor and
- subsequently incorporated within the Work.
-
- 2. Grant of Copyright License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- copyright license to reproduce, prepare Derivative Works of,
- publicly display, publicly perform, sublicense, and distribute the
- Work and such Derivative Works in Source or Object form.
-
- 3. Grant of Patent License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- (except as stated in this section) patent license to make, have made,
- use, offer to sell, sell, import, and otherwise transfer the Work,
- where such license applies only to those patent claims licensable
- by such Contributor that are necessarily infringed by their
- Contribution(s) alone or by combination of their Contribution(s)
- with the Work to which such Contribution(s) was submitted. If You
- institute patent litigation against any entity (including a
- cross-claim or counterclaim in a lawsuit) alleging that the Work
- or a Contribution incorporated within the Work constitutes direct
- or contributory patent infringement, then any patent licenses
- granted to You under this License for that Work shall terminate
- as of the date such litigation is filed.
-
- 4. Redistribution. You may reproduce and distribute copies of the
- Work or Derivative Works thereof in any medium, with or without
- modifications, and in Source or Object form, provided that You
- meet the following conditions:
-
- (a) You must give any other recipients of the Work or
- Derivative Works a copy of this License; and
-
- (b) You must cause any modified files to carry prominent notices
- stating that You changed the files; and
-
- (c) You must retain, in the Source form of any Derivative Works
- that You distribute, all copyright, patent, trademark, and
- attribution notices from the Source form of the Work,
- excluding those notices that do not pertain to any part of
- the Derivative Works; and
-
- (d) If the Work includes a "NOTICE" text file as part of its
- distribution, then any Derivative Works that You distribute must
- include a readable copy of the attribution notices contained
- within such NOTICE file, excluding those notices that do not
- pertain to any part of the Derivative Works, in at least one
- of the following places: within a NOTICE text file distributed
- as part of the Derivative Works; within the Source form or
- documentation, if provided along with the Derivative Works; or,
- within a display generated by the Derivative Works, if and
- wherever such third-party notices normally appear. The contents
- of the NOTICE file are for informational purposes only and
- do not modify the License. You may add Your own attribution
- notices within Derivative Works that You distribute, alongside
- or as an addendum to the NOTICE text from the Work, provided
- that such additional attribution notices cannot be construed
- as modifying the License.
-
- You may add Your own copyright statement to Your modifications and
- may provide additional or different license terms and conditions
- for use, reproduction, or distribution of Your modifications, or
- for any such Derivative Works as a whole, provided Your use,
- reproduction, and distribution of the Work otherwise complies with
- the conditions stated in this License.
-
- 5. Submission of Contributions. Unless You explicitly state otherwise,
- any Contribution intentionally submitted for inclusion in the Work
- by You to the Licensor shall be under the terms and conditions of
- this License, without any additional terms or conditions.
- Notwithstanding the above, nothing herein shall supersede or modify
- the terms of any separate license agreement you may have executed
- with Licensor regarding such Contributions.
-
- 6. Trademarks. This License does not grant permission to use the trade
- names, trademarks, service marks, or product names of the Licensor,
- except as required for reasonable and customary use in describing the
- origin of the Work and reproducing the content of the NOTICE file.
-
- 7. Disclaimer of Warranty. Unless required by applicable law or
- agreed to in writing, Licensor provides the Work (and each
- Contributor provides its Contributions) on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
- implied, including, without limitation, any warranties or conditions
- of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
- PARTICULAR PURPOSE. You are solely responsible for determining the
- appropriateness of using or redistributing the Work and assume any
- risks associated with Your exercise of permissions under this License.
-
- 8. Limitation of Liability. In no event and under no legal theory,
- whether in tort (including negligence), contract, or otherwise,
- unless required by applicable law (such as deliberate and grossly
- negligent acts) or agreed to in writing, shall any Contributor be
- liable to You for damages, including any direct, indirect, special,
- incidental, or consequential damages of any character arising as a
- result of this License or out of the use or inability to use the
- Work (including but not limited to damages for loss of goodwill,
- work stoppage, computer failure or malfunction, or any and all
- other commercial damages or losses), even if such Contributor
- has been advised of the possibility of such damages.
-
- 9. Accepting Warranty or Additional Liability. While redistributing
- the Work or Derivative Works thereof, You may choose to offer,
- and charge a fee for, acceptance of support, warranty, indemnity,
- or other liability obligations and/or rights consistent with this
- License. However, in accepting such obligations, You may act only
- on Your own behalf and on Your sole responsibility, not on behalf
- of any other Contributor, and only if You agree to indemnify,
- defend, and hold each Contributor harmless for any liability
- incurred by, or claims asserted against, such Contributor by reason
- of your accepting any such warranty or additional liability.
-
- END OF TERMS AND CONDITIONS
-
- Copyright The containerd Authors
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- https://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
diff --git a/vendor/github.com/containerd/console/README.md b/vendor/github.com/containerd/console/README.md
deleted file mode 100644
index 580b461a..00000000
--- a/vendor/github.com/containerd/console/README.md
+++ /dev/null
@@ -1,29 +0,0 @@
-# console
-
-[![PkgGoDev](https://pkg.go.dev/badge/github.com/containerd/console)](https://pkg.go.dev/github.com/containerd/console)
-[![Build Status](https://github.com/containerd/console/workflows/CI/badge.svg)](https://github.com/containerd/console/actions?query=workflow%3ACI)
-[![Go Report Card](https://goreportcard.com/badge/github.com/containerd/console)](https://goreportcard.com/report/github.com/containerd/console)
-
-Golang package for dealing with consoles. Light on deps and a simple API.
-
-## Modifying the current process
-
-```go
-current := console.Current()
-defer current.Reset()
-
-if err := current.SetRaw(); err != nil {
-}
-ws, err := current.Size()
-current.Resize(ws)
-```
-
-## Project details
-
-console is a containerd sub-project, licensed under the [Apache 2.0 license](./LICENSE).
-As a containerd sub-project, you will find the:
- * [Project governance](https://github.com/containerd/project/blob/master/GOVERNANCE.md),
- * [Maintainers](https://github.com/containerd/project/blob/master/MAINTAINERS),
- * and [Contributing guidelines](https://github.com/containerd/project/blob/master/CONTRIBUTING.md)
-
-information in our [`containerd/project`](https://github.com/containerd/project) repository.
diff --git a/vendor/github.com/containerd/console/console.go b/vendor/github.com/containerd/console/console.go
deleted file mode 100644
index 810a71f4..00000000
--- a/vendor/github.com/containerd/console/console.go
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- Copyright The containerd Authors.
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-*/
-
-package console
-
-import (
- "errors"
- "io"
- "os"
-)
-
-var ErrNotAConsole = errors.New("provided file is not a console")
-
-type File interface {
- io.ReadWriteCloser
-
- // Fd returns its file descriptor
- Fd() uintptr
- // Name returns its file name
- Name() string
-}
-
-type Console interface {
- File
-
- // Resize resizes the console to the provided window size
- Resize(WinSize) error
- // ResizeFrom resizes the calling console to the size of the
- // provided console
- ResizeFrom(Console) error
- // SetRaw sets the console in raw mode
- SetRaw() error
- // DisableEcho disables echo on the console
- DisableEcho() error
- // Reset restores the console to its orignal state
- Reset() error
- // Size returns the window size of the console
- Size() (WinSize, error)
-}
-
-// WinSize specifies the window size of the console
-type WinSize struct {
- // Height of the console
- Height uint16
- // Width of the console
- Width uint16
- x uint16
- y uint16
-}
-
-// Current returns the current process' console
-func Current() (c Console) {
- var err error
- // Usually all three streams (stdin, stdout, and stderr)
- // are open to the same console, but some might be redirected,
- // so try all three.
- for _, s := range []*os.File{os.Stderr, os.Stdout, os.Stdin} {
- if c, err = ConsoleFromFile(s); err == nil {
- return c
- }
- }
- // One of the std streams should always be a console
- // for the design of this function.
- panic(err)
-}
-
-// ConsoleFromFile returns a console using the provided file
-// nolint:revive
-func ConsoleFromFile(f File) (Console, error) {
- if err := checkConsole(f); err != nil {
- return nil, err
- }
- return newMaster(f)
-}
diff --git a/vendor/github.com/containerd/console/console_linux.go b/vendor/github.com/containerd/console/console_linux.go
deleted file mode 100644
index 28b77b7a..00000000
--- a/vendor/github.com/containerd/console/console_linux.go
+++ /dev/null
@@ -1,281 +0,0 @@
-//go:build linux
-// +build linux
-
-/*
- Copyright The containerd Authors.
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-*/
-
-package console
-
-import (
- "io"
- "os"
- "sync"
-
- "golang.org/x/sys/unix"
-)
-
-const (
- maxEvents = 128
-)
-
-// Epoller manages multiple epoll consoles using edge-triggered epoll api so we
-// dont have to deal with repeated wake-up of EPOLLER or EPOLLHUP.
-// For more details, see:
-// - https://github.com/systemd/systemd/pull/4262
-// - https://github.com/moby/moby/issues/27202
-//
-// Example usage of Epoller and EpollConsole can be as follow:
-//
-// epoller, _ := NewEpoller()
-// epollConsole, _ := epoller.Add(console)
-// go epoller.Wait()
-// var (
-// b bytes.Buffer
-// wg sync.WaitGroup
-// )
-// wg.Add(1)
-// go func() {
-// io.Copy(&b, epollConsole)
-// wg.Done()
-// }()
-// // perform I/O on the console
-// epollConsole.Shutdown(epoller.CloseConsole)
-// wg.Wait()
-// epollConsole.Close()
-type Epoller struct {
- efd int
- mu sync.Mutex
- fdMapping map[int]*EpollConsole
- closeOnce sync.Once
-}
-
-// NewEpoller returns an instance of epoller with a valid epoll fd.
-func NewEpoller() (*Epoller, error) {
- efd, err := unix.EpollCreate1(unix.EPOLL_CLOEXEC)
- if err != nil {
- return nil, err
- }
- return &Epoller{
- efd: efd,
- fdMapping: make(map[int]*EpollConsole),
- }, nil
-}
-
-// Add creates an epoll console based on the provided console. The console will
-// be registered with EPOLLET (i.e. using edge-triggered notification) and its
-// file descriptor will be set to non-blocking mode. After this, user should use
-// the return console to perform I/O.
-func (e *Epoller) Add(console Console) (*EpollConsole, error) {
- sysfd := int(console.Fd())
- // Set sysfd to non-blocking mode
- if err := unix.SetNonblock(sysfd, true); err != nil {
- return nil, err
- }
-
- ev := unix.EpollEvent{
- Events: unix.EPOLLIN | unix.EPOLLOUT | unix.EPOLLRDHUP | unix.EPOLLET,
- Fd: int32(sysfd),
- }
- if err := unix.EpollCtl(e.efd, unix.EPOLL_CTL_ADD, sysfd, &ev); err != nil {
- return nil, err
- }
- ef := &EpollConsole{
- Console: console,
- sysfd: sysfd,
- readc: sync.NewCond(&sync.Mutex{}),
- writec: sync.NewCond(&sync.Mutex{}),
- }
- e.mu.Lock()
- e.fdMapping[sysfd] = ef
- e.mu.Unlock()
- return ef, nil
-}
-
-// Wait starts the loop to wait for its consoles' notifications and signal
-// appropriate console that it can perform I/O.
-func (e *Epoller) Wait() error {
- events := make([]unix.EpollEvent, maxEvents)
- for {
- n, err := unix.EpollWait(e.efd, events, -1)
- if err != nil {
- // EINTR: The call was interrupted by a signal handler before either
- // any of the requested events occurred or the timeout expired
- if err == unix.EINTR {
- continue
- }
- return err
- }
- for i := 0; i < n; i++ {
- ev := &events[i]
- // the console is ready to be read from
- if ev.Events&(unix.EPOLLIN|unix.EPOLLHUP|unix.EPOLLERR) != 0 {
- if epfile := e.getConsole(int(ev.Fd)); epfile != nil {
- epfile.signalRead()
- }
- }
- // the console is ready to be written to
- if ev.Events&(unix.EPOLLOUT|unix.EPOLLHUP|unix.EPOLLERR) != 0 {
- if epfile := e.getConsole(int(ev.Fd)); epfile != nil {
- epfile.signalWrite()
- }
- }
- }
- }
-}
-
-// CloseConsole unregisters the console's file descriptor from epoll interface
-func (e *Epoller) CloseConsole(fd int) error {
- e.mu.Lock()
- defer e.mu.Unlock()
- delete(e.fdMapping, fd)
- return unix.EpollCtl(e.efd, unix.EPOLL_CTL_DEL, fd, &unix.EpollEvent{})
-}
-
-func (e *Epoller) getConsole(sysfd int) *EpollConsole {
- e.mu.Lock()
- f := e.fdMapping[sysfd]
- e.mu.Unlock()
- return f
-}
-
-// Close closes the epoll fd
-func (e *Epoller) Close() error {
- closeErr := os.ErrClosed // default to "file already closed"
- e.closeOnce.Do(func() {
- closeErr = unix.Close(e.efd)
- })
- return closeErr
-}
-
-// EpollConsole acts like a console but registers its file descriptor with an
-// epoll fd and uses epoll API to perform I/O.
-type EpollConsole struct {
- Console
- readc *sync.Cond
- writec *sync.Cond
- sysfd int
- closed bool
-}
-
-// Read reads up to len(p) bytes into p. It returns the number of bytes read
-// (0 <= n <= len(p)) and any error encountered.
-//
-// If the console's read returns EAGAIN or EIO, we assume that it's a
-// temporary error because the other side went away and wait for the signal
-// generated by epoll event to continue.
-func (ec *EpollConsole) Read(p []byte) (n int, err error) {
- var read int
- ec.readc.L.Lock()
- defer ec.readc.L.Unlock()
- for {
- read, err = ec.Console.Read(p[n:])
- n += read
- if err != nil {
- var hangup bool
- if perr, ok := err.(*os.PathError); ok {
- hangup = (perr.Err == unix.EAGAIN || perr.Err == unix.EIO)
- } else {
- hangup = (err == unix.EAGAIN || err == unix.EIO)
- }
- // if the other end disappear, assume this is temporary and wait for the
- // signal to continue again. Unless we didnt read anything and the
- // console is already marked as closed then we should exit
- if hangup && !(n == 0 && len(p) > 0 && ec.closed) {
- ec.readc.Wait()
- continue
- }
- }
- break
- }
- // if we didnt read anything then return io.EOF to end gracefully
- if n == 0 && len(p) > 0 && err == nil {
- err = io.EOF
- }
- // signal for others that we finished the read
- ec.readc.Signal()
- return n, err
-}
-
-// Writes len(p) bytes from p to the console. It returns the number of bytes
-// written from p (0 <= n <= len(p)) and any error encountered that caused
-// the write to stop early.
-//
-// If writes to the console returns EAGAIN or EIO, we assume that it's a
-// temporary error because the other side went away and wait for the signal
-// generated by epoll event to continue.
-func (ec *EpollConsole) Write(p []byte) (n int, err error) {
- var written int
- ec.writec.L.Lock()
- defer ec.writec.L.Unlock()
- for {
- written, err = ec.Console.Write(p[n:])
- n += written
- if err != nil {
- var hangup bool
- if perr, ok := err.(*os.PathError); ok {
- hangup = (perr.Err == unix.EAGAIN || perr.Err == unix.EIO)
- } else {
- hangup = (err == unix.EAGAIN || err == unix.EIO)
- }
- // if the other end disappears, assume this is temporary and wait for the
- // signal to continue again.
- if hangup {
- ec.writec.Wait()
- continue
- }
- }
- // unrecoverable error, break the loop and return the error
- break
- }
- if n < len(p) && err == nil {
- err = io.ErrShortWrite
- }
- // signal for others that we finished the write
- ec.writec.Signal()
- return n, err
-}
-
-// Shutdown closes the file descriptor and signals call waiters for this fd.
-// It accepts a callback which will be called with the console's fd. The
-// callback typically will be used to do further cleanup such as unregister the
-// console's fd from the epoll interface.
-// User should call Shutdown and wait for all I/O operation to be finished
-// before closing the console.
-func (ec *EpollConsole) Shutdown(close func(int) error) error {
- ec.readc.L.Lock()
- defer ec.readc.L.Unlock()
- ec.writec.L.Lock()
- defer ec.writec.L.Unlock()
-
- ec.readc.Broadcast()
- ec.writec.Broadcast()
- ec.closed = true
- return close(ec.sysfd)
-}
-
-// signalRead signals that the console is readable.
-func (ec *EpollConsole) signalRead() {
- ec.readc.L.Lock()
- ec.readc.Signal()
- ec.readc.L.Unlock()
-}
-
-// signalWrite signals that the console is writable.
-func (ec *EpollConsole) signalWrite() {
- ec.writec.L.Lock()
- ec.writec.Signal()
- ec.writec.L.Unlock()
-}
diff --git a/vendor/github.com/containerd/console/console_unix.go b/vendor/github.com/containerd/console/console_unix.go
deleted file mode 100644
index 161f5d12..00000000
--- a/vendor/github.com/containerd/console/console_unix.go
+++ /dev/null
@@ -1,157 +0,0 @@
-//go:build darwin || freebsd || linux || netbsd || openbsd || zos
-// +build darwin freebsd linux netbsd openbsd zos
-
-/*
- Copyright The containerd Authors.
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-*/
-
-package console
-
-import (
- "golang.org/x/sys/unix"
-)
-
-// NewPty creates a new pty pair
-// The master is returned as the first console and a string
-// with the path to the pty slave is returned as the second
-func NewPty() (Console, string, error) {
- f, err := openpt()
- if err != nil {
- return nil, "", err
- }
- slave, err := ptsname(f)
- if err != nil {
- return nil, "", err
- }
- if err := unlockpt(f); err != nil {
- return nil, "", err
- }
- m, err := newMaster(f)
- if err != nil {
- return nil, "", err
- }
- return m, slave, nil
-}
-
-type master struct {
- f File
- original *unix.Termios
-}
-
-func (m *master) Read(b []byte) (int, error) {
- return m.f.Read(b)
-}
-
-func (m *master) Write(b []byte) (int, error) {
- return m.f.Write(b)
-}
-
-func (m *master) Close() error {
- return m.f.Close()
-}
-
-func (m *master) Resize(ws WinSize) error {
- return tcswinsz(m.f.Fd(), ws)
-}
-
-func (m *master) ResizeFrom(c Console) error {
- ws, err := c.Size()
- if err != nil {
- return err
- }
- return m.Resize(ws)
-}
-
-func (m *master) Reset() error {
- if m.original == nil {
- return nil
- }
- return tcset(m.f.Fd(), m.original)
-}
-
-func (m *master) getCurrent() (unix.Termios, error) {
- var termios unix.Termios
- if err := tcget(m.f.Fd(), &termios); err != nil {
- return unix.Termios{}, err
- }
- return termios, nil
-}
-
-func (m *master) SetRaw() error {
- rawState, err := m.getCurrent()
- if err != nil {
- return err
- }
- rawState = cfmakeraw(rawState)
- rawState.Oflag = rawState.Oflag | unix.OPOST
- return tcset(m.f.Fd(), &rawState)
-}
-
-func (m *master) DisableEcho() error {
- rawState, err := m.getCurrent()
- if err != nil {
- return err
- }
- rawState.Lflag = rawState.Lflag &^ unix.ECHO
- return tcset(m.f.Fd(), &rawState)
-}
-
-func (m *master) Size() (WinSize, error) {
- return tcgwinsz(m.f.Fd())
-}
-
-func (m *master) Fd() uintptr {
- return m.f.Fd()
-}
-
-func (m *master) Name() string {
- return m.f.Name()
-}
-
-// checkConsole checks if the provided file is a console
-func checkConsole(f File) error {
- var termios unix.Termios
- if tcget(f.Fd(), &termios) != nil {
- return ErrNotAConsole
- }
- return nil
-}
-
-func newMaster(f File) (Console, error) {
- m := &master{
- f: f,
- }
- t, err := m.getCurrent()
- if err != nil {
- return nil, err
- }
- m.original = &t
- return m, nil
-}
-
-// ClearONLCR sets the necessary tty_ioctl(4)s to ensure that a pty pair
-// created by us acts normally. In particular, a not-very-well-known default of
-// Linux unix98 ptys is that they have +onlcr by default. While this isn't a
-// problem for terminal emulators, because we relay data from the terminal we
-// also relay that funky line discipline.
-func ClearONLCR(fd uintptr) error {
- return setONLCR(fd, false)
-}
-
-// SetONLCR sets the necessary tty_ioctl(4)s to ensure that a pty pair
-// created by us acts as intended for a terminal emulator.
-func SetONLCR(fd uintptr) error {
- return setONLCR(fd, true)
-}
diff --git a/vendor/github.com/containerd/console/console_windows.go b/vendor/github.com/containerd/console/console_windows.go
deleted file mode 100644
index f48e4861..00000000
--- a/vendor/github.com/containerd/console/console_windows.go
+++ /dev/null
@@ -1,222 +0,0 @@
-/*
- Copyright The containerd Authors.
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-*/
-
-package console
-
-import (
- "errors"
- "fmt"
- "os"
-
- "golang.org/x/sys/windows"
-)
-
-var (
- vtInputSupported bool
- ErrNotImplemented = errors.New("not implemented")
-)
-
-func (m *master) initStdios() {
- // Note: We discard console mode warnings, because in/out can be redirected.
- //
- // TODO: Investigate opening CONOUT$/CONIN$ to handle this correctly
-
- m.in = windows.Handle(os.Stdin.Fd())
- if err := windows.GetConsoleMode(m.in, &m.inMode); err == nil {
- // Validate that windows.ENABLE_VIRTUAL_TERMINAL_INPUT is supported, but do not set it.
- if err = windows.SetConsoleMode(m.in, m.inMode|windows.ENABLE_VIRTUAL_TERMINAL_INPUT); err == nil {
- vtInputSupported = true
- }
- // Unconditionally set the console mode back even on failure because SetConsoleMode
- // remembers invalid bits on input handles.
- windows.SetConsoleMode(m.in, m.inMode)
- }
-
- m.out = windows.Handle(os.Stdout.Fd())
- if err := windows.GetConsoleMode(m.out, &m.outMode); err == nil {
- if err := windows.SetConsoleMode(m.out, m.outMode|windows.ENABLE_VIRTUAL_TERMINAL_PROCESSING); err == nil {
- m.outMode |= windows.ENABLE_VIRTUAL_TERMINAL_PROCESSING
- } else {
- windows.SetConsoleMode(m.out, m.outMode)
- }
- }
-
- m.err = windows.Handle(os.Stderr.Fd())
- if err := windows.GetConsoleMode(m.err, &m.errMode); err == nil {
- if err := windows.SetConsoleMode(m.err, m.errMode|windows.ENABLE_VIRTUAL_TERMINAL_PROCESSING); err == nil {
- m.errMode |= windows.ENABLE_VIRTUAL_TERMINAL_PROCESSING
- } else {
- windows.SetConsoleMode(m.err, m.errMode)
- }
- }
-}
-
-type master struct {
- in windows.Handle
- inMode uint32
-
- out windows.Handle
- outMode uint32
-
- err windows.Handle
- errMode uint32
-}
-
-func (m *master) SetRaw() error {
- if err := makeInputRaw(m.in, m.inMode); err != nil {
- return err
- }
-
- // Set StdOut and StdErr to raw mode, we ignore failures since
- // windows.DISABLE_NEWLINE_AUTO_RETURN might not be supported on this version of
- // Windows.
-
- windows.SetConsoleMode(m.out, m.outMode|windows.DISABLE_NEWLINE_AUTO_RETURN)
-
- windows.SetConsoleMode(m.err, m.errMode|windows.DISABLE_NEWLINE_AUTO_RETURN)
-
- return nil
-}
-
-func (m *master) Reset() error {
- var errs []error
-
- for _, s := range []struct {
- fd windows.Handle
- mode uint32
- }{
- {m.in, m.inMode},
- {m.out, m.outMode},
- {m.err, m.errMode},
- } {
- if err := windows.SetConsoleMode(s.fd, s.mode); err != nil {
- // we can't just abort on the first error, otherwise we might leave
- // the console in an unexpected state.
- errs = append(errs, fmt.Errorf("unable to restore console mode: %w", err))
- }
- }
-
- if len(errs) > 0 {
- return errs[0]
- }
-
- return nil
-}
-
-func (m *master) Size() (WinSize, error) {
- var info windows.ConsoleScreenBufferInfo
- err := windows.GetConsoleScreenBufferInfo(m.out, &info)
- if err != nil {
- return WinSize{}, fmt.Errorf("unable to get console info: %w", err)
- }
-
- winsize := WinSize{
- Width: uint16(info.Window.Right - info.Window.Left + 1),
- Height: uint16(info.Window.Bottom - info.Window.Top + 1),
- }
-
- return winsize, nil
-}
-
-func (m *master) Resize(ws WinSize) error {
- return ErrNotImplemented
-}
-
-func (m *master) ResizeFrom(c Console) error {
- return ErrNotImplemented
-}
-
-func (m *master) DisableEcho() error {
- mode := m.inMode &^ windows.ENABLE_ECHO_INPUT
- mode |= windows.ENABLE_PROCESSED_INPUT
- mode |= windows.ENABLE_LINE_INPUT
-
- if err := windows.SetConsoleMode(m.in, mode); err != nil {
- return fmt.Errorf("unable to set console to disable echo: %w", err)
- }
-
- return nil
-}
-
-func (m *master) Close() error {
- return nil
-}
-
-func (m *master) Read(b []byte) (int, error) {
- return os.Stdin.Read(b)
-}
-
-func (m *master) Write(b []byte) (int, error) {
- return os.Stdout.Write(b)
-}
-
-func (m *master) Fd() uintptr {
- return uintptr(m.in)
-}
-
-// on windows, console can only be made from os.Std{in,out,err}, hence there
-// isnt a single name here we can use. Return a dummy "console" value in this
-// case should be sufficient.
-func (m *master) Name() string {
- return "console"
-}
-
-// makeInputRaw puts the terminal (Windows Console) connected to the given
-// file descriptor into raw mode
-func makeInputRaw(fd windows.Handle, mode uint32) error {
- // See
- // -- https://msdn.microsoft.com/en-us/library/windows/desktop/ms686033(v=vs.85).aspx
- // -- https://msdn.microsoft.com/en-us/library/windows/desktop/ms683462(v=vs.85).aspx
-
- // Disable these modes
- mode &^= windows.ENABLE_ECHO_INPUT
- mode &^= windows.ENABLE_LINE_INPUT
- mode &^= windows.ENABLE_MOUSE_INPUT
- mode &^= windows.ENABLE_WINDOW_INPUT
- mode &^= windows.ENABLE_PROCESSED_INPUT
-
- // Enable these modes
- mode |= windows.ENABLE_EXTENDED_FLAGS
- mode |= windows.ENABLE_INSERT_MODE
- mode |= windows.ENABLE_QUICK_EDIT_MODE
-
- if vtInputSupported {
- mode |= windows.ENABLE_VIRTUAL_TERMINAL_INPUT
- }
-
- if err := windows.SetConsoleMode(fd, mode); err != nil {
- return fmt.Errorf("unable to set console to raw mode: %w", err)
- }
-
- return nil
-}
-
-func checkConsole(f File) error {
- var mode uint32
- if err := windows.GetConsoleMode(windows.Handle(f.Fd()), &mode); err != nil {
- return err
- }
- return nil
-}
-
-func newMaster(f File) (Console, error) {
- if f != os.Stdin && f != os.Stdout && f != os.Stderr {
- return nil, errors.New("creating a console from a file is not supported on windows")
- }
- m := &master{}
- m.initStdios()
- return m, nil
-}
diff --git a/vendor/github.com/containerd/console/pty_freebsd_cgo.go b/vendor/github.com/containerd/console/pty_freebsd_cgo.go
deleted file mode 100644
index 22368623..00000000
--- a/vendor/github.com/containerd/console/pty_freebsd_cgo.go
+++ /dev/null
@@ -1,46 +0,0 @@
-//go:build freebsd && cgo
-// +build freebsd,cgo
-
-/*
- Copyright The containerd Authors.
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-*/
-
-package console
-
-import (
- "fmt"
- "os"
-)
-
-/*
-#include
-#include
-#include
-*/
-import "C"
-
-// openpt allocates a new pseudo-terminal and establishes a connection with its
-// control device.
-func openpt() (*os.File, error) {
- fd, err := C.posix_openpt(C.O_RDWR)
- if err != nil {
- return nil, fmt.Errorf("posix_openpt: %w", err)
- }
- if _, err := C.grantpt(fd); err != nil {
- C.close(fd)
- return nil, fmt.Errorf("grantpt: %w", err)
- }
- return os.NewFile(uintptr(fd), ""), nil
-}
diff --git a/vendor/github.com/containerd/console/pty_freebsd_nocgo.go b/vendor/github.com/containerd/console/pty_freebsd_nocgo.go
deleted file mode 100644
index ceb90a47..00000000
--- a/vendor/github.com/containerd/console/pty_freebsd_nocgo.go
+++ /dev/null
@@ -1,37 +0,0 @@
-//go:build freebsd && !cgo
-// +build freebsd,!cgo
-
-/*
- Copyright The containerd Authors.
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-*/
-
-package console
-
-import (
- "os"
-)
-
-//
-// Implementing the functions below requires cgo support. Non-cgo stubs
-// versions are defined below to enable cross-compilation of source code
-// that depends on these functions, but the resultant cross-compiled
-// binaries cannot actually be used. If the stub function(s) below are
-// actually invoked they will display an error message and cause the
-// calling process to exit.
-//
-
-func openpt() (*os.File, error) {
- panic("openpt() support requires cgo.")
-}
diff --git a/vendor/github.com/containerd/console/pty_unix.go b/vendor/github.com/containerd/console/pty_unix.go
deleted file mode 100644
index f5a5b805..00000000
--- a/vendor/github.com/containerd/console/pty_unix.go
+++ /dev/null
@@ -1,31 +0,0 @@
-//go:build darwin || linux || netbsd || openbsd
-// +build darwin linux netbsd openbsd
-
-/*
- Copyright The containerd Authors.
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-*/
-
-package console
-
-import (
- "os"
-
- "golang.org/x/sys/unix"
-)
-
-// openpt allocates a new pseudo-terminal by opening the /dev/ptmx device
-func openpt() (*os.File, error) {
- return os.OpenFile("/dev/ptmx", unix.O_RDWR|unix.O_NOCTTY|unix.O_CLOEXEC, 0)
-}
diff --git a/vendor/github.com/containerd/console/pty_zos.go b/vendor/github.com/containerd/console/pty_zos.go
deleted file mode 100644
index 58f59aba..00000000
--- a/vendor/github.com/containerd/console/pty_zos.go
+++ /dev/null
@@ -1,43 +0,0 @@
-//go:build zos
-// +build zos
-
-/*
- Copyright The containerd Authors.
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-*/
-
-package console
-
-import (
- "fmt"
- "os"
-)
-
-// openpt allocates a new pseudo-terminal by opening the first available /dev/ptypXX device
-func openpt() (*os.File, error) {
- var f *os.File
- var err error
- for i := 0; ; i++ {
- ptyp := fmt.Sprintf("/dev/ptyp%04d", i)
- f, err = os.OpenFile(ptyp, os.O_RDWR, 0600)
- if err == nil {
- break
- }
- if os.IsNotExist(err) {
- return nil, err
- }
- // else probably Resource Busy
- }
- return f, nil
-}
diff --git a/vendor/github.com/containerd/console/tc_darwin.go b/vendor/github.com/containerd/console/tc_darwin.go
deleted file mode 100644
index 78715458..00000000
--- a/vendor/github.com/containerd/console/tc_darwin.go
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- Copyright The containerd Authors.
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-*/
-
-package console
-
-import (
- "fmt"
- "os"
-
- "golang.org/x/sys/unix"
-)
-
-const (
- cmdTcGet = unix.TIOCGETA
- cmdTcSet = unix.TIOCSETA
-)
-
-// unlockpt unlocks the slave pseudoterminal device corresponding to the master pseudoterminal referred to by f.
-// unlockpt should be called before opening the slave side of a pty.
-func unlockpt(f *os.File) error {
- return unix.IoctlSetPointerInt(int(f.Fd()), unix.TIOCPTYUNLK, 0)
-}
-
-// ptsname retrieves the name of the first available pts for the given master.
-func ptsname(f *os.File) (string, error) {
- n, err := unix.IoctlGetInt(int(f.Fd()), unix.TIOCPTYGNAME)
- if err != nil {
- return "", err
- }
- return fmt.Sprintf("/dev/pts/%d", n), nil
-}
diff --git a/vendor/github.com/containerd/console/tc_freebsd_cgo.go b/vendor/github.com/containerd/console/tc_freebsd_cgo.go
deleted file mode 100644
index 33282579..00000000
--- a/vendor/github.com/containerd/console/tc_freebsd_cgo.go
+++ /dev/null
@@ -1,58 +0,0 @@
-//go:build freebsd && cgo
-// +build freebsd,cgo
-
-/*
- Copyright The containerd Authors.
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-*/
-
-package console
-
-import (
- "fmt"
- "os"
-
- "golang.org/x/sys/unix"
-)
-
-/*
-#include
-#include
-*/
-import "C"
-
-const (
- cmdTcGet = unix.TIOCGETA
- cmdTcSet = unix.TIOCSETA
-)
-
-// unlockpt unlocks the slave pseudoterminal device corresponding to the master pseudoterminal referred to by f.
-// unlockpt should be called before opening the slave side of a pty.
-func unlockpt(f *os.File) error {
- fd := C.int(f.Fd())
- if _, err := C.unlockpt(fd); err != nil {
- C.close(fd)
- return fmt.Errorf("unlockpt: %w", err)
- }
- return nil
-}
-
-// ptsname retrieves the name of the first available pts for the given master.
-func ptsname(f *os.File) (string, error) {
- n, err := unix.IoctlGetInt(int(f.Fd()), unix.TIOCGPTN)
- if err != nil {
- return "", err
- }
- return fmt.Sprintf("/dev/pts/%d", n), nil
-}
diff --git a/vendor/github.com/containerd/console/tc_freebsd_nocgo.go b/vendor/github.com/containerd/console/tc_freebsd_nocgo.go
deleted file mode 100644
index 18a9b9cb..00000000
--- a/vendor/github.com/containerd/console/tc_freebsd_nocgo.go
+++ /dev/null
@@ -1,56 +0,0 @@
-//go:build freebsd && !cgo
-// +build freebsd,!cgo
-
-/*
- Copyright The containerd Authors.
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-*/
-
-package console
-
-import (
- "fmt"
- "os"
-
- "golang.org/x/sys/unix"
-)
-
-const (
- cmdTcGet = unix.TIOCGETA
- cmdTcSet = unix.TIOCSETA
-)
-
-//
-// Implementing the functions below requires cgo support. Non-cgo stubs
-// versions are defined below to enable cross-compilation of source code
-// that depends on these functions, but the resultant cross-compiled
-// binaries cannot actually be used. If the stub function(s) below are
-// actually invoked they will display an error message and cause the
-// calling process to exit.
-//
-
-// unlockpt unlocks the slave pseudoterminal device corresponding to the master pseudoterminal referred to by f.
-// unlockpt should be called before opening the slave side of a pty.
-func unlockpt(f *os.File) error {
- panic("unlockpt() support requires cgo.")
-}
-
-// ptsname retrieves the name of the first available pts for the given master.
-func ptsname(f *os.File) (string, error) {
- n, err := unix.IoctlGetInt(int(f.Fd()), unix.TIOCGPTN)
- if err != nil {
- return "", err
- }
- return fmt.Sprintf("/dev/pts/%d", n), nil
-}
diff --git a/vendor/github.com/containerd/console/tc_linux.go b/vendor/github.com/containerd/console/tc_linux.go
deleted file mode 100644
index 7d552ea4..00000000
--- a/vendor/github.com/containerd/console/tc_linux.go
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- Copyright The containerd Authors.
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-*/
-
-package console
-
-import (
- "fmt"
- "os"
- "unsafe"
-
- "golang.org/x/sys/unix"
-)
-
-const (
- cmdTcGet = unix.TCGETS
- cmdTcSet = unix.TCSETS
-)
-
-// unlockpt unlocks the slave pseudoterminal device corresponding to the master pseudoterminal referred to by f.
-// unlockpt should be called before opening the slave side of a pty.
-func unlockpt(f *os.File) error {
- var u int32
- // XXX do not use unix.IoctlSetPointerInt here, see commit dbd69c59b81.
- if _, _, err := unix.Syscall(unix.SYS_IOCTL, f.Fd(), unix.TIOCSPTLCK, uintptr(unsafe.Pointer(&u))); err != 0 {
- return err
- }
- return nil
-}
-
-// ptsname retrieves the name of the first available pts for the given master.
-func ptsname(f *os.File) (string, error) {
- var u uint32
- // XXX do not use unix.IoctlGetInt here, see commit dbd69c59b81.
- if _, _, err := unix.Syscall(unix.SYS_IOCTL, f.Fd(), unix.TIOCGPTN, uintptr(unsafe.Pointer(&u))); err != 0 {
- return "", err
- }
- return fmt.Sprintf("/dev/pts/%d", u), nil
-}
diff --git a/vendor/github.com/containerd/console/tc_netbsd.go b/vendor/github.com/containerd/console/tc_netbsd.go
deleted file mode 100644
index 71227aef..00000000
--- a/vendor/github.com/containerd/console/tc_netbsd.go
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- Copyright The containerd Authors.
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-*/
-
-package console
-
-import (
- "bytes"
- "os"
-
- "golang.org/x/sys/unix"
-)
-
-const (
- cmdTcGet = unix.TIOCGETA
- cmdTcSet = unix.TIOCSETA
-)
-
-// unlockpt unlocks the slave pseudoterminal device corresponding to the master pseudoterminal referred to by f.
-// unlockpt should be called before opening the slave side of a pty.
-// This does not exist on NetBSD, it does not allocate controlling terminals on open
-func unlockpt(f *os.File) error {
- return nil
-}
-
-// ptsname retrieves the name of the first available pts for the given master.
-func ptsname(f *os.File) (string, error) {
- ptm, err := unix.IoctlGetPtmget(int(f.Fd()), unix.TIOCPTSNAME)
- if err != nil {
- return "", err
- }
- return string(ptm.Sn[:bytes.IndexByte(ptm.Sn[:], 0)]), nil
-}
diff --git a/vendor/github.com/containerd/console/tc_openbsd_cgo.go b/vendor/github.com/containerd/console/tc_openbsd_cgo.go
deleted file mode 100644
index 0e76f6cc..00000000
--- a/vendor/github.com/containerd/console/tc_openbsd_cgo.go
+++ /dev/null
@@ -1,52 +0,0 @@
-//go:build openbsd && cgo
-// +build openbsd,cgo
-
-/*
- Copyright The containerd Authors.
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-*/
-
-package console
-
-import (
- "os"
-
- "golang.org/x/sys/unix"
-)
-
-//#include
-import "C"
-
-const (
- cmdTcGet = unix.TIOCGETA
- cmdTcSet = unix.TIOCSETA
-)
-
-// ptsname retrieves the name of the first available pts for the given master.
-func ptsname(f *os.File) (string, error) {
- ptspath, err := C.ptsname(C.int(f.Fd()))
- if err != nil {
- return "", err
- }
- return C.GoString(ptspath), nil
-}
-
-// unlockpt unlocks the slave pseudoterminal device corresponding to the master pseudoterminal referred to by f.
-// unlockpt should be called before opening the slave side of a pty.
-func unlockpt(f *os.File) error {
- if _, err := C.grantpt(C.int(f.Fd())); err != nil {
- return err
- }
- return nil
-}
diff --git a/vendor/github.com/containerd/console/tc_openbsd_nocgo.go b/vendor/github.com/containerd/console/tc_openbsd_nocgo.go
deleted file mode 100644
index dca92418..00000000
--- a/vendor/github.com/containerd/console/tc_openbsd_nocgo.go
+++ /dev/null
@@ -1,48 +0,0 @@
-//go:build openbsd && !cgo
-// +build openbsd,!cgo
-
-/*
- Copyright The containerd Authors.
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-*/
-
-//
-// Implementing the functions below requires cgo support. Non-cgo stubs
-// versions are defined below to enable cross-compilation of source code
-// that depends on these functions, but the resultant cross-compiled
-// binaries cannot actually be used. If the stub function(s) below are
-// actually invoked they will display an error message and cause the
-// calling process to exit.
-//
-
-package console
-
-import (
- "os"
-
- "golang.org/x/sys/unix"
-)
-
-const (
- cmdTcGet = unix.TIOCGETA
- cmdTcSet = unix.TIOCSETA
-)
-
-func ptsname(f *os.File) (string, error) {
- panic("ptsname() support requires cgo.")
-}
-
-func unlockpt(f *os.File) error {
- panic("unlockpt() support requires cgo.")
-}
diff --git a/vendor/github.com/containerd/console/tc_unix.go b/vendor/github.com/containerd/console/tc_unix.go
deleted file mode 100644
index f5053b2f..00000000
--- a/vendor/github.com/containerd/console/tc_unix.go
+++ /dev/null
@@ -1,92 +0,0 @@
-//go:build darwin || freebsd || linux || netbsd || openbsd || zos
-// +build darwin freebsd linux netbsd openbsd zos
-
-/*
- Copyright The containerd Authors.
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-*/
-
-package console
-
-import (
- "golang.org/x/sys/unix"
-)
-
-func tcget(fd uintptr, p *unix.Termios) error {
- termios, err := unix.IoctlGetTermios(int(fd), cmdTcGet)
- if err != nil {
- return err
- }
- *p = *termios
- return nil
-}
-
-func tcset(fd uintptr, p *unix.Termios) error {
- return unix.IoctlSetTermios(int(fd), cmdTcSet, p)
-}
-
-func tcgwinsz(fd uintptr) (WinSize, error) {
- var ws WinSize
-
- uws, err := unix.IoctlGetWinsize(int(fd), unix.TIOCGWINSZ)
- if err != nil {
- return ws, err
- }
-
- // Translate from unix.Winsize to console.WinSize
- ws.Height = uws.Row
- ws.Width = uws.Col
- ws.x = uws.Xpixel
- ws.y = uws.Ypixel
- return ws, nil
-}
-
-func tcswinsz(fd uintptr, ws WinSize) error {
- // Translate from console.WinSize to unix.Winsize
-
- var uws unix.Winsize
- uws.Row = ws.Height
- uws.Col = ws.Width
- uws.Xpixel = ws.x
- uws.Ypixel = ws.y
-
- return unix.IoctlSetWinsize(int(fd), unix.TIOCSWINSZ, &uws)
-}
-
-func setONLCR(fd uintptr, enable bool) error {
- var termios unix.Termios
- if err := tcget(fd, &termios); err != nil {
- return err
- }
- if enable {
- // Set +onlcr so we can act like a real terminal
- termios.Oflag |= unix.ONLCR
- } else {
- // Set -onlcr so we don't have to deal with \r.
- termios.Oflag &^= unix.ONLCR
- }
- return tcset(fd, &termios)
-}
-
-func cfmakeraw(t unix.Termios) unix.Termios {
- t.Iflag &^= (unix.IGNBRK | unix.BRKINT | unix.PARMRK | unix.ISTRIP | unix.INLCR | unix.IGNCR | unix.ICRNL | unix.IXON)
- t.Oflag &^= unix.OPOST
- t.Lflag &^= (unix.ECHO | unix.ECHONL | unix.ICANON | unix.ISIG | unix.IEXTEN)
- t.Cflag &^= (unix.CSIZE | unix.PARENB)
- t.Cflag &^= unix.CS8
- t.Cc[unix.VMIN] = 1
- t.Cc[unix.VTIME] = 0
-
- return t
-}
diff --git a/vendor/github.com/containerd/console/tc_zos.go b/vendor/github.com/containerd/console/tc_zos.go
deleted file mode 100644
index fc90ba5f..00000000
--- a/vendor/github.com/containerd/console/tc_zos.go
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- Copyright The containerd Authors.
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-*/
-
-package console
-
-import (
- "os"
- "strings"
-
- "golang.org/x/sys/unix"
-)
-
-const (
- cmdTcGet = unix.TCGETS
- cmdTcSet = unix.TCSETS
-)
-
-// unlockpt is a no-op on zos.
-func unlockpt(_ *os.File) error {
- return nil
-}
-
-// ptsname retrieves the name of the first available pts for the given master.
-func ptsname(f *os.File) (string, error) {
- return "/dev/ttyp" + strings.TrimPrefix(f.Name(), "/dev/ptyp"), nil
-}
diff --git a/vendor/github.com/erikgeiser/coninput/.gitignore b/vendor/github.com/erikgeiser/coninput/.gitignore
new file mode 100644
index 00000000..66fd13c9
--- /dev/null
+++ b/vendor/github.com/erikgeiser/coninput/.gitignore
@@ -0,0 +1,15 @@
+# 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/
diff --git a/vendor/github.com/erikgeiser/coninput/.golangci.yml b/vendor/github.com/erikgeiser/coninput/.golangci.yml
new file mode 100644
index 00000000..d3ed7103
--- /dev/null
+++ b/vendor/github.com/erikgeiser/coninput/.golangci.yml
@@ -0,0 +1,24 @@
+linters:
+ enable-all: true
+ disable:
+ - golint
+ - interfacer
+ - scopelint
+ - maligned
+ - rowserrcheck
+ - funlen
+ - depguard
+ - goerr113
+ - exhaustivestruct
+ - testpackage
+ - gochecknoglobals
+ - wrapcheck
+ - forbidigo
+ - ifshort
+ - cyclop
+ - gomoddirectives
+linters-settings:
+ exhaustive:
+ default-signifies-exhaustive: true
+issues:
+ exclude-use-default: false
diff --git a/vendor/github.com/erikgeiser/coninput/LICENSE b/vendor/github.com/erikgeiser/coninput/LICENSE
new file mode 100644
index 00000000..83c24408
--- /dev/null
+++ b/vendor/github.com/erikgeiser/coninput/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2021 Erik G.
+
+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.
diff --git a/vendor/github.com/erikgeiser/coninput/README.md b/vendor/github.com/erikgeiser/coninput/README.md
new file mode 100644
index 00000000..22619d13
--- /dev/null
+++ b/vendor/github.com/erikgeiser/coninput/README.md
@@ -0,0 +1,2 @@
+# coninput
+Go library for input handling using Windows Console API
diff --git a/vendor/github.com/erikgeiser/coninput/keycodes.go b/vendor/github.com/erikgeiser/coninput/keycodes.go
new file mode 100644
index 00000000..902ee1b7
--- /dev/null
+++ b/vendor/github.com/erikgeiser/coninput/keycodes.go
@@ -0,0 +1,205 @@
+package coninput
+
+// VirtualKeyCode holds a virtual key code (see
+// https://docs.microsoft.com/en-us/windows/win32/inputdev/virtual-key-codes).
+type VirtualKeyCode uint16
+
+const (
+ VK_LBUTTON VirtualKeyCode = 0x01
+ VK_RBUTTON VirtualKeyCode = 0x02
+ VK_CANCEL VirtualKeyCode = 0x03
+ VK_MBUTTON VirtualKeyCode = 0x04
+ VK_XBUTTON1 VirtualKeyCode = 0x05
+ VK_XBUTTON2 VirtualKeyCode = 0x06
+ VK_BACK VirtualKeyCode = 0x08
+ VK_TAB VirtualKeyCode = 0x09
+ VK_CLEAR VirtualKeyCode = 0x0C
+ VK_RETURN VirtualKeyCode = 0x0D
+ VK_SHIFT VirtualKeyCode = 0x10
+ VK_CONTROL VirtualKeyCode = 0x11
+ VK_MENU VirtualKeyCode = 0x12
+ VK_PAUSE VirtualKeyCode = 0x13
+ VK_CAPITAL VirtualKeyCode = 0x14
+ VK_KANA VirtualKeyCode = 0x15
+ VK_HANGEUL VirtualKeyCode = 0x15
+ VK_HANGUL VirtualKeyCode = 0x15
+ VK_IME_ON VirtualKeyCode = 0x16
+ VK_JUNJA VirtualKeyCode = 0x17
+ VK_FINAL VirtualKeyCode = 0x18
+ VK_HANJA VirtualKeyCode = 0x19
+ VK_KANJI VirtualKeyCode = 0x19
+ VK_IME_OFF VirtualKeyCode = 0x1A
+ VK_ESCAPE VirtualKeyCode = 0x1B
+ VK_CONVERT VirtualKeyCode = 0x1C
+ VK_NONCONVERT VirtualKeyCode = 0x1D
+ VK_ACCEPT VirtualKeyCode = 0x1E
+ VK_MODECHANGE VirtualKeyCode = 0x1F
+ VK_SPACE VirtualKeyCode = 0x20
+ VK_PRIOR VirtualKeyCode = 0x21
+ VK_NEXT VirtualKeyCode = 0x22
+ VK_END VirtualKeyCode = 0x23
+ VK_HOME VirtualKeyCode = 0x24
+ VK_LEFT VirtualKeyCode = 0x25
+ VK_UP VirtualKeyCode = 0x26
+ VK_RIGHT VirtualKeyCode = 0x27
+ VK_DOWN VirtualKeyCode = 0x28
+ VK_SELECT VirtualKeyCode = 0x29
+ VK_PRINT VirtualKeyCode = 0x2A
+ VK_EXECUTE VirtualKeyCode = 0x2B
+ VK_SNAPSHOT VirtualKeyCode = 0x2C
+ VK_INSERT VirtualKeyCode = 0x2D
+ VK_DELETE VirtualKeyCode = 0x2E
+ VK_HELP VirtualKeyCode = 0x2F
+ VK_0 VirtualKeyCode = 0x30
+ VK_1 VirtualKeyCode = 0x31
+ VK_2 VirtualKeyCode = 0x32
+ VK_3 VirtualKeyCode = 0x33
+ VK_4 VirtualKeyCode = 0x34
+ VK_5 VirtualKeyCode = 0x35
+ VK_6 VirtualKeyCode = 0x36
+ VK_7 VirtualKeyCode = 0x37
+ VK_8 VirtualKeyCode = 0x38
+ VK_9 VirtualKeyCode = 0x39
+ VK_A VirtualKeyCode = 0x41
+ VK_B VirtualKeyCode = 0x42
+ VK_C VirtualKeyCode = 0x43
+ VK_D VirtualKeyCode = 0x44
+ VK_E VirtualKeyCode = 0x45
+ VK_F VirtualKeyCode = 0x46
+ VK_G VirtualKeyCode = 0x47
+ VK_H VirtualKeyCode = 0x48
+ VK_I VirtualKeyCode = 0x49
+ VK_J VirtualKeyCode = 0x4A
+ VK_K VirtualKeyCode = 0x4B
+ VK_L VirtualKeyCode = 0x4C
+ VK_M VirtualKeyCode = 0x4D
+ VK_N VirtualKeyCode = 0x4E
+ VK_O VirtualKeyCode = 0x4F
+ VK_P VirtualKeyCode = 0x50
+ VK_Q VirtualKeyCode = 0x51
+ VK_R VirtualKeyCode = 0x52
+ VK_S VirtualKeyCode = 0x53
+ VK_T VirtualKeyCode = 0x54
+ VK_U VirtualKeyCode = 0x55
+ VK_V VirtualKeyCode = 0x56
+ VK_W VirtualKeyCode = 0x57
+ VK_X VirtualKeyCode = 0x58
+ VK_Y VirtualKeyCode = 0x59
+ VK_Z VirtualKeyCode = 0x5A
+ VK_LWIN VirtualKeyCode = 0x5B
+ VK_RWIN VirtualKeyCode = 0x5C
+ VK_APPS VirtualKeyCode = 0x5D
+ VK_SLEEP VirtualKeyCode = 0x5F
+ VK_NUMPAD0 VirtualKeyCode = 0x60
+ VK_NUMPAD1 VirtualKeyCode = 0x61
+ VK_NUMPAD2 VirtualKeyCode = 0x62
+ VK_NUMPAD3 VirtualKeyCode = 0x63
+ VK_NUMPAD4 VirtualKeyCode = 0x64
+ VK_NUMPAD5 VirtualKeyCode = 0x65
+ VK_NUMPAD6 VirtualKeyCode = 0x66
+ VK_NUMPAD7 VirtualKeyCode = 0x67
+ VK_NUMPAD8 VirtualKeyCode = 0x68
+ VK_NUMPAD9 VirtualKeyCode = 0x69
+ VK_MULTIPLY VirtualKeyCode = 0x6A
+ VK_ADD VirtualKeyCode = 0x6B
+ VK_SEPARATOR VirtualKeyCode = 0x6C
+ VK_SUBTRACT VirtualKeyCode = 0x6D
+ VK_DECIMAL VirtualKeyCode = 0x6E
+ VK_DIVIDE VirtualKeyCode = 0x6F
+ VK_F1 VirtualKeyCode = 0x70
+ VK_F2 VirtualKeyCode = 0x71
+ VK_F3 VirtualKeyCode = 0x72
+ VK_F4 VirtualKeyCode = 0x73
+ VK_F5 VirtualKeyCode = 0x74
+ VK_F6 VirtualKeyCode = 0x75
+ VK_F7 VirtualKeyCode = 0x76
+ VK_F8 VirtualKeyCode = 0x77
+ VK_F9 VirtualKeyCode = 0x78
+ VK_F10 VirtualKeyCode = 0x79
+ VK_F11 VirtualKeyCode = 0x7A
+ VK_F12 VirtualKeyCode = 0x7B
+ VK_F13 VirtualKeyCode = 0x7C
+ VK_F14 VirtualKeyCode = 0x7D
+ VK_F15 VirtualKeyCode = 0x7E
+ VK_F16 VirtualKeyCode = 0x7F
+ VK_F17 VirtualKeyCode = 0x80
+ VK_F18 VirtualKeyCode = 0x81
+ VK_F19 VirtualKeyCode = 0x82
+ VK_F20 VirtualKeyCode = 0x83
+ VK_F21 VirtualKeyCode = 0x84
+ VK_F22 VirtualKeyCode = 0x85
+ VK_F23 VirtualKeyCode = 0x86
+ VK_F24 VirtualKeyCode = 0x87
+ VK_NUMLOCK VirtualKeyCode = 0x90
+ VK_SCROLL VirtualKeyCode = 0x91
+ VK_OEM_NEC_EQUAL VirtualKeyCode = 0x92
+ VK_OEM_FJ_JISHO VirtualKeyCode = 0x92
+ VK_OEM_FJ_MASSHOU VirtualKeyCode = 0x93
+ VK_OEM_FJ_TOUROKU VirtualKeyCode = 0x94
+ VK_OEM_FJ_LOYA VirtualKeyCode = 0x95
+ VK_OEM_FJ_ROYA VirtualKeyCode = 0x96
+ VK_LSHIFT VirtualKeyCode = 0xA0
+ VK_RSHIFT VirtualKeyCode = 0xA1
+ VK_LCONTROL VirtualKeyCode = 0xA2
+ VK_RCONTROL VirtualKeyCode = 0xA3
+ VK_LMENU VirtualKeyCode = 0xA4
+ VK_RMENU VirtualKeyCode = 0xA5
+ VK_BROWSER_BACK VirtualKeyCode = 0xA6
+ VK_BROWSER_FORWARD VirtualKeyCode = 0xA7
+ VK_BROWSER_REFRESH VirtualKeyCode = 0xA8
+ VK_BROWSER_STOP VirtualKeyCode = 0xA9
+ VK_BROWSER_SEARCH VirtualKeyCode = 0xAA
+ VK_BROWSER_FAVORITES VirtualKeyCode = 0xAB
+ VK_BROWSER_HOME VirtualKeyCode = 0xAC
+ VK_VOLUME_MUTE VirtualKeyCode = 0xAD
+ VK_VOLUME_DOWN VirtualKeyCode = 0xAE
+ VK_VOLUME_UP VirtualKeyCode = 0xAF
+ VK_MEDIA_NEXT_TRACK VirtualKeyCode = 0xB0
+ VK_MEDIA_PREV_TRACK VirtualKeyCode = 0xB1
+ VK_MEDIA_STOP VirtualKeyCode = 0xB2
+ VK_MEDIA_PLAY_PAUSE VirtualKeyCode = 0xB3
+ VK_LAUNCH_MAIL VirtualKeyCode = 0xB4
+ VK_LAUNCH_MEDIA_SELECT VirtualKeyCode = 0xB5
+ VK_LAUNCH_APP1 VirtualKeyCode = 0xB6
+ VK_LAUNCH_APP2 VirtualKeyCode = 0xB7
+ VK_OEM_1 VirtualKeyCode = 0xBA
+ VK_OEM_PLUS VirtualKeyCode = 0xBB
+ VK_OEM_COMMA VirtualKeyCode = 0xBC
+ VK_OEM_MINUS VirtualKeyCode = 0xBD
+ VK_OEM_PERIOD VirtualKeyCode = 0xBE
+ VK_OEM_2 VirtualKeyCode = 0xBF
+ VK_OEM_3 VirtualKeyCode = 0xC0
+ VK_OEM_4 VirtualKeyCode = 0xDB
+ VK_OEM_5 VirtualKeyCode = 0xDC
+ VK_OEM_6 VirtualKeyCode = 0xDD
+ VK_OEM_7 VirtualKeyCode = 0xDE
+ VK_OEM_8 VirtualKeyCode = 0xDF
+ VK_OEM_AX VirtualKeyCode = 0xE1
+ VK_OEM_102 VirtualKeyCode = 0xE2
+ VK_ICO_HELP VirtualKeyCode = 0xE3
+ VK_ICO_00 VirtualKeyCode = 0xE4
+ VK_PROCESSKEY VirtualKeyCode = 0xE5
+ VK_ICO_CLEAR VirtualKeyCode = 0xE6
+ VK_OEM_RESET VirtualKeyCode = 0xE9
+ VK_OEM_JUMP VirtualKeyCode = 0xEA
+ VK_OEM_PA1 VirtualKeyCode = 0xEB
+ VK_OEM_PA2 VirtualKeyCode = 0xEC
+ VK_OEM_PA3 VirtualKeyCode = 0xED
+ VK_OEM_WSCTRL VirtualKeyCode = 0xEE
+ VK_OEM_CUSEL VirtualKeyCode = 0xEF
+ VK_OEM_ATTN VirtualKeyCode = 0xF0
+ VK_OEM_FINISH VirtualKeyCode = 0xF1
+ VK_OEM_COPY VirtualKeyCode = 0xF2
+ VK_OEM_AUTO VirtualKeyCode = 0xF3
+ VK_OEM_ENLW VirtualKeyCode = 0xF4
+ VK_OEM_BACKTAB VirtualKeyCode = 0xF5
+ VK_ATTN VirtualKeyCode = 0xF6
+ VK_CRSEL VirtualKeyCode = 0xF7
+ VK_EXSEL VirtualKeyCode = 0xF8
+ VK_EREOF VirtualKeyCode = 0xF9
+ VK_PLAY VirtualKeyCode = 0xFA
+ VK_ZOOM VirtualKeyCode = 0xFB
+ VK_NONAME VirtualKeyCode = 0xFC
+ VK_PA1 VirtualKeyCode = 0xFD
+ VK_OEM_CLEAR VirtualKeyCode = 0xFE
+)
diff --git a/vendor/github.com/erikgeiser/coninput/mode.go b/vendor/github.com/erikgeiser/coninput/mode.go
new file mode 100644
index 00000000..e6d8bf44
--- /dev/null
+++ b/vendor/github.com/erikgeiser/coninput/mode.go
@@ -0,0 +1,82 @@
+//go:build windows
+// +build windows
+
+package coninput
+
+import (
+ "strings"
+
+ "golang.org/x/sys/windows"
+)
+
+// AddInputModes returns the given mode with one or more additional modes enabled.
+func AddInputModes(mode uint32, enableModes ...uint32) uint32 {
+ for _, enableMode := range enableModes {
+ mode |= enableMode
+ }
+
+ return mode
+}
+
+// RemoveInputModes returns the given mode with one or more additional modes disabled.
+func RemoveInputModes(mode uint32, disableModes ...uint32) uint32 {
+ for _, disableMode := range disableModes {
+ mode &^= disableMode
+ }
+
+ return mode
+}
+
+// ToggleInputModes returns the given mode with one or more additional modes toggeled.
+func ToggleInputModes(mode uint32, toggleModes ...uint32) uint32 {
+ for _, toggeMode := range toggleModes {
+ mode ^= toggeMode
+ }
+
+ return mode
+}
+
+var inputModes = []struct {
+ mode uint32
+ name string
+}{
+ {mode: windows.ENABLE_ECHO_INPUT, name: "ENABLE_ECHO_INPUT"},
+ {mode: windows.ENABLE_INSERT_MODE, name: "ENABLE_INSERT_MODE"},
+ {mode: windows.ENABLE_LINE_INPUT, name: "ENABLE_LINE_INPUT"},
+ {mode: windows.ENABLE_MOUSE_INPUT, name: "ENABLE_MOUSE_INPUT"},
+ {mode: windows.ENABLE_PROCESSED_INPUT, name: "ENABLE_PROCESSED_INPUT"},
+ {mode: windows.ENABLE_QUICK_EDIT_MODE, name: "ENABLE_QUICK_EDIT_MODE"},
+ {mode: windows.ENABLE_WINDOW_INPUT, name: "ENABLE_WINDOW_INPUT"},
+ {mode: windows.ENABLE_VIRTUAL_TERMINAL_INPUT, name: "ENABLE_VIRTUAL_TERMINAL_INPUT"},
+}
+
+// ListInputMode returnes the isolated enabled input modes as a list.
+func ListInputModes(mode uint32) []uint32 {
+ modes := []uint32{}
+
+ for _, inputMode := range inputModes {
+ if mode&inputMode.mode > 0 {
+ modes = append(modes, inputMode.mode)
+ }
+ }
+
+ return modes
+}
+
+// ListInputMode returnes the isolated enabled input mode names as a list.
+func ListInputModeNames(mode uint32) []string {
+ modes := []string{}
+
+ for _, inputMode := range inputModes {
+ if mode&inputMode.mode > 0 {
+ modes = append(modes, inputMode.name)
+ }
+ }
+
+ return modes
+}
+
+// DescribeInputMode returns a string containing the names of each enabled input mode.
+func DescribeInputMode(mode uint32) string {
+ return strings.Join(ListInputModeNames(mode), "|")
+}
diff --git a/vendor/github.com/erikgeiser/coninput/read.go b/vendor/github.com/erikgeiser/coninput/read.go
new file mode 100644
index 00000000..b2dd82f1
--- /dev/null
+++ b/vendor/github.com/erikgeiser/coninput/read.go
@@ -0,0 +1,154 @@
+//go:build windows
+// +build windows
+
+package coninput
+
+import (
+ "fmt"
+ "syscall"
+ "unsafe"
+
+ "golang.org/x/sys/windows"
+)
+
+var (
+ modkernel32 = windows.NewLazySystemDLL("kernel32.dll")
+ procReadConsoleInputW = modkernel32.NewProc("ReadConsoleInputW")
+ procPeekConsoleInputW = modkernel32.NewProc("PeekConsoleInputW")
+ procGetNumberOfConsoleInputEvents = modkernel32.NewProc("GetNumberOfConsoleInputEvents")
+ procFlushConsoleInputBuffer = modkernel32.NewProc("FlushConsoleInputBuffer")
+)
+
+// NewStdinHandle is a shortcut for windows.GetStdHandle(windows.STD_INPUT_HANDLE).
+func NewStdinHandle() (windows.Handle, error) {
+ return windows.GetStdHandle(windows.STD_INPUT_HANDLE)
+}
+
+// WinReadConsoleInput is a thin wrapper around the Windows console API function
+// ReadConsoleInput (see
+// https://docs.microsoft.com/en-us/windows/console/readconsoleinput). In most
+// cases it is more practical to either use ReadConsoleInput or
+// ReadNConsoleInputs.
+func WinReadConsoleInput(consoleInput windows.Handle, buffer *InputRecord,
+ length uint32, numberOfEventsRead *uint32) error {
+ r, _, e := syscall.Syscall6(procReadConsoleInputW.Addr(), 4,
+ uintptr(consoleInput), uintptr(unsafe.Pointer(buffer)), uintptr(length),
+ uintptr(unsafe.Pointer(numberOfEventsRead)), 0, 0)
+ if r == 0 {
+ return error(e)
+ }
+
+ return nil
+}
+
+// ReadNConsoleInputs is a wrapper around ReadConsoleInput (see
+// https://docs.microsoft.com/en-us/windows/console/readconsoleinput) that
+// automates the event buffer allocation in oder to provide io.Reader-like
+// sematics. maxEvents must be greater than zero.
+func ReadNConsoleInputs(console windows.Handle, maxEvents uint32) ([]InputRecord, error) {
+ if maxEvents == 0 {
+ return nil, fmt.Errorf("maxEvents cannot be zero")
+ }
+
+ var inputRecords = make([]InputRecord, maxEvents)
+ n, err := ReadConsoleInput(console, inputRecords)
+
+ return inputRecords[:n], err
+}
+
+// ReadConsoleInput provides an ideomatic interface to the Windows console API
+// function ReadConsoleInput (see
+// https://docs.microsoft.com/en-us/windows/console/readconsoleinput). The size
+// of inputRecords must be greater than zero.
+func ReadConsoleInput(console windows.Handle, inputRecords []InputRecord) (uint32, error) {
+ if len(inputRecords) == 0 {
+ return 0, fmt.Errorf("size of input record buffer cannot be zero")
+ }
+
+ var read uint32
+ err := WinReadConsoleInput(console, &inputRecords[0], uint32(len(inputRecords)), &read)
+
+ return read, err
+}
+
+// WinPeekConsoleInput is a thin wrapper around the Windows console API function
+// PeekConsoleInput (see
+// https://docs.microsoft.com/en-us/windows/console/peekconsoleinput). In most
+// cases it is more practical to either use PeekConsoleInput or
+// PeekNConsoleInputs.
+func WinPeekConsoleInput(consoleInput windows.Handle, buffer *InputRecord,
+ length uint32, numberOfEventsRead *uint32) error {
+ r, _, e := syscall.Syscall6(procPeekConsoleInputW.Addr(), 4,
+ uintptr(consoleInput), uintptr(unsafe.Pointer(buffer)), uintptr(length),
+ uintptr(unsafe.Pointer(numberOfEventsRead)), 0, 0)
+ if r == 0 {
+ return error(e)
+ }
+
+ return nil
+
+}
+
+// PeekNConsoleInputs is a wrapper around PeekConsoleInput (see
+// https://docs.microsoft.com/en-us/windows/console/peekconsoleinput) that
+// automates the event buffer allocation in oder to provide io.Reader-like
+// sematics. maxEvents must be greater than zero.
+func PeekNConsoleInputs(console windows.Handle, maxEvents uint32) ([]InputRecord, error) {
+ if maxEvents == 0 {
+ return nil, fmt.Errorf("maxEvents cannot be zero")
+ }
+
+ var inputRecords = make([]InputRecord, maxEvents)
+ n, err := PeekConsoleInput(console, inputRecords)
+
+ return inputRecords[:n], err
+}
+
+// PeekConsoleInput provides an ideomatic interface to the Windows console API
+// function PeekConsoleInput (see
+// https://docs.microsoft.com/en-us/windows/console/peekconsoleinput). The size
+// of inputRecords must be greater than zero.
+func PeekConsoleInput(console windows.Handle, inputRecords []InputRecord) (uint32, error) {
+ if len(inputRecords) == 0 {
+ return 0, fmt.Errorf("size of input record buffer cannot be zero")
+ }
+
+ var read uint32
+
+ err := WinPeekConsoleInput(console, &inputRecords[0], uint32(len(inputRecords)), &read)
+
+ return read, err
+}
+
+// WinGetNumberOfConsoleInputEvents provides an ideomatic interface to the
+// Windows console API function GetNumberOfConsoleInputEvents (see
+// https://docs.microsoft.com/en-us/windows/console/getnumberofconsoleinputevents).
+func WinGetNumberOfConsoleInputEvents(consoleInput windows.Handle, numberOfEvents *uint32) error {
+ r, _, e := syscall.Syscall6(procGetNumberOfConsoleInputEvents.Addr(), 2,
+ uintptr(consoleInput), uintptr(unsafe.Pointer(numberOfEvents)), 0,
+ 0, 0, 0)
+ if r == 0 {
+ return error(e)
+ }
+
+ return nil
+}
+
+// GetNumberOfConsoleInputEvents provides an ideomatic interface to the Windows
+// console API function GetNumberOfConsoleInputEvents (see
+// https://docs.microsoft.com/en-us/windows/console/getnumberofconsoleinputevents).
+func GetNumberOfConsoleInputEvents(console windows.Handle) (uint32, error) {
+ var nEvents uint32
+ err := WinGetNumberOfConsoleInputEvents(console, &nEvents)
+
+ return nEvents, err
+}
+
+func FlushConsoleInputBuffer(consoleInput windows.Handle) error {
+ r, _, e := syscall.Syscall(procFlushConsoleInputBuffer.Addr(), 1, uintptr(consoleInput), 0, 0)
+ if r == 0 {
+ return error(e)
+ }
+
+ return nil
+}
diff --git a/vendor/github.com/erikgeiser/coninput/records.go b/vendor/github.com/erikgeiser/coninput/records.go
new file mode 100644
index 00000000..cccf7fbf
--- /dev/null
+++ b/vendor/github.com/erikgeiser/coninput/records.go
@@ -0,0 +1,486 @@
+package coninput
+
+import (
+ "encoding/binary"
+ "fmt"
+ "strconv"
+ "strings"
+)
+
+const (
+ maxEventSize = 16
+ wordPaddingBytes = 2
+)
+
+// EventType denots the type of an event
+type EventType uint16
+
+// EventUnion is the union data type that contains the data for any event.
+type EventUnion [maxEventSize]byte
+
+// InputRecord corresponds to the INPUT_RECORD structure from the Windows
+// console API (see
+// https://docs.microsoft.com/en-us/windows/console/input-record-str).
+type InputRecord struct {
+ // EventType specifies the type of event that helt in Event.
+ EventType EventType
+
+ // Padding of the 16-bit EventType to a whole 32-bit dword.
+ _ [wordPaddingBytes]byte
+
+ // Event holds the actual event data. Use Unrap to access it as its
+ // respective event type.
+ Event EventUnion
+}
+
+// String implements fmt.Stringer for InputRecord.
+func (ir InputRecord) String() string {
+ return ir.Unwrap().String()
+}
+
+// Unwrap parses the event data into an EventRecord of the respective event
+// type. The data in the returned EventRecord does not contain any references to
+// the passed InputRecord.
+func (ir InputRecord) Unwrap() EventRecord {
+ switch ir.EventType {
+ case FocusEventType:
+ return FocusEventRecord{SetFocus: ir.Event[0] > 0}
+ case KeyEventType:
+ return KeyEventRecord{
+ KeyDown: binary.LittleEndian.Uint32(ir.Event[0:4]) > 0,
+ RepeatCount: binary.LittleEndian.Uint16(ir.Event[4:6]),
+ VirtualKeyCode: VirtualKeyCode(binary.LittleEndian.Uint16(ir.Event[6:8])),
+ VirtualScanCode: VirtualKeyCode(binary.LittleEndian.Uint16(ir.Event[8:10])),
+ Char: rune(binary.LittleEndian.Uint16(ir.Event[10:12])),
+ ControlKeyState: ControlKeyState(binary.LittleEndian.Uint32(ir.Event[12:16])),
+ }
+ case MouseEventType:
+ m := MouseEventRecord{
+ MousePositon: Coord{
+ X: binary.LittleEndian.Uint16(ir.Event[0:2]),
+ Y: binary.LittleEndian.Uint16(ir.Event[2:4]),
+ },
+ ButtonState: ButtonState(binary.LittleEndian.Uint32(ir.Event[4:8])),
+ ControlKeyState: ControlKeyState(binary.LittleEndian.Uint32(ir.Event[8:12])),
+ EventFlags: EventFlags(binary.LittleEndian.Uint32(ir.Event[12:16])),
+ }
+
+ if (m.EventFlags&MOUSE_WHEELED > 0) || (m.EventFlags&MOUSE_HWHEELED > 0) {
+ if int16(highWord(uint32(m.ButtonState))) > 0 {
+ m.WheelDirection = 1
+ } else {
+ m.WheelDirection = -1
+ }
+ }
+
+ return m
+ case WindowBufferSizeEventType:
+ return WindowBufferSizeEventRecord{
+ Size: Coord{
+ X: binary.LittleEndian.Uint16(ir.Event[0:2]),
+ Y: binary.LittleEndian.Uint16(ir.Event[2:4]),
+ },
+ }
+ case MenuEventType:
+ return MenuEventRecord{
+ CommandID: binary.LittleEndian.Uint32(ir.Event[0:4]),
+ }
+ default:
+ return &UnknownEvent{InputRecord: ir}
+ }
+}
+
+// EventRecord represents one of the following event types:
+// TypeFocusEventRecord, TypeKeyEventRecord, TypeMouseEventRecord,
+// TypeWindowBufferSizeEvent, TypeMenuEventRecord and UnknownEvent.
+type EventRecord interface {
+ Type() string
+ fmt.Stringer
+}
+
+// FocusEventType is the event type for a FocusEventRecord (see
+// https://docs.microsoft.com/en-us/windows/console/input-record-str).
+const FocusEventType EventType = 0x0010
+
+// FocusEventRecord represent the FOCUS_EVENT_RECORD structure from the Windows
+// console API (see
+// https://docs.microsoft.com/en-us/windows/console/focus-event-record-str).
+// These events are used internally by the Windows console API and should be
+// ignored.
+type FocusEventRecord struct {
+ // SetFocus is reserved and should not be used.
+ SetFocus bool
+}
+
+// Ensure that FocusEventRecord satisfies EventRecord interface.
+var _ EventRecord = FocusEventRecord{}
+
+// Type ensures that FocusEventRecord satisfies EventRecord interface.
+func (e FocusEventRecord) Type() string { return "FocusEvent" }
+
+// String ensures that FocusEventRecord satisfies EventRecord and fmt.Stringer
+// interfaces.
+func (e FocusEventRecord) String() string { return fmt.Sprintf("%s[%v]", e.Type(), e.SetFocus) }
+
+// KeyEventType is the event type for a KeyEventRecord (see
+// https://docs.microsoft.com/en-us/windows/console/input-record-str).
+const KeyEventType EventType = 0x0001
+
+// KeyEventRecord represent the KEY_EVENT_RECORD structure from the Windows
+// console API (see
+// https://docs.microsoft.com/en-us/windows/console/key-event-record-str).
+type KeyEventRecord struct {
+ // KeyDown specified whether the key is pressed or released.
+ KeyDown bool
+
+ // RepeatCount indicates that a key is being held down. For example, when a
+ // key is held down, five events with RepeatCount equal to 1 may be
+ // generated, one event with RepeatCount equal to 5, or multiple events
+ // with RepeatCount greater than or equal to 1.
+ RepeatCount uint16
+
+ // VirtualKeyCode identifies the given key in a device-independent manner
+ // (see
+ // https://docs.microsoft.com/en-us/windows/win32/inputdev/virtual-key-codes).
+ VirtualKeyCode VirtualKeyCode
+
+ // VirtualScanCode represents the device-dependent value generated by the
+ // keyboard hardware.
+ VirtualScanCode VirtualKeyCode
+
+ // Char is the character that corresponds to the pressed key. Char can be
+ // zero for some keys.
+ Char rune
+
+ //ControlKeyState holds the state of the control keys.
+ ControlKeyState ControlKeyState
+}
+
+// Ensure that KeyEventRecord satisfies EventRecord interface.
+var _ EventRecord = KeyEventRecord{}
+
+// Type ensures that KeyEventRecord satisfies EventRecord interface.
+func (e KeyEventRecord) Type() string { return "KeyEvent" }
+
+// String ensures that KeyEventRecord satisfies EventRecord and fmt.Stringer
+// interfaces.
+func (e KeyEventRecord) String() string {
+ infos := []string{}
+
+ repeat := ""
+ if e.RepeatCount > 1 {
+ repeat = "x" + strconv.Itoa(int(e.RepeatCount))
+ }
+
+ infos = append(infos, fmt.Sprintf("%q%s", e.Char, repeat))
+
+ direction := "up"
+ if e.KeyDown {
+ direction = "down"
+ }
+
+ infos = append(infos, direction)
+
+ if e.ControlKeyState != NO_CONTROL_KEY {
+ infos = append(infos, e.ControlKeyState.String())
+ }
+
+ infos = append(infos, fmt.Sprintf("KeyCode: %d", e.VirtualKeyCode))
+ infos = append(infos, fmt.Sprintf("ScanCode: %d", e.VirtualScanCode))
+
+ return fmt.Sprintf("%s[%s]", e.Type(), strings.Join(infos, ", "))
+}
+
+// MenuEventType is the event type for a MenuEventRecord (see
+// https://docs.microsoft.com/en-us/windows/console/input-record-str).
+const MenuEventType EventType = 0x0008
+
+// MenuEventRecord represent the MENU_EVENT_RECORD structure from the Windows
+// console API (see
+// https://docs.microsoft.com/en-us/windows/console/menu-event-record-str).
+// These events are deprecated by the Windows console API and should be ignored.
+type MenuEventRecord struct {
+ CommandID uint32
+}
+
+// Ensure that MenuEventRecord satisfies EventRecord interface.
+var _ EventRecord = MenuEventRecord{}
+
+// Type ensures that MenuEventRecord satisfies EventRecord interface.
+func (e MenuEventRecord) Type() string { return "MenuEvent" }
+
+// String ensures that MenuEventRecord satisfies EventRecord and fmt.Stringer
+// interfaces.
+func (e MenuEventRecord) String() string { return fmt.Sprintf("MenuEvent[%d]", e.CommandID) }
+
+// MouseEventType is the event type for a MouseEventRecord (see
+// https://docs.microsoft.com/en-us/windows/console/input-record-str).
+const MouseEventType EventType = 0x0002
+
+// MouseEventRecord represent the MOUSE_EVENT_RECORD structure from the Windows
+// console API (see
+// https://docs.microsoft.com/en-us/windows/console/mouse-event-record-str).
+type MouseEventRecord struct {
+ // MousePosition contains the location of the cursor, in terms of the
+ // console screen buffer's character-cell coordinates.
+ MousePositon Coord
+
+ // ButtonState holds the status of the mouse buttons.
+ ButtonState ButtonState
+
+ // ControlKeyState holds the state of the control keys.
+ ControlKeyState ControlKeyState
+
+ // EventFlags specify tge type of mouse event.
+ EventFlags EventFlags
+
+ // WheelDirection specified the direction in which the mouse wheel is
+ // spinning when EventFlags contains MOUSE_HWHEELED or MOUSE_WHEELED. When
+ // the event flags specify MOUSE_WHEELED it is 1 if the wheel rotated
+ // forward (away from the user) or -1 when it rotates backwards. When
+ // MOUSE_HWHEELED is specified it is 1 when the wheel rotates right and -1
+ // when it rotates left. When the EventFlags do not indicate a mouse wheel
+ // event it is 0.
+ WheelDirection int
+}
+
+// Ensure that MouseEventRecord satisfies EventRecord interface.
+var _ EventRecord = MouseEventRecord{}
+
+func (e MouseEventRecord) WheelDirectionName() string {
+ if e.EventFlags&MOUSE_WHEELED > 0 {
+ if e.WheelDirection > 0 {
+ return "Forward"
+ }
+
+ return "Backward"
+ } else if e.EventFlags&MOUSE_HWHEELED > 0 {
+ if e.WheelDirection > 0 {
+ return "Right"
+ }
+
+ return "Left"
+ }
+
+ return ""
+}
+
+// Type ensures that MouseEventRecord satisfies EventRecord interface.
+func (e MouseEventRecord) Type() string { return "MouseEvent" }
+
+// String ensures that MouseEventRecord satisfies EventRecord and fmt.Stringer
+// interfaces.
+func (e MouseEventRecord) String() string {
+ infos := []string{e.MousePositon.String()}
+
+ if e.ButtonState&0xFF != 0 {
+ infos = append(infos, e.ButtonState.String())
+ }
+
+ eventDescription := e.EventFlags.String()
+
+ wheelDirection := e.WheelDirectionName()
+ if wheelDirection != "" {
+ eventDescription += "(" + wheelDirection + ")"
+ }
+
+ infos = append(infos, eventDescription)
+
+ if e.ControlKeyState != NO_CONTROL_KEY {
+ infos = append(infos, e.ControlKeyState.String())
+ }
+
+ return fmt.Sprintf("%s[%s]", e.Type(), strings.Join(infos, ", "))
+}
+
+// WindowBufferSizeEventType is the event type for a WindowBufferSizeEventRecord
+// (see https://docs.microsoft.com/en-us/windows/console/input-record-str).
+const WindowBufferSizeEventType EventType = 0x0004
+
+// WindowBufferSizeEventRecord represent the WINDOW_BUFFER_SIZE_RECORD structure
+// from the Windows console API (see
+// https://docs.microsoft.com/en-us/windows/console/window-buffer-size-record-str).
+type WindowBufferSizeEventRecord struct {
+ // Size contains the size of the console screen buffer, in character cell columns and rows.
+ Size Coord
+}
+
+// Ensure that WindowBufferSizeEventRecord satisfies EventRecord interface.
+var _ EventRecord = WindowBufferSizeEventRecord{}
+
+// Type ensures that WindowBufferSizeEventRecord satisfies EventRecord interface.
+func (e WindowBufferSizeEventRecord) Type() string { return "WindowBufferSizeEvent" }
+
+// String ensures that WindowBufferSizeEventRecord satisfies EventRecord and fmt.Stringer
+// interfaces.
+func (e WindowBufferSizeEventRecord) String() string {
+ return fmt.Sprintf("WindowBufferSizeEvent[%s]", e.Size)
+}
+
+// UnknownEvent is generated when the event type does not match one of the
+// following types: TypeFocusEventRecord, TypeKeyEventRecord,
+// TypeMouseEventRecord, TypeWindowBufferSizeEvent, TypeMenuEventRecord and
+// UnknownEvent.
+type UnknownEvent struct {
+ InputRecord
+}
+
+// Ensure that UnknownEvent satisfies EventRecord interface.
+var _ EventRecord = UnknownEvent{}
+
+// Type ensures that UnknownEvent satisfies EventRecord interface.
+func (e UnknownEvent) Type() string { return "UnknownEvent" }
+
+// String ensures that UnknownEvent satisfies EventRecord and fmt.Stringer
+// interfaces.
+func (e UnknownEvent) String() string {
+ return fmt.Sprintf("%s[Type: %d, Data: %v]", e.Type(), e.InputRecord.EventType, e.InputRecord.Event[:])
+}
+
+// Coord represent the COORD structure from the Windows
+// console API (see https://docs.microsoft.com/en-us/windows/console/coord-str).
+type Coord struct {
+ // X is the horizontal coordinate or column value. The units depend on the function call.
+ X uint16
+ // Y is the vertical coordinate or row value. The units depend on the function call.
+ Y uint16
+}
+
+// String ensures that Coord satisfies the fmt.Stringer interface.
+func (c Coord) String() string {
+ return fmt.Sprintf("(%d, %d)", c.X, c.Y)
+}
+
+// ButtonState holds the state of the mouse buttons (see
+// https://docs.microsoft.com/en-us/windows/console/mouse-event-record-str).
+type ButtonState uint32
+
+func (bs ButtonState) Contains(state ButtonState) bool {
+ return bs&state > 0
+}
+
+// String ensures that ButtonState satisfies the fmt.Stringer interface.
+func (bs ButtonState) String() string {
+ switch {
+ case bs&FROM_LEFT_1ST_BUTTON_PRESSED > 0:
+ return "Left"
+ case bs&FROM_LEFT_2ND_BUTTON_PRESSED > 0:
+ return "2"
+ case bs&FROM_LEFT_3RD_BUTTON_PRESSED > 0:
+ return "3"
+ case bs&FROM_LEFT_4TH_BUTTON_PRESSED > 0:
+ return "4"
+ case bs&RIGHTMOST_BUTTON_PRESSED > 0:
+ return "Right"
+ case bs&0xFF == 0:
+ return "No Button"
+ default:
+ return fmt.Sprintf("Unknown(%d)", bs)
+ }
+}
+
+func (bs ButtonState) IsReleased() bool {
+ return bs&0xff > 0
+}
+
+// Valid values for ButtonState.
+const (
+ FROM_LEFT_1ST_BUTTON_PRESSED ButtonState = 0x0001
+ RIGHTMOST_BUTTON_PRESSED ButtonState = 0x0002
+ FROM_LEFT_2ND_BUTTON_PRESSED ButtonState = 0x0004
+ FROM_LEFT_3RD_BUTTON_PRESSED ButtonState = 0x0008
+ FROM_LEFT_4TH_BUTTON_PRESSED ButtonState = 0x0010
+)
+
+// ControlKeyState holds the state of the control keys for key and mouse events
+// (see https://docs.microsoft.com/en-us/windows/console/key-event-record-str
+// and https://docs.microsoft.com/en-us/windows/console/mouse-event-record-str).
+type ControlKeyState uint32
+
+func (cks ControlKeyState) Contains(state ControlKeyState) bool {
+ return cks&state > 0
+}
+
+// Valid values for ControlKeyState.
+const (
+ CAPSLOCK_ON ControlKeyState = 0x0080
+ ENHANCED_KEY ControlKeyState = 0x0100
+ LEFT_ALT_PRESSED ControlKeyState = 0x0002
+ LEFT_CTRL_PRESSED ControlKeyState = 0x0008
+ NUMLOCK_ON ControlKeyState = 0x0020
+ RIGHT_ALT_PRESSED ControlKeyState = 0x0001
+ RIGHT_CTRL_PRESSED ControlKeyState = 0x0004
+ SCROLLLOCK_ON ControlKeyState = 0x0040
+ SHIFT_PRESSED ControlKeyState = 0x0010
+ NO_CONTROL_KEY ControlKeyState = 0x0000
+)
+
+// String ensures that ControlKeyState satisfies the fmt.Stringer interface.
+func (cks ControlKeyState) String() string {
+ controlKeys := []string{}
+
+ switch {
+ case cks&CAPSLOCK_ON > 0:
+ controlKeys = append(controlKeys, "CapsLock")
+ case cks&ENHANCED_KEY > 0:
+ controlKeys = append(controlKeys, "Enhanced")
+ case cks&LEFT_ALT_PRESSED > 0:
+ controlKeys = append(controlKeys, "Alt")
+ case cks&LEFT_CTRL_PRESSED > 0:
+ controlKeys = append(controlKeys, "CTRL")
+ case cks&NUMLOCK_ON > 0:
+ controlKeys = append(controlKeys, "NumLock")
+ case cks&RIGHT_ALT_PRESSED > 0:
+ controlKeys = append(controlKeys, "RightAlt")
+ case cks&RIGHT_CTRL_PRESSED > 0:
+ controlKeys = append(controlKeys, "RightCTRL")
+ case cks&SCROLLLOCK_ON > 0:
+ controlKeys = append(controlKeys, "ScrollLock")
+ case cks&SHIFT_PRESSED > 0:
+ controlKeys = append(controlKeys, "Shift")
+ case cks == NO_CONTROL_KEY:
+ default:
+ return fmt.Sprintf("Unknown(%d)", cks)
+ }
+
+ return strings.Join(controlKeys, ",")
+}
+
+// EventFlags specifies the type of a mouse event (see
+// https://docs.microsoft.com/en-us/windows/console/mouse-event-record-str).
+type EventFlags uint32
+
+// String ensures that EventFlags satisfies the fmt.Stringer interface.
+func (ef EventFlags) String() string {
+ switch {
+ case ef&DOUBLE_CLICK > 0:
+ return "DoubleClick"
+ case ef&MOUSE_WHEELED > 0:
+ return "Wheeled"
+ case ef&MOUSE_MOVED > 0:
+ return "Moved"
+ case ef&MOUSE_HWHEELED > 0:
+ return "HWheeld"
+ case ef == CLICK:
+ return "Click"
+ default:
+ return fmt.Sprintf("Unknown(%d)", ef)
+ }
+}
+
+func (ef EventFlags) Contains(flag EventFlags) bool {
+ return ef&flag > 0
+}
+
+// Valid values for EventFlags.
+const (
+ CLICK EventFlags = 0x0000
+ MOUSE_MOVED EventFlags = 0x0001
+ DOUBLE_CLICK EventFlags = 0x0002
+ MOUSE_WHEELED EventFlags = 0x0004
+ MOUSE_HWHEELED EventFlags = 0x0008
+)
+
+func highWord(data uint32) uint16 {
+ return uint16((data & 0xFFFF0000) >> 16)
+}
diff --git a/vendor/github.com/muesli/ansi/README.md b/vendor/github.com/muesli/ansi/README.md
index cb28c656..f9d0fe9a 100644
--- a/vendor/github.com/muesli/ansi/README.md
+++ b/vendor/github.com/muesli/ansi/README.md
@@ -1,2 +1,31 @@
# ansi
+
+[![Latest Release](https://img.shields.io/github/release/muesli/ansi.svg)](https://github.com/muesli/ansi/releases)
+[![Build Status](https://github.com/muesli/ansi/workflows/build/badge.svg)](https://github.com/muesli/ansi/actions)
+[![Coverage Status](https://coveralls.io/repos/github/muesli/ansi/badge.svg?branch=master)](https://coveralls.io/github/muesli/ansi?branch=master)
+[![Go ReportCard](https://goreportcard.com/badge/muesli/ansi)](https://goreportcard.com/report/muesli/ansi)
+[![GoDoc](https://godoc.org/github.com/golang/gddo?status.svg)](https://pkg.go.dev/github.com/muesli/ansi)
+
Raw ANSI sequence helpers
+
+## ANSI Writer
+
+```go
+import "github.com/muesli/ansi"
+
+w := ansi.Writer{Forward: os.Stdout}
+w.Write([]byte("\x1b[31mHello, world!\x1b[0m"))
+w.Close()
+```
+
+## Compressor
+
+The ANSI compressor eliminates unnecessary/redundant ANSI sequences.
+
+```go
+import "github.com/muesli/ansi/compressor"
+
+w := compressor.Writer{Forward: os.Stdout}
+w.Write([]byte("\x1b[31mHello, world!\x1b[0m"))
+w.Close()
+```
diff --git a/vendor/github.com/xo/terminfo/.gitignore b/vendor/github.com/xo/terminfo/.gitignore
new file mode 100644
index 00000000..368e0c06
--- /dev/null
+++ b/vendor/github.com/xo/terminfo/.gitignore
@@ -0,0 +1,9 @@
+/.cache/
+
+/cmd/infocmp/infocmp
+/cmd/infocmp/.out/
+
+/infocmp
+/.out/
+
+*.txt
diff --git a/vendor/github.com/xo/terminfo/LICENSE b/vendor/github.com/xo/terminfo/LICENSE
new file mode 100644
index 00000000..197dadb1
--- /dev/null
+++ b/vendor/github.com/xo/terminfo/LICENSE
@@ -0,0 +1,21 @@
+The MIT License (MIT)
+
+Copyright (c) 2016 Anmol Sethi
+
+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.
diff --git a/vendor/github.com/xo/terminfo/README.md b/vendor/github.com/xo/terminfo/README.md
new file mode 100644
index 00000000..e5002d23
--- /dev/null
+++ b/vendor/github.com/xo/terminfo/README.md
@@ -0,0 +1,139 @@
+# About terminfo [![GoDoc][1]][2]
+
+Package `terminfo` provides a pure-Go implementation of reading information
+from the terminfo database.
+
+`terminfo` is meant as a replacement for `ncurses` in simple Go programs.
+
+## Installing
+
+Install in the usual Go way:
+
+```sh
+$ go get -u github.com/xo/terminfo
+```
+
+## Using
+
+Please see the [GoDoc API listing][2] for more information on using `terminfo`.
+
+```go
+// _examples/simple/main.go
+package main
+
+import (
+ "bytes"
+ "fmt"
+ "log"
+ "os"
+ "os/signal"
+ "strings"
+ "sync"
+ "syscall"
+
+ "github.com/xo/terminfo"
+)
+
+func main() {
+ //r := rand.New(nil)
+
+ // load terminfo
+ ti, err := terminfo.LoadFromEnv()
+ if err != nil {
+ log.Fatal(err)
+ }
+
+ // cleanup
+ defer func() {
+ err := recover()
+ termreset(ti)
+ if err != nil {
+ log.Fatal(err)
+ }
+ }()
+
+ terminit(ti)
+ termtitle(ti, "simple example!")
+ termputs(ti, 3, 3, "Ctrl-C to exit")
+ maxColors := termcolors(ti)
+ if maxColors > 256 {
+ maxColors = 256
+ }
+ for i := 0; i < maxColors; i++ {
+ termputs(ti, 5+i/16, 5+i%16, ti.Colorf(i, 0, "█"))
+ }
+
+ // wait for signal
+ sigs := make(chan os.Signal, 1)
+ signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM)
+ <-sigs
+}
+
+// terminit initializes the special CA mode on the terminal, and makes the
+// cursor invisible.
+func terminit(ti *terminfo.Terminfo) {
+ buf := new(bytes.Buffer)
+ // set the cursor invisible
+ ti.Fprintf(buf, terminfo.CursorInvisible)
+ // enter special mode
+ ti.Fprintf(buf, terminfo.EnterCaMode)
+ // clear the screen
+ ti.Fprintf(buf, terminfo.ClearScreen)
+ os.Stdout.Write(buf.Bytes())
+}
+
+// termreset is the inverse of terminit.
+func termreset(ti *terminfo.Terminfo) {
+ buf := new(bytes.Buffer)
+ ti.Fprintf(buf, terminfo.ExitCaMode)
+ ti.Fprintf(buf, terminfo.CursorNormal)
+ os.Stdout.Write(buf.Bytes())
+}
+
+// termputs puts a string at row, col, interpolating v.
+func termputs(ti *terminfo.Terminfo, row, col int, s string, v ...interface{}) {
+ buf := new(bytes.Buffer)
+ ti.Fprintf(buf, terminfo.CursorAddress, row, col)
+ fmt.Fprintf(buf, s, v...)
+ os.Stdout.Write(buf.Bytes())
+}
+
+// sl is the status line terminfo.
+var sl *terminfo.Terminfo
+
+// termtitle sets the window title.
+func termtitle(ti *terminfo.Terminfo, s string) {
+ var once sync.Once
+ once.Do(func() {
+ if ti.Has(terminfo.HasStatusLine) {
+ return
+ }
+ // load the sl xterm if terminal is an xterm or has COLORTERM
+ if strings.Contains(strings.ToLower(os.Getenv("TERM")), "xterm") || os.Getenv("COLORTERM") == "truecolor" {
+ sl, _ = terminfo.Load("xterm+sl")
+ }
+ })
+ if sl != nil {
+ ti = sl
+ }
+ if !ti.Has(terminfo.HasStatusLine) {
+ return
+ }
+ buf := new(bytes.Buffer)
+ ti.Fprintf(buf, terminfo.ToStatusLine)
+ fmt.Fprint(buf, s)
+ ti.Fprintf(buf, terminfo.FromStatusLine)
+ os.Stdout.Write(buf.Bytes())
+}
+
+// termcolors returns the maximum colors available for the terminal.
+func termcolors(ti *terminfo.Terminfo) int {
+ if colors := ti.Num(terminfo.MaxColors); colors > 0 {
+ return colors
+ }
+ return int(terminfo.ColorLevelBasic)
+}
+```
+
+[1]: https://godoc.org/github.com/xo/terminfo?status.svg
+[2]: https://godoc.org/github.com/xo/terminfo
diff --git a/vendor/github.com/xo/terminfo/caps.go b/vendor/github.com/xo/terminfo/caps.go
new file mode 100644
index 00000000..e5e1d41f
--- /dev/null
+++ b/vendor/github.com/xo/terminfo/caps.go
@@ -0,0 +1,31 @@
+package terminfo
+
+// BoolCapName returns the bool capability name.
+func BoolCapName(i int) string {
+ return boolCapNames[2*i]
+}
+
+// BoolCapNameShort returns the short bool capability name.
+func BoolCapNameShort(i int) string {
+ return boolCapNames[2*i+1]
+}
+
+// NumCapName returns the num capability name.
+func NumCapName(i int) string {
+ return numCapNames[2*i]
+}
+
+// NumCapNameShort returns the short num capability name.
+func NumCapNameShort(i int) string {
+ return numCapNames[2*i+1]
+}
+
+// StringCapName returns the string capability name.
+func StringCapName(i int) string {
+ return stringCapNames[2*i]
+}
+
+// StringCapNameShort returns the short string capability name.
+func StringCapNameShort(i int) string {
+ return stringCapNames[2*i+1]
+}
diff --git a/vendor/github.com/xo/terminfo/capvals.go b/vendor/github.com/xo/terminfo/capvals.go
new file mode 100644
index 00000000..0c2274e3
--- /dev/null
+++ b/vendor/github.com/xo/terminfo/capvals.go
@@ -0,0 +1,1525 @@
+package terminfo
+
+// Code generated by gen.go. DO NOT EDIT.
+// Bool capabilities.
+const (
+ // The AutoLeftMargin [auto_left_margin, bw] bool capability indicates cub1 wraps from column 0 to last column.
+ AutoLeftMargin = iota
+ // The AutoRightMargin [auto_right_margin, am] bool capability indicates terminal has automatic margins.
+ AutoRightMargin
+ // The NoEscCtlc [no_esc_ctlc, xsb] bool capability indicates beehive (f1=escape, f2=ctrl C).
+ NoEscCtlc
+ // The CeolStandoutGlitch [ceol_standout_glitch, xhp] bool capability indicates standout not erased by overwriting (hp).
+ CeolStandoutGlitch
+ // The EatNewlineGlitch [eat_newline_glitch, xenl] bool capability indicates newline ignored after 80 cols (concept).
+ EatNewlineGlitch
+ // The EraseOverstrike [erase_overstrike, eo] bool capability indicates can erase overstrikes with a blank.
+ EraseOverstrike
+ // The GenericType [generic_type, gn] bool capability indicates generic line type.
+ GenericType
+ // The HardCopy [hard_copy, hc] bool capability indicates hardcopy terminal.
+ HardCopy
+ // The HasMetaKey [has_meta_key, km] bool capability indicates Has a meta key (i.e., sets 8th-bit).
+ HasMetaKey
+ // The HasStatusLine [has_status_line, hs] bool capability indicates has extra status line.
+ HasStatusLine
+ // The InsertNullGlitch [insert_null_glitch, in] bool capability indicates insert mode distinguishes nulls.
+ InsertNullGlitch
+ // The MemoryAbove [memory_above, da] bool capability indicates display may be retained above the screen.
+ MemoryAbove
+ // The MemoryBelow [memory_below, db] bool capability indicates display may be retained below the screen.
+ MemoryBelow
+ // The MoveInsertMode [move_insert_mode, mir] bool capability indicates safe to move while in insert mode.
+ MoveInsertMode
+ // The MoveStandoutMode [move_standout_mode, msgr] bool capability indicates safe to move while in standout mode.
+ MoveStandoutMode
+ // The OverStrike [over_strike, os] bool capability indicates terminal can overstrike.
+ OverStrike
+ // The StatusLineEscOk [status_line_esc_ok, eslok] bool capability indicates escape can be used on the status line.
+ StatusLineEscOk
+ // The DestTabsMagicSmso [dest_tabs_magic_smso, xt] bool capability indicates tabs destructive, magic so char (t1061).
+ DestTabsMagicSmso
+ // The TildeGlitch [tilde_glitch, hz] bool capability indicates cannot print ~'s (Hazeltine).
+ TildeGlitch
+ // The TransparentUnderline [transparent_underline, ul] bool capability indicates underline character overstrikes.
+ TransparentUnderline
+ // The XonXoff [xon_xoff, xon] bool capability indicates terminal uses xon/xoff handshaking.
+ XonXoff
+ // The NeedsXonXoff [needs_xon_xoff, nxon] bool capability indicates padding will not work, xon/xoff required.
+ NeedsXonXoff
+ // The PrtrSilent [prtr_silent, mc5i] bool capability indicates printer will not echo on screen.
+ PrtrSilent
+ // The HardCursor [hard_cursor, chts] bool capability indicates cursor is hard to see.
+ HardCursor
+ // The NonRevRmcup [non_rev_rmcup, nrrmc] bool capability indicates smcup does not reverse rmcup.
+ NonRevRmcup
+ // The NoPadChar [no_pad_char, npc] bool capability indicates pad character does not exist.
+ NoPadChar
+ // The NonDestScrollRegion [non_dest_scroll_region, ndscr] bool capability indicates scrolling region is non-destructive.
+ NonDestScrollRegion
+ // The CanChange [can_change, ccc] bool capability indicates terminal can re-define existing colors.
+ CanChange
+ // The BackColorErase [back_color_erase, bce] bool capability indicates screen erased with background color.
+ BackColorErase
+ // The HueLightnessSaturation [hue_lightness_saturation, hls] bool capability indicates terminal uses only HLS color notation (Tektronix).
+ HueLightnessSaturation
+ // The ColAddrGlitch [col_addr_glitch, xhpa] bool capability indicates only positive motion for hpa/mhpa caps.
+ ColAddrGlitch
+ // The CrCancelsMicroMode [cr_cancels_micro_mode, crxm] bool capability indicates using cr turns off micro mode.
+ CrCancelsMicroMode
+ // The HasPrintWheel [has_print_wheel, daisy] bool capability indicates printer needs operator to change character set.
+ HasPrintWheel
+ // The RowAddrGlitch [row_addr_glitch, xvpa] bool capability indicates only positive motion for vpa/mvpa caps.
+ RowAddrGlitch
+ // The SemiAutoRightMargin [semi_auto_right_margin, sam] bool capability indicates printing in last column causes cr.
+ SemiAutoRightMargin
+ // The CpiChangesRes [cpi_changes_res, cpix] bool capability indicates changing character pitch changes resolution.
+ CpiChangesRes
+ // The LpiChangesRes [lpi_changes_res, lpix] bool capability indicates changing line pitch changes resolution.
+ LpiChangesRes
+ // The BackspacesWithBs [backspaces_with_bs, OTbs] bool capability indicates uses ^H to move left.
+ BackspacesWithBs
+ // The CrtNoScrolling [crt_no_scrolling, OTns] bool capability indicates crt cannot scroll.
+ CrtNoScrolling
+ // The NoCorrectlyWorkingCr [no_correctly_working_cr, OTnc] bool capability indicates no way to go to start of line.
+ NoCorrectlyWorkingCr
+ // The GnuHasMetaKey [gnu_has_meta_key, OTMT] bool capability indicates has meta key.
+ GnuHasMetaKey
+ // The LinefeedIsNewline [linefeed_is_newline, OTNL] bool capability indicates move down with \n.
+ LinefeedIsNewline
+ // The HasHardwareTabs [has_hardware_tabs, OTpt] bool capability indicates has 8-char tabs invoked with ^I.
+ HasHardwareTabs
+ // The ReturnDoesClrEol [return_does_clr_eol, OTxr] bool capability indicates return clears the line.
+ ReturnDoesClrEol
+)
+
+// Num capabilities.
+const (
+ // The Columns [columns, cols] num capability is number of columns in a line.
+ Columns = iota
+ // The InitTabs [init_tabs, it] num capability is tabs initially every # spaces.
+ InitTabs
+ // The Lines [lines, lines] num capability is number of lines on screen or page.
+ Lines
+ // The LinesOfMemory [lines_of_memory, lm] num capability is lines of memory if > line. 0 means varies.
+ LinesOfMemory
+ // The MagicCookieGlitch [magic_cookie_glitch, xmc] num capability is number of blank characters left by smso or rmso.
+ MagicCookieGlitch
+ // The PaddingBaudRate [padding_baud_rate, pb] num capability is lowest baud rate where padding needed.
+ PaddingBaudRate
+ // The VirtualTerminal [virtual_terminal, vt] num capability is virtual terminal number (CB/unix).
+ VirtualTerminal
+ // The WidthStatusLine [width_status_line, wsl] num capability is number of columns in status line.
+ WidthStatusLine
+ // The NumLabels [num_labels, nlab] num capability is number of labels on screen.
+ NumLabels
+ // The LabelHeight [label_height, lh] num capability is rows in each label.
+ LabelHeight
+ // The LabelWidth [label_width, lw] num capability is columns in each label.
+ LabelWidth
+ // The MaxAttributes [max_attributes, ma] num capability is maximum combined attributes terminal can handle.
+ MaxAttributes
+ // The MaximumWindows [maximum_windows, wnum] num capability is maximum number of definable windows.
+ MaximumWindows
+ // The MaxColors [max_colors, colors] num capability is maximum number of colors on screen.
+ MaxColors
+ // The MaxPairs [max_pairs, pairs] num capability is maximum number of color-pairs on the screen.
+ MaxPairs
+ // The NoColorVideo [no_color_video, ncv] num capability is video attributes that cannot be used with colors.
+ NoColorVideo
+ // The BufferCapacity [buffer_capacity, bufsz] num capability is numbers of bytes buffered before printing.
+ BufferCapacity
+ // The DotVertSpacing [dot_vert_spacing, spinv] num capability is spacing of pins vertically in pins per inch.
+ DotVertSpacing
+ // The DotHorzSpacing [dot_horz_spacing, spinh] num capability is spacing of dots horizontally in dots per inch.
+ DotHorzSpacing
+ // The MaxMicroAddress [max_micro_address, maddr] num capability is maximum value in micro_..._address.
+ MaxMicroAddress
+ // The MaxMicroJump [max_micro_jump, mjump] num capability is maximum value in parm_..._micro.
+ MaxMicroJump
+ // The MicroColSize [micro_col_size, mcs] num capability is character step size when in micro mode.
+ MicroColSize
+ // The MicroLineSize [micro_line_size, mls] num capability is line step size when in micro mode.
+ MicroLineSize
+ // The NumberOfPins [number_of_pins, npins] num capability is numbers of pins in print-head.
+ NumberOfPins
+ // The OutputResChar [output_res_char, orc] num capability is horizontal resolution in units per line.
+ OutputResChar
+ // The OutputResLine [output_res_line, orl] num capability is vertical resolution in units per line.
+ OutputResLine
+ // The OutputResHorzInch [output_res_horz_inch, orhi] num capability is horizontal resolution in units per inch.
+ OutputResHorzInch
+ // The OutputResVertInch [output_res_vert_inch, orvi] num capability is vertical resolution in units per inch.
+ OutputResVertInch
+ // The PrintRate [print_rate, cps] num capability is print rate in characters per second.
+ PrintRate
+ // The WideCharSize [wide_char_size, widcs] num capability is character step size when in double wide mode.
+ WideCharSize
+ // The Buttons [buttons, btns] num capability is number of buttons on mouse.
+ Buttons
+ // The BitImageEntwining [bit_image_entwining, bitwin] num capability is number of passes for each bit-image row.
+ BitImageEntwining
+ // The BitImageType [bit_image_type, bitype] num capability is type of bit-image device.
+ BitImageType
+ // The MagicCookieGlitchUl [magic_cookie_glitch_ul, OTug] num capability is number of blanks left by ul.
+ MagicCookieGlitchUl
+ // The CarriageReturnDelay [carriage_return_delay, OTdC] num capability is pad needed for CR.
+ CarriageReturnDelay
+ // The NewLineDelay [new_line_delay, OTdN] num capability is pad needed for LF.
+ NewLineDelay
+ // The BackspaceDelay [backspace_delay, OTdB] num capability is padding required for ^H.
+ BackspaceDelay
+ // The HorizontalTabDelay [horizontal_tab_delay, OTdT] num capability is padding required for ^I.
+ HorizontalTabDelay
+ // The NumberOfFunctionKeys [number_of_function_keys, OTkn] num capability is count of function keys.
+ NumberOfFunctionKeys
+)
+
+// String capabilities.
+const (
+ // The BackTab [back_tab, cbt] string capability is the back tab (P).
+ BackTab = iota
+ // The Bell [bell, bel] string capability is the audible signal (bell) (P).
+ Bell
+ // The CarriageReturn [carriage_return, cr] string capability is the carriage return (P*) (P*).
+ CarriageReturn
+ // The ChangeScrollRegion [change_scroll_region, csr] string capability is the change region to line #1 to line #2 (P).
+ ChangeScrollRegion
+ // The ClearAllTabs [clear_all_tabs, tbc] string capability is the clear all tab stops (P).
+ ClearAllTabs
+ // The ClearScreen [clear_screen, clear] string capability is the clear screen and home cursor (P*).
+ ClearScreen
+ // The ClrEol [clr_eol, el] string capability is the clear to end of line (P).
+ ClrEol
+ // The ClrEos [clr_eos, ed] string capability is the clear to end of screen (P*).
+ ClrEos
+ // The ColumnAddress [column_address, hpa] string capability is the horizontal position #1, absolute (P).
+ ColumnAddress
+ // The CommandCharacter [command_character, cmdch] string capability is the terminal settable cmd character in prototype !?.
+ CommandCharacter
+ // The CursorAddress [cursor_address, cup] string capability is the move to row #1 columns #2.
+ CursorAddress
+ // The CursorDown [cursor_down, cud1] string capability is the down one line.
+ CursorDown
+ // The CursorHome [cursor_home, home] string capability is the home cursor (if no cup).
+ CursorHome
+ // The CursorInvisible [cursor_invisible, civis] string capability is the make cursor invisible.
+ CursorInvisible
+ // The CursorLeft [cursor_left, cub1] string capability is the move left one space.
+ CursorLeft
+ // The CursorMemAddress [cursor_mem_address, mrcup] string capability is the memory relative cursor addressing, move to row #1 columns #2.
+ CursorMemAddress
+ // The CursorNormal [cursor_normal, cnorm] string capability is the make cursor appear normal (undo civis/cvvis).
+ CursorNormal
+ // The CursorRight [cursor_right, cuf1] string capability is the non-destructive space (move right one space).
+ CursorRight
+ // The CursorToLl [cursor_to_ll, ll] string capability is the last line, first column (if no cup).
+ CursorToLl
+ // The CursorUp [cursor_up, cuu1] string capability is the up one line.
+ CursorUp
+ // The CursorVisible [cursor_visible, cvvis] string capability is the make cursor very visible.
+ CursorVisible
+ // The DeleteCharacter [delete_character, dch1] string capability is the delete character (P*).
+ DeleteCharacter
+ // The DeleteLine [delete_line, dl1] string capability is the delete line (P*).
+ DeleteLine
+ // The DisStatusLine [dis_status_line, dsl] string capability is the disable status line.
+ DisStatusLine
+ // The DownHalfLine [down_half_line, hd] string capability is the half a line down.
+ DownHalfLine
+ // The EnterAltCharsetMode [enter_alt_charset_mode, smacs] string capability is the start alternate character set (P).
+ EnterAltCharsetMode
+ // The EnterBlinkMode [enter_blink_mode, blink] string capability is the turn on blinking.
+ EnterBlinkMode
+ // The EnterBoldMode [enter_bold_mode, bold] string capability is the turn on bold (extra bright) mode.
+ EnterBoldMode
+ // The EnterCaMode [enter_ca_mode, smcup] string capability is the string to start programs using cup.
+ EnterCaMode
+ // The EnterDeleteMode [enter_delete_mode, smdc] string capability is the enter delete mode.
+ EnterDeleteMode
+ // The EnterDimMode [enter_dim_mode, dim] string capability is the turn on half-bright mode.
+ EnterDimMode
+ // The EnterInsertMode [enter_insert_mode, smir] string capability is the enter insert mode.
+ EnterInsertMode
+ // The EnterSecureMode [enter_secure_mode, invis] string capability is the turn on blank mode (characters invisible).
+ EnterSecureMode
+ // The EnterProtectedMode [enter_protected_mode, prot] string capability is the turn on protected mode.
+ EnterProtectedMode
+ // The EnterReverseMode [enter_reverse_mode, rev] string capability is the turn on reverse video mode.
+ EnterReverseMode
+ // The EnterStandoutMode [enter_standout_mode, smso] string capability is the begin standout mode.
+ EnterStandoutMode
+ // The EnterUnderlineMode [enter_underline_mode, smul] string capability is the begin underline mode.
+ EnterUnderlineMode
+ // The EraseChars [erase_chars, ech] string capability is the erase #1 characters (P).
+ EraseChars
+ // The ExitAltCharsetMode [exit_alt_charset_mode, rmacs] string capability is the end alternate character set (P).
+ ExitAltCharsetMode
+ // The ExitAttributeMode [exit_attribute_mode, sgr0] string capability is the turn off all attributes.
+ ExitAttributeMode
+ // The ExitCaMode [exit_ca_mode, rmcup] string capability is the strings to end programs using cup.
+ ExitCaMode
+ // The ExitDeleteMode [exit_delete_mode, rmdc] string capability is the end delete mode.
+ ExitDeleteMode
+ // The ExitInsertMode [exit_insert_mode, rmir] string capability is the exit insert mode.
+ ExitInsertMode
+ // The ExitStandoutMode [exit_standout_mode, rmso] string capability is the exit standout mode.
+ ExitStandoutMode
+ // The ExitUnderlineMode [exit_underline_mode, rmul] string capability is the exit underline mode.
+ ExitUnderlineMode
+ // The FlashScreen [flash_screen, flash] string capability is the visible bell (may not move cursor).
+ FlashScreen
+ // The FormFeed [form_feed, ff] string capability is the hardcopy terminal page eject (P*).
+ FormFeed
+ // The FromStatusLine [from_status_line, fsl] string capability is the return from status line.
+ FromStatusLine
+ // The Init1string [init_1string, is1] string capability is the initialization string.
+ Init1string
+ // The Init2string [init_2string, is2] string capability is the initialization string.
+ Init2string
+ // The Init3string [init_3string, is3] string capability is the initialization string.
+ Init3string
+ // The InitFile [init_file, if] string capability is the name of initialization file.
+ InitFile
+ // The InsertCharacter [insert_character, ich1] string capability is the insert character (P).
+ InsertCharacter
+ // The InsertLine [insert_line, il1] string capability is the insert line (P*).
+ InsertLine
+ // The InsertPadding [insert_padding, ip] string capability is the insert padding after inserted character.
+ InsertPadding
+ // The KeyBackspace [key_backspace, kbs] string capability is the backspace key.
+ KeyBackspace
+ // The KeyCatab [key_catab, ktbc] string capability is the clear-all-tabs key.
+ KeyCatab
+ // The KeyClear [key_clear, kclr] string capability is the clear-screen or erase key.
+ KeyClear
+ // The KeyCtab [key_ctab, kctab] string capability is the clear-tab key.
+ KeyCtab
+ // The KeyDc [key_dc, kdch1] string capability is the delete-character key.
+ KeyDc
+ // The KeyDl [key_dl, kdl1] string capability is the delete-line key.
+ KeyDl
+ // The KeyDown [key_down, kcud1] string capability is the down-arrow key.
+ KeyDown
+ // The KeyEic [key_eic, krmir] string capability is the sent by rmir or smir in insert mode.
+ KeyEic
+ // The KeyEol [key_eol, kel] string capability is the clear-to-end-of-line key.
+ KeyEol
+ // The KeyEos [key_eos, ked] string capability is the clear-to-end-of-screen key.
+ KeyEos
+ // The KeyF0 [key_f0, kf0] string capability is the F0 function key.
+ KeyF0
+ // The KeyF1 [key_f1, kf1] string capability is the F1 function key.
+ KeyF1
+ // The KeyF10 [key_f10, kf10] string capability is the F10 function key.
+ KeyF10
+ // The KeyF2 [key_f2, kf2] string capability is the F2 function key.
+ KeyF2
+ // The KeyF3 [key_f3, kf3] string capability is the F3 function key.
+ KeyF3
+ // The KeyF4 [key_f4, kf4] string capability is the F4 function key.
+ KeyF4
+ // The KeyF5 [key_f5, kf5] string capability is the F5 function key.
+ KeyF5
+ // The KeyF6 [key_f6, kf6] string capability is the F6 function key.
+ KeyF6
+ // The KeyF7 [key_f7, kf7] string capability is the F7 function key.
+ KeyF7
+ // The KeyF8 [key_f8, kf8] string capability is the F8 function key.
+ KeyF8
+ // The KeyF9 [key_f9, kf9] string capability is the F9 function key.
+ KeyF9
+ // The KeyHome [key_home, khome] string capability is the home key.
+ KeyHome
+ // The KeyIc [key_ic, kich1] string capability is the insert-character key.
+ KeyIc
+ // The KeyIl [key_il, kil1] string capability is the insert-line key.
+ KeyIl
+ // The KeyLeft [key_left, kcub1] string capability is the left-arrow key.
+ KeyLeft
+ // The KeyLl [key_ll, kll] string capability is the lower-left key (home down).
+ KeyLl
+ // The KeyNpage [key_npage, knp] string capability is the next-page key.
+ KeyNpage
+ // The KeyPpage [key_ppage, kpp] string capability is the previous-page key.
+ KeyPpage
+ // The KeyRight [key_right, kcuf1] string capability is the right-arrow key.
+ KeyRight
+ // The KeySf [key_sf, kind] string capability is the scroll-forward key.
+ KeySf
+ // The KeySr [key_sr, kri] string capability is the scroll-backward key.
+ KeySr
+ // The KeyStab [key_stab, khts] string capability is the set-tab key.
+ KeyStab
+ // The KeyUp [key_up, kcuu1] string capability is the up-arrow key.
+ KeyUp
+ // The KeypadLocal [keypad_local, rmkx] string capability is the leave 'keyboard_transmit' mode.
+ KeypadLocal
+ // The KeypadXmit [keypad_xmit, smkx] string capability is the enter 'keyboard_transmit' mode.
+ KeypadXmit
+ // The LabF0 [lab_f0, lf0] string capability is the label on function key f0 if not f0.
+ LabF0
+ // The LabF1 [lab_f1, lf1] string capability is the label on function key f1 if not f1.
+ LabF1
+ // The LabF10 [lab_f10, lf10] string capability is the label on function key f10 if not f10.
+ LabF10
+ // The LabF2 [lab_f2, lf2] string capability is the label on function key f2 if not f2.
+ LabF2
+ // The LabF3 [lab_f3, lf3] string capability is the label on function key f3 if not f3.
+ LabF3
+ // The LabF4 [lab_f4, lf4] string capability is the label on function key f4 if not f4.
+ LabF4
+ // The LabF5 [lab_f5, lf5] string capability is the label on function key f5 if not f5.
+ LabF5
+ // The LabF6 [lab_f6, lf6] string capability is the label on function key f6 if not f6.
+ LabF6
+ // The LabF7 [lab_f7, lf7] string capability is the label on function key f7 if not f7.
+ LabF7
+ // The LabF8 [lab_f8, lf8] string capability is the label on function key f8 if not f8.
+ LabF8
+ // The LabF9 [lab_f9, lf9] string capability is the label on function key f9 if not f9.
+ LabF9
+ // The MetaOff [meta_off, rmm] string capability is the turn off meta mode.
+ MetaOff
+ // The MetaOn [meta_on, smm] string capability is the turn on meta mode (8th-bit on).
+ MetaOn
+ // The Newline [newline, nel] string capability is the newline (behave like cr followed by lf).
+ Newline
+ // The PadChar [pad_char, pad] string capability is the padding char (instead of null).
+ PadChar
+ // The ParmDch [parm_dch, dch] string capability is the delete #1 characters (P*).
+ ParmDch
+ // The ParmDeleteLine [parm_delete_line, dl] string capability is the delete #1 lines (P*).
+ ParmDeleteLine
+ // The ParmDownCursor [parm_down_cursor, cud] string capability is the down #1 lines (P*).
+ ParmDownCursor
+ // The ParmIch [parm_ich, ich] string capability is the insert #1 characters (P*).
+ ParmIch
+ // The ParmIndex [parm_index, indn] string capability is the scroll forward #1 lines (P).
+ ParmIndex
+ // The ParmInsertLine [parm_insert_line, il] string capability is the insert #1 lines (P*).
+ ParmInsertLine
+ // The ParmLeftCursor [parm_left_cursor, cub] string capability is the move #1 characters to the left (P).
+ ParmLeftCursor
+ // The ParmRightCursor [parm_right_cursor, cuf] string capability is the move #1 characters to the right (P*).
+ ParmRightCursor
+ // The ParmRindex [parm_rindex, rin] string capability is the scroll back #1 lines (P).
+ ParmRindex
+ // The ParmUpCursor [parm_up_cursor, cuu] string capability is the up #1 lines (P*).
+ ParmUpCursor
+ // The PkeyKey [pkey_key, pfkey] string capability is the program function key #1 to type string #2.
+ PkeyKey
+ // The PkeyLocal [pkey_local, pfloc] string capability is the program function key #1 to execute string #2.
+ PkeyLocal
+ // The PkeyXmit [pkey_xmit, pfx] string capability is the program function key #1 to transmit string #2.
+ PkeyXmit
+ // The PrintScreen [print_screen, mc0] string capability is the print contents of screen.
+ PrintScreen
+ // The PrtrOff [prtr_off, mc4] string capability is the turn off printer.
+ PrtrOff
+ // The PrtrOn [prtr_on, mc5] string capability is the turn on printer.
+ PrtrOn
+ // The RepeatChar [repeat_char, rep] string capability is the repeat char #1 #2 times (P*).
+ RepeatChar
+ // The Reset1string [reset_1string, rs1] string capability is the reset string.
+ Reset1string
+ // The Reset2string [reset_2string, rs2] string capability is the reset string.
+ Reset2string
+ // The Reset3string [reset_3string, rs3] string capability is the reset string.
+ Reset3string
+ // The ResetFile [reset_file, rf] string capability is the name of reset file.
+ ResetFile
+ // The RestoreCursor [restore_cursor, rc] string capability is the restore cursor to position of last save_cursor.
+ RestoreCursor
+ // The RowAddress [row_address, vpa] string capability is the vertical position #1 absolute (P).
+ RowAddress
+ // The SaveCursor [save_cursor, sc] string capability is the save current cursor position (P).
+ SaveCursor
+ // The ScrollForward [scroll_forward, ind] string capability is the scroll text up (P).
+ ScrollForward
+ // The ScrollReverse [scroll_reverse, ri] string capability is the scroll text down (P).
+ ScrollReverse
+ // The SetAttributes [set_attributes, sgr] string capability is the define video attributes #1-#9 (PG9).
+ SetAttributes
+ // The SetTab [set_tab, hts] string capability is the set a tab in every row, current columns.
+ SetTab
+ // The SetWindow [set_window, wind] string capability is the current window is lines #1-#2 cols #3-#4.
+ SetWindow
+ // The Tab [tab, ht] string capability is the tab to next 8-space hardware tab stop.
+ Tab
+ // The ToStatusLine [to_status_line, tsl] string capability is the move to status line, column #1.
+ ToStatusLine
+ // The UnderlineChar [underline_char, uc] string capability is the underline char and move past it.
+ UnderlineChar
+ // The UpHalfLine [up_half_line, hu] string capability is the half a line up.
+ UpHalfLine
+ // The InitProg [init_prog, iprog] string capability is the path name of program for initialization.
+ InitProg
+ // The KeyA1 [key_a1, ka1] string capability is the upper left of keypad.
+ KeyA1
+ // The KeyA3 [key_a3, ka3] string capability is the upper right of keypad.
+ KeyA3
+ // The KeyB2 [key_b2, kb2] string capability is the center of keypad.
+ KeyB2
+ // The KeyC1 [key_c1, kc1] string capability is the lower left of keypad.
+ KeyC1
+ // The KeyC3 [key_c3, kc3] string capability is the lower right of keypad.
+ KeyC3
+ // The PrtrNon [prtr_non, mc5p] string capability is the turn on printer for #1 bytes.
+ PrtrNon
+ // The CharPadding [char_padding, rmp] string capability is the like ip but when in insert mode.
+ CharPadding
+ // The AcsChars [acs_chars, acsc] string capability is the graphics charset pairs, based on vt100.
+ AcsChars
+ // The PlabNorm [plab_norm, pln] string capability is the program label #1 to show string #2.
+ PlabNorm
+ // The KeyBtab [key_btab, kcbt] string capability is the back-tab key.
+ KeyBtab
+ // The EnterXonMode [enter_xon_mode, smxon] string capability is the turn on xon/xoff handshaking.
+ EnterXonMode
+ // The ExitXonMode [exit_xon_mode, rmxon] string capability is the turn off xon/xoff handshaking.
+ ExitXonMode
+ // The EnterAmMode [enter_am_mode, smam] string capability is the turn on automatic margins.
+ EnterAmMode
+ // The ExitAmMode [exit_am_mode, rmam] string capability is the turn off automatic margins.
+ ExitAmMode
+ // The XonCharacter [xon_character, xonc] string capability is the XON character.
+ XonCharacter
+ // The XoffCharacter [xoff_character, xoffc] string capability is the XOFF character.
+ XoffCharacter
+ // The EnaAcs [ena_acs, enacs] string capability is the enable alternate char set.
+ EnaAcs
+ // The LabelOn [label_on, smln] string capability is the turn on soft labels.
+ LabelOn
+ // The LabelOff [label_off, rmln] string capability is the turn off soft labels.
+ LabelOff
+ // The KeyBeg [key_beg, kbeg] string capability is the begin key.
+ KeyBeg
+ // The KeyCancel [key_cancel, kcan] string capability is the cancel key.
+ KeyCancel
+ // The KeyClose [key_close, kclo] string capability is the close key.
+ KeyClose
+ // The KeyCommand [key_command, kcmd] string capability is the command key.
+ KeyCommand
+ // The KeyCopy [key_copy, kcpy] string capability is the copy key.
+ KeyCopy
+ // The KeyCreate [key_create, kcrt] string capability is the create key.
+ KeyCreate
+ // The KeyEnd [key_end, kend] string capability is the end key.
+ KeyEnd
+ // The KeyEnter [key_enter, kent] string capability is the enter/send key.
+ KeyEnter
+ // The KeyExit [key_exit, kext] string capability is the exit key.
+ KeyExit
+ // The KeyFind [key_find, kfnd] string capability is the find key.
+ KeyFind
+ // The KeyHelp [key_help, khlp] string capability is the help key.
+ KeyHelp
+ // The KeyMark [key_mark, kmrk] string capability is the mark key.
+ KeyMark
+ // The KeyMessage [key_message, kmsg] string capability is the message key.
+ KeyMessage
+ // The KeyMove [key_move, kmov] string capability is the move key.
+ KeyMove
+ // The KeyNext [key_next, knxt] string capability is the next key.
+ KeyNext
+ // The KeyOpen [key_open, kopn] string capability is the open key.
+ KeyOpen
+ // The KeyOptions [key_options, kopt] string capability is the options key.
+ KeyOptions
+ // The KeyPrevious [key_previous, kprv] string capability is the previous key.
+ KeyPrevious
+ // The KeyPrint [key_print, kprt] string capability is the print key.
+ KeyPrint
+ // The KeyRedo [key_redo, krdo] string capability is the redo key.
+ KeyRedo
+ // The KeyReference [key_reference, kref] string capability is the reference key.
+ KeyReference
+ // The KeyRefresh [key_refresh, krfr] string capability is the refresh key.
+ KeyRefresh
+ // The KeyReplace [key_replace, krpl] string capability is the replace key.
+ KeyReplace
+ // The KeyRestart [key_restart, krst] string capability is the restart key.
+ KeyRestart
+ // The KeyResume [key_resume, kres] string capability is the resume key.
+ KeyResume
+ // The KeySave [key_save, ksav] string capability is the save key.
+ KeySave
+ // The KeySuspend [key_suspend, kspd] string capability is the suspend key.
+ KeySuspend
+ // The KeyUndo [key_undo, kund] string capability is the undo key.
+ KeyUndo
+ // The KeySbeg [key_sbeg, kBEG] string capability is the shifted begin key.
+ KeySbeg
+ // The KeyScancel [key_scancel, kCAN] string capability is the shifted cancel key.
+ KeyScancel
+ // The KeyScommand [key_scommand, kCMD] string capability is the shifted command key.
+ KeyScommand
+ // The KeyScopy [key_scopy, kCPY] string capability is the shifted copy key.
+ KeyScopy
+ // The KeyScreate [key_screate, kCRT] string capability is the shifted create key.
+ KeyScreate
+ // The KeySdc [key_sdc, kDC] string capability is the shifted delete-character key.
+ KeySdc
+ // The KeySdl [key_sdl, kDL] string capability is the shifted delete-line key.
+ KeySdl
+ // The KeySelect [key_select, kslt] string capability is the select key.
+ KeySelect
+ // The KeySend [key_send, kEND] string capability is the shifted end key.
+ KeySend
+ // The KeySeol [key_seol, kEOL] string capability is the shifted clear-to-end-of-line key.
+ KeySeol
+ // The KeySexit [key_sexit, kEXT] string capability is the shifted exit key.
+ KeySexit
+ // The KeySfind [key_sfind, kFND] string capability is the shifted find key.
+ KeySfind
+ // The KeyShelp [key_shelp, kHLP] string capability is the shifted help key.
+ KeyShelp
+ // The KeyShome [key_shome, kHOM] string capability is the shifted home key.
+ KeyShome
+ // The KeySic [key_sic, kIC] string capability is the shifted insert-character key.
+ KeySic
+ // The KeySleft [key_sleft, kLFT] string capability is the shifted left-arrow key.
+ KeySleft
+ // The KeySmessage [key_smessage, kMSG] string capability is the shifted message key.
+ KeySmessage
+ // The KeySmove [key_smove, kMOV] string capability is the shifted move key.
+ KeySmove
+ // The KeySnext [key_snext, kNXT] string capability is the shifted next key.
+ KeySnext
+ // The KeySoptions [key_soptions, kOPT] string capability is the shifted options key.
+ KeySoptions
+ // The KeySprevious [key_sprevious, kPRV] string capability is the shifted previous key.
+ KeySprevious
+ // The KeySprint [key_sprint, kPRT] string capability is the shifted print key.
+ KeySprint
+ // The KeySredo [key_sredo, kRDO] string capability is the shifted redo key.
+ KeySredo
+ // The KeySreplace [key_sreplace, kRPL] string capability is the shifted replace key.
+ KeySreplace
+ // The KeySright [key_sright, kRIT] string capability is the shifted right-arrow key.
+ KeySright
+ // The KeySrsume [key_srsume, kRES] string capability is the shifted resume key.
+ KeySrsume
+ // The KeySsave [key_ssave, kSAV] string capability is the shifted save key.
+ KeySsave
+ // The KeySsuspend [key_ssuspend, kSPD] string capability is the shifted suspend key.
+ KeySsuspend
+ // The KeySundo [key_sundo, kUND] string capability is the shifted undo key.
+ KeySundo
+ // The ReqForInput [req_for_input, rfi] string capability is the send next input char (for ptys).
+ ReqForInput
+ // The KeyF11 [key_f11, kf11] string capability is the F11 function key.
+ KeyF11
+ // The KeyF12 [key_f12, kf12] string capability is the F12 function key.
+ KeyF12
+ // The KeyF13 [key_f13, kf13] string capability is the F13 function key.
+ KeyF13
+ // The KeyF14 [key_f14, kf14] string capability is the F14 function key.
+ KeyF14
+ // The KeyF15 [key_f15, kf15] string capability is the F15 function key.
+ KeyF15
+ // The KeyF16 [key_f16, kf16] string capability is the F16 function key.
+ KeyF16
+ // The KeyF17 [key_f17, kf17] string capability is the F17 function key.
+ KeyF17
+ // The KeyF18 [key_f18, kf18] string capability is the F18 function key.
+ KeyF18
+ // The KeyF19 [key_f19, kf19] string capability is the F19 function key.
+ KeyF19
+ // The KeyF20 [key_f20, kf20] string capability is the F20 function key.
+ KeyF20
+ // The KeyF21 [key_f21, kf21] string capability is the F21 function key.
+ KeyF21
+ // The KeyF22 [key_f22, kf22] string capability is the F22 function key.
+ KeyF22
+ // The KeyF23 [key_f23, kf23] string capability is the F23 function key.
+ KeyF23
+ // The KeyF24 [key_f24, kf24] string capability is the F24 function key.
+ KeyF24
+ // The KeyF25 [key_f25, kf25] string capability is the F25 function key.
+ KeyF25
+ // The KeyF26 [key_f26, kf26] string capability is the F26 function key.
+ KeyF26
+ // The KeyF27 [key_f27, kf27] string capability is the F27 function key.
+ KeyF27
+ // The KeyF28 [key_f28, kf28] string capability is the F28 function key.
+ KeyF28
+ // The KeyF29 [key_f29, kf29] string capability is the F29 function key.
+ KeyF29
+ // The KeyF30 [key_f30, kf30] string capability is the F30 function key.
+ KeyF30
+ // The KeyF31 [key_f31, kf31] string capability is the F31 function key.
+ KeyF31
+ // The KeyF32 [key_f32, kf32] string capability is the F32 function key.
+ KeyF32
+ // The KeyF33 [key_f33, kf33] string capability is the F33 function key.
+ KeyF33
+ // The KeyF34 [key_f34, kf34] string capability is the F34 function key.
+ KeyF34
+ // The KeyF35 [key_f35, kf35] string capability is the F35 function key.
+ KeyF35
+ // The KeyF36 [key_f36, kf36] string capability is the F36 function key.
+ KeyF36
+ // The KeyF37 [key_f37, kf37] string capability is the F37 function key.
+ KeyF37
+ // The KeyF38 [key_f38, kf38] string capability is the F38 function key.
+ KeyF38
+ // The KeyF39 [key_f39, kf39] string capability is the F39 function key.
+ KeyF39
+ // The KeyF40 [key_f40, kf40] string capability is the F40 function key.
+ KeyF40
+ // The KeyF41 [key_f41, kf41] string capability is the F41 function key.
+ KeyF41
+ // The KeyF42 [key_f42, kf42] string capability is the F42 function key.
+ KeyF42
+ // The KeyF43 [key_f43, kf43] string capability is the F43 function key.
+ KeyF43
+ // The KeyF44 [key_f44, kf44] string capability is the F44 function key.
+ KeyF44
+ // The KeyF45 [key_f45, kf45] string capability is the F45 function key.
+ KeyF45
+ // The KeyF46 [key_f46, kf46] string capability is the F46 function key.
+ KeyF46
+ // The KeyF47 [key_f47, kf47] string capability is the F47 function key.
+ KeyF47
+ // The KeyF48 [key_f48, kf48] string capability is the F48 function key.
+ KeyF48
+ // The KeyF49 [key_f49, kf49] string capability is the F49 function key.
+ KeyF49
+ // The KeyF50 [key_f50, kf50] string capability is the F50 function key.
+ KeyF50
+ // The KeyF51 [key_f51, kf51] string capability is the F51 function key.
+ KeyF51
+ // The KeyF52 [key_f52, kf52] string capability is the F52 function key.
+ KeyF52
+ // The KeyF53 [key_f53, kf53] string capability is the F53 function key.
+ KeyF53
+ // The KeyF54 [key_f54, kf54] string capability is the F54 function key.
+ KeyF54
+ // The KeyF55 [key_f55, kf55] string capability is the F55 function key.
+ KeyF55
+ // The KeyF56 [key_f56, kf56] string capability is the F56 function key.
+ KeyF56
+ // The KeyF57 [key_f57, kf57] string capability is the F57 function key.
+ KeyF57
+ // The KeyF58 [key_f58, kf58] string capability is the F58 function key.
+ KeyF58
+ // The KeyF59 [key_f59, kf59] string capability is the F59 function key.
+ KeyF59
+ // The KeyF60 [key_f60, kf60] string capability is the F60 function key.
+ KeyF60
+ // The KeyF61 [key_f61, kf61] string capability is the F61 function key.
+ KeyF61
+ // The KeyF62 [key_f62, kf62] string capability is the F62 function key.
+ KeyF62
+ // The KeyF63 [key_f63, kf63] string capability is the F63 function key.
+ KeyF63
+ // The ClrBol [clr_bol, el1] string capability is the Clear to beginning of line.
+ ClrBol
+ // The ClearMargins [clear_margins, mgc] string capability is the clear right and left soft margins.
+ ClearMargins
+ // The SetLeftMargin [set_left_margin, smgl] string capability is the set left soft margin at current column. (ML is not in BSD termcap).
+ SetLeftMargin
+ // The SetRightMargin [set_right_margin, smgr] string capability is the set right soft margin at current column.
+ SetRightMargin
+ // The LabelFormat [label_format, fln] string capability is the label format.
+ LabelFormat
+ // The SetClock [set_clock, sclk] string capability is the set clock, #1 hrs #2 mins #3 secs.
+ SetClock
+ // The DisplayClock [display_clock, dclk] string capability is the display clock.
+ DisplayClock
+ // The RemoveClock [remove_clock, rmclk] string capability is the remove clock.
+ RemoveClock
+ // The CreateWindow [create_window, cwin] string capability is the define a window #1 from #2,#3 to #4,#5.
+ CreateWindow
+ // The GotoWindow [goto_window, wingo] string capability is the go to window #1.
+ GotoWindow
+ // The Hangup [hangup, hup] string capability is the hang-up phone.
+ Hangup
+ // The DialPhone [dial_phone, dial] string capability is the dial number #1.
+ DialPhone
+ // The QuickDial [quick_dial, qdial] string capability is the dial number #1 without checking.
+ QuickDial
+ // The Tone [tone, tone] string capability is the select touch tone dialing.
+ Tone
+ // The Pulse [pulse, pulse] string capability is the select pulse dialing.
+ Pulse
+ // The FlashHook [flash_hook, hook] string capability is the flash switch hook.
+ FlashHook
+ // The FixedPause [fixed_pause, pause] string capability is the pause for 2-3 seconds.
+ FixedPause
+ // The WaitTone [wait_tone, wait] string capability is the wait for dial-tone.
+ WaitTone
+ // The User0 [user0, u0] string capability is the User string #0.
+ User0
+ // The User1 [user1, u1] string capability is the User string #1.
+ User1
+ // The User2 [user2, u2] string capability is the User string #2.
+ User2
+ // The User3 [user3, u3] string capability is the User string #3.
+ User3
+ // The User4 [user4, u4] string capability is the User string #4.
+ User4
+ // The User5 [user5, u5] string capability is the User string #5.
+ User5
+ // The User6 [user6, u6] string capability is the User string #6.
+ User6
+ // The User7 [user7, u7] string capability is the User string #7.
+ User7
+ // The User8 [user8, u8] string capability is the User string #8.
+ User8
+ // The User9 [user9, u9] string capability is the User string #9.
+ User9
+ // The OrigPair [orig_pair, op] string capability is the Set default pair to its original value.
+ OrigPair
+ // The OrigColors [orig_colors, oc] string capability is the Set all color pairs to the original ones.
+ OrigColors
+ // The InitializeColor [initialize_color, initc] string capability is the initialize color #1 to (#2,#3,#4).
+ InitializeColor
+ // The InitializePair [initialize_pair, initp] string capability is the Initialize color pair #1 to fg=(#2,#3,#4), bg=(#5,#6,#7).
+ InitializePair
+ // The SetColorPair [set_color_pair, scp] string capability is the Set current color pair to #1.
+ SetColorPair
+ // The SetForeground [set_foreground, setf] string capability is the Set foreground color #1.
+ SetForeground
+ // The SetBackground [set_background, setb] string capability is the Set background color #1.
+ SetBackground
+ // The ChangeCharPitch [change_char_pitch, cpi] string capability is the Change number of characters per inch to #1.
+ ChangeCharPitch
+ // The ChangeLinePitch [change_line_pitch, lpi] string capability is the Change number of lines per inch to #1.
+ ChangeLinePitch
+ // The ChangeResHorz [change_res_horz, chr] string capability is the Change horizontal resolution to #1.
+ ChangeResHorz
+ // The ChangeResVert [change_res_vert, cvr] string capability is the Change vertical resolution to #1.
+ ChangeResVert
+ // The DefineChar [define_char, defc] string capability is the Define a character #1, #2 dots wide, descender #3.
+ DefineChar
+ // The EnterDoublewideMode [enter_doublewide_mode, swidm] string capability is the Enter double-wide mode.
+ EnterDoublewideMode
+ // The EnterDraftQuality [enter_draft_quality, sdrfq] string capability is the Enter draft-quality mode.
+ EnterDraftQuality
+ // The EnterItalicsMode [enter_italics_mode, sitm] string capability is the Enter italic mode.
+ EnterItalicsMode
+ // The EnterLeftwardMode [enter_leftward_mode, slm] string capability is the Start leftward carriage motion.
+ EnterLeftwardMode
+ // The EnterMicroMode [enter_micro_mode, smicm] string capability is the Start micro-motion mode.
+ EnterMicroMode
+ // The EnterNearLetterQuality [enter_near_letter_quality, snlq] string capability is the Enter NLQ mode.
+ EnterNearLetterQuality
+ // The EnterNormalQuality [enter_normal_quality, snrmq] string capability is the Enter normal-quality mode.
+ EnterNormalQuality
+ // The EnterShadowMode [enter_shadow_mode, sshm] string capability is the Enter shadow-print mode.
+ EnterShadowMode
+ // The EnterSubscriptMode [enter_subscript_mode, ssubm] string capability is the Enter subscript mode.
+ EnterSubscriptMode
+ // The EnterSuperscriptMode [enter_superscript_mode, ssupm] string capability is the Enter superscript mode.
+ EnterSuperscriptMode
+ // The EnterUpwardMode [enter_upward_mode, sum] string capability is the Start upward carriage motion.
+ EnterUpwardMode
+ // The ExitDoublewideMode [exit_doublewide_mode, rwidm] string capability is the End double-wide mode.
+ ExitDoublewideMode
+ // The ExitItalicsMode [exit_italics_mode, ritm] string capability is the End italic mode.
+ ExitItalicsMode
+ // The ExitLeftwardMode [exit_leftward_mode, rlm] string capability is the End left-motion mode.
+ ExitLeftwardMode
+ // The ExitMicroMode [exit_micro_mode, rmicm] string capability is the End micro-motion mode.
+ ExitMicroMode
+ // The ExitShadowMode [exit_shadow_mode, rshm] string capability is the End shadow-print mode.
+ ExitShadowMode
+ // The ExitSubscriptMode [exit_subscript_mode, rsubm] string capability is the End subscript mode.
+ ExitSubscriptMode
+ // The ExitSuperscriptMode [exit_superscript_mode, rsupm] string capability is the End superscript mode.
+ ExitSuperscriptMode
+ // The ExitUpwardMode [exit_upward_mode, rum] string capability is the End reverse character motion.
+ ExitUpwardMode
+ // The MicroColumnAddress [micro_column_address, mhpa] string capability is the Like column_address in micro mode.
+ MicroColumnAddress
+ // The MicroDown [micro_down, mcud1] string capability is the Like cursor_down in micro mode.
+ MicroDown
+ // The MicroLeft [micro_left, mcub1] string capability is the Like cursor_left in micro mode.
+ MicroLeft
+ // The MicroRight [micro_right, mcuf1] string capability is the Like cursor_right in micro mode.
+ MicroRight
+ // The MicroRowAddress [micro_row_address, mvpa] string capability is the Like row_address #1 in micro mode.
+ MicroRowAddress
+ // The MicroUp [micro_up, mcuu1] string capability is the Like cursor_up in micro mode.
+ MicroUp
+ // The OrderOfPins [order_of_pins, porder] string capability is the Match software bits to print-head pins.
+ OrderOfPins
+ // The ParmDownMicro [parm_down_micro, mcud] string capability is the Like parm_down_cursor in micro mode.
+ ParmDownMicro
+ // The ParmLeftMicro [parm_left_micro, mcub] string capability is the Like parm_left_cursor in micro mode.
+ ParmLeftMicro
+ // The ParmRightMicro [parm_right_micro, mcuf] string capability is the Like parm_right_cursor in micro mode.
+ ParmRightMicro
+ // The ParmUpMicro [parm_up_micro, mcuu] string capability is the Like parm_up_cursor in micro mode.
+ ParmUpMicro
+ // The SelectCharSet [select_char_set, scs] string capability is the Select character set, #1.
+ SelectCharSet
+ // The SetBottomMargin [set_bottom_margin, smgb] string capability is the Set bottom margin at current line.
+ SetBottomMargin
+ // The SetBottomMarginParm [set_bottom_margin_parm, smgbp] string capability is the Set bottom margin at line #1 or (if smgtp is not given) #2 lines from bottom.
+ SetBottomMarginParm
+ // The SetLeftMarginParm [set_left_margin_parm, smglp] string capability is the Set left (right) margin at column #1.
+ SetLeftMarginParm
+ // The SetRightMarginParm [set_right_margin_parm, smgrp] string capability is the Set right margin at column #1.
+ SetRightMarginParm
+ // The SetTopMargin [set_top_margin, smgt] string capability is the Set top margin at current line.
+ SetTopMargin
+ // The SetTopMarginParm [set_top_margin_parm, smgtp] string capability is the Set top (bottom) margin at row #1.
+ SetTopMarginParm
+ // The StartBitImage [start_bit_image, sbim] string capability is the Start printing bit image graphics.
+ StartBitImage
+ // The StartCharSetDef [start_char_set_def, scsd] string capability is the Start character set definition #1, with #2 characters in the set.
+ StartCharSetDef
+ // The StopBitImage [stop_bit_image, rbim] string capability is the Stop printing bit image graphics.
+ StopBitImage
+ // The StopCharSetDef [stop_char_set_def, rcsd] string capability is the End definition of character set #1.
+ StopCharSetDef
+ // The SubscriptCharacters [subscript_characters, subcs] string capability is the List of subscriptable characters.
+ SubscriptCharacters
+ // The SuperscriptCharacters [superscript_characters, supcs] string capability is the List of superscriptable characters.
+ SuperscriptCharacters
+ // The TheseCauseCr [these_cause_cr, docr] string capability is the Printing any of these characters causes CR.
+ TheseCauseCr
+ // The ZeroMotion [zero_motion, zerom] string capability is the No motion for subsequent character.
+ ZeroMotion
+ // The CharSetNames [char_set_names, csnm] string capability is the Produce #1'th item from list of character set names.
+ CharSetNames
+ // The KeyMouse [key_mouse, kmous] string capability is the Mouse event has occurred.
+ KeyMouse
+ // The MouseInfo [mouse_info, minfo] string capability is the Mouse status information.
+ MouseInfo
+ // The ReqMousePos [req_mouse_pos, reqmp] string capability is the Request mouse position.
+ ReqMousePos
+ // The GetMouse [get_mouse, getm] string capability is the Curses should get button events, parameter #1 not documented.
+ GetMouse
+ // The SetAForeground [set_a_foreground, setaf] string capability is the Set foreground color to #1, using ANSI escape.
+ SetAForeground
+ // The SetABackground [set_a_background, setab] string capability is the Set background color to #1, using ANSI escape.
+ SetABackground
+ // The PkeyPlab [pkey_plab, pfxl] string capability is the Program function key #1 to type string #2 and show string #3.
+ PkeyPlab
+ // The DeviceType [device_type, devt] string capability is the Indicate language/codeset support.
+ DeviceType
+ // The CodeSetInit [code_set_init, csin] string capability is the Init sequence for multiple codesets.
+ CodeSetInit
+ // The Set0DesSeq [set0_des_seq, s0ds] string capability is the Shift to codeset 0 (EUC set 0, ASCII).
+ Set0DesSeq
+ // The Set1DesSeq [set1_des_seq, s1ds] string capability is the Shift to codeset 1.
+ Set1DesSeq
+ // The Set2DesSeq [set2_des_seq, s2ds] string capability is the Shift to codeset 2.
+ Set2DesSeq
+ // The Set3DesSeq [set3_des_seq, s3ds] string capability is the Shift to codeset 3.
+ Set3DesSeq
+ // The SetLrMargin [set_lr_margin, smglr] string capability is the Set both left and right margins to #1, #2. (ML is not in BSD termcap).
+ SetLrMargin
+ // The SetTbMargin [set_tb_margin, smgtb] string capability is the Sets both top and bottom margins to #1, #2.
+ SetTbMargin
+ // The BitImageRepeat [bit_image_repeat, birep] string capability is the Repeat bit image cell #1 #2 times.
+ BitImageRepeat
+ // The BitImageNewline [bit_image_newline, binel] string capability is the Move to next row of the bit image.
+ BitImageNewline
+ // The BitImageCarriageReturn [bit_image_carriage_return, bicr] string capability is the Move to beginning of same row.
+ BitImageCarriageReturn
+ // The ColorNames [color_names, colornm] string capability is the Give name for color #1.
+ ColorNames
+ // The DefineBitImageRegion [define_bit_image_region, defbi] string capability is the Define rectangular bit image region.
+ DefineBitImageRegion
+ // The EndBitImageRegion [end_bit_image_region, endbi] string capability is the End a bit-image region.
+ EndBitImageRegion
+ // The SetColorBand [set_color_band, setcolor] string capability is the Change to ribbon color #1.
+ SetColorBand
+ // The SetPageLength [set_page_length, slines] string capability is the Set page length to #1 lines.
+ SetPageLength
+ // The DisplayPcChar [display_pc_char, dispc] string capability is the Display PC character #1.
+ DisplayPcChar
+ // The EnterPcCharsetMode [enter_pc_charset_mode, smpch] string capability is the Enter PC character display mode.
+ EnterPcCharsetMode
+ // The ExitPcCharsetMode [exit_pc_charset_mode, rmpch] string capability is the Exit PC character display mode.
+ ExitPcCharsetMode
+ // The EnterScancodeMode [enter_scancode_mode, smsc] string capability is the Enter PC scancode mode.
+ EnterScancodeMode
+ // The ExitScancodeMode [exit_scancode_mode, rmsc] string capability is the Exit PC scancode mode.
+ ExitScancodeMode
+ // The PcTermOptions [pc_term_options, pctrm] string capability is the PC terminal options.
+ PcTermOptions
+ // The ScancodeEscape [scancode_escape, scesc] string capability is the Escape for scancode emulation.
+ ScancodeEscape
+ // The AltScancodeEsc [alt_scancode_esc, scesa] string capability is the Alternate escape for scancode emulation.
+ AltScancodeEsc
+ // The EnterHorizontalHlMode [enter_horizontal_hl_mode, ehhlm] string capability is the Enter horizontal highlight mode.
+ EnterHorizontalHlMode
+ // The EnterLeftHlMode [enter_left_hl_mode, elhlm] string capability is the Enter left highlight mode.
+ EnterLeftHlMode
+ // The EnterLowHlMode [enter_low_hl_mode, elohlm] string capability is the Enter low highlight mode.
+ EnterLowHlMode
+ // The EnterRightHlMode [enter_right_hl_mode, erhlm] string capability is the Enter right highlight mode.
+ EnterRightHlMode
+ // The EnterTopHlMode [enter_top_hl_mode, ethlm] string capability is the Enter top highlight mode.
+ EnterTopHlMode
+ // The EnterVerticalHlMode [enter_vertical_hl_mode, evhlm] string capability is the Enter vertical highlight mode.
+ EnterVerticalHlMode
+ // The SetAAttributes [set_a_attributes, sgr1] string capability is the Define second set of video attributes #1-#6.
+ SetAAttributes
+ // The SetPglenInch [set_pglen_inch, slength] string capability is the Set page length to #1 hundredth of an inch (some implementations use sL for termcap).
+ SetPglenInch
+ // The TermcapInit2 [termcap_init2, OTi2] string capability is the secondary initialization string.
+ TermcapInit2
+ // The TermcapReset [termcap_reset, OTrs] string capability is the terminal reset string.
+ TermcapReset
+ // The LinefeedIfNotLf [linefeed_if_not_lf, OTnl] string capability is the use to move down.
+ LinefeedIfNotLf
+ // The BackspaceIfNotBs [backspace_if_not_bs, OTbc] string capability is the move left, if not ^H.
+ BackspaceIfNotBs
+ // The OtherNonFunctionKeys [other_non_function_keys, OTko] string capability is the list of self-mapped keycaps.
+ OtherNonFunctionKeys
+ // The ArrowKeyMap [arrow_key_map, OTma] string capability is the map motion-keys for vi version 2.
+ ArrowKeyMap
+ // The AcsUlcorner [acs_ulcorner, OTG2] string capability is the single upper left.
+ AcsUlcorner
+ // The AcsLlcorner [acs_llcorner, OTG3] string capability is the single lower left.
+ AcsLlcorner
+ // The AcsUrcorner [acs_urcorner, OTG1] string capability is the single upper right.
+ AcsUrcorner
+ // The AcsLrcorner [acs_lrcorner, OTG4] string capability is the single lower right.
+ AcsLrcorner
+ // The AcsLtee [acs_ltee, OTGR] string capability is the tee pointing right.
+ AcsLtee
+ // The AcsRtee [acs_rtee, OTGL] string capability is the tee pointing left.
+ AcsRtee
+ // The AcsBtee [acs_btee, OTGU] string capability is the tee pointing up.
+ AcsBtee
+ // The AcsTtee [acs_ttee, OTGD] string capability is the tee pointing down.
+ AcsTtee
+ // The AcsHline [acs_hline, OTGH] string capability is the single horizontal line.
+ AcsHline
+ // The AcsVline [acs_vline, OTGV] string capability is the single vertical line.
+ AcsVline
+ // The AcsPlus [acs_plus, OTGC] string capability is the single intersection.
+ AcsPlus
+ // The MemoryLock [memory_lock, meml] string capability is the lock memory above cursor.
+ MemoryLock
+ // The MemoryUnlock [memory_unlock, memu] string capability is the unlock memory.
+ MemoryUnlock
+ // The BoxChars1 [box_chars_1, box1] string capability is the box characters primary set.
+ BoxChars1
+)
+const (
+ // CapCountBool is the count of bool capabilities.
+ CapCountBool = ReturnDoesClrEol + 1
+ // CapCountNum is the count of num capabilities.
+ CapCountNum = NumberOfFunctionKeys + 1
+ // CapCountString is the count of string capabilities.
+ CapCountString = BoxChars1 + 1
+)
+
+// boolCapNames are the bool term cap names.
+var boolCapNames = [...]string{
+ "auto_left_margin", "bw",
+ "auto_right_margin", "am",
+ "no_esc_ctlc", "xsb",
+ "ceol_standout_glitch", "xhp",
+ "eat_newline_glitch", "xenl",
+ "erase_overstrike", "eo",
+ "generic_type", "gn",
+ "hard_copy", "hc",
+ "has_meta_key", "km",
+ "has_status_line", "hs",
+ "insert_null_glitch", "in",
+ "memory_above", "da",
+ "memory_below", "db",
+ "move_insert_mode", "mir",
+ "move_standout_mode", "msgr",
+ "over_strike", "os",
+ "status_line_esc_ok", "eslok",
+ "dest_tabs_magic_smso", "xt",
+ "tilde_glitch", "hz",
+ "transparent_underline", "ul",
+ "xon_xoff", "xon",
+ "needs_xon_xoff", "nxon",
+ "prtr_silent", "mc5i",
+ "hard_cursor", "chts",
+ "non_rev_rmcup", "nrrmc",
+ "no_pad_char", "npc",
+ "non_dest_scroll_region", "ndscr",
+ "can_change", "ccc",
+ "back_color_erase", "bce",
+ "hue_lightness_saturation", "hls",
+ "col_addr_glitch", "xhpa",
+ "cr_cancels_micro_mode", "crxm",
+ "has_print_wheel", "daisy",
+ "row_addr_glitch", "xvpa",
+ "semi_auto_right_margin", "sam",
+ "cpi_changes_res", "cpix",
+ "lpi_changes_res", "lpix",
+ "backspaces_with_bs", "OTbs",
+ "crt_no_scrolling", "OTns",
+ "no_correctly_working_cr", "OTnc",
+ "gnu_has_meta_key", "OTMT",
+ "linefeed_is_newline", "OTNL",
+ "has_hardware_tabs", "OTpt",
+ "return_does_clr_eol", "OTxr",
+}
+
+// numCapNames are the num term cap names.
+var numCapNames = [...]string{
+ "columns", "cols",
+ "init_tabs", "it",
+ "lines", "lines",
+ "lines_of_memory", "lm",
+ "magic_cookie_glitch", "xmc",
+ "padding_baud_rate", "pb",
+ "virtual_terminal", "vt",
+ "width_status_line", "wsl",
+ "num_labels", "nlab",
+ "label_height", "lh",
+ "label_width", "lw",
+ "max_attributes", "ma",
+ "maximum_windows", "wnum",
+ "max_colors", "colors",
+ "max_pairs", "pairs",
+ "no_color_video", "ncv",
+ "buffer_capacity", "bufsz",
+ "dot_vert_spacing", "spinv",
+ "dot_horz_spacing", "spinh",
+ "max_micro_address", "maddr",
+ "max_micro_jump", "mjump",
+ "micro_col_size", "mcs",
+ "micro_line_size", "mls",
+ "number_of_pins", "npins",
+ "output_res_char", "orc",
+ "output_res_line", "orl",
+ "output_res_horz_inch", "orhi",
+ "output_res_vert_inch", "orvi",
+ "print_rate", "cps",
+ "wide_char_size", "widcs",
+ "buttons", "btns",
+ "bit_image_entwining", "bitwin",
+ "bit_image_type", "bitype",
+ "magic_cookie_glitch_ul", "OTug",
+ "carriage_return_delay", "OTdC",
+ "new_line_delay", "OTdN",
+ "backspace_delay", "OTdB",
+ "horizontal_tab_delay", "OTdT",
+ "number_of_function_keys", "OTkn",
+}
+
+// stringCapNames are the string term cap names.
+var stringCapNames = [...]string{
+ "back_tab", "cbt",
+ "bell", "bel",
+ "carriage_return", "cr",
+ "change_scroll_region", "csr",
+ "clear_all_tabs", "tbc",
+ "clear_screen", "clear",
+ "clr_eol", "el",
+ "clr_eos", "ed",
+ "column_address", "hpa",
+ "command_character", "cmdch",
+ "cursor_address", "cup",
+ "cursor_down", "cud1",
+ "cursor_home", "home",
+ "cursor_invisible", "civis",
+ "cursor_left", "cub1",
+ "cursor_mem_address", "mrcup",
+ "cursor_normal", "cnorm",
+ "cursor_right", "cuf1",
+ "cursor_to_ll", "ll",
+ "cursor_up", "cuu1",
+ "cursor_visible", "cvvis",
+ "delete_character", "dch1",
+ "delete_line", "dl1",
+ "dis_status_line", "dsl",
+ "down_half_line", "hd",
+ "enter_alt_charset_mode", "smacs",
+ "enter_blink_mode", "blink",
+ "enter_bold_mode", "bold",
+ "enter_ca_mode", "smcup",
+ "enter_delete_mode", "smdc",
+ "enter_dim_mode", "dim",
+ "enter_insert_mode", "smir",
+ "enter_secure_mode", "invis",
+ "enter_protected_mode", "prot",
+ "enter_reverse_mode", "rev",
+ "enter_standout_mode", "smso",
+ "enter_underline_mode", "smul",
+ "erase_chars", "ech",
+ "exit_alt_charset_mode", "rmacs",
+ "exit_attribute_mode", "sgr0",
+ "exit_ca_mode", "rmcup",
+ "exit_delete_mode", "rmdc",
+ "exit_insert_mode", "rmir",
+ "exit_standout_mode", "rmso",
+ "exit_underline_mode", "rmul",
+ "flash_screen", "flash",
+ "form_feed", "ff",
+ "from_status_line", "fsl",
+ "init_1string", "is1",
+ "init_2string", "is2",
+ "init_3string", "is3",
+ "init_file", "if",
+ "insert_character", "ich1",
+ "insert_line", "il1",
+ "insert_padding", "ip",
+ "key_backspace", "kbs",
+ "key_catab", "ktbc",
+ "key_clear", "kclr",
+ "key_ctab", "kctab",
+ "key_dc", "kdch1",
+ "key_dl", "kdl1",
+ "key_down", "kcud1",
+ "key_eic", "krmir",
+ "key_eol", "kel",
+ "key_eos", "ked",
+ "key_f0", "kf0",
+ "key_f1", "kf1",
+ "key_f10", "kf10",
+ "key_f2", "kf2",
+ "key_f3", "kf3",
+ "key_f4", "kf4",
+ "key_f5", "kf5",
+ "key_f6", "kf6",
+ "key_f7", "kf7",
+ "key_f8", "kf8",
+ "key_f9", "kf9",
+ "key_home", "khome",
+ "key_ic", "kich1",
+ "key_il", "kil1",
+ "key_left", "kcub1",
+ "key_ll", "kll",
+ "key_npage", "knp",
+ "key_ppage", "kpp",
+ "key_right", "kcuf1",
+ "key_sf", "kind",
+ "key_sr", "kri",
+ "key_stab", "khts",
+ "key_up", "kcuu1",
+ "keypad_local", "rmkx",
+ "keypad_xmit", "smkx",
+ "lab_f0", "lf0",
+ "lab_f1", "lf1",
+ "lab_f10", "lf10",
+ "lab_f2", "lf2",
+ "lab_f3", "lf3",
+ "lab_f4", "lf4",
+ "lab_f5", "lf5",
+ "lab_f6", "lf6",
+ "lab_f7", "lf7",
+ "lab_f8", "lf8",
+ "lab_f9", "lf9",
+ "meta_off", "rmm",
+ "meta_on", "smm",
+ "newline", "nel",
+ "pad_char", "pad",
+ "parm_dch", "dch",
+ "parm_delete_line", "dl",
+ "parm_down_cursor", "cud",
+ "parm_ich", "ich",
+ "parm_index", "indn",
+ "parm_insert_line", "il",
+ "parm_left_cursor", "cub",
+ "parm_right_cursor", "cuf",
+ "parm_rindex", "rin",
+ "parm_up_cursor", "cuu",
+ "pkey_key", "pfkey",
+ "pkey_local", "pfloc",
+ "pkey_xmit", "pfx",
+ "print_screen", "mc0",
+ "prtr_off", "mc4",
+ "prtr_on", "mc5",
+ "repeat_char", "rep",
+ "reset_1string", "rs1",
+ "reset_2string", "rs2",
+ "reset_3string", "rs3",
+ "reset_file", "rf",
+ "restore_cursor", "rc",
+ "row_address", "vpa",
+ "save_cursor", "sc",
+ "scroll_forward", "ind",
+ "scroll_reverse", "ri",
+ "set_attributes", "sgr",
+ "set_tab", "hts",
+ "set_window", "wind",
+ "tab", "ht",
+ "to_status_line", "tsl",
+ "underline_char", "uc",
+ "up_half_line", "hu",
+ "init_prog", "iprog",
+ "key_a1", "ka1",
+ "key_a3", "ka3",
+ "key_b2", "kb2",
+ "key_c1", "kc1",
+ "key_c3", "kc3",
+ "prtr_non", "mc5p",
+ "char_padding", "rmp",
+ "acs_chars", "acsc",
+ "plab_norm", "pln",
+ "key_btab", "kcbt",
+ "enter_xon_mode", "smxon",
+ "exit_xon_mode", "rmxon",
+ "enter_am_mode", "smam",
+ "exit_am_mode", "rmam",
+ "xon_character", "xonc",
+ "xoff_character", "xoffc",
+ "ena_acs", "enacs",
+ "label_on", "smln",
+ "label_off", "rmln",
+ "key_beg", "kbeg",
+ "key_cancel", "kcan",
+ "key_close", "kclo",
+ "key_command", "kcmd",
+ "key_copy", "kcpy",
+ "key_create", "kcrt",
+ "key_end", "kend",
+ "key_enter", "kent",
+ "key_exit", "kext",
+ "key_find", "kfnd",
+ "key_help", "khlp",
+ "key_mark", "kmrk",
+ "key_message", "kmsg",
+ "key_move", "kmov",
+ "key_next", "knxt",
+ "key_open", "kopn",
+ "key_options", "kopt",
+ "key_previous", "kprv",
+ "key_print", "kprt",
+ "key_redo", "krdo",
+ "key_reference", "kref",
+ "key_refresh", "krfr",
+ "key_replace", "krpl",
+ "key_restart", "krst",
+ "key_resume", "kres",
+ "key_save", "ksav",
+ "key_suspend", "kspd",
+ "key_undo", "kund",
+ "key_sbeg", "kBEG",
+ "key_scancel", "kCAN",
+ "key_scommand", "kCMD",
+ "key_scopy", "kCPY",
+ "key_screate", "kCRT",
+ "key_sdc", "kDC",
+ "key_sdl", "kDL",
+ "key_select", "kslt",
+ "key_send", "kEND",
+ "key_seol", "kEOL",
+ "key_sexit", "kEXT",
+ "key_sfind", "kFND",
+ "key_shelp", "kHLP",
+ "key_shome", "kHOM",
+ "key_sic", "kIC",
+ "key_sleft", "kLFT",
+ "key_smessage", "kMSG",
+ "key_smove", "kMOV",
+ "key_snext", "kNXT",
+ "key_soptions", "kOPT",
+ "key_sprevious", "kPRV",
+ "key_sprint", "kPRT",
+ "key_sredo", "kRDO",
+ "key_sreplace", "kRPL",
+ "key_sright", "kRIT",
+ "key_srsume", "kRES",
+ "key_ssave", "kSAV",
+ "key_ssuspend", "kSPD",
+ "key_sundo", "kUND",
+ "req_for_input", "rfi",
+ "key_f11", "kf11",
+ "key_f12", "kf12",
+ "key_f13", "kf13",
+ "key_f14", "kf14",
+ "key_f15", "kf15",
+ "key_f16", "kf16",
+ "key_f17", "kf17",
+ "key_f18", "kf18",
+ "key_f19", "kf19",
+ "key_f20", "kf20",
+ "key_f21", "kf21",
+ "key_f22", "kf22",
+ "key_f23", "kf23",
+ "key_f24", "kf24",
+ "key_f25", "kf25",
+ "key_f26", "kf26",
+ "key_f27", "kf27",
+ "key_f28", "kf28",
+ "key_f29", "kf29",
+ "key_f30", "kf30",
+ "key_f31", "kf31",
+ "key_f32", "kf32",
+ "key_f33", "kf33",
+ "key_f34", "kf34",
+ "key_f35", "kf35",
+ "key_f36", "kf36",
+ "key_f37", "kf37",
+ "key_f38", "kf38",
+ "key_f39", "kf39",
+ "key_f40", "kf40",
+ "key_f41", "kf41",
+ "key_f42", "kf42",
+ "key_f43", "kf43",
+ "key_f44", "kf44",
+ "key_f45", "kf45",
+ "key_f46", "kf46",
+ "key_f47", "kf47",
+ "key_f48", "kf48",
+ "key_f49", "kf49",
+ "key_f50", "kf50",
+ "key_f51", "kf51",
+ "key_f52", "kf52",
+ "key_f53", "kf53",
+ "key_f54", "kf54",
+ "key_f55", "kf55",
+ "key_f56", "kf56",
+ "key_f57", "kf57",
+ "key_f58", "kf58",
+ "key_f59", "kf59",
+ "key_f60", "kf60",
+ "key_f61", "kf61",
+ "key_f62", "kf62",
+ "key_f63", "kf63",
+ "clr_bol", "el1",
+ "clear_margins", "mgc",
+ "set_left_margin", "smgl",
+ "set_right_margin", "smgr",
+ "label_format", "fln",
+ "set_clock", "sclk",
+ "display_clock", "dclk",
+ "remove_clock", "rmclk",
+ "create_window", "cwin",
+ "goto_window", "wingo",
+ "hangup", "hup",
+ "dial_phone", "dial",
+ "quick_dial", "qdial",
+ "tone", "tone",
+ "pulse", "pulse",
+ "flash_hook", "hook",
+ "fixed_pause", "pause",
+ "wait_tone", "wait",
+ "user0", "u0",
+ "user1", "u1",
+ "user2", "u2",
+ "user3", "u3",
+ "user4", "u4",
+ "user5", "u5",
+ "user6", "u6",
+ "user7", "u7",
+ "user8", "u8",
+ "user9", "u9",
+ "orig_pair", "op",
+ "orig_colors", "oc",
+ "initialize_color", "initc",
+ "initialize_pair", "initp",
+ "set_color_pair", "scp",
+ "set_foreground", "setf",
+ "set_background", "setb",
+ "change_char_pitch", "cpi",
+ "change_line_pitch", "lpi",
+ "change_res_horz", "chr",
+ "change_res_vert", "cvr",
+ "define_char", "defc",
+ "enter_doublewide_mode", "swidm",
+ "enter_draft_quality", "sdrfq",
+ "enter_italics_mode", "sitm",
+ "enter_leftward_mode", "slm",
+ "enter_micro_mode", "smicm",
+ "enter_near_letter_quality", "snlq",
+ "enter_normal_quality", "snrmq",
+ "enter_shadow_mode", "sshm",
+ "enter_subscript_mode", "ssubm",
+ "enter_superscript_mode", "ssupm",
+ "enter_upward_mode", "sum",
+ "exit_doublewide_mode", "rwidm",
+ "exit_italics_mode", "ritm",
+ "exit_leftward_mode", "rlm",
+ "exit_micro_mode", "rmicm",
+ "exit_shadow_mode", "rshm",
+ "exit_subscript_mode", "rsubm",
+ "exit_superscript_mode", "rsupm",
+ "exit_upward_mode", "rum",
+ "micro_column_address", "mhpa",
+ "micro_down", "mcud1",
+ "micro_left", "mcub1",
+ "micro_right", "mcuf1",
+ "micro_row_address", "mvpa",
+ "micro_up", "mcuu1",
+ "order_of_pins", "porder",
+ "parm_down_micro", "mcud",
+ "parm_left_micro", "mcub",
+ "parm_right_micro", "mcuf",
+ "parm_up_micro", "mcuu",
+ "select_char_set", "scs",
+ "set_bottom_margin", "smgb",
+ "set_bottom_margin_parm", "smgbp",
+ "set_left_margin_parm", "smglp",
+ "set_right_margin_parm", "smgrp",
+ "set_top_margin", "smgt",
+ "set_top_margin_parm", "smgtp",
+ "start_bit_image", "sbim",
+ "start_char_set_def", "scsd",
+ "stop_bit_image", "rbim",
+ "stop_char_set_def", "rcsd",
+ "subscript_characters", "subcs",
+ "superscript_characters", "supcs",
+ "these_cause_cr", "docr",
+ "zero_motion", "zerom",
+ "char_set_names", "csnm",
+ "key_mouse", "kmous",
+ "mouse_info", "minfo",
+ "req_mouse_pos", "reqmp",
+ "get_mouse", "getm",
+ "set_a_foreground", "setaf",
+ "set_a_background", "setab",
+ "pkey_plab", "pfxl",
+ "device_type", "devt",
+ "code_set_init", "csin",
+ "set0_des_seq", "s0ds",
+ "set1_des_seq", "s1ds",
+ "set2_des_seq", "s2ds",
+ "set3_des_seq", "s3ds",
+ "set_lr_margin", "smglr",
+ "set_tb_margin", "smgtb",
+ "bit_image_repeat", "birep",
+ "bit_image_newline", "binel",
+ "bit_image_carriage_return", "bicr",
+ "color_names", "colornm",
+ "define_bit_image_region", "defbi",
+ "end_bit_image_region", "endbi",
+ "set_color_band", "setcolor",
+ "set_page_length", "slines",
+ "display_pc_char", "dispc",
+ "enter_pc_charset_mode", "smpch",
+ "exit_pc_charset_mode", "rmpch",
+ "enter_scancode_mode", "smsc",
+ "exit_scancode_mode", "rmsc",
+ "pc_term_options", "pctrm",
+ "scancode_escape", "scesc",
+ "alt_scancode_esc", "scesa",
+ "enter_horizontal_hl_mode", "ehhlm",
+ "enter_left_hl_mode", "elhlm",
+ "enter_low_hl_mode", "elohlm",
+ "enter_right_hl_mode", "erhlm",
+ "enter_top_hl_mode", "ethlm",
+ "enter_vertical_hl_mode", "evhlm",
+ "set_a_attributes", "sgr1",
+ "set_pglen_inch", "slength",
+ "termcap_init2", "OTi2",
+ "termcap_reset", "OTrs",
+ "linefeed_if_not_lf", "OTnl",
+ "backspace_if_not_bs", "OTbc",
+ "other_non_function_keys", "OTko",
+ "arrow_key_map", "OTma",
+ "acs_ulcorner", "OTG2",
+ "acs_llcorner", "OTG3",
+ "acs_urcorner", "OTG1",
+ "acs_lrcorner", "OTG4",
+ "acs_ltee", "OTGR",
+ "acs_rtee", "OTGL",
+ "acs_btee", "OTGU",
+ "acs_ttee", "OTGD",
+ "acs_hline", "OTGH",
+ "acs_vline", "OTGV",
+ "acs_plus", "OTGC",
+ "memory_lock", "meml",
+ "memory_unlock", "memu",
+ "box_chars_1", "box1",
+}
diff --git a/vendor/github.com/xo/terminfo/color.go b/vendor/github.com/xo/terminfo/color.go
new file mode 100644
index 00000000..76c439fc
--- /dev/null
+++ b/vendor/github.com/xo/terminfo/color.go
@@ -0,0 +1,88 @@
+package terminfo
+
+import (
+ "os"
+ "strconv"
+ "strings"
+)
+
+// ColorLevel is the color level supported by a terminal.
+type ColorLevel uint
+
+// ColorLevel values.
+const (
+ ColorLevelNone ColorLevel = iota
+ ColorLevelBasic
+ ColorLevelHundreds
+ ColorLevelMillions
+)
+
+// String satisfies the Stringer interface.
+func (c ColorLevel) String() string {
+ switch c {
+ case ColorLevelBasic:
+ return "basic"
+ case ColorLevelHundreds:
+ return "hundreds"
+ case ColorLevelMillions:
+ return "millions"
+ }
+ return "none"
+}
+
+// ChromaFormatterName returns the github.com/alecthomas/chroma compatible
+// formatter name for the color level.
+func (c ColorLevel) ChromaFormatterName() string {
+ switch c {
+ case ColorLevelBasic:
+ return "terminal"
+ case ColorLevelHundreds:
+ return "terminal256"
+ case ColorLevelMillions:
+ return "terminal16m"
+ }
+ return "noop"
+}
+
+// ColorLevelFromEnv returns the color level COLORTERM, FORCE_COLOR,
+// TERM_PROGRAM, or determined from the TERM environment variable.
+func ColorLevelFromEnv() (ColorLevel, error) {
+ // check for overriding environment variables
+ colorTerm, termProg, forceColor := os.Getenv("COLORTERM"), os.Getenv("TERM_PROGRAM"), os.Getenv("FORCE_COLOR")
+ switch {
+ case strings.Contains(colorTerm, "truecolor") || strings.Contains(colorTerm, "24bit") || termProg == "Hyper":
+ return ColorLevelMillions, nil
+ case colorTerm != "" || forceColor != "":
+ return ColorLevelBasic, nil
+ case termProg == "Apple_Terminal":
+ return ColorLevelHundreds, nil
+ case termProg == "iTerm.app":
+ ver := os.Getenv("TERM_PROGRAM_VERSION")
+ if ver == "" {
+ return ColorLevelHundreds, nil
+ }
+ i, err := strconv.Atoi(strings.Split(ver, ".")[0])
+ if err != nil {
+ return ColorLevelNone, ErrInvalidTermProgramVersion
+ }
+ if i == 3 {
+ return ColorLevelMillions, nil
+ }
+ return ColorLevelHundreds, nil
+ }
+ // otherwise determine from TERM's max_colors capability
+ if term := os.Getenv("TERM"); term != "" {
+ ti, err := Load(term)
+ if err != nil {
+ return ColorLevelNone, err
+ }
+ v, ok := ti.Nums[MaxColors]
+ switch {
+ case !ok || v <= 16:
+ return ColorLevelNone, nil
+ case ok && v >= 256:
+ return ColorLevelHundreds, nil
+ }
+ }
+ return ColorLevelBasic, nil
+}
diff --git a/vendor/github.com/xo/terminfo/dec.go b/vendor/github.com/xo/terminfo/dec.go
new file mode 100644
index 00000000..dacc88e3
--- /dev/null
+++ b/vendor/github.com/xo/terminfo/dec.go
@@ -0,0 +1,245 @@
+package terminfo
+
+import (
+ "sort"
+)
+
+const (
+ // maxFileLength is the max file length.
+ maxFileLength = 4096
+ // magic is the file magic for terminfo files.
+ magic = 0o432
+ // magicExtended is the file magic for terminfo files with the extended
+ // number format.
+ magicExtended = 0o1036
+)
+
+// header fields.
+const (
+ fieldMagic = iota
+ fieldNameSize
+ fieldBoolCount
+ fieldNumCount
+ fieldStringCount
+ fieldTableSize
+)
+
+// header extended fields.
+const (
+ fieldExtBoolCount = iota
+ fieldExtNumCount
+ fieldExtStringCount
+ fieldExtOffsetCount
+ fieldExtTableSize
+)
+
+// hasInvalidCaps determines if the capabilities in h are invalid.
+func hasInvalidCaps(h []int) bool {
+ return h[fieldBoolCount] > CapCountBool ||
+ h[fieldNumCount] > CapCountNum ||
+ h[fieldStringCount] > CapCountString
+}
+
+// capLength returns the total length of the capabilities in bytes.
+func capLength(h []int) int {
+ return h[fieldNameSize] +
+ h[fieldBoolCount] +
+ (h[fieldNameSize]+h[fieldBoolCount])%2 + // account for word align
+ h[fieldNumCount]*2 +
+ h[fieldStringCount]*2 +
+ h[fieldTableSize]
+}
+
+// hasInvalidExtOffset determines if the extended offset field is valid.
+func hasInvalidExtOffset(h []int) bool {
+ return h[fieldExtBoolCount]+
+ h[fieldExtNumCount]+
+ h[fieldExtStringCount]*2 != h[fieldExtOffsetCount]
+}
+
+// extCapLength returns the total length of extended capabilities in bytes.
+func extCapLength(h []int, numWidth int) int {
+ return h[fieldExtBoolCount] +
+ h[fieldExtBoolCount]%2 + // account for word align
+ h[fieldExtNumCount]*(numWidth/8) +
+ h[fieldExtOffsetCount]*2 +
+ h[fieldExtTableSize]
+}
+
+// findNull finds the position of null in buf.
+func findNull(buf []byte, i int) int {
+ for ; i < len(buf); i++ {
+ if buf[i] == 0 {
+ return i
+ }
+ }
+ return -1
+}
+
+// readStrings decodes n strings from string data table buf using the indexes in idx.
+func readStrings(idx []int, buf []byte, n int) (map[int][]byte, int, error) {
+ var last int
+ m := make(map[int][]byte)
+ for i := 0; i < n; i++ {
+ start := idx[i]
+ if start < 0 {
+ continue
+ }
+ if end := findNull(buf, start); end != -1 {
+ m[i], last = buf[start:end], end+1
+ } else {
+ return nil, 0, ErrInvalidStringTable
+ }
+ }
+ return m, last, nil
+}
+
+// decoder holds state info while decoding a terminfo file.
+type decoder struct {
+ buf []byte
+ pos int
+ n int
+}
+
+// readBytes reads the next n bytes of buf, incrementing pos by n.
+func (d *decoder) readBytes(n int) ([]byte, error) {
+ if d.n < d.pos+n {
+ return nil, ErrUnexpectedFileEnd
+ }
+ n, d.pos = d.pos, d.pos+n
+ return d.buf[n:d.pos], nil
+}
+
+// readInts reads n number of ints with width w.
+func (d *decoder) readInts(n, w int) ([]int, error) {
+ w /= 8
+ l := n * w
+ buf, err := d.readBytes(l)
+ if err != nil {
+ return nil, err
+ }
+ // align
+ d.pos += d.pos % 2
+ z := make([]int, n)
+ for i, j := 0, 0; i < l; i, j = i+w, j+1 {
+ switch w {
+ case 1:
+ z[i] = int(buf[i])
+ case 2:
+ z[j] = int(int16(buf[i+1])<<8 | int16(buf[i]))
+ case 4:
+ z[j] = int(buf[i+3])<<24 | int(buf[i+2])<<16 | int(buf[i+1])<<8 | int(buf[i])
+ }
+ }
+ return z, nil
+}
+
+// readBools reads the next n bools.
+func (d *decoder) readBools(n int) (map[int]bool, map[int]bool, error) {
+ buf, err := d.readInts(n, 8)
+ if err != nil {
+ return nil, nil, err
+ }
+ // process
+ bools, boolsM := make(map[int]bool), make(map[int]bool)
+ for i, b := range buf {
+ bools[i] = b == 1
+ if int8(b) == -2 {
+ boolsM[i] = true
+ }
+ }
+ return bools, boolsM, nil
+}
+
+// readNums reads the next n nums.
+func (d *decoder) readNums(n, w int) (map[int]int, map[int]bool, error) {
+ buf, err := d.readInts(n, w)
+ if err != nil {
+ return nil, nil, err
+ }
+ // process
+ nums, numsM := make(map[int]int), make(map[int]bool)
+ for i := 0; i < n; i++ {
+ nums[i] = buf[i]
+ if buf[i] == -2 {
+ numsM[i] = true
+ }
+ }
+ return nums, numsM, nil
+}
+
+// readStringTable reads the string data for n strings and the accompanying data
+// table of length sz.
+func (d *decoder) readStringTable(n, sz int) ([][]byte, []int, error) {
+ buf, err := d.readInts(n, 16)
+ if err != nil {
+ return nil, nil, err
+ }
+ // read string data table
+ data, err := d.readBytes(sz)
+ if err != nil {
+ return nil, nil, err
+ }
+ // align
+ d.pos += d.pos % 2
+ // process
+ s := make([][]byte, n)
+ var m []int
+ for i := 0; i < n; i++ {
+ start := buf[i]
+ if start == -2 {
+ m = append(m, i)
+ } else if start >= 0 {
+ if end := findNull(data, start); end != -1 {
+ s[i] = data[start:end]
+ } else {
+ return nil, nil, ErrInvalidStringTable
+ }
+ }
+ }
+ return s, m, nil
+}
+
+// readStrings reads the next n strings and processes the string data table of
+// length sz.
+func (d *decoder) readStrings(n, sz int) (map[int][]byte, map[int]bool, error) {
+ s, m, err := d.readStringTable(n, sz)
+ if err != nil {
+ return nil, nil, err
+ }
+ strs := make(map[int][]byte)
+ for k, v := range s {
+ if k == AcsChars {
+ v = canonicalizeAscChars(v)
+ }
+ strs[k] = v
+ }
+ strsM := make(map[int]bool, len(m))
+ for _, k := range m {
+ strsM[k] = true
+ }
+ return strs, strsM, nil
+}
+
+// canonicalizeAscChars reorders chars to be unique, in order.
+//
+// see repair_ascc in ncurses-6.3/progs/dump_entry.c
+func canonicalizeAscChars(z []byte) []byte {
+ var c []byte
+ enc := make(map[byte]byte, len(z)/2)
+ for i := 0; i < len(z); i += 2 {
+ if _, ok := enc[z[i]]; !ok {
+ a, b := z[i], z[i+1]
+ // log.Printf(">>> a: %d %c, b: %d %c", a, a, b, b)
+ c, enc[a] = append(c, b), b
+ }
+ }
+ sort.Slice(c, func(i, j int) bool {
+ return c[i] < c[j]
+ })
+ r := make([]byte, 2*len(c))
+ for i := 0; i < len(c); i++ {
+ r[i*2], r[i*2+1] = c[i], enc[c[i]]
+ }
+ return r
+}
diff --git a/vendor/github.com/xo/terminfo/load.go b/vendor/github.com/xo/terminfo/load.go
new file mode 100644
index 00000000..d7cd266c
--- /dev/null
+++ b/vendor/github.com/xo/terminfo/load.go
@@ -0,0 +1,64 @@
+package terminfo
+
+import (
+ "os"
+ "os/user"
+ "path"
+ "strings"
+ "sync"
+)
+
+// termCache is the terminfo cache.
+var termCache = struct {
+ db map[string]*Terminfo
+ sync.RWMutex
+}{
+ db: make(map[string]*Terminfo),
+}
+
+// Load follows the behavior described in terminfo(5) to find correct the
+// terminfo file using the name, reads the file and then returns a Terminfo
+// struct that describes the file.
+func Load(name string) (*Terminfo, error) {
+ if name == "" {
+ return nil, ErrEmptyTermName
+ }
+ termCache.RLock()
+ ti, ok := termCache.db[name]
+ termCache.RUnlock()
+ if ok {
+ return ti, nil
+ }
+ var checkDirs []string
+ // check $TERMINFO
+ if dir := os.Getenv("TERMINFO"); dir != "" {
+ checkDirs = append(checkDirs, dir)
+ }
+ // check $HOME/.terminfo
+ u, err := user.Current()
+ if err != nil {
+ return nil, err
+ }
+ checkDirs = append(checkDirs, path.Join(u.HomeDir, ".terminfo"))
+ // check $TERMINFO_DIRS
+ if dirs := os.Getenv("TERMINFO_DIRS"); dirs != "" {
+ checkDirs = append(checkDirs, strings.Split(dirs, ":")...)
+ }
+ // check fallback directories
+ checkDirs = append(checkDirs, "/etc/terminfo", "/lib/terminfo", "/usr/share/terminfo")
+ for _, dir := range checkDirs {
+ ti, err = Open(dir, name)
+ if err != nil && err != ErrFileNotFound && !os.IsNotExist(err) {
+ return nil, err
+ } else if err == nil {
+ return ti, nil
+ }
+ }
+ return nil, ErrDatabaseDirectoryNotFound
+}
+
+// LoadFromEnv loads the terminal info based on the name contained in
+// environment variable TERM.
+func LoadFromEnv() (*Terminfo, error) {
+ return Load(os.Getenv("TERM"))
+}
diff --git a/vendor/github.com/xo/terminfo/param.go b/vendor/github.com/xo/terminfo/param.go
new file mode 100644
index 00000000..ed4cb86b
--- /dev/null
+++ b/vendor/github.com/xo/terminfo/param.go
@@ -0,0 +1,405 @@
+package terminfo
+
+import (
+ "bytes"
+ "fmt"
+ "io"
+ "strconv"
+ "strings"
+ "sync"
+)
+
+// parametizer represents the a scan state for a parameterized string.
+type parametizer struct {
+ // z is the string to parameterize
+ z []byte
+ // pos is the current position in s.
+ pos int
+ // nest is the current nest level.
+ nest int
+ // s is the variable stack.
+ s stack
+ // skipElse keeps the state of skipping else.
+ skipElse bool
+ // buf is the result buffer.
+ buf *bytes.Buffer
+ // params are the parameters to interpolate.
+ params [9]interface{}
+ // vars are dynamic variables.
+ vars [26]interface{}
+}
+
+// staticVars are the static, global variables.
+var staticVars = struct {
+ vars [26]interface{}
+ sync.Mutex
+}{}
+
+var parametizerPool = sync.Pool{
+ New: func() interface{} {
+ p := new(parametizer)
+ p.buf = bytes.NewBuffer(make([]byte, 0, 45))
+ return p
+ },
+}
+
+// newParametizer returns a new initialized parametizer from the pool.
+func newParametizer(z []byte) *parametizer {
+ p := parametizerPool.Get().(*parametizer)
+ p.z = z
+ return p
+}
+
+// reset resets the parametizer.
+func (p *parametizer) reset() {
+ p.pos, p.nest = 0, 0
+ p.s.reset()
+ p.buf.Reset()
+ p.params, p.vars = [9]interface{}{}, [26]interface{}{}
+ parametizerPool.Put(p)
+}
+
+// stateFn represents the state of the scanner as a function that returns the
+// next state.
+type stateFn func() stateFn
+
+// exec executes the parameterizer, interpolating the supplied parameters.
+func (p *parametizer) exec() string {
+ for state := p.scanTextFn; state != nil; {
+ state = state()
+ }
+ return p.buf.String()
+}
+
+// peek returns the next byte.
+func (p *parametizer) peek() (byte, error) {
+ if p.pos >= len(p.z) {
+ return 0, io.EOF
+ }
+ return p.z[p.pos], nil
+}
+
+// writeFrom writes the characters from ppos to pos to the buffer.
+func (p *parametizer) writeFrom(ppos int) {
+ if p.pos > ppos {
+ // append remaining characters.
+ p.buf.Write(p.z[ppos:p.pos])
+ }
+}
+
+func (p *parametizer) scanTextFn() stateFn {
+ ppos := p.pos
+ for {
+ ch, err := p.peek()
+ if err != nil {
+ p.writeFrom(ppos)
+ return nil
+ }
+ if ch == '%' {
+ p.writeFrom(ppos)
+ p.pos++
+ return p.scanCodeFn
+ }
+ p.pos++
+ }
+}
+
+func (p *parametizer) scanCodeFn() stateFn {
+ ch, err := p.peek()
+ if err != nil {
+ return nil
+ }
+ switch ch {
+ case '%':
+ p.buf.WriteByte('%')
+ case ':':
+ // this character is used to avoid interpreting "%-" and "%+" as operators.
+ // the next character is where the format really begins.
+ p.pos++
+ _, err = p.peek()
+ if err != nil {
+ return nil
+ }
+ return p.scanFormatFn
+ case '#', ' ', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '.':
+ return p.scanFormatFn
+ case 'o':
+ p.buf.WriteString(strconv.FormatInt(int64(p.s.popInt()), 8))
+ case 'd':
+ p.buf.WriteString(strconv.Itoa(p.s.popInt()))
+ case 'x':
+ p.buf.WriteString(strconv.FormatInt(int64(p.s.popInt()), 16))
+ case 'X':
+ p.buf.WriteString(strings.ToUpper(strconv.FormatInt(int64(p.s.popInt()), 16)))
+ case 's':
+ p.buf.WriteString(p.s.popString())
+ case 'c':
+ p.buf.WriteByte(p.s.popByte())
+ case 'p':
+ p.pos++
+ return p.pushParamFn
+ case 'P':
+ p.pos++
+ return p.setDsVarFn
+ case 'g':
+ p.pos++
+ return p.getDsVarFn
+ case '\'':
+ p.pos++
+ ch, err = p.peek()
+ if err != nil {
+ return nil
+ }
+ p.s.push(ch)
+ // skip the '\''
+ p.pos++
+ case '{':
+ p.pos++
+ return p.pushIntfn
+ case 'l':
+ p.s.push(len(p.s.popString()))
+ case '+':
+ bi, ai := p.s.popInt(), p.s.popInt()
+ p.s.push(ai + bi)
+ case '-':
+ bi, ai := p.s.popInt(), p.s.popInt()
+ p.s.push(ai - bi)
+ case '*':
+ bi, ai := p.s.popInt(), p.s.popInt()
+ p.s.push(ai * bi)
+ case '/':
+ bi, ai := p.s.popInt(), p.s.popInt()
+ if bi != 0 {
+ p.s.push(ai / bi)
+ } else {
+ p.s.push(0)
+ }
+ case 'm':
+ bi, ai := p.s.popInt(), p.s.popInt()
+ if bi != 0 {
+ p.s.push(ai % bi)
+ } else {
+ p.s.push(0)
+ }
+ case '&':
+ bi, ai := p.s.popInt(), p.s.popInt()
+ p.s.push(ai & bi)
+ case '|':
+ bi, ai := p.s.popInt(), p.s.popInt()
+ p.s.push(ai | bi)
+ case '^':
+ bi, ai := p.s.popInt(), p.s.popInt()
+ p.s.push(ai ^ bi)
+ case '=':
+ bi, ai := p.s.popInt(), p.s.popInt()
+ p.s.push(ai == bi)
+ case '>':
+ bi, ai := p.s.popInt(), p.s.popInt()
+ p.s.push(ai > bi)
+ case '<':
+ bi, ai := p.s.popInt(), p.s.popInt()
+ p.s.push(ai < bi)
+ case 'A':
+ bi, ai := p.s.popBool(), p.s.popBool()
+ p.s.push(ai && bi)
+ case 'O':
+ bi, ai := p.s.popBool(), p.s.popBool()
+ p.s.push(ai || bi)
+ case '!':
+ p.s.push(!p.s.popBool())
+ case '~':
+ p.s.push(^p.s.popInt())
+ case 'i':
+ for i := range p.params[:2] {
+ if n, ok := p.params[i].(int); ok {
+ p.params[i] = n + 1
+ }
+ }
+ case '?', ';':
+ case 't':
+ return p.scanThenFn
+ case 'e':
+ p.skipElse = true
+ return p.skipTextFn
+ }
+ p.pos++
+ return p.scanTextFn
+}
+
+func (p *parametizer) scanFormatFn() stateFn {
+ // the character was already read, so no need to check the error.
+ ch, _ := p.peek()
+ // 6 should be the maximum length of a format string, for example "%:-9.9d".
+ f := []byte{'%', ch, 0, 0, 0, 0}
+ var err error
+ for {
+ p.pos++
+ ch, err = p.peek()
+ if err != nil {
+ return nil
+ }
+ f = append(f, ch)
+ switch ch {
+ case 'o', 'd', 'x', 'X':
+ fmt.Fprintf(p.buf, string(f), p.s.popInt())
+ break
+ case 's':
+ fmt.Fprintf(p.buf, string(f), p.s.popString())
+ break
+ case 'c':
+ fmt.Fprintf(p.buf, string(f), p.s.popByte())
+ break
+ }
+ }
+ p.pos++
+ return p.scanTextFn
+}
+
+func (p *parametizer) pushParamFn() stateFn {
+ ch, err := p.peek()
+ if err != nil {
+ return nil
+ }
+ if ai := int(ch - '1'); ai >= 0 && ai < len(p.params) {
+ p.s.push(p.params[ai])
+ } else {
+ p.s.push(0)
+ }
+ // skip the '}'
+ p.pos++
+ return p.scanTextFn
+}
+
+func (p *parametizer) setDsVarFn() stateFn {
+ ch, err := p.peek()
+ if err != nil {
+ return nil
+ }
+ if ch >= 'A' && ch <= 'Z' {
+ staticVars.Lock()
+ staticVars.vars[int(ch-'A')] = p.s.pop()
+ staticVars.Unlock()
+ } else if ch >= 'a' && ch <= 'z' {
+ p.vars[int(ch-'a')] = p.s.pop()
+ }
+ p.pos++
+ return p.scanTextFn
+}
+
+func (p *parametizer) getDsVarFn() stateFn {
+ ch, err := p.peek()
+ if err != nil {
+ return nil
+ }
+ var a byte
+ if ch >= 'A' && ch <= 'Z' {
+ a = 'A'
+ } else if ch >= 'a' && ch <= 'z' {
+ a = 'a'
+ }
+ staticVars.Lock()
+ p.s.push(staticVars.vars[int(ch-a)])
+ staticVars.Unlock()
+ p.pos++
+ return p.scanTextFn
+}
+
+func (p *parametizer) pushIntfn() stateFn {
+ var ai int
+ for {
+ ch, err := p.peek()
+ if err != nil {
+ return nil
+ }
+ p.pos++
+ if ch < '0' || ch > '9' {
+ p.s.push(ai)
+ return p.scanTextFn
+ }
+ ai = (ai * 10) + int(ch-'0')
+ }
+}
+
+func (p *parametizer) scanThenFn() stateFn {
+ p.pos++
+ if p.s.popBool() {
+ return p.scanTextFn
+ }
+ p.skipElse = false
+ return p.skipTextFn
+}
+
+func (p *parametizer) skipTextFn() stateFn {
+ for {
+ ch, err := p.peek()
+ if err != nil {
+ return nil
+ }
+ p.pos++
+ if ch == '%' {
+ break
+ }
+ }
+ if p.skipElse {
+ return p.skipElseFn
+ }
+ return p.skipThenFn
+}
+
+func (p *parametizer) skipThenFn() stateFn {
+ ch, err := p.peek()
+ if err != nil {
+ return nil
+ }
+ p.pos++
+ switch ch {
+ case ';':
+ if p.nest == 0 {
+ return p.scanTextFn
+ }
+ p.nest--
+ case '?':
+ p.nest++
+ case 'e':
+ if p.nest == 0 {
+ return p.scanTextFn
+ }
+ }
+ return p.skipTextFn
+}
+
+func (p *parametizer) skipElseFn() stateFn {
+ ch, err := p.peek()
+ if err != nil {
+ return nil
+ }
+ p.pos++
+ switch ch {
+ case ';':
+ if p.nest == 0 {
+ return p.scanTextFn
+ }
+ p.nest--
+ case '?':
+ p.nest++
+ }
+ return p.skipTextFn
+}
+
+// Printf evaluates a parameterized terminfo value z, interpolating params.
+func Printf(z []byte, params ...interface{}) string {
+ p := newParametizer(z)
+ defer p.reset()
+ // make sure we always have 9 parameters -- makes it easier
+ // later to skip checks and its faster
+ for i := 0; i < len(p.params) && i < len(params); i++ {
+ p.params[i] = params[i]
+ }
+ return p.exec()
+}
+
+// Fprintf evaluates a parameterized terminfo value z, interpolating params and
+// writing to w.
+func Fprintf(w io.Writer, z []byte, params ...interface{}) {
+ w.Write([]byte(Printf(z, params...)))
+}
diff --git a/vendor/github.com/xo/terminfo/stack.go b/vendor/github.com/xo/terminfo/stack.go
new file mode 100644
index 00000000..a6de3950
--- /dev/null
+++ b/vendor/github.com/xo/terminfo/stack.go
@@ -0,0 +1,48 @@
+package terminfo
+
+type stack []interface{}
+
+func (s *stack) push(v interface{}) {
+ *s = append(*s, v)
+}
+
+func (s *stack) pop() interface{} {
+ if len(*s) == 0 {
+ return nil
+ }
+ v := (*s)[len(*s)-1]
+ *s = (*s)[:len(*s)-1]
+ return v
+}
+
+func (s *stack) popInt() int {
+ if i, ok := s.pop().(int); ok {
+ return i
+ }
+ return 0
+}
+
+func (s *stack) popBool() bool {
+ if b, ok := s.pop().(bool); ok {
+ return b
+ }
+ return false
+}
+
+func (s *stack) popByte() byte {
+ if b, ok := s.pop().(byte); ok {
+ return b
+ }
+ return 0
+}
+
+func (s *stack) popString() string {
+ if a, ok := s.pop().(string); ok {
+ return a
+ }
+ return ""
+}
+
+func (s *stack) reset() {
+ *s = (*s)[:0]
+}
diff --git a/vendor/github.com/xo/terminfo/terminfo.go b/vendor/github.com/xo/terminfo/terminfo.go
new file mode 100644
index 00000000..69e3b606
--- /dev/null
+++ b/vendor/github.com/xo/terminfo/terminfo.go
@@ -0,0 +1,479 @@
+// Package terminfo implements reading terminfo files in pure go.
+package terminfo
+
+//go:generate go run gen.go
+
+import (
+ "io"
+ "io/ioutil"
+ "path"
+ "strconv"
+ "strings"
+)
+
+// Error is a terminfo error.
+type Error string
+
+// Error satisfies the error interface.
+func (err Error) Error() string {
+ return string(err)
+}
+
+const (
+ // ErrInvalidFileSize is the invalid file size error.
+ ErrInvalidFileSize Error = "invalid file size"
+ // ErrUnexpectedFileEnd is the unexpected file end error.
+ ErrUnexpectedFileEnd Error = "unexpected file end"
+ // ErrInvalidStringTable is the invalid string table error.
+ ErrInvalidStringTable Error = "invalid string table"
+ // ErrInvalidMagic is the invalid magic error.
+ ErrInvalidMagic Error = "invalid magic"
+ // ErrInvalidHeader is the invalid header error.
+ ErrInvalidHeader Error = "invalid header"
+ // ErrInvalidNames is the invalid names error.
+ ErrInvalidNames Error = "invalid names"
+ // ErrInvalidExtendedHeader is the invalid extended header error.
+ ErrInvalidExtendedHeader Error = "invalid extended header"
+ // ErrEmptyTermName is the empty term name error.
+ ErrEmptyTermName Error = "empty term name"
+ // ErrDatabaseDirectoryNotFound is the database directory not found error.
+ ErrDatabaseDirectoryNotFound Error = "database directory not found"
+ // ErrFileNotFound is the file not found error.
+ ErrFileNotFound Error = "file not found"
+ // ErrInvalidTermProgramVersion is the invalid TERM_PROGRAM_VERSION error.
+ ErrInvalidTermProgramVersion Error = "invalid TERM_PROGRAM_VERSION"
+)
+
+// Terminfo describes a terminal's capabilities.
+type Terminfo struct {
+ // File is the original source file.
+ File string
+ // Names are the provided cap names.
+ Names []string
+ // Bools are the bool capabilities.
+ Bools map[int]bool
+ // BoolsM are the missing bool capabilities.
+ BoolsM map[int]bool
+ // Nums are the num capabilities.
+ Nums map[int]int
+ // NumsM are the missing num capabilities.
+ NumsM map[int]bool
+ // Strings are the string capabilities.
+ Strings map[int][]byte
+ // StringsM are the missing string capabilities.
+ StringsM map[int]bool
+ // ExtBools are the extended bool capabilities.
+ ExtBools map[int]bool
+ // ExtBoolsNames is the map of extended bool capabilities to their index.
+ ExtBoolNames map[int][]byte
+ // ExtNums are the extended num capabilities.
+ ExtNums map[int]int
+ // ExtNumsNames is the map of extended num capabilities to their index.
+ ExtNumNames map[int][]byte
+ // ExtStrings are the extended string capabilities.
+ ExtStrings map[int][]byte
+ // ExtStringsNames is the map of extended string capabilities to their index.
+ ExtStringNames map[int][]byte
+}
+
+// Decode decodes the terminfo data contained in buf.
+func Decode(buf []byte) (*Terminfo, error) {
+ var err error
+ // check max file length
+ if len(buf) >= maxFileLength {
+ return nil, ErrInvalidFileSize
+ }
+ d := &decoder{
+ buf: buf,
+ n: len(buf),
+ }
+ // read header
+ h, err := d.readInts(6, 16)
+ if err != nil {
+ return nil, err
+ }
+ var numWidth int
+ // check magic
+ switch {
+ case h[fieldMagic] == magic:
+ numWidth = 16
+ case h[fieldMagic] == magicExtended:
+ numWidth = 32
+ default:
+ return nil, ErrInvalidMagic
+ }
+ // check header
+ if hasInvalidCaps(h) {
+ return nil, ErrInvalidHeader
+ }
+ // check remaining length
+ if d.n-d.pos < capLength(h) {
+ return nil, ErrUnexpectedFileEnd
+ }
+ // read names
+ names, err := d.readBytes(h[fieldNameSize])
+ if err != nil {
+ return nil, err
+ }
+ // check name is terminated properly
+ i := findNull(names, 0)
+ if i == -1 {
+ return nil, ErrInvalidNames
+ }
+ names = names[:i]
+ // read bool caps
+ bools, boolsM, err := d.readBools(h[fieldBoolCount])
+ if err != nil {
+ return nil, err
+ }
+ // read num caps
+ nums, numsM, err := d.readNums(h[fieldNumCount], numWidth)
+ if err != nil {
+ return nil, err
+ }
+ // read string caps
+ strs, strsM, err := d.readStrings(h[fieldStringCount], h[fieldTableSize])
+ if err != nil {
+ return nil, err
+ }
+ ti := &Terminfo{
+ Names: strings.Split(string(names), "|"),
+ Bools: bools,
+ BoolsM: boolsM,
+ Nums: nums,
+ NumsM: numsM,
+ Strings: strs,
+ StringsM: strsM,
+ }
+ // at the end of file, so no extended caps
+ if d.pos >= d.n {
+ return ti, nil
+ }
+ // decode extended header
+ eh, err := d.readInts(5, 16)
+ if err != nil {
+ return nil, err
+ }
+ // check extended offset field
+ if hasInvalidExtOffset(eh) {
+ return nil, ErrInvalidExtendedHeader
+ }
+ // check extended cap lengths
+ if d.n-d.pos != extCapLength(eh, numWidth) {
+ return nil, ErrInvalidExtendedHeader
+ }
+ // read extended bool caps
+ ti.ExtBools, _, err = d.readBools(eh[fieldExtBoolCount])
+ if err != nil {
+ return nil, err
+ }
+ // read extended num caps
+ ti.ExtNums, _, err = d.readNums(eh[fieldExtNumCount], numWidth)
+ if err != nil {
+ return nil, err
+ }
+ // read extended string data table indexes
+ extIndexes, err := d.readInts(eh[fieldExtOffsetCount], 16)
+ if err != nil {
+ return nil, err
+ }
+ // read string data table
+ extData, err := d.readBytes(eh[fieldExtTableSize])
+ if err != nil {
+ return nil, err
+ }
+ // precautionary check that exactly at end of file
+ if d.pos != d.n {
+ return nil, ErrUnexpectedFileEnd
+ }
+ var last int
+ // read extended string caps
+ ti.ExtStrings, last, err = readStrings(extIndexes, extData, eh[fieldExtStringCount])
+ if err != nil {
+ return nil, err
+ }
+ extIndexes, extData = extIndexes[eh[fieldExtStringCount]:], extData[last:]
+ // read extended bool names
+ ti.ExtBoolNames, _, err = readStrings(extIndexes, extData, eh[fieldExtBoolCount])
+ if err != nil {
+ return nil, err
+ }
+ extIndexes = extIndexes[eh[fieldExtBoolCount]:]
+ // read extended num names
+ ti.ExtNumNames, _, err = readStrings(extIndexes, extData, eh[fieldExtNumCount])
+ if err != nil {
+ return nil, err
+ }
+ extIndexes = extIndexes[eh[fieldExtNumCount]:]
+ // read extended string names
+ ti.ExtStringNames, _, err = readStrings(extIndexes, extData, eh[fieldExtStringCount])
+ if err != nil {
+ return nil, err
+ }
+ // extIndexes = extIndexes[eh[fieldExtStringCount]:]
+ return ti, nil
+}
+
+// Open reads the terminfo file name from the specified directory dir.
+func Open(dir, name string) (*Terminfo, error) {
+ var err error
+ var buf []byte
+ var filename string
+ for _, f := range []string{
+ path.Join(dir, name[0:1], name),
+ path.Join(dir, strconv.FormatUint(uint64(name[0]), 16), name),
+ } {
+ buf, err = ioutil.ReadFile(f)
+ if err == nil {
+ filename = f
+ break
+ }
+ }
+ if buf == nil {
+ return nil, ErrFileNotFound
+ }
+ // decode
+ ti, err := Decode(buf)
+ if err != nil {
+ return nil, err
+ }
+ // save original file name
+ ti.File = filename
+ // add to cache
+ termCache.Lock()
+ for _, n := range ti.Names {
+ termCache.db[n] = ti
+ }
+ termCache.Unlock()
+ return ti, nil
+}
+
+// boolCaps returns all bool and extended capabilities using f to format the
+// index key.
+func (ti *Terminfo) boolCaps(f func(int) string, extended bool) map[string]bool {
+ m := make(map[string]bool, len(ti.Bools)+len(ti.ExtBools))
+ if !extended {
+ for k, v := range ti.Bools {
+ m[f(k)] = v
+ }
+ } else {
+ for k, v := range ti.ExtBools {
+ m[string(ti.ExtBoolNames[k])] = v
+ }
+ }
+ return m
+}
+
+// BoolCaps returns all bool capabilities.
+func (ti *Terminfo) BoolCaps() map[string]bool {
+ return ti.boolCaps(BoolCapName, false)
+}
+
+// BoolCapsShort returns all bool capabilities, using the short name as the
+// index.
+func (ti *Terminfo) BoolCapsShort() map[string]bool {
+ return ti.boolCaps(BoolCapNameShort, false)
+}
+
+// ExtBoolCaps returns all extended bool capabilities.
+func (ti *Terminfo) ExtBoolCaps() map[string]bool {
+ return ti.boolCaps(BoolCapName, true)
+}
+
+// ExtBoolCapsShort returns all extended bool capabilities, using the short
+// name as the index.
+func (ti *Terminfo) ExtBoolCapsShort() map[string]bool {
+ return ti.boolCaps(BoolCapNameShort, true)
+}
+
+// numCaps returns all num and extended capabilities using f to format the
+// index key.
+func (ti *Terminfo) numCaps(f func(int) string, extended bool) map[string]int {
+ m := make(map[string]int, len(ti.Nums)+len(ti.ExtNums))
+ if !extended {
+ for k, v := range ti.Nums {
+ m[f(k)] = v
+ }
+ } else {
+ for k, v := range ti.ExtNums {
+ m[string(ti.ExtNumNames[k])] = v
+ }
+ }
+ return m
+}
+
+// NumCaps returns all num capabilities.
+func (ti *Terminfo) NumCaps() map[string]int {
+ return ti.numCaps(NumCapName, false)
+}
+
+// NumCapsShort returns all num capabilities, using the short name as the
+// index.
+func (ti *Terminfo) NumCapsShort() map[string]int {
+ return ti.numCaps(NumCapNameShort, false)
+}
+
+// ExtNumCaps returns all extended num capabilities.
+func (ti *Terminfo) ExtNumCaps() map[string]int {
+ return ti.numCaps(NumCapName, true)
+}
+
+// ExtNumCapsShort returns all extended num capabilities, using the short
+// name as the index.
+func (ti *Terminfo) ExtNumCapsShort() map[string]int {
+ return ti.numCaps(NumCapNameShort, true)
+}
+
+// stringCaps returns all string and extended capabilities using f to format the
+// index key.
+func (ti *Terminfo) stringCaps(f func(int) string, extended bool) map[string][]byte {
+ m := make(map[string][]byte, len(ti.Strings)+len(ti.ExtStrings))
+ if !extended {
+ for k, v := range ti.Strings {
+ m[f(k)] = v
+ }
+ } else {
+ for k, v := range ti.ExtStrings {
+ m[string(ti.ExtStringNames[k])] = v
+ }
+ }
+ return m
+}
+
+// StringCaps returns all string capabilities.
+func (ti *Terminfo) StringCaps() map[string][]byte {
+ return ti.stringCaps(StringCapName, false)
+}
+
+// StringCapsShort returns all string capabilities, using the short name as the
+// index.
+func (ti *Terminfo) StringCapsShort() map[string][]byte {
+ return ti.stringCaps(StringCapNameShort, false)
+}
+
+// ExtStringCaps returns all extended string capabilities.
+func (ti *Terminfo) ExtStringCaps() map[string][]byte {
+ return ti.stringCaps(StringCapName, true)
+}
+
+// ExtStringCapsShort returns all extended string capabilities, using the short
+// name as the index.
+func (ti *Terminfo) ExtStringCapsShort() map[string][]byte {
+ return ti.stringCaps(StringCapNameShort, true)
+}
+
+// Has determines if the bool cap i is present.
+func (ti *Terminfo) Has(i int) bool {
+ return ti.Bools[i]
+}
+
+// Num returns the num cap i, or -1 if not present.
+func (ti *Terminfo) Num(i int) int {
+ n, ok := ti.Nums[i]
+ if !ok {
+ return -1
+ }
+ return n
+}
+
+// Printf formats the string cap i, interpolating parameters v.
+func (ti *Terminfo) Printf(i int, v ...interface{}) string {
+ return Printf(ti.Strings[i], v...)
+}
+
+// Fprintf prints the string cap i to writer w, interpolating parameters v.
+func (ti *Terminfo) Fprintf(w io.Writer, i int, v ...interface{}) {
+ Fprintf(w, ti.Strings[i], v...)
+}
+
+// Color takes a foreground and background color and returns string that sets
+// them for this terminal.
+func (ti *Terminfo) Colorf(fg, bg int, str string) string {
+ maxColors := int(ti.Nums[MaxColors])
+ // map bright colors to lower versions if the color table only holds 8.
+ if maxColors == 8 {
+ if fg > 7 && fg < 16 {
+ fg -= 8
+ }
+ if bg > 7 && bg < 16 {
+ bg -= 8
+ }
+ }
+ var s string
+ if maxColors > fg && fg >= 0 {
+ s += ti.Printf(SetAForeground, fg)
+ }
+ if maxColors > bg && bg >= 0 {
+ s += ti.Printf(SetABackground, bg)
+ }
+ return s + str + ti.Printf(ExitAttributeMode)
+}
+
+// Goto returns a string suitable for addressing the cursor at the given
+// row and column. The origin 0, 0 is in the upper left corner of the screen.
+func (ti *Terminfo) Goto(row, col int) string {
+ return Printf(ti.Strings[CursorAddress], row, col)
+}
+
+// Puts emits the string to the writer, but expands inline padding indications
+// (of the form $<[delay]> where [delay] is msec) to a suitable number of
+// padding characters (usually null bytes) based upon the supplied baud. At
+// high baud rates, more padding characters will be inserted.
+/*func (ti *Terminfo) Puts(w io.Writer, s string, lines, baud int) (int, error) {
+ var err error
+ for {
+ start := strings.Index(s, "$<")
+ if start == -1 {
+ // most strings don't need padding, which is good news!
+ return io.WriteString(w, s)
+ }
+ end := strings.Index(s, ">")
+ if end == -1 {
+ // unterminated... just emit bytes unadulterated.
+ return io.WriteString(w, "$<"+s)
+ }
+ var c int
+ c, err = io.WriteString(w, s[:start])
+ if err != nil {
+ return n + c, err
+ }
+ n += c
+ s = s[start+2:]
+ val := s[:end]
+ s = s[end+1:]
+ var ms int
+ var dot, mandatory, asterisk bool
+ unit := 1000
+ for _, ch := range val {
+ switch {
+ case ch >= '0' && ch <= '9':
+ ms = (ms * 10) + int(ch-'0')
+ if dot {
+ unit *= 10
+ }
+ case ch == '.' && !dot:
+ dot = true
+ case ch == '*' && !asterisk:
+ ms *= lines
+ asterisk = true
+ case ch == '/':
+ mandatory = true
+ default:
+ break
+ }
+ }
+ z, pad := ((baud/8)/unit)*ms, ti.Strings[PadChar]
+ b := make([]byte, len(pad)*z)
+ for bp := copy(b, pad); bp < len(b); bp *= 2 {
+ copy(b[bp:], b[:bp])
+ }
+ if (!ti.Bools[XonXoff] && baud > int(ti.Nums[PaddingBaudRate])) || mandatory {
+ c, err = w.Write(b)
+ if err != nil {
+ return n + c, err
+ }
+ n += c
+ }
+ }
+ return n, nil
+}*/
diff --git a/vendor/modules.txt b/vendor/modules.txt
index e635074d..1408f65c 100644
--- a/vendor/modules.txt
+++ b/vendor/modules.txt
@@ -62,8 +62,8 @@ github.com/charmbracelet/bubbles/runeutil
github.com/charmbracelet/bubbles/spinner
github.com/charmbracelet/bubbles/textinput
github.com/charmbracelet/bubbles/viewport
-# github.com/charmbracelet/bubbletea v0.25.0
-## explicit; go 1.17
+# github.com/charmbracelet/bubbletea v0.26.6
+## explicit; go 1.18
github.com/charmbracelet/bubbletea
# github.com/charmbracelet/glamour v0.6.0
## explicit; go 1.13
@@ -72,9 +72,19 @@ github.com/charmbracelet/glamour/ansi
# github.com/charmbracelet/lipgloss v0.10.0
## explicit; go 1.18
github.com/charmbracelet/lipgloss
-# github.com/containerd/console v1.0.4-0.20230313162750-1ae8d489ac81
-## explicit; go 1.13
-github.com/containerd/console
+# github.com/charmbracelet/x/ansi v0.1.2
+## explicit; go 1.18
+github.com/charmbracelet/x/ansi
+github.com/charmbracelet/x/ansi/parser
+# github.com/charmbracelet/x/input v0.1.0
+## explicit; go 1.18
+github.com/charmbracelet/x/input
+# github.com/charmbracelet/x/term v0.1.1
+## explicit; go 1.18
+github.com/charmbracelet/x/term
+# github.com/charmbracelet/x/windows v0.1.0
+## explicit; go 1.18
+github.com/charmbracelet/x/windows
# github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc
## explicit
github.com/davecgh/go-spew/spew
@@ -82,6 +92,9 @@ github.com/davecgh/go-spew/spew
## explicit
github.com/dlclark/regexp2
github.com/dlclark/regexp2/syntax
+# github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f
+## explicit; go 1.16
+github.com/erikgeiser/coninput
# github.com/felixge/httpsnoop v1.0.3
## explicit; go 1.13
github.com/felixge/httpsnoop
@@ -231,7 +244,7 @@ github.com/mitchellh/mapstructure
# github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826
## explicit
github.com/mohae/deepcopy
-# github.com/muesli/ansi v0.0.0-20211018074035-2e021307bc4b
+# github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6
## explicit; go 1.17
github.com/muesli/ansi
github.com/muesli/ansi/compressor
@@ -339,6 +352,9 @@ github.com/stretchr/testify/require
# github.com/subosito/gotenv v1.6.0
## explicit; go 1.18
github.com/subosito/gotenv
+# github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e
+## explicit; go 1.19
+github.com/xo/terminfo
# github.com/yuin/goldmark v1.5.2
## explicit; go 1.18
github.com/yuin/goldmark