diff --git a/go.mod b/go.mod index bc0819fcd..62c2e3b0f 100644 --- a/go.mod +++ b/go.mod @@ -16,7 +16,7 @@ require ( github.com/hako/durafmt v0.0.0-20210608085754-5c1018a4e16b github.com/hinshun/vt10x v0.0.0-20220228203356-1ab2cad5fd82 github.com/jonboulle/clockwork v0.4.0 - github.com/ktr0731/go-fuzzyfinder v0.7.0 + github.com/ktr0731/go-fuzzyfinder v0.8.0 github.com/mitchellh/go-homedir v1.1.0 github.com/pkg/errors v0.9.1 github.com/sigstore/cosign/v2 v2.2.0 @@ -133,7 +133,7 @@ require ( github.com/fsnotify/fsnotify v1.6.0 // indirect github.com/gabriel-vasile/mimetype v1.4.2 // indirect github.com/gdamore/encoding v1.0.0 // indirect - github.com/gdamore/tcell/v2 v2.5.3 // indirect + github.com/gdamore/tcell/v2 v2.6.0 // indirect github.com/go-chi/chi v4.1.2+incompatible // indirect github.com/go-chi/chi/v5 v5.0.10 // indirect github.com/go-errors/errors v1.0.1 // indirect @@ -219,7 +219,7 @@ require ( github.com/mailru/easyjson v0.7.7 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.20 // indirect - github.com/mattn/go-runewidth v0.0.14 // indirect + github.com/mattn/go-runewidth v0.0.15 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d // indirect github.com/miekg/pkcs11 v1.1.1 // indirect @@ -247,7 +247,7 @@ require ( github.com/prometheus/procfs v0.11.1 // indirect github.com/prometheus/statsd_exporter v0.22.7 // indirect github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect - github.com/rivo/uniseg v0.4.2 // indirect + github.com/rivo/uniseg v0.4.3 // indirect github.com/russross/blackfriday v1.6.0 // indirect github.com/ryanuber/go-glob v1.0.0 // indirect github.com/sagikazarmark/locafero v0.3.0 // indirect diff --git a/go.sum b/go.sum index dd871789f..ee97f9d81 100644 --- a/go.sum +++ b/go.sum @@ -437,8 +437,8 @@ github.com/gabriel-vasile/mimetype v1.4.2 h1:w5qFW6JKBz9Y393Y4q372O9A7cUSequkh1Q github.com/gabriel-vasile/mimetype v1.4.2/go.mod h1:zApsH/mKG4w07erKIaJPFiX0Tsq9BFQgN3qGY5GnNgA= github.com/gdamore/encoding v1.0.0 h1:+7OoQ1Bc6eTm5niUzBa0Ctsh6JbMW6Ra+YNuAtDBdko= github.com/gdamore/encoding v1.0.0/go.mod h1:alR0ol34c49FCSBLjhosxzcPHQbf2trDkoo5dl+VrEg= -github.com/gdamore/tcell/v2 v2.5.3 h1:b9XQrT6QGbgI7JvZOJXFNczOQeIYbo8BfeSMzt2sAV0= -github.com/gdamore/tcell/v2 v2.5.3/go.mod h1:wSkrPaXoiIWZqW/g7Px4xc79di6FTcpB8tvaKJ6uGBo= +github.com/gdamore/tcell/v2 v2.6.0 h1:OKbluoP9VYmJwZwq/iLb4BxwKcwGthaa1YNBJIyCySg= +github.com/gdamore/tcell/v2 v2.6.0/go.mod h1:be9omFATkdr0D9qewWW3d+MEvl5dha+Etb5y65J2H8Y= github.com/getkin/kin-openapi v0.76.0/go.mod h1:660oXbgy5JFMKreazJaQTw7o+X00qeSyhcnluiMv+Xg= github.com/getsentry/raven-go v0.2.0/go.mod h1:KungGk8q33+aIAZUIVWZDr2OfAEBsO49PX4NzFV5kcQ= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= @@ -898,8 +898,8 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/ktr0731/go-ansisgr v0.1.0 h1:fbuupput8739hQbEmZn1cEKjqQFwtCCZNznnF6ANo5w= github.com/ktr0731/go-ansisgr v0.1.0/go.mod h1:G9lxwgBwH0iey0Dw5YQd7n6PmQTwTuTM/X5Sgm/UrzE= -github.com/ktr0731/go-fuzzyfinder v0.7.0 h1:EqkCoqQh9Xpqet0PMAGSwgEnqLPXOSiRwIUMzhWQw2I= -github.com/ktr0731/go-fuzzyfinder v0.7.0/go.mod h1:/5RXp7U9PRhvIrM86u/9TK0FjPbZQVT/NaplQO7CZmU= +github.com/ktr0731/go-fuzzyfinder v0.8.0 h1:+yobwo9lqZZ7jd1URPdCgZXTE2U1mpIVTkQoo4roi6w= +github.com/ktr0731/go-fuzzyfinder v0.8.0/go.mod h1:Bjpz5im+tppKE9Ii6UK1h+6RaX/lUvJ0ruO4LIYRkqo= github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= github.com/leodido/go-urn v1.2.4 h1:XlAE/cm/ms7TE/VMVoduSpNBoyc2dOxHs5MZSwAN63Q= @@ -935,9 +935,9 @@ github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/ github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= -github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= -github.com/mattn/go-runewidth v0.0.14 h1:+xnbZSEeDbOIg5/mE6JF0w6n9duR1l3/WmbinWVwUuU= github.com/mattn/go-runewidth v0.0.14/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= +github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U= +github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/mattn/goveralls v0.0.2/go.mod h1:8d1ZMHsd7fW6IRPKQh46F2WRpyib5/X4FOpevwGNQEw= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= @@ -1117,8 +1117,8 @@ github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475/go.mod h1:bCqn github.com/rickb777/date v1.13.0/go.mod h1:GZf3LoGnxPWjX+/1TXOuzHefZFDovTyNLHDMd3qH70k= github.com/rickb777/plural v1.2.1/go.mod h1:j058+3M5QQFgcZZ2oKIOekcygoZUL8gKW5yRO14BuAw= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= -github.com/rivo/uniseg v0.4.2 h1:YwD0ulJSJytLpiaWua0sBDusfsCZohxjxzVTYjwxfV8= -github.com/rivo/uniseg v0.4.2/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= +github.com/rivo/uniseg v0.4.3 h1:utMvzDsuh3suAEnhH0RdHmoPbU648o6CvXxTx4SBMOw= +github.com/rivo/uniseg v0.4.3/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= @@ -1686,7 +1686,6 @@ golang.org/x/sys v0.0.0-20211124211545-fe61309f8881/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220318055525-2edf467146b5/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220319134239-a9b59b0215f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220422013727-9388b58f7150/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -1706,7 +1705,6 @@ golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc= golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.0.0-20201210144234-2321bbc49cbf/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= diff --git a/vendor/github.com/gdamore/tcell/v2/README-wasm.md b/vendor/github.com/gdamore/tcell/v2/README-wasm.md new file mode 100644 index 000000000..faf96856f --- /dev/null +++ b/vendor/github.com/gdamore/tcell/v2/README-wasm.md @@ -0,0 +1,61 @@ +# WASM for _Tcell_ + +You can build _Tcell_ project into a webpage by compiling it slightly differently. This will result in a _Tcell_ project you can embed into another html page, or use as a standalone page. + +## Building your project + +WASM needs special build flags in order to work. You can build it by executing +```sh +GOOS=js GOARCH=wasm go build -o yourfile.wasm +``` + +## Additional files + +You also need 5 other files in the same directory as the wasm. Four (`tcell.html`, `tcell.js`, `termstyle.css`, and `beep.wav`) are provided in the `webfiles` directory. The last one, `wasm_exec.js`, can be copied from GOROOT into the current directory by executing +```sh +cp "$(go env GOROOT)/misc/wasm/wasm_exec.js" ./ +``` + +In `tcell.js`, you also need to change the constant +```js +const wasmFilePath = "yourfile.wasm" +``` +to the file you outputed to when building. + +## Displaying your project + +### Standalone + +You can see the project (with an white background around the terminal) by serving the directory. You can do this using any framework, including another golang project: + +```golang +// server.go + +package main + +import ( + "log" + "net/http" +) + +func main() { + log.Fatal(http.ListenAndServe(":8080", + http.FileServer(http.Dir("/path/to/dir/to/serve")), + )) +} + +``` + +To see the webpage with this example, you can type in `localhost:8080/tcell.html` into your browser while `server.go` is running. + +### Embedding +It is recomended to use an iframe if you want to embed the app into a webpage: +```html + +``` + +## Other considerations + +### Accessing files + +`io.Open(filename)` and other related functions for reading file systems do not work; use `http.Get(filename)` instead. \ No newline at end of file diff --git a/vendor/github.com/gdamore/tcell/v2/README.md b/vendor/github.com/gdamore/tcell/v2/README.md index 78c76b6ad..347e274a2 100644 --- a/vendor/github.com/gdamore/tcell/v2/README.md +++ b/vendor/github.com/gdamore/tcell/v2/README.md @@ -6,16 +6,17 @@ _Tcell_ is a _Go_ package that provides a cell based view for text terminals, li It was inspired by _termbox_, but includes many additional improvements. [![Stand With Ukraine](https://raw.githubusercontent.com/vshymanskyy/StandWithUkraine/main/badges/StandWithUkraine.svg)](https://stand-with-ukraine.pp.ua) -[![Linux](https://img.shields.io/github/workflow/status/gdamore/tcell/linux?logoColor=grey&logo=linux&label=)](https://github.com/gdamore/tcell/actions/workflows/linux.yml) -[![Windows](https://img.shields.io/github/workflow/status/gdamore/tcell/windows?logoColor=grey&logo=windows&label=)](https://github.com/gdamore/tcell/actions/workflows/windows.yml) +[![Linux](https://img.shields.io/github/actions/workflow/status/gdamore/tcell/linux.yml?branch=main&logoColor=grey&logo=linux&label=)](https://github.com/gdamore/tcell/actions/workflows/linux.yml) +[![Windows](https://img.shields.io/github/actions/workflow/status/gdamore/tcell/windows.yml?branch=main&logoColor=grey&logo=windows&label=)](https://github.com/gdamore/tcell/actions/workflows/windows.yml) [![Apache License](https://img.shields.io/github/license/gdamore/tcell.svg?logoColor=silver&logo=opensourceinitiative&color=blue&label=)](https://github.com/gdamore/tcell/blob/master/LICENSE) [![Docs](https://img.shields.io/badge/godoc-reference-blue.svg?label=&logo=go)](https://pkg.go.dev/github.com/gdamore/tcell/v2) [![Discord](https://img.shields.io/discord/639503822733180969?label=&logo=discord)](https://discord.gg/urTTxDN) [![Coverage](https://img.shields.io/codecov/c/github/gdamore/tcell?logoColor=grey&logo=codecov&label=)](https://codecov.io/gh/gdamore/tcell) +[![Go Report Card](https://goreportcard.com/badge/github.com/gdamore/tcell/v2)](https://goreportcard.com/report/github.com/gdamore/tcell/v2) Please see [here](UKRAINE.md) for an important message for the people of Russia. -NOTE: This is version 2 of _Tcell_. There are breaking changes relative to version 1. +NOTE: This is version 2 of _Tcell_. There are breaking changes relative to version 1. Version 1.x remains available using the import `github.com/gdamore/tcell`. ## Tutorial @@ -24,51 +25,51 @@ A brief, and still somewhat rough, [tutorial](TUTORIAL.md) is available. ## Examples -* [proxima5](https://github.com/gdamore/proxima5) - space shooter ([video](https://youtu.be/jNxKTCmY_bQ)) -* [govisor](https://github.com/gdamore/govisor) - service management UI ([screenshot](http://2.bp.blogspot.com/--OsvnfzSNow/Vf7aqMw3zXI/AAAAAAAAARo/uOMtOvw4Sbg/s1600/Screen%2BShot%2B2015-09-20%2Bat%2B9.08.41%2BAM.png)) -* mouse demo - included mouse test ([screenshot](http://2.bp.blogspot.com/-fWvW5opT0es/VhIdItdKqJI/AAAAAAAAATE/7Ojc0L1SpB0/s1600/Screen%2BShot%2B2015-10-04%2Bat%2B11.47.13%2BPM.png)) -* [gomatrix](https://github.com/gdamore/gomatrix) - converted from Termbox -* [micro](https://github.com/zyedidia/micro/) - lightweight text editor with syntax-highlighting and themes -* [godu](https://github.com/viktomas/godu) - utility to discover large files/folders -* [tview](https://github.com/rivo/tview/) - rich interactive widgets -* [cview](https://code.rocketnine.space/tslocum/cview) - user interface toolkit (fork of _tview_) -* [awsome gocui](https://github.com/awesome-gocui/gocui) - Go Console User Interface -* [gomandelbrot](https://github.com/rgm3/gomandelbrot) - Mandelbrot! -* [WTF](https://github.com/senorprogrammer/wtf) - personal information dashboard -* [browsh](https://github.com/browsh-org/browsh) - modern web browser ([video](https://www.youtube.com/watch?v=HZq86XfBoRo)) -* [go-life](https://github.com/sachaos/go-life) - Conway's Game of Life -* [gowid](https://github.com/gcla/gowid) - compositional widgets for terminal UIs, inspired by _urwid_ -* [termshark](https://termshark.io) - interface for _tshark_, inspired by Wireshark, built on _gowid_ -* [go-tetris](https://github.com/MichaelS11/go-tetris) - Go Tetris with AI option -* [fzf](https://github.com/junegunn/fzf) - command-line fuzzy finder -* [ascii-fluid](https://github.com/esimov/ascii-fluid) - fluid simulation controlled by webcam -* [cbind](https://code.rocketnine.space/tslocum/cbind) - key event encoding, decoding and handling -* [tpong](https://github.com/spinzed/tpong) - old-school Pong -* [aerc](https://git.sr.ht/~sircmpwn/aerc) - email client -* [tblogs](https://github.com/ezeoleaf/tblogs) - development blogs reader -* [spinc](https://github.com/lallassu/spinc) - _irssi_ inspired chat application for Cisco Spark/WebEx -* [gorss](https://github.com/lallassu/gorss) - RSS/Atom feed reader -* [memoryalike](https://github.com/Bios-Marcel/memoryalike) - memorization game -* [lf](https://github.com/gokcehan/lf) - file manager -* [goful](https://github.com/anmitsu/goful) - CUI file manager -* [gokeybr](https://github.com/bunyk/gokeybr) - deliberately practice your typing -* [gonano](https://github.com/jbaramidze/gonano) - editor, mimics _nano_ -* [uchess](https://github.com/tmountain/uchess) - UCI chess client -* [min](https://github.com/a-h/min) - Gemini browser -* [ov](https://github.com/noborus/ov) - file pager -* [tmux-wormhole](https://github.com/gcla/tmux-wormhole) - _tmux_ plugin to transfer files -* [gruid-tcell](https://github.com/anaseto/gruid-tcell) - driver for the grid based UI and game framework -* [aretext](https://github.com/aretext/aretext) - minimalist text editor with _vim_ key bindings -* [sync](https://github.com/kyprifog/sync) - GitHub repo synchronization tool -* [statusbar](https://github.com/kyprifog/statusbar) - statusbar motivation tool for tracking periodic tasks/goals -* [todo](https://github.com/kyprifog/todo) - simple todo app -* [gosnakego](https://github.com/liweiyi88/gosnakego) - a snake game - +- [proxima5](https://github.com/gdamore/proxima5) - space shooter ([video](https://youtu.be/jNxKTCmY_bQ)) +- [govisor](https://github.com/gdamore/govisor) - service management UI ([screenshot](http://2.bp.blogspot.com/--OsvnfzSNow/Vf7aqMw3zXI/AAAAAAAAARo/uOMtOvw4Sbg/s1600/Screen%2BShot%2B2015-09-20%2Bat%2B9.08.41%2BAM.png)) +- mouse demo - included mouse test ([screenshot](http://2.bp.blogspot.com/-fWvW5opT0es/VhIdItdKqJI/AAAAAAAAATE/7Ojc0L1SpB0/s1600/Screen%2BShot%2B2015-10-04%2Bat%2B11.47.13%2BPM.png)) +- [gomatrix](https://github.com/gdamore/gomatrix) - converted from Termbox +- [micro](https://github.com/zyedidia/micro/) - lightweight text editor with syntax-highlighting and themes +- [godu](https://github.com/viktomas/godu) - utility to discover large files/folders +- [tview](https://github.com/rivo/tview/) - rich interactive widgets +- [cview](https://code.rocketnine.space/tslocum/cview) - user interface toolkit (fork of _tview_) +- [awsome gocui](https://github.com/awesome-gocui/gocui) - Go Console User Interface +- [gomandelbrot](https://github.com/rgm3/gomandelbrot) - Mandelbrot! +- [WTF](https://github.com/senorprogrammer/wtf) - personal information dashboard +- [browsh](https://github.com/browsh-org/browsh) - modern web browser ([video](https://www.youtube.com/watch?v=HZq86XfBoRo)) +- [go-life](https://github.com/sachaos/go-life) - Conway's Game of Life +- [gowid](https://github.com/gcla/gowid) - compositional widgets for terminal UIs, inspired by _urwid_ +- [termshark](https://termshark.io) - interface for _tshark_, inspired by Wireshark, built on _gowid_ +- [go-tetris](https://github.com/MichaelS11/go-tetris) - Go Tetris with AI option +- [fzf](https://github.com/junegunn/fzf) - command-line fuzzy finder +- [ascii-fluid](https://github.com/esimov/ascii-fluid) - fluid simulation controlled by webcam +- [cbind](https://code.rocketnine.space/tslocum/cbind) - key event encoding, decoding and handling +- [tpong](https://github.com/spinzed/tpong) - old-school Pong +- [aerc](https://git.sr.ht/~sircmpwn/aerc) - email client +- [tblogs](https://github.com/ezeoleaf/tblogs) - development blogs reader +- [spinc](https://github.com/lallassu/spinc) - _irssi_ inspired chat application for Cisco Spark/WebEx +- [gorss](https://github.com/lallassu/gorss) - RSS/Atom feed reader +- [memoryalike](https://github.com/Bios-Marcel/memoryalike) - memorization game +- [lf](https://github.com/gokcehan/lf) - file manager +- [goful](https://github.com/anmitsu/goful) - CUI file manager +- [gokeybr](https://github.com/bunyk/gokeybr) - deliberately practice your typing +- [gonano](https://github.com/jbaramidze/gonano) - editor, mimics _nano_ +- [uchess](https://github.com/tmountain/uchess) - UCI chess client +- [min](https://github.com/a-h/min) - Gemini browser +- [ov](https://github.com/noborus/ov) - file pager +- [tmux-wormhole](https://github.com/gcla/tmux-wormhole) - _tmux_ plugin to transfer files +- [gruid-tcell](https://github.com/anaseto/gruid-tcell) - driver for the grid based UI and game framework +- [aretext](https://github.com/aretext/aretext) - minimalist text editor with _vim_ key bindings +- [sync](https://github.com/kyprifog/sync) - GitHub repo synchronization tool +- [statusbar](https://github.com/kyprifog/statusbar) - statusbar motivation tool for tracking periodic tasks/goals +- [todo](https://github.com/kyprifog/todo) - simple todo app +- [gosnakego](https://github.com/liweiyi88/gosnakego) - a snake game +- [gbb](https://github.com/sdemingo/gbb) - A classical bulletin board app for tildes or public unix servers ## Pure Go Terminfo Database _Tcell_ includes a full parser and expander for terminfo capability strings, -so that it can avoid hard coding escape strings for formatting. It also favors +so that it can avoid hard coding escape strings for formatting. It also favors portability, and includes support for all POSIX systems. The database is also flexible & extensible, and can be modified by either running @@ -113,7 +114,7 @@ For example attempts to emit color sequences on VT100 terminals won't result in unintended consequences. In legacy Windows mode, _Tcell_ supports 16 colors, bold, dim, and reverse, -instead of just termbox's 8 colors with reverse. (Note that there is some +instead of just termbox's 8 colors with reverse. (Note that there is some conflation with bold/dim and colors.) Modern Windows 10 can benefit from much richer colors however. @@ -126,7 +127,7 @@ _Tcell_ supports enhanced mouse tracking mode, so your application can receive regular mouse motion events, and wheel events, if your terminal supports it. (Note: The Windows 10 Terminal application suffers from a flaw in this regard, -and does not support mouse interaction. The stock Windows 10 console host +and does not support mouse interaction. The stock Windows 10 console host fired up with cmd.exe or PowerShell works fine however.) ## _Termbox_ Compatibility @@ -151,7 +152,7 @@ The `SetContent()` API takes a primary rune, and an optional list of combining r If any of the runes is a wide (East Asian) rune occupying two cells, then the library will skip output from the following cell. Care must be taken in the application to avoid explicitly attempting to set content in the -next cell, otherwise the results are undefined. (Normally the wide character +next cell, otherwise the results are undefined. (Normally the wide character is displayed, and the other character is not; do not depend on that behavior.) Older terminal applications (especially on systems like Windows 8) lack support @@ -160,15 +161,15 @@ for advanced Unicode, and thus may not fare well. ## Colors _Tcell_ assumes the ANSI/XTerm color model, including the 256 color map that -XTerm uses when it supports 256 colors. The terminfo guidance will be -honored, with respect to the number of colors supported. Also, only +XTerm uses when it supports 256 colors. The terminfo guidance will be +honored, with respect to the number of colors supported. Also, only terminals which expose ANSI style `setaf` and `setab` will support color; if you have a color terminal that only has `setf` and `setb`, please submit a ticket. ## 24-bit Color -_Tcell_ _supports 24-bit color!_ (That is, if your terminal can support it.) +_Tcell_ _supports 24-bit color!_ (That is, if your terminal can support it.) NOTE: Technically the approach of using 24-bit RGB values for color is more accurately described as "direct color", but most people use the term "true color". @@ -176,26 +177,26 @@ We follow the (inaccurate) common convention. There are a few ways you can enable (or disable) true color. -* For many terminals, we can detect it automatically if your terminal -includes the `RGB` or `Tc` capabilities (or rather it did when the database -was updated.) +- For many terminals, we can detect it automatically if your terminal + includes the `RGB` or `Tc` capabilities (or rather it did when the database + was updated.) -* You can force this one by setting the `COLORTERM` environment variable to -`24-bit`, `truecolor` or `24bit`. This is the same method used -by most other terminal applications that support 24-bit color. +- You can force this one by setting the `COLORTERM` environment variable to + `24-bit`, `truecolor` or `24bit`. This is the same method used + by most other terminal applications that support 24-bit color. -* If you set your `TERM` environment variable to a value with the suffix `-truecolor` -then 24-bit color compatible with XTerm and ECMA-48 will be assumed. -(This feature is deprecated. -It is recommended to use one of other methods listed above.) +- If you set your `TERM` environment variable to a value with the suffix `-truecolor` + then 24-bit color compatible with XTerm and ECMA-48 will be assumed. + (This feature is deprecated. + It is recommended to use one of other methods listed above.) -* You can disable 24-bit color by setting `TCELL_TRUECOLOR=disable` in your -environment. +- You can disable 24-bit color by setting `TCELL_TRUECOLOR=disable` in your + environment. When using TrueColor, programs will display the colors that the programmer intended, overriding any "`themes`" you may have set in your terminal -emulator. (For some cases, accurate color fidelity is more important -than respecting themes. For other cases, such as typical text apps that +emulator. (For some cases, accurate color fidelity is more important +than respecting themes. For other cases, such as typical text apps that only use a few colors, its more desirable to respect the themes that the user has established.) @@ -209,7 +210,7 @@ avoiding repeated sequences or drawing the same cell on refresh updates. (Not relevant for Windows users.) The Terminfo implementation operates with a built-in database. -This should satisfy most users. However, it can also (on systems +This should satisfy most users. However, it can also (on systems with ncurses installed), dynamically parse the output from `infocmp` for terminals it does not already know about. @@ -226,8 +227,8 @@ since the early 1970s. Mouse support is detected via the `kmous` terminfo variable, however, enablement/disablement and decoding mouse events is done using hard coded -sequences based on the XTerm X11 model. All popular -terminals with mouse tracking support this model. (Full terminfo support +sequences based on the XTerm X11 model. All popular +terminals with mouse tracking support this model. (Full terminfo support is not possible as terminfo sequences are not defined.) On Windows, the mouse works normally. @@ -240,12 +241,12 @@ Modern _xterm_, macOS _Terminal_, and _iTerm_ all work well. ## Bracketed Paste Terminals that appear to support the XTerm mouse model also can support -bracketed paste, for applications that opt-in. See `EnablePaste()` for details. +bracketed paste, for applications that opt-in. See `EnablePaste()` for details. ## Testability There is a `SimulationScreen`, that can be used to simulate a real screen -for automated testing. The supplied tests do this. The simulation contains +for automated testing. The supplied tests do this. The simulation contains event delivery, screen resizing support, and capabilities to inject events and examine "`physical`" screen contents. @@ -253,8 +254,8 @@ and examine "`physical`" screen contents. ### POSIX (Linux, FreeBSD, macOS, Solaris, etc.) -Everything works using pure Go on mainstream platforms. Some more esoteric -platforms (e.g., AIX) may need to be added. Pull requests are welcome! +Everything works using pure Go on mainstream platforms. Some more esoteric +platforms (e.g., AIX) may need to be added. Pull requests are welcome! ### Windows @@ -263,19 +264,23 @@ Windows console mode applications are supported. Modern console applications like ConEmu and the Windows 10 terminal, support all the good features (resize, mouse tracking, etc.) -### Plan9, WASM, and others +### WASM + +WASM is supported, but needs additional setup detailed in [README-wasm](README-wasm.md). + +### Plan9 and others These platforms won't work, but compilation stubs are supplied for folks that want to include parts of this in software for those -platforms. The Simulation screen works, but as _Tcell_ doesn't know how to +platforms. The Simulation screen works, but as _Tcell_ doesn't know how to allocate a real screen object on those platforms, `NewScreen()` will fail. If anyone has wisdom about how to improve support for these, -please let me know. PRs are especially welcome. +please let me know. PRs are especially welcome. ### Commercial Support _Tcell_ is absolutely free, but if you want to obtain commercial, professional support, there are options. -* [TideLift](https://tidelift.com/) subscriptions include support for _Tcell_, as well as many other open source packages. -* [Staysail Systems Inc.](mailto:info@staysail.tech) offers direct support, and custom development around _Tcell_ on an hourly basis. +- [TideLift](https://tidelift.com/) subscriptions include support for _Tcell_, as well as many other open source packages. +- [Staysail Systems Inc.](mailto:info@staysail.tech) offers direct support, and custom development around _Tcell_ on an hourly basis. \ No newline at end of file diff --git a/vendor/github.com/gdamore/tcell/v2/TUTORIAL.md b/vendor/github.com/gdamore/tcell/v2/TUTORIAL.md index 8d14f3311..f52fcff0d 100644 --- a/vendor/github.com/gdamore/tcell/v2/TUTORIAL.md +++ b/vendor/github.com/gdamore/tcell/v2/TUTORIAL.md @@ -18,7 +18,7 @@ to the terminal capabilities. Applications receive an event of type `EventResize` when they are first initialized and each time the terminal is resized. The new size is available as `Size`. -```golang +```go switch ev := ev.(type) { case *tcell.EventResize: w, h := ev.Size() @@ -35,7 +35,7 @@ When a rune key is pressed, an event with its `Key` set to `KeyRune` is dispatch When a non-rune key is pressed, it is available as the `Key` of the event. -```golang +```go switch ev := ev.(type) { case *tcell.EventKey: mod, key, ch := ev.Mod(), ev.Key(), ev.Rune() @@ -62,7 +62,7 @@ Mouse events are only delivered if The mouse buttons being pressed (if any) are available as `Buttons`, and the position of the mouse is available as `Position`. -```golang +```go switch ev := ev.(type) { case *tcell.EventMouse: mod := ev.Modifiers() @@ -81,12 +81,16 @@ Button2 | ButtonSecondary | Right button Button3 | ButtonMiddle | Middle button Button4 | | Side button (thumb/next) Button5 | | Side button (thumb/prev) +WheelUp | | Scroll wheel up +WheelDown | | Scroll wheel down +WheelLeft | | Horizontal wheel left +WheelRight | | Horizontal wheel right ## Usage -To create a tcell application, first initialize a screen to hold it. +To create a _Tcell_ application, first initialize a screen to hold it. -```golang +```go s, err := tcell.NewScreen() if err != nil { log.Fatalf("%+v", err) @@ -105,7 +109,7 @@ s.Clear() Text may be drawn on the screen using `SetContent`. -```golang +```go s.SetContent(0, 0, 'H', nil, defStyle) s.SetContent(1, 0, 'i', nil, defStyle) s.SetContent(2, 0, '!', nil, defStyle) @@ -113,7 +117,7 @@ s.SetContent(2, 0, '!', nil, defStyle) To draw text more easily, define a render function. -```golang +```go func drawText(s tcell.Screen, x1, y1, x2, y2 int, style tcell.Style, text string) { row := y1 col := x1 @@ -133,7 +137,7 @@ func drawText(s tcell.Screen, x1, y1, x2, y2 int, style tcell.Style, text string Lastly, define an event loop to handle user input and update application state. -```golang +```go quit := func() { s.Fini() os.Exit(0) @@ -161,13 +165,12 @@ for { The following demonstrates how to initialize a screen, draw text/graphics and handle user input. -```golang +```go package main import ( "fmt" "log" - "os" "github.com/gdamore/tcell/v2" ) @@ -245,12 +248,29 @@ func main() { drawBox(s, 1, 1, 42, 7, boxStyle, "Click and drag to draw a box") drawBox(s, 5, 9, 32, 14, boxStyle, "Press C to reset") - // Event loop - ox, oy := -1, -1 quit := func() { + // You have to catch panics in a defer, clean up, and + // re-raise them - otherwise your application can + // die without leaving any diagnostic trace. + maybePanic := recover() s.Fini() - os.Exit(0) + if maybePanic != nil { + panic(maybePanic) + } } + defer quit() + + // Here's how to get the screen size when you need it. + // xmax, ymax := s.Size() + + // Here's an example of how to inject a keystroke where it will + // be picked up by the next PollEvent call. Note that the + // queue is LIFO, it has a limited length, and PostEvent() can + // return an error. + // s.PostEvent(tcell.NewEventKey(tcell.KeyRune, rune('a'), 0)) + + // Event loop + ox, oy := -1, -1 for { // Update screen s.Show() @@ -264,7 +284,7 @@ func main() { s.Sync() case *tcell.EventKey: if ev.Key() == tcell.KeyEscape || ev.Key() == tcell.KeyCtrlC { - quit() + return } else if ev.Key() == tcell.KeyCtrlL { s.Sync() } else if ev.Rune() == 'C' || ev.Rune() == 'c' { @@ -272,14 +292,13 @@ func main() { } case *tcell.EventMouse: x, y := ev.Position() - button := ev.Buttons() - // Only process button events, not wheel events - button &= tcell.ButtonMask(0xff) - if button != tcell.ButtonNone && ox < 0 { - ox, oy = x, y - } switch ev.Buttons() { + case tcell.Button1, tcell.Button2: + if ox < 0 { + ox, oy = x, y // record location when click started + } + case tcell.ButtonNone: if ox >= 0 { label := fmt.Sprintf("%d,%d to %d,%d", ox, oy, x, y) @@ -291,3 +310,4 @@ func main() { } } ``` + diff --git a/vendor/github.com/gdamore/tcell/v2/cell.go b/vendor/github.com/gdamore/tcell/v2/cell.go index c7f8f1ade..756a5068d 100644 --- a/vendor/github.com/gdamore/tcell/v2/cell.go +++ b/vendor/github.com/gdamore/tcell/v2/cell.go @@ -1,4 +1,4 @@ -// Copyright 2019 The TCell Authors +// Copyright 2022 The TCell Authors // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use file except in compliance with the License. @@ -15,6 +15,8 @@ package tcell import ( + "os" + runewidth "github.com/mattn/go-runewidth" ) @@ -48,6 +50,10 @@ func (cb *CellBuffer) SetContent(x int, y int, if x >= 0 && y >= 0 && x < cb.w && y < cb.h { c := &cb.cells[(y*cb.w)+x] + for i := 1; i < c.width; i++ { + cb.SetDirty(x+i, y, true) + } + c.currComb = append([]rune{}, combc...) if c.currMain != mainc { @@ -175,3 +181,21 @@ func (cb *CellBuffer) Fill(r rune, style Style) { c.width = 1 } } + +var runeConfig *runewidth.Condition + +func init() { + // The defaults for the runewidth package are poorly chosen for terminal + // applications. We however will honor the setting in the environment if + // it is set. + if os.Getenv("RUNEWIDTH_EASTASIAN") == "" { + runewidth.DefaultCondition.EastAsianWidth = false + } + + // For performance reasons, we create a lookup table. However some users + // might be more memory conscious. If that's you, set the TCELL_MINIMIZE + // environment variable. + if os.Getenv("TCELL_MINIMIZE") == "" { + runewidth.CreateLUT() + } +} diff --git a/vendor/github.com/gdamore/tcell/v2/charset_stub.go b/vendor/github.com/gdamore/tcell/v2/charset_stub.go index c1c1594c7..ec4d260da 100644 --- a/vendor/github.com/gdamore/tcell/v2/charset_stub.go +++ b/vendor/github.com/gdamore/tcell/v2/charset_stub.go @@ -1,3 +1,4 @@ +//go:build plan9 || nacl // +build plan9 nacl // Copyright 2015 The TCell Authors diff --git a/vendor/github.com/gdamore/tcell/v2/charset_unix.go b/vendor/github.com/gdamore/tcell/v2/charset_unix.go index d9f9d8e1f..8bbf1f5ed 100644 --- a/vendor/github.com/gdamore/tcell/v2/charset_unix.go +++ b/vendor/github.com/gdamore/tcell/v2/charset_unix.go @@ -1,3 +1,4 @@ +//go:build !windows && !nacl && !plan9 // +build !windows,!nacl,!plan9 // Copyright 2016 The TCell Authors diff --git a/vendor/github.com/gdamore/tcell/v2/charset_windows.go b/vendor/github.com/gdamore/tcell/v2/charset_windows.go index 2400aa8a3..08068a02b 100644 --- a/vendor/github.com/gdamore/tcell/v2/charset_windows.go +++ b/vendor/github.com/gdamore/tcell/v2/charset_windows.go @@ -1,3 +1,4 @@ +//go:build windows // +build windows // Copyright 2015 The TCell Authors diff --git a/vendor/github.com/gdamore/tcell/v2/color.go b/vendor/github.com/gdamore/tcell/v2/color.go index 8e50fa302..e6581b0f6 100644 --- a/vendor/github.com/gdamore/tcell/v2/color.go +++ b/vendor/github.com/gdamore/tcell/v2/color.go @@ -1002,14 +1002,14 @@ func (c Color) IsRGB() bool { } // Hex returns the color's hexadecimal RGB 24-bit value with each component -// consisting of a single byte, ala R << 16 | G << 8 | B. If the color +// consisting of a single byte, R << 16 | G << 8 | B. If the color // is unknown or unset, -1 is returned. func (c Color) Hex() int32 { if !c.Valid() { return -1 } if c&ColorIsRGB != 0 { - return int32(c) & 0xffffff + return int32(c & 0xffffff) } if v, ok := ColorValues[c]; ok { return v @@ -1036,7 +1036,7 @@ func (c Color) TrueColor() Color { return ColorDefault } if c&ColorIsRGB != 0 { - return c + return c | ColorValid } return Color(c.Hex()) | ColorIsRGB | ColorValid } diff --git a/vendor/github.com/gdamore/tcell/v2/colorfit.go b/vendor/github.com/gdamore/tcell/v2/colorfit.go index b7740b8ae..f690097f5 100644 --- a/vendor/github.com/gdamore/tcell/v2/colorfit.go +++ b/vendor/github.com/gdamore/tcell/v2/colorfit.go @@ -15,8 +15,9 @@ package tcell import ( - "github.com/lucasb-eyer/go-colorful" "math" + + "github.com/lucasb-eyer/go-colorful" ) // FindColor attempts to find a given color, or the best match possible for it, diff --git a/vendor/github.com/gdamore/tcell/v2/console_stub.go b/vendor/github.com/gdamore/tcell/v2/console_stub.go index fda2f0926..6ff7e92a0 100644 --- a/vendor/github.com/gdamore/tcell/v2/console_stub.go +++ b/vendor/github.com/gdamore/tcell/v2/console_stub.go @@ -1,3 +1,4 @@ +//go:build !windows // +build !windows // Copyright 2015 The TCell Authors diff --git a/vendor/github.com/gdamore/tcell/v2/doc.go b/vendor/github.com/gdamore/tcell/v2/doc.go index b67196135..690dd27ad 100644 --- a/vendor/github.com/gdamore/tcell/v2/doc.go +++ b/vendor/github.com/gdamore/tcell/v2/doc.go @@ -36,13 +36,12 @@ // // Note that support for non-UTF-8 locales (other than C) must be enabled // by the application using RegisterEncoding() -- we don't have them all -// enabled by default to avoid bloating the application unneccessarily. +// enabled by default to avoid bloating the application unnecessarily. // (These days UTF-8 is good enough for almost everyone, and nobody should // be using legacy locales anymore.) Also, actual glyphs for various code // point will only be displayed if your terminal or emulator (or the font // the emulator is using) supports them. // -// A rich set of keycodes is supported, with support for up to 65 function +// A rich set of key codes is supported, with support for up to 65 function // keys, and various other special keys. -// package tcell diff --git a/vendor/github.com/gdamore/tcell/v2/encoding.go b/vendor/github.com/gdamore/tcell/v2/encoding.go index 596a6e800..8bb449d67 100644 --- a/vendor/github.com/gdamore/tcell/v2/encoding.go +++ b/vendor/github.com/gdamore/tcell/v2/encoding.go @@ -1,4 +1,4 @@ -// Copyright 2015 The TCell Authors +// Copyright 2022 The TCell Authors // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use file except in compliance with the License. @@ -38,19 +38,19 @@ var encodingFallback EncodingFallback = EncodingFallbackFail // the common ones exist already as stock variables. For example, ISO8859-15 // can be registered using the following code: // -// import "golang.org/x/text/encoding/charmap" +// import "golang.org/x/text/encoding/charmap" // -// ... -// RegisterEncoding("ISO8859-15", charmap.ISO8859_15) +// ... +// RegisterEncoding("ISO8859-15", charmap.ISO8859_15) // // Aliases can be registered as well, for example "8859-15" could be an alias // for "ISO8859-15". // -// For POSIX systems, the tcell package will check the environment variables +// For POSIX systems, this package will check the environment variables // LC_ALL, LC_CTYPE, and LANG (in that order) to determine the character set. // These are expected to have the following pattern: // -// $language[.$codeset[@$variant] +// $language[.$codeset[@$variant] // // We extract only the $codeset part, which will usually be something like // UTF-8 or ISO8859-15 or KOI8-R. Note that if the locale is either "POSIX" @@ -64,9 +64,11 @@ var encodingFallback EncodingFallback = EncodingFallbackFail // quite a lot processing overhead. // // Note that some encodings are quite large (for example GB18030 which is a -// superset of Unicode) and so the application size can be expected ot -// increase quite a bit as each encoding is added. The East Asian encodings -// have been seen to add 100-200K per encoding to the application size. +// superset of Unicode) and so the application size can be expected to +// increase quite a bit as each encoding is added. + +// The East Asian encodings have been seen to add 100-200K per encoding to the +// size of the resulting binary. // func RegisterEncoding(charset string, enc encoding.Encoding) { encodingLk.Lock() @@ -75,7 +77,7 @@ func RegisterEncoding(charset string, enc encoding.Encoding) { encodingLk.Unlock() } -// EncodingFallback describes how the system behavees when the locale +// EncodingFallback describes how the system behaves when the locale // requires a character set that we do not support. The system always // supports UTF-8 and US-ASCII. On Windows consoles, UTF-16LE is also // supported automatically. Other character sets must be added using the @@ -88,7 +90,7 @@ const ( // when it cannot find an encoding. EncodingFallbackFail = iota - // EncodingFallbackASCII behaviore causes GetEncoding to fall back + // EncodingFallbackASCII behavior causes GetEncoding to fall back // to a 7-bit ASCII encoding, if no other encoding can be found. EncodingFallbackASCII diff --git a/vendor/github.com/gdamore/tcell/v2/nonblock_bsd.go b/vendor/github.com/gdamore/tcell/v2/nonblock_bsd.go index 28fd4644c..622888e31 100644 --- a/vendor/github.com/gdamore/tcell/v2/nonblock_bsd.go +++ b/vendor/github.com/gdamore/tcell/v2/nonblock_bsd.go @@ -12,6 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. +//go:build darwin || dragonfly || freebsd || netbsd || openbsd // +build darwin dragonfly freebsd netbsd openbsd package tcell diff --git a/vendor/github.com/gdamore/tcell/v2/nonblock_unix.go b/vendor/github.com/gdamore/tcell/v2/nonblock_unix.go index fe31844cf..160a6419d 100644 --- a/vendor/github.com/gdamore/tcell/v2/nonblock_unix.go +++ b/vendor/github.com/gdamore/tcell/v2/nonblock_unix.go @@ -12,6 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. +//go:build linux || aix || zos || solaris // +build linux aix zos solaris package tcell diff --git a/vendor/github.com/gdamore/tcell/v2/screen.go b/vendor/github.com/gdamore/tcell/v2/screen.go index 43c3a54b1..5598a8c7a 100644 --- a/vendor/github.com/gdamore/tcell/v2/screen.go +++ b/vendor/github.com/gdamore/tcell/v2/screen.go @@ -24,12 +24,13 @@ type Screen interface { // Fini finalizes the screen also releasing resources. Fini() - // Clear erases the screen. The contents of any screen buffers - // will also be cleared. This has the logical effect of - // filling the screen with spaces, using the global default style. + // Clear logically erases the screen. + // This is effectively a short-cut for Fill(' ', StyleDefault). Clear() // Fill fills the screen with the given character and style. + // The effect of filling the screen is not visible until Show + // is called (or Sync). Fill(rune, Style) // SetCell is an older API, and will be removed. Please use @@ -42,7 +43,7 @@ type Screen interface { // and may not actually be what is displayed, but rather are what will // be displayed if Show() or Sync() is called. The width is the width // in screen cells; most often this will be 1, but some East Asian - // characters require two cells. + // characters and emoji require two cells. GetContent(x, y int) (primary rune, combining []rune, style Style, width int) // SetContent sets the contents of the given cell location. If @@ -54,7 +55,7 @@ type Screen interface { // // The results are not displayed until Show() or Sync() is called. // - // Note that wide (East Asian full width) runes occupy two cells, + // Note that wide (East Asian full width and emoji) runes occupy two cells, // and attempts to place character at next cell to the right will have // undefined effects. Wide runes that are printed in the // last column will be replaced with a single width space on output. diff --git a/vendor/github.com/gdamore/tcell/v2/stdin_unix.go b/vendor/github.com/gdamore/tcell/v2/stdin_unix.go index e3d32e9fd..4c0d6e12d 100644 --- a/vendor/github.com/gdamore/tcell/v2/stdin_unix.go +++ b/vendor/github.com/gdamore/tcell/v2/stdin_unix.go @@ -12,6 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. +//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || zos // +build aix darwin dragonfly freebsd linux netbsd openbsd solaris zos package tcell @@ -60,7 +61,7 @@ func (tty *stdIoTty) Start() error { defer tty.l.Unlock() // We open another copy of /dev/tty. This is a workaround for unusual behavior - // observed in macOS, apparently caused when a subshell (for example) closes our + // observed in macOS, apparently caused when a sub-shell (for example) closes our // own tty device (when it exits for example). Getting a fresh new one seems to // resolve the problem. (We believe this is a bug in the macOS tty driver that // fails to account for dup() references to the same file before applying close() @@ -162,7 +163,7 @@ func (tty *stdIoTty) NotifyResize(cb func()) { func NewStdIoTty() (Tty, error) { tty := &stdIoTty{ sig: make(chan os.Signal), - in: os.Stdin, + in: os.Stdin, out: os.Stdout, } var err error diff --git a/vendor/github.com/gdamore/tcell/v2/style.go b/vendor/github.com/gdamore/tcell/v2/style.go index ad4b47f21..98354c853 100644 --- a/vendor/github.com/gdamore/tcell/v2/style.go +++ b/vendor/github.com/gdamore/tcell/v2/style.go @@ -27,6 +27,7 @@ type Style struct { bg Color attrs AttrMask url string + urlId string } // StyleDefault represents a default style, based upon the context. @@ -44,6 +45,7 @@ func (s Style) Foreground(c Color) Style { bg: s.bg, attrs: s.attrs, url: s.url, + urlId: s.urlId, } } @@ -55,6 +57,7 @@ func (s Style) Background(c Color) Style { bg: c, attrs: s.attrs, url: s.url, + urlId: s.urlId, } } @@ -71,6 +74,7 @@ func (s Style) setAttrs(attrs AttrMask, on bool) Style { bg: s.bg, attrs: s.attrs | attrs, url: s.url, + urlId: s.urlId, } } return Style{ @@ -78,6 +82,7 @@ func (s Style) setAttrs(attrs AttrMask, on bool) Style { bg: s.bg, attrs: s.attrs &^ attrs, url: s.url, + urlId: s.urlId, } } @@ -139,6 +144,7 @@ func (s Style) Attributes(attrs AttrMask) Style { bg: s.bg, attrs: attrs, url: s.url, + urlId: s.urlId, } } @@ -151,5 +157,20 @@ func (s Style) Url(url string) Style { bg: s.bg, attrs: s.attrs, url: url, + urlId: s.urlId, + } +} + +// UrlId returns a style with the UrlId set. If the provided UrlId is not empty, +// any marked up Url with this style will be given the UrlId also. If the +// terminal supports it, any text with the same UrlId will be grouped as if it +// were one Url, even if it spans multiple lines. +func (s Style) UrlId(id string) Style { + return Style{ + fg: s.fg, + bg: s.bg, + attrs: s.attrs, + url: s.url, + urlId: "id=" + id, } } diff --git a/vendor/github.com/gdamore/tcell/v2/terminfo/a/alacritty/direct.go b/vendor/github.com/gdamore/tcell/v2/terminfo/a/alacritty/direct.go new file mode 100644 index 000000000..db6351af2 --- /dev/null +++ b/vendor/github.com/gdamore/tcell/v2/terminfo/a/alacritty/direct.go @@ -0,0 +1,69 @@ +// Generated automatically. DO NOT HAND-EDIT. + +package alacritty + +import "github.com/gdamore/tcell/v2/terminfo" + +func init() { + + // alacritty with direct color indexing + terminfo.AddTerminfo(&terminfo.Terminfo{ + Name: "alacritty-direct", + Columns: 80, + Lines: 24, + Colors: 16777216, + Bell: "\a", + Clear: "\x1b[H\x1b[2J", + EnterCA: "\x1b[?1049h\x1b[22;0;0t", + ExitCA: "\x1b[?1049l\x1b[23;0;0t", + ShowCursor: "\x1b[?12l\x1b[?25h", + HideCursor: "\x1b[?25l", + AttrOff: "\x1b(B\x1b[m", + Underline: "\x1b[4m", + Bold: "\x1b[1m", + Dim: "\x1b[2m", + Italic: "\x1b[3m", + Reverse: "\x1b[7m", + EnterKeypad: "\x1b[?1h\x1b=", + ExitKeypad: "\x1b[?1l\x1b>", + SetFg: "\x1b[%?%p1%{8}%<%t3%p1%d%e%p1%{16}%<%t9%p1%{8}%-%d%e38;5;%p1%d%;m", + SetBg: "\x1b[%?%p1%{8}%<%t4%p1%d%e%p1%{16}%<%t10%p1%{8}%-%d%e48;5;%p1%d%;m", + SetFgBg: "\x1b[%?%p1%{8}%<%t3%p1%d%e%p1%{16}%<%t9%p1%{8}%-%d%e38;5;%p1%d%;;%?%p2%{8}%<%t4%p2%d%e%p2%{16}%<%t10%p2%{8}%-%d%e48;5;%p2%d%;m", + ResetFgBg: "\x1b[39;49m", + AltChars: "``aaffggiijjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~", + EnterAcs: "\x1b(0", + ExitAcs: "\x1b(B", + StrikeThrough: "\x1b[9m", + Mouse: "\x1b[M", + SetCursor: "\x1b[%i%p1%d;%p2%dH", + CursorBack1: "\b", + CursorUp1: "\x1b[A", + KeyUp: "\x1bOA", + KeyDown: "\x1bOB", + KeyRight: "\x1bOC", + KeyLeft: "\x1bOD", + KeyInsert: "\x1b[2~", + KeyDelete: "\x1b[3~", + KeyBackspace: "\x7f", + KeyHome: "\x1bOH", + KeyEnd: "\x1bOF", + KeyPgUp: "\x1b[5~", + KeyPgDn: "\x1b[6~", + KeyF1: "\x1bOP", + KeyF2: "\x1bOQ", + KeyF3: "\x1bOR", + KeyF4: "\x1bOS", + KeyF5: "\x1b[15~", + KeyF6: "\x1b[17~", + KeyF7: "\x1b[18~", + KeyF8: "\x1b[19~", + KeyF9: "\x1b[20~", + KeyF10: "\x1b[21~", + KeyF11: "\x1b[23~", + KeyF12: "\x1b[24~", + KeyBacktab: "\x1b[Z", + Modifiers: 1, + TrueColor: true, + AutoMargin: true, + }) +} diff --git a/vendor/github.com/gdamore/tcell/v2/terminfo/f/foot/foot.go b/vendor/github.com/gdamore/tcell/v2/terminfo/f/foot/foot.go index 3197d8285..5daa3c8ac 100644 --- a/vendor/github.com/gdamore/tcell/v2/terminfo/f/foot/foot.go +++ b/vendor/github.com/gdamore/tcell/v2/terminfo/f/foot/foot.go @@ -8,63 +8,63 @@ func init() { // foot terminal emulator terminfo.AddTerminfo(&terminfo.Terminfo{ - Name: "foot", - Aliases: []string{"foot-extra"}, - Columns: 80, - Lines: 24, - Colors: 256, - Bell: "\a", - Clear: "\x1b[H\x1b[2J", - EnterCA: "\x1b[?1049h\x1b[22;0;0t", - ExitCA: "\x1b[?1049l\x1b[23;0;0t", - ShowCursor: "\x1b[?12l\x1b[?25h", - HideCursor: "\x1b[?25l", - AttrOff: "\x1b(B\x1b[m", - Underline: "\x1b[4m", - Bold: "\x1b[1m", - Dim: "\x1b[2m", - Italic: "\x1b[3m", - Blink: "\x1b[5m", - Reverse: "\x1b[7m", - EnterKeypad: "\x1b[?1h\x1b=", - ExitKeypad: "\x1b[?1l\x1b>", - SetFg: "\x1b[%?%p1%{8}%<%t3%p1%d%e%p1%{16}%<%t9%p1%{8}%-%d%e38:5:%p1%d%;m", - SetBg: "\x1b[%?%p1%{8}%<%t4%p1%d%e%p1%{16}%<%t10%p1%{8}%-%d%e48:5:%p1%d%;m", - SetFgBg: "\x1b[%?%p1%{8}%<%t3%p1%d%e%p1%{16}%<%t9%p1%{8}%-%d%e38:5:%p1%d%;;%?%p2%{8}%<%t4%p2%d%e%p2%{16}%<%t10%p2%{8}%-%d%e48:5:%p2%d%;m", - ResetFgBg: "\x1b[39;49m", - AltChars: "``aaffggiijjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~", - EnterAcs: "\x1b(0", - ExitAcs: "\x1b(B", + Name: "foot", + Aliases: []string{"foot-extra"}, + Columns: 80, + Lines: 24, + Colors: 256, + Bell: "\a", + Clear: "\x1b[H\x1b[2J", + EnterCA: "\x1b[?1049h\x1b[22;0;0t", + ExitCA: "\x1b[?1049l\x1b[23;0;0t", + ShowCursor: "\x1b[?12l\x1b[?25h", + HideCursor: "\x1b[?25l", + AttrOff: "\x1b(B\x1b[m", + Underline: "\x1b[4m", + Bold: "\x1b[1m", + Dim: "\x1b[2m", + Italic: "\x1b[3m", + Blink: "\x1b[5m", + Reverse: "\x1b[7m", + EnterKeypad: "\x1b[?1h\x1b=", + ExitKeypad: "\x1b[?1l\x1b>", + SetFg: "\x1b[%?%p1%{8}%<%t3%p1%d%e%p1%{16}%<%t9%p1%{8}%-%d%e38:5:%p1%d%;m", + SetBg: "\x1b[%?%p1%{8}%<%t4%p1%d%e%p1%{16}%<%t10%p1%{8}%-%d%e48:5:%p1%d%;m", + SetFgBg: "\x1b[%?%p1%{8}%<%t3%p1%d%e%p1%{16}%<%t9%p1%{8}%-%d%e38:5:%p1%d%;;%?%p2%{8}%<%t4%p2%d%e%p2%{16}%<%t10%p2%{8}%-%d%e48:5:%p2%d%;m", + ResetFgBg: "\x1b[39;49m", + AltChars: "``aaffggiijjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~", + EnterAcs: "\x1b(0", + ExitAcs: "\x1b(B", StrikeThrough: "\x1b[9m", - Mouse: "\x1b[M", - SetCursor: "\x1b[%i%p1%d;%p2%dH", - CursorBack1: "\b", - CursorUp1: "\x1b[A", - KeyUp: "\x1bOA", - KeyDown: "\x1bOB", - KeyRight: "\x1bOC", - KeyLeft: "\x1bOD", - KeyInsert: "\x1b[2~", - KeyDelete: "\x1b[3~", - KeyBackspace: "\u007f", - KeyHome: "\x1bOH", - KeyEnd: "\x1bOF", - KeyPgUp: "\x1b[5~", - KeyPgDn: "\x1b[6~", - KeyF1: "\x1bOP", - KeyF2: "\x1bOQ", - KeyF3: "\x1bOR", - KeyF4: "\x1bOS", - KeyF5: "\x1b[15~", - KeyF6: "\x1b[17~", - KeyF7: "\x1b[18~", - KeyF8: "\x1b[19~", - KeyF9: "\x1b[20~", - KeyF10: "\x1b[21~", - KeyF11: "\x1b[23~", - KeyF12: "\x1b[24~", - KeyBacktab: "\x1b[Z", - Modifiers: 1, - AutoMargin: true, + Mouse: "\x1b[M", + SetCursor: "\x1b[%i%p1%d;%p2%dH", + CursorBack1: "\b", + CursorUp1: "\x1b[A", + KeyUp: "\x1bOA", + KeyDown: "\x1bOB", + KeyRight: "\x1bOC", + KeyLeft: "\x1bOD", + KeyInsert: "\x1b[2~", + KeyDelete: "\x1b[3~", + KeyBackspace: "\u007f", + KeyHome: "\x1bOH", + KeyEnd: "\x1bOF", + KeyPgUp: "\x1b[5~", + KeyPgDn: "\x1b[6~", + KeyF1: "\x1bOP", + KeyF2: "\x1bOQ", + KeyF3: "\x1bOR", + KeyF4: "\x1bOS", + KeyF5: "\x1b[15~", + KeyF6: "\x1b[17~", + KeyF7: "\x1b[18~", + KeyF8: "\x1b[19~", + KeyF9: "\x1b[20~", + KeyF10: "\x1b[21~", + KeyF11: "\x1b[23~", + KeyF12: "\x1b[24~", + KeyBacktab: "\x1b[Z", + Modifiers: 1, + AutoMargin: true, }) } diff --git a/vendor/github.com/gdamore/tcell/v2/terminfo/terminfo.go b/vendor/github.com/gdamore/tcell/v2/terminfo/terminfo.go index 7028b51be..cf1578648 100644 --- a/vendor/github.com/gdamore/tcell/v2/terminfo/terminfo.go +++ b/vendor/github.com/gdamore/tcell/v2/terminfo/terminfo.go @@ -240,15 +240,14 @@ const ( type stack []interface{} func (st stack) Push(v interface{}) stack { - return append(st, v) -} - -func (st stack) Pop() (interface{}, stack) { - if len(st) > 0 { - e := st[len(st)-1] - return e, st[:len(st)-1] + if b, ok := v.(bool); ok { + if b { + return append(st, 1) + } else { + return append(st, 0) + } } - return 0, st + return append(st, v) } func (st stack) PopString() (string, stack) { @@ -258,8 +257,6 @@ func (st stack) PopString() (string, stack) { switch v := e.(type) { case int: s = strconv.Itoa(v) - case bool: - s = strconv.FormatBool(v) case string: s = v } @@ -275,12 +272,6 @@ func (st stack) PopInt() (int, stack) { switch v := e.(type) { case int: i = v - case bool: - if v { - i = 1 - } else { - i = 0 - } case string: i, _ = strconv.Atoi(v) } @@ -289,42 +280,18 @@ func (st stack) PopInt() (int, stack) { return 0, st } -func (st stack) PopBool() (bool, stack) { - var b bool - if len(st) > 0 { - e := st[len(st)-1] - switch v := e.(type) { - case int: - b = v != 0 - case bool: - b = v - case string: - b = v != "" && v != "false" - } - return b, st[:len(st)-1] - } - return false, st -} - // static vars var svars [26]string -// paramsBuffer handles some persistent state for TParam. Technically we -// could probably dispense with this, but caching buffer arrays gives us -// a nice little performance boost. Furthermore, we know that TParam is -// rarely (never?) called re-entrantly, so we can just reuse the same -// buffers, making it thread-safe by stashing a lock. type paramsBuffer struct { out bytes.Buffer buf bytes.Buffer - lk sync.Mutex } // Start initializes the params buffer with the initial string data. // It also locks the paramsBuffer. The caller must call End() when // finished. func (pb *paramsBuffer) Start(s string) { - pb.lk.Lock() pb.out.Reset() pb.buf.Reset() pb.buf.WriteString(s) @@ -333,7 +300,6 @@ func (pb *paramsBuffer) Start(s string) { // End returns the final output from TParam, but it also releases the lock. func (pb *paramsBuffer) End() string { s := pb.out.String() - pb.lk.Unlock() return s } @@ -352,18 +318,16 @@ func (pb *paramsBuffer) PutString(s string) { pb.out.WriteString(s) } -var pb = ¶msBuffer{} - // TParm takes a terminfo parameterized string, such as setaf or cup, and // evaluates the string, and returns the result with the parameter // applied. func (t *Terminfo) TParm(s string, p ...interface{}) string { var stk stack - var a, b string + var a string var ai, bi int - var ab bool var dvars [26]string var params [9]interface{} + var pb = ¶msBuffer{} pb.Start(s) @@ -373,7 +337,13 @@ func (t *Terminfo) TParm(s string, p ...interface{}) string { params[i] = p[i] } - nest := 0 + const ( + emit = iota + toEnd + toElse + ) + + skip := emit for { @@ -383,7 +353,9 @@ func (t *Terminfo) TParm(s string, p ...interface{}) string { } if ch != '%' { - pb.PutCh(ch) + if skip == emit { + pb.PutCh(ch) + } continue } @@ -392,6 +364,17 @@ func (t *Terminfo) TParm(s string, p ...interface{}) string { // XXX Error break } + if skip == toEnd { + if ch == ';' { + skip = emit + } + continue + } else if skip == toElse { + if ch == 'e' || ch == ';' { + skip = emit + } + continue + } switch ch { case '%': // quoted % @@ -405,18 +388,23 @@ func (t *Terminfo) TParm(s string, p ...interface{}) string { params[1] = i + 1 } - case 'c', 's': - // NB: these, and 'd' below are special cased for + case 's': + // NB: 's', 'c', and 'd' below are special cased for // efficiency. They could be handled by the richer // format support below, less efficiently. a, stk = stk.PopString() pb.PutString(a) + case 'c': + // Integer as special character. + ai, stk = stk.PopInt() + pb.PutCh(byte(ai)) + case 'd': ai, stk = stk.PopInt() pb.PutString(strconv.Itoa(ai)) - case '0', '1', '2', '3', '4', 'x', 'X', 'o', ':': + case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'x', 'X', 'o', ':': // This is pretty suboptimal, but this is rarely used. // None of the mainstream terminals use any of this, // and it would surprise me if this code is ever @@ -438,9 +426,12 @@ func (t *Terminfo) TParm(s string, p ...interface{}) string { case 'd', 'x', 'X', 'o': ai, stk = stk.PopInt() pb.PutString(fmt.Sprintf(f, ai)) - case 'c', 's': + case 's': a, stk = stk.PopString() pb.PutString(fmt.Sprintf(f, a)) + case 'c': + ai, stk = stk.PopInt() + pb.PutString(fmt.Sprintf(f, ai)) } case 'p': // push parameter @@ -468,10 +459,10 @@ func (t *Terminfo) TParm(s string, p ...interface{}) string { stk = stk.Push(dvars[int(ch-'a')]) } - case '\'': // push(char) + case '\'': // push(char) - the integer value of it ch, _ = pb.NextCh() _, _ = pb.NextCh() // must be ' but we don't check - stk = stk.Push(string(ch)) + stk = stk.Push(int(ch)) case '{': // push(int) ai = 0 @@ -542,12 +533,12 @@ func (t *Terminfo) TParm(s string, p ...interface{}) string { case '!': // logical NOT ai, stk = stk.PopInt() - stk = stk.Push(ai != 0) + stk = stk.Push(ai == 0) - case '=': // numeric compare or string compare - b, stk = stk.PopString() - a, stk = stk.PopString() - stk = stk.Push(a == b) + case '=': // numeric compare + bi, stk = stk.PopInt() + ai, stk = stk.PopInt() + stk = stk.Push(ai == bi) case '>': // greater than, numeric bi, stk = stk.PopInt() @@ -561,68 +552,20 @@ func (t *Terminfo) TParm(s string, p ...interface{}) string { case '?': // start conditional + case ';': + skip = emit + case 't': - ab, stk = stk.PopBool() - if ab { - // just keep going - break - } - nest = 0 - ifloop: - // this loop consumes everything until we hit our else, - // or the end of the conditional - for { - ch, err = pb.NextCh() - if err != nil { - break - } - if ch != '%' { - continue - } - ch, _ = pb.NextCh() - switch ch { - case ';': - if nest == 0 { - break ifloop - } - nest-- - case '?': - nest++ - case 'e': - if nest == 0 { - break ifloop - } - } + ai, stk = stk.PopInt() + if ai == 0 { + skip = toElse } case 'e': - // if we got here, it means we didn't use the else - // in the 't' case above, and we should skip until - // the end of the conditional - nest = 0 - elloop: - for { - ch, err = pb.NextCh() - if err != nil { - break - } - if ch != '%' { - continue - } - ch, _ = pb.NextCh() - switch ch { - case ';': - if nest == 0 { - break elloop - } - nest-- - case '?': - nest++ - } - } - - case ';': // endif + skip = toEnd + default: + pb.PutString("%" + string(ch)) } } diff --git a/vendor/github.com/gdamore/tcell/v2/terms_default.go b/vendor/github.com/gdamore/tcell/v2/terms_default.go index 4ce763702..fefcf8938 100644 --- a/vendor/github.com/gdamore/tcell/v2/terms_default.go +++ b/vendor/github.com/gdamore/tcell/v2/terms_default.go @@ -1,3 +1,4 @@ +//go:build !tcell_minimal // +build !tcell_minimal // Copyright 2019 The TCell Authors diff --git a/vendor/github.com/gdamore/tcell/v2/terms_dynamic.go b/vendor/github.com/gdamore/tcell/v2/terms_dynamic.go index 8f0994a86..f552b0e8e 100644 --- a/vendor/github.com/gdamore/tcell/v2/terms_dynamic.go +++ b/vendor/github.com/gdamore/tcell/v2/terms_dynamic.go @@ -1,3 +1,4 @@ +//go:build !tcell_minimal && !nacl && !js && !zos && !plan9 && !windows && !android // +build !tcell_minimal,!nacl,!js,!zos,!plan9,!windows,!android // Copyright 2019 The TCell Authors diff --git a/vendor/github.com/gdamore/tcell/v2/terms_static.go b/vendor/github.com/gdamore/tcell/v2/terms_static.go index 8b3fe1295..6d725cbcc 100644 --- a/vendor/github.com/gdamore/tcell/v2/terms_static.go +++ b/vendor/github.com/gdamore/tcell/v2/terms_static.go @@ -1,4 +1,5 @@ -// +build tcell_minimal nacl js zos plan9 windows android +//go:build tcell_minimal || nacl || zos || plan9 || windows || android || js +// +build tcell_minimal nacl zos plan9 windows android js // Copyright 2019 The TCell Authors // diff --git a/vendor/github.com/gdamore/tcell/v2/tscreen.go b/vendor/github.com/gdamore/tcell/v2/tscreen.go index dcde34edd..e36e6e41f 100644 --- a/vendor/github.com/gdamore/tcell/v2/tscreen.go +++ b/vendor/github.com/gdamore/tcell/v2/tscreen.go @@ -12,6 +12,9 @@ // See the License for the specific language governing permissions and // limitations under the License. +//go:build !(js && wasm) +// +build !js !wasm + package tcell import ( @@ -134,7 +137,6 @@ type tScreen struct { clear bool cursorx int cursory int - wasbtn bool acs map[rune]string charset string encoder transform.Transformer @@ -199,9 +201,13 @@ func (t *tScreen) Init() error { if os.Getenv("TCELL_TRUECOLOR") == "disable" { t.truecolor = false } - t.colors = make(map[Color]Color) - t.palette = make([]Color, t.nColors()) - for i := 0; i < t.nColors(); i++ { + nColors := t.nColors() + if nColors > 256 { + nColors = 256 // clip to reasonable limits + } + t.colors = make(map[Color]Color, nColors) + t.palette = make([]Color, nColors) + for i := 0; i < nColors; i++ { t.palette[i] = Color(i) | ColorValid // identity map for our builtin colors t.colors[Color(i)|ColorValid] = Color(i) | ColorValid @@ -338,6 +344,11 @@ func (t *tScreen) prepareBracketedPaste() { } func (t *tScreen) prepareExtendedOSC() { + // Linux is a special beast - because it has a mouse entry, but does + // not swallow these OSC commands properly. + if (strings.Contains(t.ti.Name, "linux")) { + return; + } // More stuff for limits in terminfo. This time we are applying // the most common OSC (operating system commands). Generally // terminals that don't understand these will ignore them. @@ -346,7 +357,7 @@ func (t *tScreen) prepareExtendedOSC() { t.enterUrl = t.ti.EnterUrl t.exitUrl = t.ti.ExitUrl } else if t.ti.Mouse != "" { - t.enterUrl = "\x1b]8;;%p1%s\x1b\\" + t.enterUrl = "\x1b]8;%p2%s;%p1%s\x1b\\" t.exitUrl = "\x1b]8;;\x1b\\" } @@ -572,18 +583,6 @@ func (t *tScreen) SetStyle(style Style) { func (t *tScreen) Clear() { t.Fill(' ', t.style) - t.Lock() - t.clear = true - w, h := t.cells.Size() - // because we are going to clear (see t.clear) in the next cycle, - // let's also unmark the dirty bit so that we don't waste cycles - // drawing things that are already dealt with via the clear escape sequence. - for row := 0; row < h; row++ { - for col := 0; col < w; col++ { - t.cells.SetDirty(col, row, false) - } - } - t.Unlock() } func (t *tScreen) Fill(r rune, style Style) { @@ -794,7 +793,7 @@ func (t *tScreen) drawCell(x, y int) int { // URL string can be long, so don't send it unless we really need to if t.enterUrl != "" && t.curstyle != style { if style.url != "" { - t.TPuts(ti.TParm(t.enterUrl, style.url)) + t.TPuts(ti.TParm(t.enterUrl, style.url, style.urlId)) } else { t.TPuts(t.exitUrl) } @@ -1229,28 +1228,16 @@ func (t *tScreen) buildMouseEvent(x, y, btn int) *EventMouse { switch btn & 0x43 { case 0: button = Button1 - t.wasbtn = true case 1: button = Button3 // Note we prefer to treat right as button 2 - t.wasbtn = true case 2: button = Button2 // And the middle button as button 3 - t.wasbtn = true case 3: button = ButtonNone - t.wasbtn = false case 0x40: - if !t.wasbtn { - button = WheelUp - } else { - button = Button1 - } + button = WheelUp case 0x41: - if !t.wasbtn { - button = WheelDown - } else { - button = Button2 - } + button = WheelDown } if btn&0x4 != 0 { diff --git a/vendor/github.com/gdamore/tcell/v2/tscreen_stub.go b/vendor/github.com/gdamore/tcell/v2/tscreen_stub.go index 1611cb553..0e4deae02 100644 --- a/vendor/github.com/gdamore/tcell/v2/tscreen_stub.go +++ b/vendor/github.com/gdamore/tcell/v2/tscreen_stub.go @@ -1,6 +1,7 @@ -// +build js plan9 windows +//go:build plan9 || windows +// +build plan9 windows -// Copyright 2021 The TCell Authors +// Copyright 2022 The TCell Authors // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use file except in compliance with the License. @@ -21,5 +22,11 @@ package tcell // that we can obtain with the console API present on Windows. func (t *tScreen) initialize() error { - return ErrNoScreen + if t.tty == nil { + return ErrNoScreen + } + // If a tty was supplied (custom), it should work. + // Custom screen implementations will need to provide a TTY + // implementation that we can use. + return nil } diff --git a/vendor/github.com/gdamore/tcell/v2/tscreen_unix.go b/vendor/github.com/gdamore/tcell/v2/tscreen_unix.go index 1eb7504a7..84727f881 100644 --- a/vendor/github.com/gdamore/tcell/v2/tscreen_unix.go +++ b/vendor/github.com/gdamore/tcell/v2/tscreen_unix.go @@ -12,6 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. +//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || zos // +build aix darwin dragonfly freebsd linux netbsd openbsd solaris zos package tcell diff --git a/vendor/github.com/gdamore/tcell/v2/tty.go b/vendor/github.com/gdamore/tcell/v2/tty.go index 567b04187..1e7c02e4e 100644 --- a/vendor/github.com/gdamore/tcell/v2/tty.go +++ b/vendor/github.com/gdamore/tcell/v2/tty.go @@ -53,4 +53,4 @@ type Tty interface { WindowSize() (width int, height int, err error) io.ReadWriteCloser -} \ No newline at end of file +} diff --git a/vendor/github.com/gdamore/tcell/v2/tty_unix.go b/vendor/github.com/gdamore/tcell/v2/tty_unix.go index aa6b7d5a8..05d5a7dd0 100644 --- a/vendor/github.com/gdamore/tcell/v2/tty_unix.go +++ b/vendor/github.com/gdamore/tcell/v2/tty_unix.go @@ -12,6 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. +//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || zos // +build aix darwin dragonfly freebsd linux netbsd openbsd solaris zos package tcell diff --git a/vendor/github.com/gdamore/tcell/v2/wscreen.go b/vendor/github.com/gdamore/tcell/v2/wscreen.go new file mode 100644 index 000000000..080472065 --- /dev/null +++ b/vendor/github.com/gdamore/tcell/v2/wscreen.go @@ -0,0 +1,678 @@ +// Copyright 2023 The TCell Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use 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. + +//go:build js && wasm +// +build js,wasm + +package tcell + +import ( + "errors" + "strings" + "sync" + "syscall/js" + "unicode/utf8" +) + +func NewTerminfoScreen() (Screen, error) { + t := &wScreen{} + t.fallback = make(map[rune]string) + + return t, nil +} + +type wScreen struct { + w, h int + style Style + cells CellBuffer + + running bool + clear bool + flagsPresent bool + pasteEnabled bool + mouseFlags MouseFlags + + cursorStyle CursorStyle + + quit chan struct{} + evch chan Event + fallback map[rune]string + + sync.Mutex +} + +func (t *wScreen) Init() error { + t.w, t.h = 80, 24 // default for html as of now + t.evch = make(chan Event, 10) + t.quit = make(chan struct{}) + + t.Lock() + t.running = true + t.style = StyleDefault + t.cells.Resize(t.w, t.h) + t.Unlock() + + js.Global().Set("onKeyEvent", js.FuncOf(t.onKeyEvent)) + + return nil +} + +func (t *wScreen) Fini() { + close(t.quit) +} + +func (t *wScreen) SetStyle(style Style) { + t.Lock() + t.style = style + t.Unlock() +} + +func (t *wScreen) Clear() { + t.Fill(' ', t.style) +} + +func (t *wScreen) Fill(r rune, style Style) { + t.Lock() + t.cells.Fill(r, style) + t.Unlock() +} + +func (t *wScreen) SetContent(x, y int, mainc rune, combc []rune, style Style) { + t.Lock() + t.cells.SetContent(x, y, mainc, combc, style) + t.Unlock() +} + +func (t *wScreen) GetContent(x, y int) (rune, []rune, Style, int) { + t.Lock() + mainc, combc, style, width := t.cells.GetContent(x, y) + t.Unlock() + return mainc, combc, style, width +} + +func (t *wScreen) SetCell(x, y int, style Style, ch ...rune) { + if len(ch) > 0 { + t.SetContent(x, y, ch[0], ch[1:], style) + } else { + t.SetContent(x, y, ' ', nil, style) + } +} + +// paletteColor gives a more natural palette color actually matching +// typical XTerm. We might in the future want to permit styling these +// via CSS. + +var palette = map[Color]int32{ + ColorBlack: 0x000000, + ColorMaroon: 0xcd0000, + ColorGreen: 0x00cd00, + ColorOlive: 0xcdcd00, + ColorNavy: 0x0000ee, + ColorPurple: 0xcd00cd, + ColorTeal: 0x00cdcd, + ColorSilver: 0xe5e5e5, + ColorGray: 0x7f7f7f, + ColorRed: 0xff0000, + ColorLime: 0x00ff00, + ColorYellow: 0xffff00, + ColorBlue: 0x5c5cff, + ColorFuchsia: 0xff00ff, + ColorAqua: 0x00ffff, + ColorWhite: 0xffffff, +} + +func paletteColor(c Color) int32 { + if (c.IsRGB()) { + return int32(c & 0xffffff); + } + if (c >= ColorBlack && c <= ColorWhite) { + return palette[c] + } + return c.Hex() +} + +func (t *wScreen) drawCell(x, y int) int { + mainc, combc, style, width := t.cells.GetContent(x, y) + + if !t.cells.Dirty(x, y) { + return width + } + + if style == StyleDefault { + style = t.style + } + + fg, bg := paletteColor(style.fg), paletteColor(style.bg) + if (fg == -1) { + fg = 0xe5e5e5; + } + if (bg == -1) { + bg = 0x000000; + } + + var combcarr []interface{} = make([]interface{}, len(combc)) + for i, c := range combc { + combcarr[i] = c + } + + t.cells.SetDirty(x, y, false) + js.Global().Call("drawCell", x, y, mainc, combcarr, fg, bg, int(style.attrs)) + + return width +} + +func (t *wScreen) ShowCursor(x, y int) { + t.Lock() + js.Global().Call("showCursor", x, y) + t.Unlock() +} + +func (t *wScreen) SetCursorStyle(cs CursorStyle) { + t.Lock() + js.Global().Call("setCursorStyle", curStyleClasses[cs]) + t.Unlock() +} + +func (t *wScreen) HideCursor() { + t.ShowCursor(-1, -1) +} + +func (t *wScreen) Show() { + t.Lock() + t.resize() + t.draw() + t.Unlock() +} + +func (t *wScreen) clearScreen() { + js.Global().Call("clearScreen", t.style.fg.Hex(), t.style.bg.Hex()) + t.clear = false +} + +func (t *wScreen) draw() { + if t.clear { + t.clearScreen() + } + + for y := 0; y < t.h; y++ { + for x := 0; x < t.w; x++ { + width := t.drawCell(x, y) + x += width - 1 + } + } + + js.Global().Call("show") +} + +func (t *wScreen) EnableMouse(flags ...MouseFlags) { + var f MouseFlags + flagsPresent := false + for _, flag := range flags { + f |= flag + flagsPresent = true + } + if !flagsPresent { + f = MouseMotionEvents | MouseDragEvents | MouseButtonEvents + } + + t.Lock() + t.mouseFlags = f + t.enableMouse(f) + t.Unlock() +} + +func (t *wScreen) enableMouse(f MouseFlags) { + if f&MouseButtonEvents != 0 { + js.Global().Set("onMouseClick", js.FuncOf(t.onMouseEvent)) + } else { + js.Global().Set("onMouseClick", js.FuncOf(t.unset)) + } + + if f&MouseDragEvents != 0 || f&MouseMotionEvents != 0 { + js.Global().Set("onMouseMove", js.FuncOf(t.onMouseEvent)) + } else { + js.Global().Set("onMouseMove", js.FuncOf(t.unset)) + } +} + +func (t *wScreen) DisableMouse() { + t.Lock() + t.mouseFlags = 0 + t.enableMouse(0) + t.Unlock() +} + +func (t *wScreen) EnablePaste() { + t.Lock() + t.pasteEnabled = true + t.enablePasting(true) + t.Unlock() +} + +func (t *wScreen) DisablePaste() { + t.Lock() + t.pasteEnabled = false + t.enablePasting(false) + t.Unlock() +} + +func (t *wScreen) enablePasting(on bool) { + if on { + js.Global().Set("onPaste", js.FuncOf(t.onPaste)) + } else { + js.Global().Set("onPaste", js.FuncOf(t.unset)) + } +} + +func (t *wScreen) Size() (int, int) { + t.Lock() + w, h := t.w, t.h + t.Unlock() + return w, h +} + +// resize does nothing, as asking the web window to resize +// without a specified width or height will cause no change. +func (t *wScreen) resize() {} + +func (t *wScreen) Colors() int { + return 16777216 // 256 ^ 3 +} + +func (t *wScreen) ChannelEvents(ch chan<- Event, quit <-chan struct{}) { + defer close(ch) + for { + select { + case <-quit: + return + case <-t.quit: + return + case ev := <-t.evch: + select { + case <-quit: + return + case <-t.quit: + return + case ch <- ev: + } + } + } +} + +func (t *wScreen) PollEvent() Event { + select { + case <-t.quit: + return nil + case ev := <-t.evch: + return ev + } +} + +func (t *wScreen) HasPendingEvent() bool { + return len(t.evch) > 0 +} + +func (t *wScreen) PostEventWait(ev Event) { + t.evch <- ev +} + +func (t *wScreen) PostEvent(ev Event) error { + select { + case t.evch <- ev: + return nil + default: + return ErrEventQFull + } +} + +func (t *wScreen) clip(x, y int) (int, int) { + w, h := t.cells.Size() + if x < 0 { + x = 0 + } + if y < 0 { + y = 0 + } + if x > w-1 { + x = w - 1 + } + if y > h-1 { + y = h - 1 + } + return x, y +} + +func (t *wScreen) onMouseEvent(this js.Value, args []js.Value) interface{} { + mod := ModNone + button := ButtonNone + + switch args[2].Int() { + case 0: + if t.mouseFlags&MouseMotionEvents == 0 { + // don't want this event! is a mouse motion event, but user has asked not. + return nil + } + button = ButtonNone + case 1: + button = Button1 + case 2: + button = Button3 // Note we prefer to treat right as button 2 + case 3: + button = Button2 // And the middle button as button 3 + } + + if args[3].Bool() { // mod shift + mod |= ModShift + } + + if args[4].Bool() { // mod alt + mod |= ModAlt + } + + if args[5].Bool() { // mod ctrl + mod |= ModCtrl + } + + t.PostEventWait(NewEventMouse(args[0].Int(), args[1].Int(), button, mod)) + return nil +} + +func (t *wScreen) onKeyEvent(this js.Value, args []js.Value) interface{} { + key := args[0].String() + + // don't accept any modifier keys as their own + if key == "Control" || key == "Alt" || key == "Meta" || key == "Shift" { + return nil + } + + mod := ModNone + if args[1].Bool() { // mod shift + mod |= ModShift + } + + if args[2].Bool() { // mod alt + mod |= ModAlt + } + + if args[3].Bool() { // mod ctrl + mod |= ModCtrl + } + + if args[4].Bool() { // mod meta + mod |= ModMeta + } + + // check for special case of Ctrl + key + if mod == ModCtrl { + if k, ok := WebKeyNames["Ctrl-"+strings.ToLower(key)]; ok { + t.PostEventWait(NewEventKey(k, 0, mod)) + return nil + } + } + + // next try function keys + if k, ok := WebKeyNames[key]; ok { + t.PostEventWait(NewEventKey(k, 0, mod)) + return nil + } + + // finally try normal, printable chars + r, _ := utf8.DecodeRuneInString(key) + t.PostEventWait(NewEventKey(KeyRune, r, mod)) + return nil +} + +func (t *wScreen) onPaste(this js.Value, args []js.Value) interface{} { + t.PostEventWait(NewEventPaste(args[0].Bool())) + return nil +} + +// unset is a dummy function for js when we want nothing to +// happen when javascript calls a function (for example, when +// mouse input is disabled, when onMouseEvent() is called from +// js, it redirects here and does nothing). +func (t *wScreen) unset(this js.Value, args []js.Value) interface{} { + return nil +} + +func (t *wScreen) Sync() { + t.Lock() + t.resize() + t.clear = true + t.cells.Invalidate() + t.draw() + t.Unlock() +} + +func (t *wScreen) CharacterSet() string { + return "UTF-8" +} + +func (t *wScreen) RegisterRuneFallback(orig rune, fallback string) { + t.Lock() + t.fallback[orig] = fallback + t.Unlock() +} + +func (t *wScreen) UnregisterRuneFallback(orig rune) { + t.Lock() + delete(t.fallback, orig) + t.Unlock() +} + +func (t *wScreen) CanDisplay(r rune, checkFallbacks bool) bool { + if utf8.ValidRune(r) { + return true + } + if !checkFallbacks { + return false + } + if _, ok := t.fallback[r]; ok { + return true + } + return false +} + +func (t *wScreen) HasMouse() bool { + return true +} + +func (t *wScreen) HasKey(k Key) bool { + return true +} + +func (t *wScreen) SetSize(w, h int) { + if w == t.w && h == t.h { + return + } + + t.cells.Invalidate() + t.cells.Resize(w, h) + js.Global().Call("resize", w, h) + t.w, t.h = w, h + t.PostEvent(NewEventResize(w, h)) +} + +func (t *wScreen) Resize(int, int, int, int) {} + +// Suspend simply pauses all input and output, and clears the screen. +// There isn't a "default terminal" to go back to. +func (t *wScreen) Suspend() error { + t.Lock() + if !t.running { + t.Unlock() + return nil + } + t.running = false + t.clearScreen() + t.enableMouse(0) + t.enablePasting(false) + js.Global().Set("onKeyEvent", js.FuncOf(t.unset)) // stop keypresses + return nil +} + +func (t *wScreen) Resume() error { + t.Lock() + + if t.running { + return errors.New("already engaged") + } + t.running = true + + t.enableMouse(t.mouseFlags) + t.enablePasting(t.pasteEnabled) + + js.Global().Set("onKeyEvent", js.FuncOf(t.onKeyEvent)) + + t.Unlock() + return nil +} + +func (t *wScreen) Beep() error { + js.Global().Call("beep") + return nil +} + +// WebKeyNames maps string names reported from HTML +// (KeyboardEvent.key) to tcell accepted keys. +var WebKeyNames = map[string]Key{ + "Enter": KeyEnter, + "Backspace": KeyBackspace, + "Tab": KeyTab, + "Backtab": KeyBacktab, + "Escape": KeyEsc, + "Backspace2": KeyBackspace2, + "Delete": KeyDelete, + "Insert": KeyInsert, + "ArrowUp": KeyUp, + "ArrowDown": KeyDown, + "ArrowLeft": KeyLeft, + "ArrowRight": KeyRight, + "Home": KeyHome, + "End": KeyEnd, + "UpLeft": KeyUpLeft, // not supported by HTML + "UpRight": KeyUpRight, // not supported by HTML + "DownLeft": KeyDownLeft, // not supported by HTML + "DownRight": KeyDownRight, // not supported by HTML + "Center": KeyCenter, + "PgDn": KeyPgDn, + "PgUp": KeyPgUp, + "Clear": KeyClear, + "Exit": KeyExit, + "Cancel": KeyCancel, + "Pause": KeyPause, + "Print": KeyPrint, + "F1": KeyF1, + "F2": KeyF2, + "F3": KeyF3, + "F4": KeyF4, + "F5": KeyF5, + "F6": KeyF6, + "F7": KeyF7, + "F8": KeyF8, + "F9": KeyF9, + "F10": KeyF10, + "F11": KeyF11, + "F12": KeyF12, + "F13": KeyF13, + "F14": KeyF14, + "F15": KeyF15, + "F16": KeyF16, + "F17": KeyF17, + "F18": KeyF18, + "F19": KeyF19, + "F20": KeyF20, + "F21": KeyF21, + "F22": KeyF22, + "F23": KeyF23, + "F24": KeyF24, + "F25": KeyF25, + "F26": KeyF26, + "F27": KeyF27, + "F28": KeyF28, + "F29": KeyF29, + "F30": KeyF30, + "F31": KeyF31, + "F32": KeyF32, + "F33": KeyF33, + "F34": KeyF34, + "F35": KeyF35, + "F36": KeyF36, + "F37": KeyF37, + "F38": KeyF38, + "F39": KeyF39, + "F40": KeyF40, + "F41": KeyF41, + "F42": KeyF42, + "F43": KeyF43, + "F44": KeyF44, + "F45": KeyF45, + "F46": KeyF46, + "F47": KeyF47, + "F48": KeyF48, + "F49": KeyF49, + "F50": KeyF50, + "F51": KeyF51, + "F52": KeyF52, + "F53": KeyF53, + "F54": KeyF54, + "F55": KeyF55, + "F56": KeyF56, + "F57": KeyF57, + "F58": KeyF58, + "F59": KeyF59, + "F60": KeyF60, + "F61": KeyF61, + "F62": KeyF62, + "F63": KeyF63, + "F64": KeyF64, + "Ctrl-a": KeyCtrlA, // not reported by HTML- need to do special check + "Ctrl-b": KeyCtrlB, // not reported by HTML- need to do special check + "Ctrl-c": KeyCtrlC, // not reported by HTML- need to do special check + "Ctrl-d": KeyCtrlD, // not reported by HTML- need to do special check + "Ctrl-e": KeyCtrlE, // not reported by HTML- need to do special check + "Ctrl-f": KeyCtrlF, // not reported by HTML- need to do special check + "Ctrl-g": KeyCtrlG, // not reported by HTML- need to do special check + "Ctrl-j": KeyCtrlJ, // not reported by HTML- need to do special check + "Ctrl-k": KeyCtrlK, // not reported by HTML- need to do special check + "Ctrl-l": KeyCtrlL, // not reported by HTML- need to do special check + "Ctrl-n": KeyCtrlN, // not reported by HTML- need to do special check + "Ctrl-o": KeyCtrlO, // not reported by HTML- need to do special check + "Ctrl-p": KeyCtrlP, // not reported by HTML- need to do special check + "Ctrl-q": KeyCtrlQ, // not reported by HTML- need to do special check + "Ctrl-r": KeyCtrlR, // not reported by HTML- need to do special check + "Ctrl-s": KeyCtrlS, // not reported by HTML- need to do special check + "Ctrl-t": KeyCtrlT, // not reported by HTML- need to do special check + "Ctrl-u": KeyCtrlU, // not reported by HTML- need to do special check + "Ctrl-v": KeyCtrlV, // not reported by HTML- need to do special check + "Ctrl-w": KeyCtrlW, // not reported by HTML- need to do special check + "Ctrl-x": KeyCtrlX, // not reported by HTML- need to do special check + "Ctrl-y": KeyCtrlY, // not reported by HTML- need to do special check + "Ctrl-z": KeyCtrlZ, // not reported by HTML- need to do special check + "Ctrl- ": KeyCtrlSpace, // not reported by HTML- need to do special check + "Ctrl-_": KeyCtrlUnderscore, // not reported by HTML- need to do special check + "Ctrl-]": KeyCtrlRightSq, // not reported by HTML- need to do special check + "Ctrl-\\": KeyCtrlBackslash, // not reported by HTML- need to do special check + "Ctrl-^": KeyCtrlCarat, // not reported by HTML- need to do special check +} + +var curStyleClasses = map[CursorStyle]string{ + CursorStyleDefault: "cursor-blinking-block", + CursorStyleBlinkingBlock: "cursor-blinking-block", + CursorStyleSteadyBlock: "cursor-steady-block", + CursorStyleBlinkingUnderline: "cursor-blinking-underline", + CursorStyleSteadyUnderline: "cursor-steady-underline", + CursorStyleBlinkingBar: "cursor-blinking-bar", + CursorStyleSteadyBar: "cursor-steady-bar", +} diff --git a/vendor/github.com/ktr0731/go-fuzzyfinder/fuzzyfinder.go b/vendor/github.com/ktr0731/go-fuzzyfinder/fuzzyfinder.go index 2cc965a39..7b1330b61 100644 --- a/vendor/github.com/ktr0731/go-fuzzyfinder/fuzzyfinder.go +++ b/vendor/github.com/ktr0731/go-fuzzyfinder/fuzzyfinder.go @@ -76,6 +76,8 @@ type finder struct { drawTimer *time.Timer eventCh chan struct{} opt *opt + + termEventsChan <-chan tcell.Event } func newFinder() *finder { @@ -94,6 +96,10 @@ func (f *finder) initFinder(items []string, matched []matching.Matched, opt opt) if err := f.term.Init(); err != nil { return errors.Wrap(err, "failed to initialize screen") } + + eventsChan := make(chan tcell.Event) + go f.term.ChannelEvents(eventsChan, nil) + f.termEventsChan = eventsChan } f.opt = &opt @@ -123,6 +129,14 @@ func (f *finder) initFinder(items []string, matched []matching.Matched, opt opt) f.drawTimer.Stop() } f.eventCh = make(chan struct{}, 30) // A large value + + if opt.query != "" { + f.state.input = []rune(opt.query) + f.state.cursorX = runewidth.StringWidth(opt.query) + f.state.x = len(opt.query) + f.filter() + } + return nil } @@ -442,9 +456,10 @@ func (f *finder) draw(d time.Duration) { } // readKey reads a key input. -// It returns ErrAbort if esc, CTRL-C or CTRL-D keys are inputted. -// Also, it returns errEntered if enter key is inputted. -func (f *finder) readKey() error { +// It returns ErrAbort if esc, CTRL-C or CTRL-D keys are inputted, +// errEntered in case of enter key, and a context error when the passed +// context is cancelled. +func (f *finder) readKey(ctx context.Context) error { f.stateMu.RLock() prevInputLen := len(f.state.input) f.stateMu.RUnlock() @@ -457,7 +472,15 @@ func (f *finder) readKey() error { } }() - e := f.term.PollEvent() + var e tcell.Event + + select { + case ee := <-f.termEventsChan: + e = ee + case <-ctx.Done(): + return ctx.Err() + } + f.stateMu.Lock() defer f.stateMu.Unlock() @@ -670,7 +693,14 @@ func (f *finder) find(slice interface{}, itemFunc func(i int) string, opts []Opt matched []matching.Matched ) - ctx, cancel := context.WithCancel(context.Background()) + var parentContext context.Context + if opt.context != nil { + parentContext = opt.context + } else { + parentContext = context.Background() + } + + ctx, cancel := context.WithCancel(parentContext) defer cancel() inited := make(chan struct{}) @@ -714,6 +744,10 @@ func (f *finder) find(slice interface{}, itemFunc func(i int) string, opts []Opt close(inited) + if opt.selectOne && len(f.state.matched) == 1 { + return []int{f.state.matched[0].Idx}, nil + } + go func() { for { select { @@ -727,40 +761,45 @@ func (f *finder) find(slice interface{}, itemFunc func(i int) string, opts []Opt }() for { - f.draw(10 * time.Millisecond) - - err := f.readKey() - // hack for earning time to filter exec - if isInTesting() { - time.Sleep(50 * time.Millisecond) - } - switch { - case errors.Is(err, ErrAbort): - return nil, ErrAbort - case errors.Is(err, errEntered): - f.stateMu.RLock() - defer f.stateMu.RUnlock() + select { + case <-ctx.Done(): + return nil, ctx.Err() + default: + f.draw(10 * time.Millisecond) - if len(f.state.matched) == 0 { - return nil, ErrAbort + err := f.readKey(ctx) + // hack for earning time to filter exec + if isInTesting() { + time.Sleep(50 * time.Millisecond) } - if f.opt.multi { - if len(f.state.selection) == 0 { - return []int{f.state.matched[f.state.y].Idx}, nil + switch { + case errors.Is(err, ErrAbort): + return nil, ErrAbort + case errors.Is(err, errEntered): + f.stateMu.RLock() + defer f.stateMu.RUnlock() + + if len(f.state.matched) == 0 { + return nil, ErrAbort } - poss, idxs := make([]int, 0, len(f.state.selection)), make([]int, 0, len(f.state.selection)) - for idx, pos := range f.state.selection { - idxs = append(idxs, idx) - poss = append(poss, pos) + if f.opt.multi { + if len(f.state.selection) == 0 { + return []int{f.state.matched[f.state.y].Idx}, nil + } + poss, idxs := make([]int, 0, len(f.state.selection)), make([]int, 0, len(f.state.selection)) + for idx, pos := range f.state.selection { + idxs = append(idxs, idx) + poss = append(poss, pos) + } + sort.Slice(idxs, func(i, j int) bool { + return poss[i] < poss[j] + }) + return idxs, nil } - sort.Slice(idxs, func(i, j int) bool { - return poss[i] < poss[j] - }) - return idxs, nil + return []int{f.state.matched[f.state.y].Idx}, nil + case err != nil: + return nil, errors.Wrap(err, "failed to read a key") } - return []int{f.state.matched[f.state.y].Idx}, nil - case err != nil: - return nil, errors.Wrap(err, "failed to read a key") } } } diff --git a/vendor/github.com/ktr0731/go-fuzzyfinder/option.go b/vendor/github.com/ktr0731/go-fuzzyfinder/option.go index 1943e37cf..271989e4d 100644 --- a/vendor/github.com/ktr0731/go-fuzzyfinder/option.go +++ b/vendor/github.com/ktr0731/go-fuzzyfinder/option.go @@ -1,6 +1,9 @@ package fuzzyfinder -import "sync" +import ( + "context" + "sync" +) type opt struct { mode mode @@ -11,6 +14,9 @@ type opt struct { promptString string header string beginAtTop bool + context context.Context + query string + selectOne bool } type mode int @@ -27,7 +33,7 @@ const ( ) var defaultOption = opt{ - promptString: "> ", + promptString: "> ", hotReloadLock: &sync.Mutex{}, // this won't resolve the race condition but avoid nil panic } @@ -69,7 +75,7 @@ func WithHotReload() Option { // The caller must pass a pointer of the slice instead of the slice itself. // The caller must pass a RLock which is used to synchronize access to the slice. // The caller MUST NOT lock in the itemFunc passed to Find / FindMulti because it will be locked by the fuzzyfinder. -// If used together with WithPreviewWindow, the caller MUST use the RLock only in the previewFunc passed to WithPreviewWindow. +// If used together with WithPreviewWindow, the caller MUST use the RLock only in the previewFunc passed to WithPreviewWindow. func WithHotReloadLock(lock sync.Locker) Option { return func(o *opt) { o.hotReload = true @@ -116,3 +122,24 @@ func WithHeader(s string) Option { o.header = s } } + +// WithContext enables closing the fuzzy finder from parent. +func WithContext(ctx context.Context) Option { + return func(o *opt) { + o.context = ctx + } +} + +// WithQuery enables to set the initial query. +func WithQuery(s string) Option { + return func(o *opt) { + o.query = s + } +} + +// WithQuery enables to set the initial query. +func WithSelectOne() Option { + return func(o *opt) { + o.selectOne = true + } +} diff --git a/vendor/github.com/rivo/uniseg/README.md b/vendor/github.com/rivo/uniseg/README.md index 7e3d12e79..25e934687 100644 --- a/vendor/github.com/rivo/uniseg/README.md +++ b/vendor/github.com/rivo/uniseg/README.md @@ -133,6 +133,13 @@ Similarly, use - [`FirstSentence`](https://pkg.go.dev/github.com/rivo/uniseg#FirstSentence) or [`FirstSentenceInString`](https://pkg.go.dev/github.com/rivo/uniseg#FirstSentenceInString) for sentence segmentation only, and - [`FirstLineSegment`](https://pkg.go.dev/github.com/rivo/uniseg#FirstLineSegment) or [`FirstLineSegmentInString`](https://pkg.go.dev/github.com/rivo/uniseg#FirstLineSegmentInString) for line breaking / word wrapping (although using [`Step`](https://pkg.go.dev/github.com/rivo/uniseg#Step) or [`StepString`](https://pkg.go.dev/github.com/rivo/uniseg#StepString) is preferred as it will observe grapheme cluster boundaries). +Finally, if you need to reverse a string while preserving grapheme clusters, use [`ReverseString`](https://pkg.go.dev/github.com/rivo/uniseg#ReverseString): + +```go +fmt.Println(uniseg.ReverseString("🇩🇪🏳️‍🌈")) +// 🏳️‍🌈🇩🇪 +``` + ## Documentation Refer to https://pkg.go.dev/github.com/rivo/uniseg for the package's documentation. diff --git a/vendor/github.com/rivo/uniseg/doc.go b/vendor/github.com/rivo/uniseg/doc.go index 0fc2d8b43..11224ae22 100644 --- a/vendor/github.com/rivo/uniseg/doc.go +++ b/vendor/github.com/rivo/uniseg/doc.go @@ -70,10 +70,10 @@ broken. Monospace width, as referred to in this package, is the width of a string in a monospace font. This is commonly used in terminal user interfaces or text displays or editors that don't support proportional fonts. A width of 1 -corresponds to a single character cell. The C function [wcwidth()] and its +corresponds to a single character cell. The C function [wcswidth()] and its implementation in other programming languages is in widespread use for the same purpose. However, there is no standard for the calculation of such widths, and -this package differs from wcwidth() in a number of ways, presumably to generate +this package differs from wcswidth() in a number of ways, presumably to generate more visually pleasing results. To start, we assume that every code point has a width of 1, with the following @@ -103,6 +103,6 @@ Note that whether these widths appear correct depends on your application's render engine, to which extent it conforms to the Unicode Standard, and its choice of font. -[wcwidth()]: https://man7.org/linux/man-pages/man3/wcwidth.3.html +[wcswidth()]: https://man7.org/linux/man-pages/man3/wcswidth.3.html */ package uniseg diff --git a/vendor/github.com/rivo/uniseg/grapheme.go b/vendor/github.com/rivo/uniseg/grapheme.go index 997abbefd..d5d4c09e5 100644 --- a/vendor/github.com/rivo/uniseg/grapheme.go +++ b/vendor/github.com/rivo/uniseg/grapheme.go @@ -163,6 +163,25 @@ func GraphemeClusterCount(s string) (n int) { return } +// ReverseString reverses the given string while observing grapheme cluster +// boundaries. +func ReverseString(s string) string { + str := []byte(s) + reversed := make([]byte, len(str)) + state := -1 + index := len(str) + for len(str) > 0 { + var cluster []byte + cluster, str, _, state = FirstGraphemeCluster(str, state) + index -= len(cluster) + copy(reversed[index:], cluster) + if index <= len(str)/2 { + break + } + } + return string(reversed) +} + // The number of bits the grapheme property must be shifted to make place for // grapheme states. const shiftGraphemePropState = 4 diff --git a/vendor/modules.txt b/vendor/modules.txt index e2868316e..fbe3197d4 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -517,7 +517,7 @@ github.com/gabriel-vasile/mimetype/internal/magic # github.com/gdamore/encoding v1.0.0 ## explicit; go 1.9 github.com/gdamore/encoding -# github.com/gdamore/tcell/v2 v2.5.3 +# github.com/gdamore/tcell/v2 v2.6.0 ## explicit; go 1.12 github.com/gdamore/tcell/v2 github.com/gdamore/tcell/v2/terminfo @@ -976,7 +976,7 @@ github.com/klauspost/compress/zstd/internal/xxhash # github.com/ktr0731/go-ansisgr v0.1.0 ## explicit; go 1.19 github.com/ktr0731/go-ansisgr -# github.com/ktr0731/go-fuzzyfinder v0.7.0 +# github.com/ktr0731/go-fuzzyfinder v0.8.0 ## explicit; go 1.13 github.com/ktr0731/go-fuzzyfinder github.com/ktr0731/go-fuzzyfinder/matching @@ -1019,7 +1019,7 @@ github.com/mattn/go-colorable # github.com/mattn/go-isatty v0.0.20 ## explicit; go 1.15 github.com/mattn/go-isatty -# github.com/mattn/go-runewidth v0.0.14 +# github.com/mattn/go-runewidth v0.0.15 ## explicit; go 1.9 github.com/mattn/go-runewidth # github.com/matttproud/golang_protobuf_extensions v1.0.4 @@ -1130,7 +1130,7 @@ github.com/prometheus/statsd_exporter/pkg/mapper/fsm # github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 ## explicit github.com/rcrowley/go-metrics -# github.com/rivo/uniseg v0.4.2 +# github.com/rivo/uniseg v0.4.3 ## explicit; go 1.18 github.com/rivo/uniseg # github.com/russross/blackfriday v1.6.0