mirror of
https://github.com/jesseduffield/lazygit.git
synced 2026-01-26 01:41:35 +03:00
Bump gocui (and tcell)
and adapt lazygit's client code accordingly.
This commit is contained in:
16
go.mod
16
go.mod
@@ -12,13 +12,13 @@ require (
|
||||
github.com/aybabtme/humanlog v0.4.1
|
||||
github.com/cloudfoundry/jibber_jabber v0.0.0-20151120183258-bcc4c8345a21
|
||||
github.com/creack/pty v1.1.11
|
||||
github.com/gdamore/tcell/v2 v2.9.0
|
||||
github.com/gdamore/tcell/v2 v2.13.5
|
||||
github.com/go-errors/errors v1.5.1
|
||||
github.com/gookit/color v1.4.2
|
||||
github.com/integrii/flaggy v1.4.0
|
||||
github.com/jesseduffield/generics v0.0.0-20250517122708-b0b4a53a6f5c
|
||||
github.com/jesseduffield/go-git/v5 v5.14.1-0.20250407170251-e1a013310ccd
|
||||
github.com/jesseduffield/gocui v0.3.1-0.20251223144240-29fe12e8d53f
|
||||
github.com/jesseduffield/gocui v0.3.1-0.20251223154739-d4b2428354c3
|
||||
github.com/jesseduffield/lazycore v0.0.0-20221012050358-03d2e40243c5
|
||||
github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0
|
||||
github.com/karimkhaleel/jsonschema v0.0.0-20231001195015-d933f0d94ea3
|
||||
@@ -38,8 +38,8 @@ require (
|
||||
github.com/stretchr/testify v1.10.0
|
||||
github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778
|
||||
golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56
|
||||
golang.org/x/sync v0.18.0
|
||||
golang.org/x/sys v0.38.0
|
||||
golang.org/x/sync v0.19.0
|
||||
golang.org/x/sys v0.39.0
|
||||
gopkg.in/ozeidan/fuzzy-patricia.v3 v3.0.0
|
||||
gopkg.in/yaml.v3 v3.0.1
|
||||
)
|
||||
@@ -49,7 +49,8 @@ require (
|
||||
github.com/ProtonMail/go-crypto v1.1.6 // indirect
|
||||
github.com/bahlo/generic-list-go v0.2.0 // indirect
|
||||
github.com/buger/jsonparser v1.1.1 // indirect
|
||||
github.com/clipperhouse/uax29/v2 v2.2.0 // indirect
|
||||
github.com/clipperhouse/stringish v0.1.1 // indirect
|
||||
github.com/clipperhouse/uax29/v2 v2.3.0 // indirect
|
||||
github.com/cloudflare/circl v1.6.1 // indirect
|
||||
github.com/cyphar/filepath-securejoin v0.4.1 // indirect
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
@@ -73,14 +74,15 @@ require (
|
||||
github.com/petermattis/goid v0.0.0-20250813065127-a731cc31b4fe // indirect
|
||||
github.com/pjbgf/sha1cd v0.3.2 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/rivo/uniseg v0.4.7 // indirect
|
||||
github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 // indirect
|
||||
github.com/skeema/knownhosts v1.3.1 // indirect
|
||||
github.com/wk8/go-ordered-map/v2 v2.1.8 // indirect
|
||||
github.com/xanzy/ssh-agent v0.3.3 // indirect
|
||||
golang.org/x/crypto v0.45.0 // indirect
|
||||
golang.org/x/net v0.47.0 // indirect
|
||||
golang.org/x/term v0.37.0 // indirect
|
||||
golang.org/x/text v0.31.0 // indirect
|
||||
golang.org/x/term v0.38.0 // indirect
|
||||
golang.org/x/text v0.32.0 // indirect
|
||||
gopkg.in/fsnotify.v1 v1.4.7 // indirect
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect
|
||||
gopkg.in/warnings.v0 v0.1.2 // indirect
|
||||
|
||||
69
go.sum
69
go.sum
@@ -65,8 +65,10 @@ github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWR
|
||||
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
|
||||
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
|
||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||
github.com/clipperhouse/uax29/v2 v2.2.0 h1:ChwIKnQN3kcZteTXMgb1wztSgaU+ZemkgWdohwgs8tY=
|
||||
github.com/clipperhouse/uax29/v2 v2.2.0/go.mod h1:EFJ2TJMRUaplDxHKj1qAEhCtQPW2tJSwu5BF98AuoVM=
|
||||
github.com/clipperhouse/stringish v0.1.1 h1:+NSqMOr3GR6k1FdRhhnXrLfztGzuG+VuFDfatpWHKCs=
|
||||
github.com/clipperhouse/stringish v0.1.1/go.mod h1:v/WhFtE1q0ovMta2+m+UbpZ+2/HEXNWYXQgCt4hdOzA=
|
||||
github.com/clipperhouse/uax29/v2 v2.3.0 h1:SNdx9DVUqMoBuBoW3iLOj4FQv3dN5mDtuqwuhIGpJy4=
|
||||
github.com/clipperhouse/uax29/v2 v2.3.0/go.mod h1:Wn1g7MK6OoeDT0vL+Q0SQLDz/KpfsVRgg6W7ihQeh4g=
|
||||
github.com/cloudflare/circl v1.6.1 h1:zqIqSPIndyBh1bjLVVDHMPpVKqp8Su/V+6MeDzzQBQ0=
|
||||
github.com/cloudflare/circl v1.6.1/go.mod h1:uddAzsPgqdMAYatqJ0lsjX1oECcQLIlRpzZh3pJrofs=
|
||||
github.com/cloudfoundry/jibber_jabber v0.0.0-20151120183258-bcc4c8345a21 h1:tuijfIjZyjZaHq9xDUh0tNitwXshJpbLkqMOJv4H3do=
|
||||
@@ -97,12 +99,10 @@ github.com/fatih/color v1.9.0 h1:8xPHl4/q1VyqGIPif1F+1V3Y3lSmrq01EabUW3CoW5s=
|
||||
github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU=
|
||||
github.com/gdamore/encoding v1.0.1 h1:YzKZckdBL6jVt2Gc+5p82qhrGiqMdG/eNs6Wy0u3Uhw=
|
||||
github.com/gdamore/encoding v1.0.1/go.mod h1:0Z0cMFinngz9kS1QfMjCP8TY7em3bZYeeklsSDPivEo=
|
||||
github.com/gdamore/tcell/v2 v2.8.0/go.mod h1:bj8ori1BG3OYMjmb3IklZVWfZUJ1UBQt9JXrOCOhGWw=
|
||||
github.com/gdamore/tcell/v2 v2.9.0 h1:N6t+eqK7/xwtRPwxzs1PXeRWnm0H9l02CrgJ7DLn1ys=
|
||||
github.com/gdamore/tcell/v2 v2.9.0/go.mod h1:8/ZoqM9rxzYphT9tH/9LnunhV9oPBqwS8WHGYm5nrmo=
|
||||
github.com/gdamore/tcell/v2 v2.13.5 h1:YvWYCSr6gr2Ovs84dXbZLjDuOfQchhj8buOEqY52rpA=
|
||||
github.com/gdamore/tcell/v2 v2.13.5/go.mod h1:+Wfe208WDdB7INEtCsNrAN6O2m+wsTPk1RAovjaILlo=
|
||||
github.com/gliderlabs/ssh v0.3.8 h1:a4YXD1V7xMF9g5nTkdfnja3Sxy1PVDCj1Zg4Wb8vY6c=
|
||||
github.com/gliderlabs/ssh v0.3.8/go.mod h1:xYoytBv1sV0aL3CavoDuJIQNURXkkfPA/wxQ1pL1fAU=
|
||||
github.com/go-errors/errors v1.0.2/go.mod h1:psDX2osz5VnTOnFWbDeWwS7yejl+uV3FEWEp4lssFEs=
|
||||
github.com/go-errors/errors v1.5.1 h1:ZwEMSLRCapFLflTpT7NKaAc7ukJ8ZPEjzlxt8rPN8bk=
|
||||
github.com/go-errors/errors v1.5.1/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og=
|
||||
github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 h1:+zs/tPmkDkHx3U66DAb0lQFJrpS6731Oaa12ikc+DiI=
|
||||
@@ -155,7 +155,6 @@ github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
|
||||
github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
|
||||
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
|
||||
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
|
||||
@@ -194,8 +193,8 @@ github.com/jesseduffield/generics v0.0.0-20250517122708-b0b4a53a6f5c h1:tC2Paiis
|
||||
github.com/jesseduffield/generics v0.0.0-20250517122708-b0b4a53a6f5c/go.mod h1:F2fEBk0ddf6ixrBrJjY7phfQ3hL9rXG0uSjvwYe50bE=
|
||||
github.com/jesseduffield/go-git/v5 v5.14.1-0.20250407170251-e1a013310ccd h1:ViKj6qth8FgcIWizn9KiACWwPemWSymx62OPN0tHT+Q=
|
||||
github.com/jesseduffield/go-git/v5 v5.14.1-0.20250407170251-e1a013310ccd/go.mod h1:lRhCiBr6XjQrvcQVa+UYsy/99d3wMXn/a0nSQlhnhlA=
|
||||
github.com/jesseduffield/gocui v0.3.1-0.20251223144240-29fe12e8d53f h1:5ArylWehV98WTxJM7AcSa53YNskEFpHHv+VePONQn58=
|
||||
github.com/jesseduffield/gocui v0.3.1-0.20251223144240-29fe12e8d53f/go.mod h1:sLIyZ2J42R6idGdtemZzsiR3xY5EF0KsvYEGh3dQv3s=
|
||||
github.com/jesseduffield/gocui v0.3.1-0.20251223154739-d4b2428354c3 h1:Jp2YnNnWNTf39WIagOMJQx+ovekC387fYcbXR/7ye2A=
|
||||
github.com/jesseduffield/gocui v0.3.1-0.20251223154739-d4b2428354c3/go.mod h1:lQCd2TvvNXVKFBowy4A7xxZbUp+1KEiGs4j0Q5Zt9gQ=
|
||||
github.com/jesseduffield/lazycore v0.0.0-20221012050358-03d2e40243c5 h1:CDuQmfOjAtb1Gms6a1p5L2P8RhbLUq5t8aL7PiQd2uY=
|
||||
github.com/jesseduffield/lazycore v0.0.0-20221012050358-03d2e40243c5/go.mod h1:qxN4mHOAyeIDLP7IK7defgPClM/z1Kze8VVQiaEjzsQ=
|
||||
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
|
||||
@@ -222,7 +221,6 @@ github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0
|
||||
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
|
||||
github.com/kyokomi/emoji/v2 v2.2.8 h1:jcofPxjHWEkJtkIbcLHvZhxKgCPl6C7MyjTrD4KDqUE=
|
||||
github.com/kyokomi/emoji/v2 v2.2.8/go.mod h1:JUcn42DTdsXJo1SWanHh4HKDEyPaR5CqkmoirZZP9qE=
|
||||
github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0=
|
||||
github.com/lucasb-eyer/go-colorful v1.3.0 h1:2/yBRLdWBZKrf7gB40FoiKfAWYQ0lqNcbuQwVHXptag=
|
||||
github.com/lucasb-eyer/go-colorful v1.3.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0=
|
||||
github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
|
||||
@@ -236,7 +234,6 @@ github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hd
|
||||
github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE=
|
||||
github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y=
|
||||
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
|
||||
github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
|
||||
github.com/mattn/go-runewidth v0.0.19 h1:v++JhqYnZuu5jSKrk9RbgF5v4CGUjqRfBm05byFGLdw=
|
||||
github.com/mattn/go-runewidth v0.0.19/go.mod h1:XBkDxAl56ILZc9knddidhrOlY5R/pDhgLpndooCuJAs=
|
||||
github.com/mgutz/str v1.2.0 h1:4IzWSdIz9qPQWLfKZ0rJcV0jcUDpxvP4JVZ4GXQyvSw=
|
||||
@@ -258,8 +255,7 @@ github.com/pmezard/go-difflib v0.0.0-20151028094244-d8ed2627bdf0/go.mod h1:iKH77
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
|
||||
github.com/rivo/uniseg v0.4.3/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
|
||||
github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ=
|
||||
github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
|
||||
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||
github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ=
|
||||
@@ -323,9 +319,6 @@ golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc=
|
||||
golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
|
||||
golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8=
|
||||
golang.org/x/crypto v0.45.0 h1:jMBrvKuj23MTlT0bQEOBcAE0mjg8mK9RXFhRH6nyF3Q=
|
||||
golang.org/x/crypto v0.45.0/go.mod h1:XTGrrkGJve7CYK7J8PEww4aY7gM3qMCElcJQ8n8JdX4=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
@@ -365,9 +358,6 @@ golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||
golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||
golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
||||
golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
@@ -402,10 +392,6 @@ golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v
|
||||
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
|
||||
golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk=
|
||||
golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
|
||||
golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM=
|
||||
golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY=
|
||||
golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
@@ -429,12 +415,8 @@ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJ
|
||||
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
|
||||
golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sync v0.18.0 h1:kr88TuHDroi+UVf+0hZnirlk8o8T+4MrK6mr60WkH/I=
|
||||
golang.org/x/sync v0.18.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
|
||||
golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4=
|
||||
golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
|
||||
golang.org/x/sys v0.0.0-20170407050850-f3918c30c5c2/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
@@ -482,24 +464,13 @@ golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBc
|
||||
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc=
|
||||
golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
|
||||
golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE=
|
||||
golang.org/x/sys v0.39.0 h1:CvCKL8MeisomCi6qNZ+wbb0DN9E5AATixKsvNtMoMFk=
|
||||
golang.org/x/sys v0.39.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
||||
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
|
||||
golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU=
|
||||
golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk=
|
||||
golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY=
|
||||
golang.org/x/term v0.28.0/go.mod h1:Sw/lC2IAUZ92udQNf3WodGtn4k/XoLyZoh8v/8uiwek=
|
||||
golang.org/x/term v0.37.0 h1:8EGAD0qCmHYZg6J17DvsMy9/wJ7/D/4pV/wfnld5lTU=
|
||||
golang.org/x/term v0.37.0/go.mod h1:5pB4lxRNYYVZuTLmy8oR2BH8dflOR+IbTYFD8fi3254=
|
||||
golang.org/x/term v0.38.0 h1:PQ5pkm/rLO6HnxFR7N2lJHOZX6Kez5Y1gDSJla6jo7Q=
|
||||
golang.org/x/term v0.38.0/go.mod h1:bSEAKrOT1W+VSu9TSCMtoGEOUcKxOKgl3LE5QEF/xVg=
|
||||
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
@@ -509,13 +480,9 @@ golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
||||
golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
||||
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||
golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||
golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
|
||||
golang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM=
|
||||
golang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM=
|
||||
golang.org/x/text v0.32.0 h1:ZD01bjUt1FQ9WJ0ClOL5vxgxOI/sVCNgX1YtKwcY0mU=
|
||||
golang.org/x/text v0.32.0/go.mod h1:o/rUWzghvpD5TXrTIBuJU77MTaN0ljMWE47kxGJQ7jY=
|
||||
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
@@ -568,8 +535,6 @@ golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4f
|
||||
golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
|
||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
|
||||
golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58=
|
||||
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
|
||||
@@ -196,7 +196,7 @@ func (self *ContextMgr) Activate(c types.Context, opts types.OnFocusOpts) {
|
||||
|
||||
v.Visible = true
|
||||
|
||||
self.gui.c.GocuiGui().Cursor = v.Editable && v.Mask == 0
|
||||
self.gui.c.GocuiGui().Cursor = v.Editable && v.Mask == ""
|
||||
|
||||
c.HandleFocus(opts)
|
||||
}
|
||||
|
||||
@@ -61,28 +61,25 @@ func (self *CommitsHelper) JoinCommitMessageAndUnwrappedDescription() string {
|
||||
}
|
||||
|
||||
func TryRemoveHardLineBreaks(message string, autoWrapWidth int) string {
|
||||
messageRunes := []rune(message)
|
||||
lastHardLineStart := 0
|
||||
for i, r := range messageRunes {
|
||||
if r == '\n' {
|
||||
result := message
|
||||
for i, b := range message {
|
||||
if b == '\n' {
|
||||
// Try to make this a soft linebreak by turning it into a space, and
|
||||
// checking whether it still wraps to the same result then.
|
||||
messageRunes[i] = ' '
|
||||
str := message[lastHardLineStart:i] + " " + message[i+1:]
|
||||
softLineBreakIndices := gocui.AutoWrapContent(str, autoWrapWidth)
|
||||
|
||||
_, cursorMapping := gocui.AutoWrapContent(messageRunes[lastHardLineStart:], autoWrapWidth)
|
||||
|
||||
// Look at the cursorMapping to check whether auto-wrapping inserted
|
||||
// a line break. If it did, there will be a cursorMapping entry with
|
||||
// Orig pointing to the position after the inserted line break.
|
||||
if len(cursorMapping) == 0 || cursorMapping[0].Orig != i-lastHardLineStart+1 {
|
||||
// It didn't, so change it back to a newline
|
||||
messageRunes[i] = '\n'
|
||||
// See if auto-wrapping inserted a soft line break:
|
||||
if len(softLineBreakIndices) > 0 && softLineBreakIndices[0] == i-lastHardLineStart+1 {
|
||||
// It did, so change it to a space in the result.
|
||||
result = result[:i] + " " + result[i+1:]
|
||||
}
|
||||
lastHardLineStart = i + 1
|
||||
}
|
||||
}
|
||||
|
||||
return string(messageRunes)
|
||||
return result
|
||||
}
|
||||
|
||||
func (self *CommitsHelper) SwitchToEditor() error {
|
||||
|
||||
@@ -152,7 +152,7 @@ func (self *ConfirmationHelper) preparePromptPanel(
|
||||
) {
|
||||
self.c.Views().Prompt.Title = opts.Title
|
||||
self.c.Views().Prompt.FgColor = theme.GocuiDefaultTextColor
|
||||
self.c.Views().Prompt.Mask = runeForMask(opts.Mask)
|
||||
self.c.Views().Prompt.Mask = characterForMask(opts.Mask)
|
||||
self.c.Views().Prompt.SetOrigin(0, 0)
|
||||
|
||||
textArea := self.c.Views().Prompt.TextArea
|
||||
@@ -173,11 +173,11 @@ func (self *ConfirmationHelper) preparePromptPanel(
|
||||
}
|
||||
}
|
||||
|
||||
func runeForMask(mask bool) rune {
|
||||
func characterForMask(mask bool) string {
|
||||
if mask {
|
||||
return '*'
|
||||
return "*"
|
||||
}
|
||||
return 0
|
||||
return ""
|
||||
}
|
||||
|
||||
func (self *ConfirmationHelper) CreatePopupPanel(ctx goContext.Context, opts types.CreatePopupPanelOpts) {
|
||||
|
||||
@@ -29,12 +29,12 @@ func (gui *Gui) handleEditorKeypress(textArea *gocui.TextArea, key gocui.Key, ch
|
||||
textArea.MoveCursorRight()
|
||||
case key == gocui.KeyEnter:
|
||||
if allowMultiline {
|
||||
textArea.TypeRune('\n')
|
||||
textArea.TypeCharacter("\n")
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
case key == gocui.KeySpace:
|
||||
textArea.TypeRune(' ')
|
||||
textArea.TypeCharacter(" ")
|
||||
case key == gocui.KeyInsert:
|
||||
textArea.ToggleOverwrite()
|
||||
case key == gocui.KeyCtrlU:
|
||||
@@ -49,7 +49,7 @@ func (gui *Gui) handleEditorKeypress(textArea *gocui.TextArea, key gocui.Key, ch
|
||||
textArea.Yank()
|
||||
|
||||
case unicode.IsPrint(ch):
|
||||
textArea.TypeRune(ch)
|
||||
textArea.TypeCharacter(string(ch))
|
||||
default:
|
||||
return false
|
||||
}
|
||||
|
||||
2
vendor/github.com/clipperhouse/stringish/.gitignore
generated
vendored
Normal file
2
vendor/github.com/clipperhouse/stringish/.gitignore
generated
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
.DS_Store
|
||||
*.test
|
||||
21
vendor/github.com/clipperhouse/stringish/LICENSE
generated
vendored
Normal file
21
vendor/github.com/clipperhouse/stringish/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2025 Matt Sherman
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
64
vendor/github.com/clipperhouse/stringish/README.md
generated
vendored
Normal file
64
vendor/github.com/clipperhouse/stringish/README.md
generated
vendored
Normal file
@@ -0,0 +1,64 @@
|
||||
# stringish
|
||||
|
||||
A small Go module that provides a generic type constraint for “string-like”
|
||||
data, and a utf8 package that works with both strings and byte slices
|
||||
without conversions.
|
||||
|
||||
```go
|
||||
type Interface interface {
|
||||
~[]byte | ~string
|
||||
}
|
||||
```
|
||||
|
||||
[](https://pkg.go.dev/github.com/clipperhouse/stringish/utf8)
|
||||
[](https://github.com/clipperhouse/stringish/actions/workflows/gotest.yml)
|
||||
|
||||
## Install
|
||||
|
||||
```
|
||||
go get github.com/clipperhouse/stringish
|
||||
```
|
||||
|
||||
## Examples
|
||||
|
||||
```go
|
||||
import (
|
||||
"github.com/clipperhouse/stringish"
|
||||
"github.com/clipperhouse/stringish/utf8"
|
||||
)
|
||||
|
||||
s := "Hello, 世界"
|
||||
r, size := utf8.DecodeRune(s) // not DecodeRuneInString 🎉
|
||||
|
||||
b := []byte("Hello, 世界")
|
||||
r, size = utf8.DecodeRune(b) // same API!
|
||||
|
||||
func MyFoo[T stringish.Interface](s T) T {
|
||||
// pass a string or a []byte
|
||||
// iterate, slice, transform, whatever
|
||||
}
|
||||
```
|
||||
|
||||
## Motivation
|
||||
|
||||
Sometimes we want APIs to accept `string` or `[]byte` without having to convert
|
||||
between those types. That conversion usually allocates!
|
||||
|
||||
By implementing with `stringish.Interface`, we can have a single API, and
|
||||
single implementation for both types: one `Foo` instead of `Foo` and
|
||||
`FooString`.
|
||||
|
||||
We have converted the
|
||||
[`unicode/utf8` package](https://github.com/clipperhouse/stringish/blob/main/utf8/utf8.go)
|
||||
as an example -- note the absence of`*InString` funcs. We might look at `x/text`
|
||||
next.
|
||||
|
||||
## Used by
|
||||
|
||||
- clipperhouse/uax29: [stringish trie](https://github.com/clipperhouse/uax29/blob/master/graphemes/trie.go#L27), [stringish iterator](https://github.com/clipperhouse/uax29/blob/master/internal/iterators/iterator.go#L9), [stringish SplitFunc](https://github.com/clipperhouse/uax29/blob/master/graphemes/splitfunc.go#L21)
|
||||
|
||||
- [clipperhouse/displaywidth](https://github.com/clipperhouse/displaywidth)
|
||||
|
||||
## Prior discussion
|
||||
|
||||
- [Consideration of similar by the Go team](https://github.com/golang/go/issues/48643)
|
||||
5
vendor/github.com/clipperhouse/stringish/interface.go
generated
vendored
Normal file
5
vendor/github.com/clipperhouse/stringish/interface.go
generated
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
package stringish
|
||||
|
||||
type Interface interface {
|
||||
~[]byte | ~string
|
||||
}
|
||||
24
vendor/github.com/clipperhouse/uax29/v2/graphemes/README.md
generated
vendored
24
vendor/github.com/clipperhouse/uax29/v2/graphemes/README.md
generated
vendored
@@ -1,5 +1,9 @@
|
||||
An implementation of grapheme cluster boundaries from [Unicode text segmentation](https://unicode.org/reports/tr29/#Grapheme_Cluster_Boundaries) (UAX 29), for Unicode version 15.0.0.
|
||||
|
||||
[](https://pkg.go.dev/github.com/clipperhouse/uax29/v2/graphemes)
|
||||

|
||||

|
||||
|
||||
## Quick start
|
||||
|
||||
```
|
||||
@@ -18,15 +22,14 @@ for tokens.Next() { // Next() returns true until end of data
|
||||
}
|
||||
```
|
||||
|
||||
[](https://pkg.go.dev/github.com/clipperhouse/uax29/v2/graphemes)
|
||||
|
||||
_A grapheme is a “single visible character”, which might be a simple as a single letter, or a complex emoji that consists of several Unicode code points._
|
||||
|
||||
## Conformance
|
||||
|
||||
We use the Unicode [test suite](https://unicode.org/reports/tr41/tr41-26.html#Tests29). Status:
|
||||
We use the Unicode [test suite](https://unicode.org/reports/tr41/tr41-26.html#Tests29).
|
||||
|
||||

|
||||

|
||||

|
||||
|
||||
## APIs
|
||||
|
||||
@@ -71,9 +74,18 @@ for tokens.Next() { // Next() returns true until end of data
|
||||
}
|
||||
```
|
||||
|
||||
### Performance
|
||||
### Benchmarks
|
||||
|
||||
On a Mac M2 laptop, we see around 200MB/s, or around 100 million graphemes per second. You should see ~constant memory, and no allocations.
|
||||
On a Mac M2 laptop, we see around 200MB/s, or around 100 million graphemes per second, and no allocations.
|
||||
|
||||
```
|
||||
goos: darwin
|
||||
goarch: arm64
|
||||
pkg: github.com/clipperhouse/uax29/graphemes/comparative
|
||||
cpu: Apple M2
|
||||
BenchmarkGraphemes/clipperhouse/uax29-8 173805 ns/op 201.16 MB/s 0 B/op 0 allocs/op
|
||||
BenchmarkGraphemes/rivo/uniseg-8 2045128 ns/op 17.10 MB/s 0 B/op 0 allocs/op
|
||||
```
|
||||
|
||||
### Invalid inputs
|
||||
|
||||
|
||||
7
vendor/github.com/clipperhouse/uax29/v2/graphemes/iterator.go
generated
vendored
7
vendor/github.com/clipperhouse/uax29/v2/graphemes/iterator.go
generated
vendored
@@ -1,8 +1,11 @@
|
||||
package graphemes
|
||||
|
||||
import "github.com/clipperhouse/uax29/v2/internal/iterators"
|
||||
import (
|
||||
"github.com/clipperhouse/stringish"
|
||||
"github.com/clipperhouse/uax29/v2/internal/iterators"
|
||||
)
|
||||
|
||||
type Iterator[T iterators.Stringish] struct {
|
||||
type Iterator[T stringish.Interface] struct {
|
||||
*iterators.Iterator[T]
|
||||
}
|
||||
|
||||
|
||||
4
vendor/github.com/clipperhouse/uax29/v2/graphemes/splitfunc.go
generated
vendored
4
vendor/github.com/clipperhouse/uax29/v2/graphemes/splitfunc.go
generated
vendored
@@ -3,7 +3,7 @@ package graphemes
|
||||
import (
|
||||
"bufio"
|
||||
|
||||
"github.com/clipperhouse/uax29/v2/internal/iterators"
|
||||
"github.com/clipperhouse/stringish"
|
||||
)
|
||||
|
||||
// is determines if lookup intersects propert(ies)
|
||||
@@ -18,7 +18,7 @@ const _Ignore = _Extend
|
||||
// See https://unicode.org/reports/tr29/#Grapheme_Cluster_Boundaries.
|
||||
var SplitFunc bufio.SplitFunc = splitFunc[[]byte]
|
||||
|
||||
func splitFunc[T iterators.Stringish](data T, atEOF bool) (advance int, token T, err error) {
|
||||
func splitFunc[T stringish.Interface](data T, atEOF bool) (advance int, token T, err error) {
|
||||
var empty T
|
||||
if len(data) == 0 {
|
||||
return 0, empty, nil
|
||||
|
||||
6
vendor/github.com/clipperhouse/uax29/v2/graphemes/trie.go
generated
vendored
6
vendor/github.com/clipperhouse/uax29/v2/graphemes/trie.go
generated
vendored
@@ -1,10 +1,10 @@
|
||||
package graphemes
|
||||
|
||||
import "github.com/clipperhouse/stringish"
|
||||
|
||||
// generated by github.com/clipperhouse/uax29/v2
|
||||
// from https://www.unicode.org/Public/15.0.0/ucd/auxiliary/GraphemeBreakProperty.txt
|
||||
|
||||
import "github.com/clipperhouse/uax29/v2/internal/iterators"
|
||||
|
||||
type property uint16
|
||||
|
||||
const (
|
||||
@@ -27,7 +27,7 @@ const (
|
||||
// lookup returns the trie value for the first UTF-8 encoding in s and
|
||||
// the width in bytes of this encoding. The size will be 0 if s does not
|
||||
// hold enough bytes to complete the encoding. len(s) must be greater than 0.
|
||||
func lookup[T iterators.Stringish](s T) (v property, sz int) {
|
||||
func lookup[T stringish.Interface](s T) (v property, sz int) {
|
||||
c0 := s[0]
|
||||
switch {
|
||||
case c0 < 0x80: // is ASCII
|
||||
|
||||
27
vendor/github.com/clipperhouse/uax29/v2/internal/iterators/iterator.go
generated
vendored
27
vendor/github.com/clipperhouse/uax29/v2/internal/iterators/iterator.go
generated
vendored
@@ -1,14 +1,12 @@
|
||||
package iterators
|
||||
|
||||
type Stringish interface {
|
||||
[]byte | string
|
||||
}
|
||||
import "github.com/clipperhouse/stringish"
|
||||
|
||||
type SplitFunc[T Stringish] func(T, bool) (int, T, error)
|
||||
type SplitFunc[T stringish.Interface] func(T, bool) (int, T, error)
|
||||
|
||||
// Iterator is a generic iterator for words that are either []byte or string.
|
||||
// Iterate while Next() is true, and access the word via Value().
|
||||
type Iterator[T Stringish] struct {
|
||||
type Iterator[T stringish.Interface] struct {
|
||||
split SplitFunc[T]
|
||||
data T
|
||||
start int
|
||||
@@ -16,7 +14,7 @@ type Iterator[T Stringish] struct {
|
||||
}
|
||||
|
||||
// New creates a new Iterator for the given data and SplitFunc.
|
||||
func New[T Stringish](split SplitFunc[T], data T) *Iterator[T] {
|
||||
func New[T stringish.Interface](split SplitFunc[T], data T) *Iterator[T] {
|
||||
return &Iterator[T]{
|
||||
split: split,
|
||||
data: data,
|
||||
@@ -83,3 +81,20 @@ func (iter *Iterator[T]) Reset() {
|
||||
iter.start = 0
|
||||
iter.pos = 0
|
||||
}
|
||||
|
||||
func (iter *Iterator[T]) First() T {
|
||||
if len(iter.data) == 0 {
|
||||
return iter.data
|
||||
}
|
||||
advance, _, err := iter.split(iter.data, true)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if advance <= 0 {
|
||||
panic("SplitFunc returned a zero or negative advance")
|
||||
}
|
||||
if advance > len(iter.data) {
|
||||
panic("SplitFunc advanced beyond the end of the data")
|
||||
}
|
||||
return iter.data[:advance]
|
||||
}
|
||||
|
||||
2
vendor/github.com/gdamore/tcell/v2/.gitignore
generated
vendored
2
vendor/github.com/gdamore/tcell/v2/.gitignore
generated
vendored
@@ -1 +1,3 @@
|
||||
coverage.txt
|
||||
.zed
|
||||
.idea
|
||||
|
||||
4
vendor/github.com/gdamore/tcell/v2/README-wasm.md
generated
vendored
4
vendor/github.com/gdamore/tcell/v2/README-wasm.md
generated
vendored
@@ -13,7 +13,7 @@ GOOS=js GOARCH=wasm go build -o yourfile.wasm
|
||||
|
||||
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" ./
|
||||
cp "$(go env GOROOT)/lib/wasm/wasm_exec.js" ./
|
||||
```
|
||||
|
||||
In `tcell.js`, you also need to change the constant
|
||||
@@ -58,4 +58,4 @@ It is recommended to use an iframe if you want to embed the app into a webpage:
|
||||
|
||||
### Accessing files
|
||||
|
||||
`io.Open(filename)` and other related functions for reading file systems do not work; use `http.Get(filename)` instead.
|
||||
`io.Open(filename)` and other related functions for reading file systems do not work; use `http.Get(filename)` instead.
|
||||
|
||||
85
vendor/github.com/gdamore/tcell/v2/README.md
generated
vendored
85
vendor/github.com/gdamore/tcell/v2/README.md
generated
vendored
@@ -16,8 +16,6 @@ It was inspired by _termbox_, but includes many additional improvements.
|
||||
[](https://goreportcard.com/report/github.com/gdamore/tcell/v2)
|
||||
[](https://github.com/gdamore/tcell/releases)
|
||||
|
||||
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.
|
||||
Version 1.x remains available using the import `github.com/gdamore/tcell`.
|
||||
|
||||
@@ -31,15 +29,6 @@ A number of example are posted up on our [Gallery](https://github.com/gdamore/tc
|
||||
|
||||
Let us know if you want to add your masterpiece to the list!
|
||||
|
||||
## 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
|
||||
portability, and includes support for all POSIX systems.
|
||||
|
||||
The database is also flexible & extensible, and can be modified by either running
|
||||
a program to build the entire database, or an entry for just a single terminal.
|
||||
|
||||
## More Portable
|
||||
|
||||
_Tcell_ is portable to a wide variety of systems, and is pure Go, without
|
||||
@@ -51,14 +40,6 @@ and the version immediately prior ("oldstable"). This policy is necessary to ma
|
||||
update dependencies to pick up security fixes and new features, and it allows us to adopt changes
|
||||
(such as library and language features) that are only supported in newer versions of Go.
|
||||
|
||||
## No Async IO
|
||||
|
||||
_Tcell_ is able to operate without requiring `SIGIO` signals (unlike _termbox_),
|
||||
or asynchronous I/O, and can instead use standard Go file objects and Go routines.
|
||||
This means it should be safe, especially for
|
||||
use with programs that use exec, or otherwise need to manipulate the tty streams.
|
||||
This model is also much closer to idiomatic Go, leading to fewer surprises.
|
||||
|
||||
## Rich Unicode & non-Unicode support
|
||||
|
||||
_Tcell_ includes enhanced support for Unicode, including wide characters and
|
||||
@@ -77,15 +58,6 @@ drawing certain characters.
|
||||
_Tcell_ also has richer support for a larger number of special keys that some
|
||||
terminals can send.
|
||||
|
||||
## Better Color Handling
|
||||
|
||||
_Tcell_ will respect your terminal's color space as specified within your terminfo entries.
|
||||
For example attempts to emit color sequences on VT100 terminals
|
||||
won't result in unintended consequences.
|
||||
|
||||
_Tcell_ maps 16 colors down to 8, for terminals that need it.
|
||||
(The upper 8 colors are just brighter versions of the lower 8.)
|
||||
|
||||
## Better Mouse Support
|
||||
|
||||
_Tcell_ supports enhanced mouse tracking mode, so your application can receive
|
||||
@@ -109,12 +81,15 @@ If you're lazy, and want them all anyway, see the `encoding` sub-directory.
|
||||
|
||||
## Wide & Combining Characters
|
||||
|
||||
The `SetContent()` API takes a primary rune, and an optional list of combining runes.
|
||||
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
|
||||
is displayed, and the other character is not; do not depend on that behavior.)
|
||||
The `Put()` API takes a string, which should be legal UTF-8, and displays
|
||||
the first grapheme (which may composed of multiple runes). It returns the
|
||||
actual width displayed, which can be used to advance the column positiion
|
||||
for the next display grapheme. Alternatively, `PutStr()` or `PutStrStyled()`
|
||||
can be used to display a single line of text (which will be clipped at the
|
||||
edge of the screen).
|
||||
|
||||
If a second character is displayed immediately in the cell adjacent to a
|
||||
wide character (offset by one instead of by two), then the results are undefined.
|
||||
|
||||
## Colors
|
||||
|
||||
@@ -129,11 +104,7 @@ a ticket.
|
||||
|
||||
_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".
|
||||
We follow the (inaccurate) common convention.
|
||||
|
||||
There are a few ways you can enable (or disable) true color.
|
||||
There are a few ways you can enable (or disable) 24-bit 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
|
||||
@@ -151,8 +122,8 @@ There are a few ways you can enable (or disable) true color.
|
||||
- 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
|
||||
When using 24-bit color, programs will display the colors that the programmer
|
||||
intended, overriding any "`themes`" the user may have set in their terminal
|
||||
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
|
||||
@@ -163,38 +134,10 @@ the user has established.)
|
||||
Reasonable attempts have been made to minimize sending data to terminals,
|
||||
avoiding repeated sequences or drawing the same cell on refresh updates.
|
||||
|
||||
## Terminfo
|
||||
|
||||
(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
|
||||
with ncurses installed), dynamically parse the output from `infocmp`
|
||||
for terminals it does not already know about.
|
||||
|
||||
See the `terminfo/` directory for more information about generating
|
||||
new entries for the built-in database.
|
||||
|
||||
_Tcell_ requires that the terminal support the `cup` mode of cursor addressing.
|
||||
Ancient terminals without the ability to position the cursor directly
|
||||
are not supported.
|
||||
This is unlikely to be a problem; such terminals have not been mass-produced
|
||||
since the early 1970s.
|
||||
|
||||
## Mouse Support
|
||||
|
||||
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
|
||||
is not possible as terminfo sequences are not defined.)
|
||||
|
||||
On Windows, the mouse works normally.
|
||||
|
||||
Mouse wheel buttons on various terminals are known to work, but the support
|
||||
in terminal emulators, as well as support for various buttons and
|
||||
live mouse tracking, varies widely.
|
||||
Modern _xterm_, macOS _Terminal_, and _iTerm_ all work well.
|
||||
Mouse tracking, buttons, and even wheel mice works fine on most terminal
|
||||
emulators, as well as Windows.
|
||||
|
||||
## Bracketed Paste
|
||||
|
||||
|
||||
57
vendor/github.com/gdamore/tcell/v2/TUTORIAL.md
generated
vendored
57
vendor/github.com/gdamore/tcell/v2/TUTORIAL.md
generated
vendored
@@ -107,23 +107,30 @@ s.SetStyle(defStyle)
|
||||
s.Clear()
|
||||
```
|
||||
|
||||
Text may be drawn on the screen using `SetContent`.
|
||||
Text may be drawn on the screen using `Put`, `PutStr`, or `PutStrStyled`.
|
||||
|
||||
```go
|
||||
s.SetContent(0, 0, 'H', nil, defStyle)
|
||||
s.SetContent(1, 0, 'i', nil, defStyle)
|
||||
s.SetContent(2, 0, '!', nil, defStyle)
|
||||
s.Put(0, 0, 'H', defStyle)
|
||||
s.Put(1, 0, 'i', defStyle)
|
||||
s.Put(2, 0, '!', defStyle)
|
||||
```
|
||||
|
||||
To draw text more easily, define a render function.
|
||||
which is equivalent to
|
||||
|
||||
```go
|
||||
s.PutStrStyled(0, 0, "Hi!", defStyle)
|
||||
````
|
||||
|
||||
To draw text more easily with wrapping, define a render function.
|
||||
|
||||
```go
|
||||
func drawText(s tcell.Screen, x1, y1, x2, y2 int, style tcell.Style, text string) {
|
||||
row := y1
|
||||
col := x1
|
||||
for _, r := range []rune(text) {
|
||||
s.SetContent(col, row, r, nil, style)
|
||||
col++
|
||||
var width int
|
||||
for text != "" {
|
||||
text, width = s.Put(col, row, text, style)
|
||||
col += width
|
||||
if col >= x2 {
|
||||
row++
|
||||
col = x1
|
||||
@@ -131,6 +138,10 @@ func drawText(s tcell.Screen, x1, y1, x2, y2 int, style tcell.Style, text string
|
||||
if row > y2 {
|
||||
break
|
||||
}
|
||||
if width == 0 {
|
||||
// incomplete grapheme at end of string
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
@@ -178,9 +189,10 @@ import (
|
||||
func drawText(s tcell.Screen, x1, y1, x2, y2 int, style tcell.Style, text string) {
|
||||
row := y1
|
||||
col := x1
|
||||
for _, r := range []rune(text) {
|
||||
s.SetContent(col, row, r, nil, style)
|
||||
col++
|
||||
var width int
|
||||
for text != "" {
|
||||
text, width = s.Put(col, row, text, style)
|
||||
col += width
|
||||
if col >= x2 {
|
||||
row++
|
||||
col = x1
|
||||
@@ -188,6 +200,10 @@ func drawText(s tcell.Screen, x1, y1, x2, y2 int, style tcell.Style, text string
|
||||
if row > y2 {
|
||||
break
|
||||
}
|
||||
if width == 0 {
|
||||
// incomplete grapheme at end of string
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -202,26 +218,26 @@ func drawBox(s tcell.Screen, x1, y1, x2, y2 int, style tcell.Style, text string)
|
||||
// Fill background
|
||||
for row := y1; row <= y2; row++ {
|
||||
for col := x1; col <= x2; col++ {
|
||||
s.SetContent(col, row, ' ', nil, style)
|
||||
s.Put(col, row, " ", style)
|
||||
}
|
||||
}
|
||||
|
||||
// Draw borders
|
||||
for col := x1; col <= x2; col++ {
|
||||
s.SetContent(col, y1, tcell.RuneHLine, nil, style)
|
||||
s.SetContent(col, y2, tcell.RuneHLine, nil, style)
|
||||
s.Put(col, y1, string(tcell.RuneHLine), style)
|
||||
s.Put(col, y2, string(tcell.RuneHLine), style)
|
||||
}
|
||||
for row := y1 + 1; row < y2; row++ {
|
||||
s.SetContent(x1, row, tcell.RuneVLine, nil, style)
|
||||
s.SetContent(x2, row, tcell.RuneVLine, nil, style)
|
||||
s.Put(x1, row, string(tcell.RuneVLine), style)
|
||||
s.Put(x2, row, string(tcell.RuneVLine), style)
|
||||
}
|
||||
|
||||
// Only draw corners if necessary
|
||||
if y1 != y2 && x1 != x2 {
|
||||
s.SetContent(x1, y1, tcell.RuneULCorner, nil, style)
|
||||
s.SetContent(x2, y1, tcell.RuneURCorner, nil, style)
|
||||
s.SetContent(x1, y2, tcell.RuneLLCorner, nil, style)
|
||||
s.SetContent(x2, y2, tcell.RuneLRCorner, nil, style)
|
||||
s.Put(x1, y1, string(tcell.RuneULCorner), style)
|
||||
s.Put(x2, y1, string(tcell.RuneURCorner), style)
|
||||
s.Put(x1, y2, string(tcell.RuneLLCorner), style)
|
||||
s.Put(x2, y2, string(tcell.RuneLRCorner), style)
|
||||
}
|
||||
|
||||
drawText(s, x1+1, y1+1, x2-1, y2-1, style, text)
|
||||
@@ -310,4 +326,3 @@ func main() {
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
77
vendor/github.com/gdamore/tcell/v2/UKRAINE.md
generated
vendored
77
vendor/github.com/gdamore/tcell/v2/UKRAINE.md
generated
vendored
@@ -1,77 +0,0 @@
|
||||
# Ukraine, Russia, and a World Tragedy
|
||||
|
||||
## A message to those inside Russia
|
||||
|
||||
### Written March 4, 2022.
|
||||
|
||||
It is with a very heavy heart that I write this. I am normally opposed to the use of open source
|
||||
projects to communicate political positions or advocate for things outside the immediate relevancy
|
||||
to that project.
|
||||
|
||||
However, the events occurring in Ukraine, and specifically the unprecedented invasion of Ukraine by
|
||||
Russian forces operating under orders from Russian President Vladimir Putin compel me to speak out.
|
||||
|
||||
Those who know me, know that I have family, friends, and colleagues in Russia, and Ukraine both. My closest friends
|
||||
have historically been Russian friends my wife's hometown of Chelyabinsk. I myself have in the past
|
||||
frequently traveled to Russia, and indeed operated a software development firm with offices in St. Petersburg.
|
||||
I had a special kinship with Russia and its people.
|
||||
|
||||
I say "had", because I fear that the actions of Putin, and the massive disinformation campaign that his regime
|
||||
has waged inside Russia, mean that it's likely that I won't see those friends again. At present, I'm not sure
|
||||
my wife will see her own mother again. We no longer feel it's safe for either of us to return Russia given
|
||||
actions taken by the regime to crack down on those who express disagreement.
|
||||
|
||||
Russian citizens are being led to believe it is acting purely defensively, and that only legitimate military
|
||||
targets are being targeted, and that all the information we have received in the West are fakes.
|
||||
|
||||
I am confident that nothing could be further from the truth.
|
||||
|
||||
This has caused many in Russia, including people whom I respect and believe to be smarter than this, to
|
||||
stand by Putin, and endorse his actions. The claim is that the entirety of NATO is operating at the behest
|
||||
of the USA, and that the entirety of Europe was poised to attack Russia. While this is clearly absurd to those
|
||||
of us with any understanding of western politics, Russian citizens are being fed this lie, and believing it.
|
||||
|
||||
If you're reading this from inside Russia -- YOU are the person that I hope this message reaches. Your
|
||||
government is LYING to you. Of course, all governments lie all the time. But consider this. Almost the
|
||||
entire world has condemned the invasion of Ukraine as criminal, and has applied sanctions. Even countries
|
||||
which have poor relations with the US sanctioning Russia, as well as nations which historically have remained
|
||||
neutral. (Famously neutral -- even during World War II, Switzerland has acted to apply sanctions in
|
||||
concert with the rest of the world.)
|
||||
|
||||
Ask yourself, why does Putin fear a free press so much, if what he says is true? Why the crack-downs on
|
||||
children expressing only a desire for peace with Ukraine? Why would the entire world unified against him,
|
||||
if Putin was in the right? Why would the only countries that stood with Russia against
|
||||
the UN resolution to condemn these acts as crimes be Belarus, North Korea, and Syria? Even countries normally
|
||||
allied to Russia could not bring themselves to do more than abstain from the vote to condemn it.
|
||||
|
||||
To be clear, I do not claim that the actions taken by the West or by the Ukrainian government were completely
|
||||
blameless. On the contrary, I understand that Western media is biased, and the truth is rarely exactly
|
||||
as reported. I believe that there is a kernel of truth in the claims of fascists and ultra-nationalist
|
||||
militias operating in Ukraine and specifically Donbas. However, I am also equally certain that Putin's
|
||||
response is out of proportion, and that concerns about such militias are principally just a pretext to justify
|
||||
an invasion.
|
||||
|
||||
Europe is at war, unlike we've seen in my lifetime. The world is more divided, and closer to nuclear holocaust
|
||||
than it has been since the Cold War. And that is 100% the fault of Putin.
|
||||
|
||||
While Putin remains in power, there cannot really be any way for Russian international relations to return
|
||||
to normal. Putin has set your country on a path to return to the Cold War, likely because he fancies himself
|
||||
to be a new Stalin. However, unlike the Soviet Union, the Russian economy does not have the wherewithal to
|
||||
stand on its own, and the invasion of Ukraine has fully ensured that Russia will not find any friends anywhere
|
||||
else in Europe, and probably few places in Asia.
|
||||
|
||||
The *only* paths forward for Russia are either a Russia without Putin (and those who would support his agenda),
|
||||
or a complete breakdown of Russian prosperity, likely followed by the increasing international conflict that will
|
||||
be the natural escalation from a country that is isolated and impoverished. Those of us observing from the West are
|
||||
gravely concerned, because we cannot see any end to this madness that does not result in nuclear conflict,
|
||||
unless from within.
|
||||
|
||||
In the meantime, the worst prices will be paid for by innocents in Ukraine, and by young Russian mean
|
||||
forced to carry out the orders of Putin's corrupt regime.
|
||||
|
||||
And *that* is why I write this -- to appeal to those within Russia to open your eyes, and think with
|
||||
your minds. It is right and proper to be proud of your country and its rich heritage. But it is also
|
||||
right and proper to look for ways to save it from the ruinous path that its current leadership has set it upon,
|
||||
and to recognize when that leadership is no longer acting in interest of the country or its people.
|
||||
|
||||
- Garrett D'Amore, March 4, 2022
|
||||
147
vendor/github.com/gdamore/tcell/v2/cell.go
generated
vendored
147
vendor/github.com/gdamore/tcell/v2/cell.go
generated
vendored
@@ -1,4 +1,4 @@
|
||||
// Copyright 2024 The TCell Authors
|
||||
// Copyright 2025 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,23 +15,30 @@
|
||||
package tcell
|
||||
|
||||
import (
|
||||
"os"
|
||||
"reflect"
|
||||
|
||||
runewidth "github.com/mattn/go-runewidth"
|
||||
"github.com/rivo/uniseg"
|
||||
)
|
||||
|
||||
type cell struct {
|
||||
currMain rune
|
||||
currComb []rune
|
||||
currStr string
|
||||
lastStr string
|
||||
currStyle Style
|
||||
lastMain rune
|
||||
lastStyle Style
|
||||
lastComb []rune
|
||||
width int
|
||||
lock bool
|
||||
}
|
||||
|
||||
func (c *cell) setDirty(dirty bool) {
|
||||
if dirty {
|
||||
c.lastStr = ""
|
||||
} else {
|
||||
if c.currStr == "" {
|
||||
c.currStr = " "
|
||||
}
|
||||
c.lastStr = c.currStr
|
||||
c.lastStyle = c.currStyle
|
||||
}
|
||||
}
|
||||
|
||||
// CellBuffer represents a two-dimensional array of character cells.
|
||||
// This is primarily intended for use by Screen implementors; it
|
||||
// contains much of the common code they need. To create one, just
|
||||
@@ -48,28 +55,47 @@ type CellBuffer struct {
|
||||
// and style) for a cell at a given location. If the background or
|
||||
// foreground of the style is set to ColorNone, then the respective
|
||||
// color is left un changed.
|
||||
func (cb *CellBuffer) SetContent(x int, y int,
|
||||
mainc rune, combc []rune, style Style,
|
||||
) {
|
||||
//
|
||||
// Deprecated: Use Put instead, which this is implemented in terms of.
|
||||
func (cb *CellBuffer) SetContent(x int, y int, mainc rune, combc []rune, style Style) {
|
||||
cb.Put(x, y, string(append([]rune{mainc}, combc...)), style)
|
||||
}
|
||||
|
||||
// Put a single styled grapheme using the given string and style
|
||||
// at the same location. Note that only the first grapheme in the string
|
||||
// will bre displayed, using only the 1 or 2 (depending on width) cells
|
||||
// located at x, y. It returns the rest of the string, and the width used.
|
||||
func (cb *CellBuffer) Put(x int, y int, str string, style Style) (string, int) {
|
||||
var width int = 0
|
||||
if x >= 0 && y >= 0 && x < cb.w && y < cb.h {
|
||||
var cl string
|
||||
c := &cb.cells[(y*cb.w)+x]
|
||||
state := -1
|
||||
for width == 0 && str != "" {
|
||||
var g string
|
||||
g, str, width, state = uniseg.FirstGraphemeClusterInString(str, state)
|
||||
cl += g
|
||||
if g == "" {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// Wide characters: we want to mark the "wide" cells
|
||||
// dirty as well as the base cell, to make sure we consider
|
||||
// both cells as dirty together. We only need to do this
|
||||
// if we're changing content
|
||||
if (c.width > 0) && (mainc != c.currMain || len(combc) != len(c.currComb) || (len(combc) > 0 && !reflect.DeepEqual(combc, c.currComb))) {
|
||||
for i := 0; i < c.width; i++ {
|
||||
if width > 0 && cl != c.currStr {
|
||||
// Prevent unnecessary boundchecks for first cell, since we already
|
||||
// received that one.
|
||||
c.setDirty(true)
|
||||
for i := 1; i < width; i++ {
|
||||
cb.SetDirty(x+i, y, true)
|
||||
}
|
||||
}
|
||||
|
||||
c.currComb = append([]rune{}, combc...)
|
||||
c.currStr = cl
|
||||
c.width = width
|
||||
|
||||
if c.currMain != mainc {
|
||||
c.width = runewidth.RuneWidth(mainc)
|
||||
}
|
||||
c.currMain = mainc
|
||||
if style.fg == ColorNone {
|
||||
style.fg = c.currStyle.fg
|
||||
}
|
||||
@@ -78,23 +104,45 @@ func (cb *CellBuffer) SetContent(x int, y int,
|
||||
}
|
||||
c.currStyle = style
|
||||
}
|
||||
return str, width
|
||||
}
|
||||
|
||||
// Get the contents of a character cell (or two adjacent cells), including the
|
||||
// the style and the display width in cells. (The width can be either 1, normally,
|
||||
// or 2 for East Asian full-width characters. If the width is 0, then the cell is
|
||||
// is empty.)
|
||||
func (cb *CellBuffer) Get(x, y int) (string, Style, int) {
|
||||
var style Style
|
||||
var width int
|
||||
var str string
|
||||
if x >= 0 && y >= 0 && x < cb.w && y < cb.h {
|
||||
c := &cb.cells[(y*cb.w)+x]
|
||||
str, style = c.currStr, c.currStyle
|
||||
if width = c.width; width == 0 || str == "" {
|
||||
width = 1
|
||||
str = " "
|
||||
}
|
||||
}
|
||||
return str, style, width
|
||||
}
|
||||
|
||||
// GetContent returns the contents of a character cell, including the
|
||||
// primary rune, any combining character runes (which will usually be
|
||||
// nil), the style, and the display width in cells. (The width can be
|
||||
// either 1, normally, or 2 for East Asian full-width characters.)
|
||||
//
|
||||
// Deprecated: Use Get, which this implemented in terms of.
|
||||
func (cb *CellBuffer) GetContent(x, y int) (rune, []rune, Style, int) {
|
||||
var mainc rune
|
||||
var combc []rune
|
||||
var style Style
|
||||
var width int
|
||||
if x >= 0 && y >= 0 && x < cb.w && y < cb.h {
|
||||
c := &cb.cells[(y*cb.w)+x]
|
||||
mainc, combc, style = c.currMain, c.currComb, c.currStyle
|
||||
if width = c.width; width == 0 || mainc < ' ' {
|
||||
width = 1
|
||||
mainc = ' '
|
||||
var mainc rune
|
||||
var combc []rune
|
||||
str, style, width := cb.Get(x, y)
|
||||
for i, r := range str {
|
||||
if i == 0 {
|
||||
mainc = r
|
||||
} else {
|
||||
combc = append(combc, r)
|
||||
}
|
||||
}
|
||||
return mainc, combc, style, width
|
||||
@@ -108,7 +156,7 @@ func (cb *CellBuffer) Size() (int, int) {
|
||||
// Invalidate marks all characters within the buffer as dirty.
|
||||
func (cb *CellBuffer) Invalidate() {
|
||||
for i := range cb.cells {
|
||||
cb.cells[i].lastMain = rune(0)
|
||||
cb.cells[i].lastStr = ""
|
||||
}
|
||||
}
|
||||
|
||||
@@ -121,23 +169,12 @@ func (cb *CellBuffer) Dirty(x, y int) bool {
|
||||
if c.lock {
|
||||
return false
|
||||
}
|
||||
if c.lastMain == rune(0) {
|
||||
return true
|
||||
}
|
||||
if c.lastMain != c.currMain {
|
||||
return true
|
||||
}
|
||||
if c.lastStyle != c.currStyle {
|
||||
return true
|
||||
}
|
||||
if len(c.lastComb) != len(c.currComb) {
|
||||
if c.lastStr != c.currStr {
|
||||
return true
|
||||
}
|
||||
for i := range c.lastComb {
|
||||
if c.lastComb[i] != c.currComb[i] {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
@@ -148,16 +185,7 @@ func (cb *CellBuffer) Dirty(x, y int) bool {
|
||||
func (cb *CellBuffer) SetDirty(x, y int, dirty bool) {
|
||||
if x >= 0 && y >= 0 && x < cb.w && y < cb.h {
|
||||
c := &cb.cells[(y*cb.w)+x]
|
||||
if dirty {
|
||||
c.lastMain = rune(0)
|
||||
} else {
|
||||
if c.currMain == rune(0) {
|
||||
c.currMain = ' '
|
||||
}
|
||||
c.lastMain = c.currMain
|
||||
c.lastComb = c.currComb
|
||||
c.lastStyle = c.currStyle
|
||||
}
|
||||
c.setDirty(dirty)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -203,11 +231,10 @@ func (cb *CellBuffer) Resize(w, h int) {
|
||||
for x := 0; x < w && x < cb.w; x++ {
|
||||
oc := &cb.cells[(y*cb.w)+x]
|
||||
nc := &newc[(y*w)+x]
|
||||
nc.currMain = oc.currMain
|
||||
nc.currComb = oc.currComb
|
||||
nc.currStr = oc.currStr
|
||||
nc.currStyle = oc.currStyle
|
||||
nc.width = oc.width
|
||||
nc.lastMain = rune(0)
|
||||
nc.lastStr = ""
|
||||
}
|
||||
}
|
||||
cb.cells = newc
|
||||
@@ -223,8 +250,7 @@ func (cb *CellBuffer) Resize(w, h int) {
|
||||
func (cb *CellBuffer) Fill(r rune, style Style) {
|
||||
for i := range cb.cells {
|
||||
c := &cb.cells[i]
|
||||
c.currMain = r
|
||||
c.currComb = nil
|
||||
c.currStr = string(r)
|
||||
cs := style
|
||||
if cs.fg == ColorNone {
|
||||
cs.fg = c.currStyle.fg
|
||||
@@ -236,14 +262,3 @@ 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
|
||||
}
|
||||
}
|
||||
|
||||
2
vendor/github.com/gdamore/tcell/v2/charset_windows.go
generated
vendored
2
vendor/github.com/gdamore/tcell/v2/charset_windows.go
generated
vendored
@@ -18,5 +18,5 @@
|
||||
package tcell
|
||||
|
||||
func getCharset() string {
|
||||
return "UTF-16"
|
||||
return "UTF-8"
|
||||
}
|
||||
|
||||
278
vendor/github.com/gdamore/tcell/v2/console_win.go
generated
vendored
278
vendor/github.com/gdamore/tcell/v2/console_win.go
generated
vendored
@@ -1,7 +1,7 @@
|
||||
//go:build windows
|
||||
// +build windows
|
||||
|
||||
// Copyright 2024 The TCell Authors
|
||||
// Copyright 2025 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,7 +38,6 @@ type cScreen struct {
|
||||
cury int
|
||||
style Style
|
||||
fini bool
|
||||
vten bool
|
||||
truecolor bool
|
||||
running bool
|
||||
disableAlt bool // disable the alternate screen
|
||||
@@ -106,7 +105,6 @@ var winColors = map[Color]Color{
|
||||
}
|
||||
|
||||
var (
|
||||
k32 = syscall.NewLazyDLL("kernel32.dll")
|
||||
u32 = syscall.NewLazyDLL("user32.dll")
|
||||
)
|
||||
|
||||
@@ -117,18 +115,8 @@ var (
|
||||
// characters (Unicode) are in use. The documentation refers to them
|
||||
// without this suffix, as the resolution is made via preprocessor.
|
||||
var (
|
||||
procReadConsoleInput = k32.NewProc("ReadConsoleInputW")
|
||||
procWaitForMultipleObjects = k32.NewProc("WaitForMultipleObjects")
|
||||
procCreateEvent = k32.NewProc("CreateEventW")
|
||||
procSetEvent = k32.NewProc("SetEvent")
|
||||
procGetConsoleCursorInfo = k32.NewProc("GetConsoleCursorInfo")
|
||||
procSetConsoleCursorInfo = k32.NewProc("SetConsoleCursorInfo")
|
||||
procSetConsoleCursorPosition = k32.NewProc("SetConsoleCursorPosition")
|
||||
procSetConsoleMode = k32.NewProc("SetConsoleMode")
|
||||
procGetConsoleMode = k32.NewProc("GetConsoleMode")
|
||||
procGetConsoleScreenBufferInfo = k32.NewProc("GetConsoleScreenBufferInfo")
|
||||
procFillConsoleOutputAttribute = k32.NewProc("FillConsoleOutputAttribute")
|
||||
procFillConsoleOutputCharacter = k32.NewProc("FillConsoleOutputCharacterW")
|
||||
procSetConsoleWindowInfo = k32.NewProc("SetConsoleWindowInfo")
|
||||
procSetConsoleScreenBufferSize = k32.NewProc("SetConsoleScreenBufferSize")
|
||||
procSetConsoleTextAttribute = k32.NewProc("SetConsoleTextAttribute")
|
||||
@@ -195,6 +183,10 @@ var vtCursorStyles = map[CursorStyle]string{
|
||||
// NewConsoleScreen returns a Screen for the Windows console associated
|
||||
// with the current process. The Screen makes use of the Windows Console
|
||||
// API to display content and read events.
|
||||
//
|
||||
// Deprecated: The console API based implementation will be fully replaced
|
||||
// with the VT based model. Use NewScreen() to get a reasonable screen
|
||||
// by default.
|
||||
func NewConsoleScreen() (Screen, error) {
|
||||
return &baseScreen{screenImpl: &cScreen{}}, nil
|
||||
}
|
||||
@@ -217,22 +209,11 @@ func (s *cScreen) Init() error {
|
||||
|
||||
s.truecolor = true
|
||||
|
||||
// ConEmu handling of colors and scrolling when in VT output mode is extremely poor.
|
||||
// The color palette will scroll even though characters do not, when
|
||||
// emitting stuff for the last character. In the future we might change this to
|
||||
// look at specific versions of ConEmu if they fix the bug.
|
||||
// We can also try disabling auto margin mode.
|
||||
tryVt := true
|
||||
if os.Getenv("ConEmuPID") != "" {
|
||||
s.truecolor = false
|
||||
tryVt = false
|
||||
}
|
||||
switch os.Getenv("TCELL_TRUECOLOR") {
|
||||
case "disable":
|
||||
s.truecolor = false
|
||||
case "enable":
|
||||
s.truecolor = true
|
||||
tryVt = true
|
||||
}
|
||||
|
||||
s.Lock()
|
||||
@@ -249,33 +230,17 @@ func (s *cScreen) Init() error {
|
||||
s.fini = false
|
||||
s.setInMode(modeResizeEn | modeExtendFlg)
|
||||
|
||||
// If a user needs to force old style console, they may do so
|
||||
// by setting TCELL_VTMODE to disable. This is an undocumented safety net for now.
|
||||
// It may be removed in the future. (This mostly exists because of ConEmu.)
|
||||
switch os.Getenv("TCELL_VTMODE") {
|
||||
case "disable":
|
||||
tryVt = false
|
||||
case "enable":
|
||||
tryVt = true
|
||||
}
|
||||
switch os.Getenv("TCELL_ALTSCREEN") {
|
||||
case "enable":
|
||||
s.disableAlt = false // also the default
|
||||
case "disable":
|
||||
s.disableAlt = true
|
||||
}
|
||||
if tryVt {
|
||||
s.setOutMode(modeVtOutput | modeNoAutoNL | modeCookedOut | modeUnderline)
|
||||
var om uint32
|
||||
s.getOutMode(&om)
|
||||
if om&modeVtOutput == modeVtOutput {
|
||||
s.vten = true
|
||||
} else {
|
||||
s.truecolor = false
|
||||
s.setOutMode(0)
|
||||
}
|
||||
} else {
|
||||
s.setOutMode(0)
|
||||
s.setOutMode(modeVtOutput | modeNoAutoNL | modeCookedOut | modeUnderline)
|
||||
var om uint32
|
||||
s.getOutMode(&om)
|
||||
if om&modeVtOutput != modeVtOutput {
|
||||
return errors.New("failed to initialize: VT output not supported?")
|
||||
}
|
||||
|
||||
s.Unlock()
|
||||
@@ -349,17 +314,12 @@ func (s *cScreen) disengage() {
|
||||
|
||||
s.wg.Wait()
|
||||
|
||||
if s.vten {
|
||||
s.emitVtString(vtCursorStyles[CursorStyleDefault])
|
||||
s.emitVtString(vtCursorColorReset)
|
||||
s.emitVtString(vtEnableAm)
|
||||
if !s.disableAlt {
|
||||
s.emitVtString(vtRestoreTitle)
|
||||
s.emitVtString(vtExitCA)
|
||||
}
|
||||
} else if !s.disableAlt {
|
||||
s.clearScreen(StyleDefault, s.vten)
|
||||
s.setCursorPos(0, 0, false)
|
||||
s.emitVtString(vtCursorStyles[CursorStyleDefault])
|
||||
s.emitVtString(vtCursorColorReset)
|
||||
s.emitVtString(vtEnableAm)
|
||||
if !s.disableAlt {
|
||||
s.emitVtString(vtRestoreTitle)
|
||||
s.emitVtString(vtExitCA)
|
||||
}
|
||||
s.setCursorInfo(&s.ocursor)
|
||||
s.setBufferSize(int(s.oscreen.size.x), int(s.oscreen.size.y))
|
||||
@@ -388,22 +348,18 @@ func (s *cScreen) engage() error {
|
||||
s.running = true
|
||||
s.cancelflag = syscall.Handle(cf)
|
||||
s.enableMouse(s.mouseEnabled)
|
||||
|
||||
if s.vten {
|
||||
s.setOutMode(modeVtOutput | modeNoAutoNL | modeCookedOut | modeUnderline)
|
||||
if !s.disableAlt {
|
||||
s.emitVtString(vtSaveTitle)
|
||||
s.emitVtString(vtEnterCA)
|
||||
}
|
||||
s.emitVtString(vtDisableAm)
|
||||
if s.title != "" {
|
||||
s.emitVtString(fmt.Sprintf(vtSetTitle, s.title))
|
||||
}
|
||||
} else {
|
||||
s.setOutMode(0)
|
||||
s.setInMode(modeVtInput | modeResizeEn | modeExtendFlg)
|
||||
s.setOutMode(modeVtOutput | modeNoAutoNL | modeCookedOut | modeUnderline)
|
||||
if !s.disableAlt {
|
||||
s.emitVtString(vtSaveTitle)
|
||||
s.emitVtString(vtEnterCA)
|
||||
}
|
||||
s.emitVtString(vtDisableAm)
|
||||
if s.title != "" {
|
||||
s.emitVtString(fmt.Sprintf(vtSetTitle, s.title))
|
||||
}
|
||||
|
||||
s.clearScreen(s.style, s.vten)
|
||||
s.clearScreen(s.style)
|
||||
s.hideCursor()
|
||||
|
||||
s.cells.Invalidate()
|
||||
@@ -445,26 +401,18 @@ func (s *cScreen) emitVtString(vs string) {
|
||||
}
|
||||
|
||||
func (s *cScreen) showCursor() {
|
||||
if s.vten {
|
||||
s.emitVtString(vtShowCursor)
|
||||
s.emitVtString(vtCursorStyles[s.cursorStyle])
|
||||
if s.cursorColor == ColorReset {
|
||||
s.emitVtString(vtCursorColorReset)
|
||||
} else if s.cursorColor.Valid() {
|
||||
r, g, b := s.cursorColor.RGB()
|
||||
s.emitVtString(fmt.Sprintf(vtCursorColorRGB, r, g, b))
|
||||
}
|
||||
} else {
|
||||
s.setCursorInfo(&cursorInfo{size: 100, visible: 1})
|
||||
s.emitVtString(vtShowCursor)
|
||||
s.emitVtString(vtCursorStyles[s.cursorStyle])
|
||||
if s.cursorColor == ColorReset {
|
||||
s.emitVtString(vtCursorColorReset)
|
||||
} else if s.cursorColor.Valid() {
|
||||
r, g, b := s.cursorColor.RGB()
|
||||
s.emitVtString(fmt.Sprintf(vtCursorColorRGB, r, g, b))
|
||||
}
|
||||
}
|
||||
|
||||
func (s *cScreen) hideCursor() {
|
||||
if s.vten {
|
||||
s.emitVtString(vtHideCursor)
|
||||
} else {
|
||||
s.setCursorInfo(&cursorInfo{size: 1, visible: 0})
|
||||
}
|
||||
s.emitVtString(vtHideCursor)
|
||||
}
|
||||
|
||||
func (s *cScreen) ShowCursor(x, y int) {
|
||||
@@ -495,7 +443,7 @@ func (s *cScreen) doCursor() {
|
||||
if x < 0 || y < 0 || x >= s.w || y >= s.h {
|
||||
s.hideCursor()
|
||||
} else {
|
||||
s.setCursorPos(x, y, s.vten)
|
||||
s.setCursorPos(x, y)
|
||||
s.showCursor()
|
||||
}
|
||||
}
|
||||
@@ -504,20 +452,6 @@ func (s *cScreen) HideCursor() {
|
||||
s.ShowCursor(-1, -1)
|
||||
}
|
||||
|
||||
type inputRecord struct {
|
||||
typ uint16
|
||||
_ uint16
|
||||
data [16]byte
|
||||
}
|
||||
|
||||
const (
|
||||
keyEvent uint16 = 1
|
||||
mouseEvent uint16 = 2
|
||||
resizeEvent uint16 = 4
|
||||
menuEvent uint16 = 8 // don't use
|
||||
focusEvent uint16 = 16
|
||||
)
|
||||
|
||||
type mouseRecord struct {
|
||||
x int16
|
||||
y int16
|
||||
@@ -790,6 +724,10 @@ func (s *cScreen) getConsoleInput() error {
|
||||
if krec.ch != 0 {
|
||||
// synthesized key code
|
||||
for krec.repeat > 0 {
|
||||
if krec.ch < ' ' && mod2mask(krec.mod, false) == ModCtrl {
|
||||
krec.ch += '\x60'
|
||||
}
|
||||
|
||||
// convert shift+tab to backtab
|
||||
if mod2mask(krec.mod, false) == ModShift && krec.ch == vkTab {
|
||||
s.postEvent(NewEventKey(KeyBacktab, 0, ModNone))
|
||||
@@ -861,11 +799,10 @@ func (s *cScreen) scanInput(stopQ chan struct{}) {
|
||||
}
|
||||
|
||||
func (s *cScreen) Colors() int {
|
||||
if s.vten {
|
||||
return 1 << 24
|
||||
if !s.truecolor {
|
||||
return 16
|
||||
}
|
||||
// Windows console can display 8 colors, in either low or high intensity
|
||||
return 16
|
||||
return 1 << 24
|
||||
}
|
||||
|
||||
var vgaColors = map[Color]uint16{
|
||||
@@ -1014,20 +951,12 @@ func (s *cScreen) writeString(x, y int, style Style, vtBuf, ch []uint16) {
|
||||
return
|
||||
}
|
||||
|
||||
if s.vten {
|
||||
vtBuf = append(vtBuf, utf16.Encode([]rune(fmt.Sprintf(vtCursorPos, y+1, x+1)))...)
|
||||
styleStr := s.makeVtStyle(style)
|
||||
vtBuf = append(vtBuf, utf16.Encode([]rune(styleStr))...)
|
||||
vtBuf = append(vtBuf, ch...)
|
||||
_ = syscall.WriteConsole(s.out, &vtBuf[0], uint32(len(vtBuf)), nil, nil)
|
||||
vtBuf = vtBuf[:0]
|
||||
} else {
|
||||
s.setCursorPos(x, y, s.vten)
|
||||
_, _, _ = procSetConsoleTextAttribute.Call(
|
||||
uintptr(s.out),
|
||||
uintptr(s.mapStyle(style)))
|
||||
_ = syscall.WriteConsole(s.out, &ch[0], uint32(len(ch)), nil, nil)
|
||||
}
|
||||
vtBuf = append(vtBuf, utf16.Encode([]rune(fmt.Sprintf(vtCursorPos, y+1, x+1)))...)
|
||||
styleStr := s.makeVtStyle(style)
|
||||
vtBuf = append(vtBuf, utf16.Encode([]rune(styleStr))...)
|
||||
vtBuf = append(vtBuf, ch...)
|
||||
_ = syscall.WriteConsole(s.out, &vtBuf[0], uint32(len(vtBuf)), nil, nil)
|
||||
vtBuf = vtBuf[:0]
|
||||
}
|
||||
|
||||
func (s *cScreen) draw() {
|
||||
@@ -1135,15 +1064,9 @@ func (s *cScreen) setCursorInfo(info *cursorInfo) {
|
||||
uintptr(unsafe.Pointer(info)))
|
||||
}
|
||||
|
||||
func (s *cScreen) setCursorPos(x, y int, vtEnable bool) {
|
||||
if vtEnable {
|
||||
// Note that the string is Y first. Origin is 1,1.
|
||||
s.emitVtString(fmt.Sprintf(vtCursorPos, y+1, x+1))
|
||||
} else {
|
||||
_, _, _ = procSetConsoleCursorPosition.Call(
|
||||
uintptr(s.out),
|
||||
coord{int16(x), int16(y)}.uintptr())
|
||||
}
|
||||
func (s *cScreen) setCursorPos(x, y int) {
|
||||
// Note that the string is Y first. Origin is 1,1.
|
||||
s.emitVtString(fmt.Sprintf(vtCursorPos, y+1, x+1))
|
||||
}
|
||||
|
||||
func (s *cScreen) setBufferSize(x, y int) {
|
||||
@@ -1219,52 +1142,30 @@ func (s *cScreen) resize() {
|
||||
}
|
||||
}
|
||||
|
||||
func (s *cScreen) clearScreen(style Style, vtEnable bool) {
|
||||
if vtEnable {
|
||||
s.sendVtStyle(style)
|
||||
row := strings.Repeat(" ", s.w)
|
||||
for y := 0; y < s.h; y++ {
|
||||
s.setCursorPos(0, y, vtEnable)
|
||||
s.emitVtString(row)
|
||||
}
|
||||
s.setCursorPos(0, 0, vtEnable)
|
||||
|
||||
} else {
|
||||
pos := coord{0, 0}
|
||||
attr := s.mapStyle(style)
|
||||
x, y := s.w, s.h
|
||||
scratch := uint32(0)
|
||||
count := uint32(x * y)
|
||||
|
||||
_, _, _ = procFillConsoleOutputAttribute.Call(
|
||||
uintptr(s.out),
|
||||
uintptr(attr),
|
||||
uintptr(count),
|
||||
pos.uintptr(),
|
||||
uintptr(unsafe.Pointer(&scratch)))
|
||||
_, _, _ = procFillConsoleOutputCharacter.Call(
|
||||
uintptr(s.out),
|
||||
uintptr(' '),
|
||||
uintptr(count),
|
||||
pos.uintptr(),
|
||||
uintptr(unsafe.Pointer(&scratch)))
|
||||
func (s *cScreen) clearScreen(style Style) {
|
||||
s.sendVtStyle(style)
|
||||
row := strings.Repeat(" ", s.w)
|
||||
for y := 0; y < s.h; y++ {
|
||||
s.setCursorPos(0, y)
|
||||
s.emitVtString(row)
|
||||
}
|
||||
s.setCursorPos(0, 0)
|
||||
}
|
||||
|
||||
const (
|
||||
// Input modes
|
||||
modeExtendFlg uint32 = 0x0080
|
||||
modeMouseEn = 0x0010
|
||||
modeResizeEn = 0x0008
|
||||
// modeCooked = 0x0001
|
||||
// modeVtInput = 0x0200
|
||||
modeExtendFlg = uint32(0x0080)
|
||||
modeMouseEn = uint32(0x0010)
|
||||
modeResizeEn = uint32(0x0008)
|
||||
modeVtInput = uint32(0x0200)
|
||||
// modeCooked = uint32(0x0001)
|
||||
|
||||
// Output modes
|
||||
modeCookedOut uint32 = 0x0001
|
||||
modeVtOutput = 0x0004
|
||||
modeNoAutoNL = 0x0008
|
||||
modeUnderline = 0x0010 // ENABLE_LVB_GRID_WORLDWIDE, needed for underlines
|
||||
// modeWrapEOL = 0x0002
|
||||
modeCookedOut = uint32(0x0001)
|
||||
modeVtOutput = uint32(0x0004)
|
||||
modeNoAutoNL = uint32(0x0008)
|
||||
modeUnderline = uint32(0x0010) // ENABLE_LVB_GRID_WORLDWIDE, needed for underlines
|
||||
// modeWrapEOL = uint32(0x0002)
|
||||
)
|
||||
|
||||
func (s *cScreen) setInMode(mode uint32) {
|
||||
@@ -1300,9 +1201,7 @@ func (s *cScreen) SetStyle(style Style) {
|
||||
func (s *cScreen) SetTitle(title string) {
|
||||
s.Lock()
|
||||
s.title = title
|
||||
if s.vten {
|
||||
s.emitVtString(fmt.Sprintf(vtSetTitle, title))
|
||||
}
|
||||
s.emitVtString(fmt.Sprintf(vtSetTitle, title))
|
||||
s.Unlock()
|
||||
}
|
||||
|
||||
@@ -1333,43 +1232,8 @@ func (s *cScreen) GetClipboard() {
|
||||
|
||||
func (s *cScreen) Resize(int, int, int, int) {}
|
||||
|
||||
func (s *cScreen) HasKey(k Key) bool {
|
||||
// Microsoft has codes for some keys, but they are unusual,
|
||||
// so we don't include them. We include all the typical
|
||||
// 101, 105 key layout keys.
|
||||
valid := map[Key]bool{
|
||||
KeyBackspace: true,
|
||||
KeyTab: true,
|
||||
KeyEscape: true,
|
||||
KeyPause: true,
|
||||
KeyPrint: true,
|
||||
KeyPgUp: true,
|
||||
KeyPgDn: true,
|
||||
KeyEnter: true,
|
||||
KeyEnd: true,
|
||||
KeyHome: true,
|
||||
KeyLeft: true,
|
||||
KeyUp: true,
|
||||
KeyRight: true,
|
||||
KeyDown: true,
|
||||
KeyInsert: true,
|
||||
KeyDelete: true,
|
||||
KeyF1: true,
|
||||
KeyF2: true,
|
||||
KeyF3: true,
|
||||
KeyF4: true,
|
||||
KeyF5: true,
|
||||
KeyF6: true,
|
||||
KeyF7: true,
|
||||
KeyF8: true,
|
||||
KeyF9: true,
|
||||
KeyF10: true,
|
||||
KeyF11: true,
|
||||
KeyF12: true,
|
||||
KeyRune: true,
|
||||
}
|
||||
|
||||
return valid[k]
|
||||
func (s *cScreen) HasKey(_ Key) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (s *cScreen) Beep() error {
|
||||
|
||||
30
vendor/github.com/gdamore/tcell/v2/eastasian.go
generated
vendored
Normal file
30
vendor/github.com/gdamore/tcell/v2/eastasian.go
generated
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
// Copyright 2025 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.
|
||||
|
||||
package tcell
|
||||
|
||||
import (
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/rivo/uniseg"
|
||||
)
|
||||
|
||||
func init() {
|
||||
if rw := strings.ToLower(os.Getenv("RUNEWIDTH_EASTASIAN")); rw == "1" || rw == "true" || rw == "yes" {
|
||||
uniseg.EastAsianAmbiguousWidth = 2
|
||||
} else {
|
||||
uniseg.EastAsianAmbiguousWidth = 1
|
||||
}
|
||||
}
|
||||
886
vendor/github.com/gdamore/tcell/v2/input.go
generated
vendored
Normal file
886
vendor/github.com/gdamore/tcell/v2/input.go
generated
vendored
Normal file
@@ -0,0 +1,886 @@
|
||||
// Copyright 2025 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.
|
||||
|
||||
// This file describes a generic VT input processor. It parses key sequences,
|
||||
// (input bytes) and loads them into events. It expects UTF-8 or UTF-16 as the input
|
||||
// feed, along with ECMA-48 sequences. The assumption here is that all potential
|
||||
// key sequences are unambiguous between terminal variants (analysis of extant terminfo
|
||||
// data appears to support this conjecture). This allows us to implement this once,
|
||||
// in the most efficient and terminal-agnostic way possible.
|
||||
//
|
||||
// There is unfortunately *one* conflict, with aixterm, for CSI-P - which is KeyDelete
|
||||
// in aixterm, but F1 in others.
|
||||
|
||||
package tcell
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
"unicode/utf16"
|
||||
"unicode/utf8"
|
||||
)
|
||||
|
||||
type inpState int
|
||||
|
||||
const (
|
||||
inpStateInit = inpState(iota)
|
||||
inpStateUtf
|
||||
inpStateEsc
|
||||
inpStateCsi // control sequence introducer
|
||||
inpStateOsc // operating system command
|
||||
inpStateDcs // device control string
|
||||
inpStateSos // start of string (unused)
|
||||
inpStatePm // privacy message (unused)
|
||||
inpStateApc // application program command
|
||||
inpStateSt // string terminator
|
||||
inpStateSs2 // single shift 2
|
||||
inpStateSs3 // single shift 3
|
||||
inpStateLFK // linux F-key (not ECMA-48 compliant - bogus CSI)
|
||||
)
|
||||
|
||||
type InputProcessor interface {
|
||||
ScanUTF8([]byte)
|
||||
ScanUTF16([]uint16)
|
||||
SetSize(rows, cols int)
|
||||
}
|
||||
|
||||
func NewInputProcessor(eq chan<- Event) InputProcessor {
|
||||
return &inputProcessor{
|
||||
evch: eq,
|
||||
buf: make([]rune, 0, 128),
|
||||
}
|
||||
}
|
||||
|
||||
type inputProcessor struct {
|
||||
ut8 []byte
|
||||
ut16 []uint16
|
||||
buf []rune
|
||||
scratch []byte
|
||||
csiParams []byte
|
||||
csiInterm []byte
|
||||
escaped bool
|
||||
btnDown bool // mouse button tracking for broken terms
|
||||
state inpState
|
||||
strState inpState // saved str state (needed for ST)
|
||||
timer *time.Timer
|
||||
expire time.Time
|
||||
l sync.Mutex
|
||||
encBuf []rune
|
||||
evch chan<- Event
|
||||
rows int // used for clipping mouse coordinates
|
||||
cols int // used for clipping mouse coordinates
|
||||
nested *inputProcessor
|
||||
}
|
||||
|
||||
func (ip *inputProcessor) SetSize(w, h int) {
|
||||
if ip.nested != nil {
|
||||
ip.nested.SetSize(w, h)
|
||||
return
|
||||
}
|
||||
go func() {
|
||||
ip.l.Lock()
|
||||
ip.rows = h
|
||||
ip.cols = w
|
||||
ip.post(NewEventResize(w, h))
|
||||
ip.l.Unlock()
|
||||
}()
|
||||
}
|
||||
func (ip *inputProcessor) post(ev Event) {
|
||||
if ip.escaped {
|
||||
ip.escaped = false
|
||||
if ke, ok := ev.(*EventKey); ok {
|
||||
ev = NewEventKey(ke.Key(), ke.Rune(), ke.Modifiers()|ModAlt)
|
||||
}
|
||||
} else if ke, ok := ev.(*EventKey); ok {
|
||||
switch ke.Key() {
|
||||
case keyPasteStart:
|
||||
ev = NewEventPaste(true)
|
||||
case keyPasteEnd:
|
||||
ev = NewEventPaste(false)
|
||||
}
|
||||
}
|
||||
|
||||
ip.evch <- ev
|
||||
}
|
||||
|
||||
func (ip *inputProcessor) escTimeout() {
|
||||
ip.l.Lock()
|
||||
defer ip.l.Unlock()
|
||||
if ip.state == inpStateEsc && ip.expire.Before(time.Now()) {
|
||||
// post it
|
||||
ip.state = inpStateInit
|
||||
ip.escaped = false
|
||||
ip.post(NewEventKey(KeyEsc, 0, ModNone))
|
||||
}
|
||||
}
|
||||
|
||||
type csiParamMode struct {
|
||||
M rune // Mode
|
||||
P int // Parameter (first)
|
||||
}
|
||||
|
||||
type keyMap struct {
|
||||
Key Key
|
||||
Mod ModMask
|
||||
}
|
||||
|
||||
var csiAllKeys = map[csiParamMode]keyMap{
|
||||
{M: 'A'}: {Key: KeyUp},
|
||||
{M: 'B'}: {Key: KeyDown},
|
||||
{M: 'C'}: {Key: KeyRight},
|
||||
{M: 'D'}: {Key: KeyLeft},
|
||||
{M: 'F'}: {Key: KeyEnd},
|
||||
{M: 'H'}: {Key: KeyHome},
|
||||
{M: 'L'}: {Key: KeyInsert},
|
||||
{M: 'P'}: {Key: KeyF1}, // except for aixterm, where this is Delete
|
||||
{M: 'Q'}: {Key: KeyF2},
|
||||
{M: 'S'}: {Key: KeyF4},
|
||||
{M: 'Z'}: {Key: KeyBacktab},
|
||||
{M: 'a'}: {Key: KeyUp, Mod: ModShift},
|
||||
{M: 'b'}: {Key: KeyDown, Mod: ModShift},
|
||||
{M: 'c'}: {Key: KeyRight, Mod: ModShift},
|
||||
{M: 'd'}: {Key: KeyLeft, Mod: ModShift},
|
||||
{M: 'q', P: 1}: {Key: KeyF1}, // all these 'q' are for aixterm
|
||||
{M: 'q', P: 2}: {Key: KeyF2},
|
||||
{M: 'q', P: 3}: {Key: KeyF3},
|
||||
{M: 'q', P: 4}: {Key: KeyF4},
|
||||
{M: 'q', P: 5}: {Key: KeyF5},
|
||||
{M: 'q', P: 6}: {Key: KeyF6},
|
||||
{M: 'q', P: 7}: {Key: KeyF7},
|
||||
{M: 'q', P: 8}: {Key: KeyF8},
|
||||
{M: 'q', P: 9}: {Key: KeyF9},
|
||||
{M: 'q', P: 10}: {Key: KeyF10},
|
||||
{M: 'q', P: 11}: {Key: KeyF11},
|
||||
{M: 'q', P: 12}: {Key: KeyF12},
|
||||
{M: 'q', P: 13}: {Key: KeyF13},
|
||||
{M: 'q', P: 14}: {Key: KeyF14},
|
||||
{M: 'q', P: 15}: {Key: KeyF15},
|
||||
{M: 'q', P: 16}: {Key: KeyF16},
|
||||
{M: 'q', P: 17}: {Key: KeyF17},
|
||||
{M: 'q', P: 18}: {Key: KeyF18},
|
||||
{M: 'q', P: 19}: {Key: KeyF19},
|
||||
{M: 'q', P: 20}: {Key: KeyF20},
|
||||
{M: 'q', P: 21}: {Key: KeyF21},
|
||||
{M: 'q', P: 22}: {Key: KeyF22},
|
||||
{M: 'q', P: 23}: {Key: KeyF23},
|
||||
{M: 'q', P: 24}: {Key: KeyF24},
|
||||
{M: 'q', P: 25}: {Key: KeyF25},
|
||||
{M: 'q', P: 26}: {Key: KeyF26},
|
||||
{M: 'q', P: 27}: {Key: KeyF27},
|
||||
{M: 'q', P: 28}: {Key: KeyF28},
|
||||
{M: 'q', P: 29}: {Key: KeyF29},
|
||||
{M: 'q', P: 30}: {Key: KeyF30},
|
||||
{M: 'q', P: 31}: {Key: KeyF31},
|
||||
{M: 'q', P: 32}: {Key: KeyF32},
|
||||
{M: 'q', P: 33}: {Key: KeyF33},
|
||||
{M: 'q', P: 34}: {Key: KeyF34},
|
||||
{M: 'q', P: 35}: {Key: KeyF35},
|
||||
{M: 'q', P: 36}: {Key: KeyF36},
|
||||
{M: 'q', P: 144}: {Key: KeyClear},
|
||||
{M: 'q', P: 146}: {Key: KeyEnd},
|
||||
{M: 'q', P: 150}: {Key: KeyPgUp},
|
||||
{M: 'q', P: 154}: {Key: KeyPgDn},
|
||||
{M: 'z', P: 214}: {Key: KeyHome},
|
||||
{M: 'z', P: 216}: {Key: KeyPgUp},
|
||||
{M: 'z', P: 220}: {Key: KeyEnd},
|
||||
{M: 'z', P: 222}: {Key: KeyPgDn},
|
||||
{M: 'z', P: 224}: {Key: KeyF1},
|
||||
{M: 'z', P: 225}: {Key: KeyF2},
|
||||
{M: 'z', P: 226}: {Key: KeyF3},
|
||||
{M: 'z', P: 227}: {Key: KeyF4},
|
||||
{M: 'z', P: 228}: {Key: KeyF5},
|
||||
{M: 'z', P: 229}: {Key: KeyF6},
|
||||
{M: 'z', P: 230}: {Key: KeyF7},
|
||||
{M: 'z', P: 231}: {Key: KeyF8},
|
||||
{M: 'z', P: 232}: {Key: KeyF9},
|
||||
{M: 'z', P: 233}: {Key: KeyF10},
|
||||
{M: 'z', P: 234}: {Key: KeyF11},
|
||||
{M: 'z', P: 235}: {Key: KeyF12},
|
||||
{M: 'z', P: 247}: {Key: KeyInsert},
|
||||
{M: '^', P: 7}: {Key: KeyHome, Mod: ModCtrl},
|
||||
{M: '^', P: 8}: {Key: KeyEnd, Mod: ModCtrl},
|
||||
{M: '^', P: 11}: {Key: KeyF23},
|
||||
{M: '^', P: 12}: {Key: KeyF24},
|
||||
{M: '^', P: 13}: {Key: KeyF25},
|
||||
{M: '^', P: 14}: {Key: KeyF26},
|
||||
{M: '^', P: 15}: {Key: KeyF27},
|
||||
{M: '^', P: 17}: {Key: KeyF28}, // 16 is a gap
|
||||
{M: '^', P: 18}: {Key: KeyF29},
|
||||
{M: '^', P: 19}: {Key: KeyF30},
|
||||
{M: '^', P: 20}: {Key: KeyF31},
|
||||
{M: '^', P: 21}: {Key: KeyF32},
|
||||
{M: '^', P: 23}: {Key: KeyF33}, // 22 is a gap
|
||||
{M: '^', P: 24}: {Key: KeyF34},
|
||||
{M: '^', P: 25}: {Key: KeyF35},
|
||||
{M: '^', P: 26}: {Key: KeyF36}, // 27 is a gap
|
||||
{M: '^', P: 28}: {Key: KeyF37},
|
||||
{M: '^', P: 29}: {Key: KeyF38}, // 30 is a gap
|
||||
{M: '^', P: 31}: {Key: KeyF39},
|
||||
{M: '^', P: 32}: {Key: KeyF40},
|
||||
{M: '^', P: 33}: {Key: KeyF41},
|
||||
{M: '^', P: 34}: {Key: KeyF42},
|
||||
{M: '@', P: 23}: {Key: KeyF43},
|
||||
{M: '@', P: 24}: {Key: KeyF44},
|
||||
{M: '$', P: 2}: {Key: KeyInsert, Mod: ModShift},
|
||||
{M: '$', P: 3}: {Key: KeyDelete, Mod: ModShift},
|
||||
{M: '$', P: 7}: {Key: KeyHome, Mod: ModShift},
|
||||
{M: '$', P: 8}: {Key: KeyEnd, Mod: ModShift},
|
||||
{M: '$', P: 23}: {Key: KeyF21},
|
||||
{M: '$', P: 24}: {Key: KeyF22},
|
||||
{M: '~', P: 1}: {Key: KeyHome},
|
||||
{M: '~', P: 2}: {Key: KeyInsert},
|
||||
{M: '~', P: 3}: {Key: KeyDelete},
|
||||
{M: '~', P: 4}: {Key: KeyEnd},
|
||||
{M: '~', P: 5}: {Key: KeyPgUp},
|
||||
{M: '~', P: 6}: {Key: KeyPgDn},
|
||||
{M: '~', P: 7}: {Key: KeyHome},
|
||||
{M: '~', P: 8}: {Key: KeyEnd},
|
||||
{M: '~', P: 11}: {Key: KeyF1},
|
||||
{M: '~', P: 12}: {Key: KeyF2},
|
||||
{M: '~', P: 13}: {Key: KeyF3},
|
||||
{M: '~', P: 14}: {Key: KeyF4},
|
||||
{M: '~', P: 15}: {Key: KeyF5},
|
||||
{M: '~', P: 17}: {Key: KeyF6},
|
||||
{M: '~', P: 18}: {Key: KeyF7},
|
||||
{M: '~', P: 19}: {Key: KeyF8},
|
||||
{M: '~', P: 20}: {Key: KeyF9},
|
||||
{M: '~', P: 21}: {Key: KeyF10},
|
||||
{M: '~', P: 23}: {Key: KeyF11},
|
||||
{M: '~', P: 24}: {Key: KeyF12},
|
||||
{M: '~', P: 25}: {Key: KeyF13},
|
||||
{M: '~', P: 26}: {Key: KeyF14},
|
||||
{M: '~', P: 28}: {Key: KeyF15}, // aka KeyHelp
|
||||
{M: '~', P: 29}: {Key: KeyF16},
|
||||
{M: '~', P: 31}: {Key: KeyF17},
|
||||
{M: '~', P: 32}: {Key: KeyF18},
|
||||
{M: '~', P: 33}: {Key: KeyF19},
|
||||
{M: '~', P: 34}: {Key: KeyF20},
|
||||
{M: '~', P: 200}: {Key: keyPasteStart},
|
||||
{M: '~', P: 201}: {Key: keyPasteEnd},
|
||||
}
|
||||
|
||||
// keys reported using Kitty csi-u protocol
|
||||
var csiUKeys = map[int]Key{
|
||||
27: KeyESC,
|
||||
9: KeyTAB,
|
||||
13: KeyEnter,
|
||||
127: KeyBS,
|
||||
57358: KeyCapsLock,
|
||||
57359: KeyScrollLock,
|
||||
57360: KeyNumLock,
|
||||
57361: KeyPrint,
|
||||
57362: KeyPause,
|
||||
57363: KeyMenu,
|
||||
57376: KeyF13,
|
||||
57377: KeyF14,
|
||||
57378: KeyF15,
|
||||
57379: KeyF16,
|
||||
57380: KeyF17,
|
||||
57381: KeyF18,
|
||||
57382: KeyF19,
|
||||
57383: KeyF20,
|
||||
57384: KeyF21,
|
||||
57385: KeyF22,
|
||||
57386: KeyF23,
|
||||
57387: KeyF24,
|
||||
57388: KeyF25,
|
||||
57389: KeyF26,
|
||||
57390: KeyF27,
|
||||
57391: KeyF28,
|
||||
57392: KeyF29,
|
||||
57393: KeyF30,
|
||||
57394: KeyF31,
|
||||
57395: KeyF32,
|
||||
57396: KeyF33,
|
||||
57397: KeyF34,
|
||||
57398: KeyF35,
|
||||
// TODO: KP keys
|
||||
// TODO: Media keys
|
||||
}
|
||||
|
||||
// windows virtual key codes per microsoft
|
||||
var winKeys = map[int]Key{
|
||||
0x03: KeyCancel, // vkCancel
|
||||
0x08: KeyBackspace, // vkBackspace
|
||||
0x09: KeyTab, // vkTab
|
||||
0x0d: KeyEnter, // vkReturn
|
||||
0x12: KeyClear, // vClear
|
||||
0x13: KeyPause, // vkPause
|
||||
0x1b: KeyEscape, // vkEscape
|
||||
0x21: KeyPgUp, // vkPrior
|
||||
0x22: KeyPgDn, // vkNext
|
||||
0x23: KeyEnd, // vkEnd
|
||||
0x24: KeyHome, // vkHome
|
||||
0x25: KeyLeft, // vkLeft
|
||||
0x26: KeyUp, // vkUp
|
||||
0x27: KeyRight, // vkRight
|
||||
0x28: KeyDown, // vkDown
|
||||
0x2a: KeyPrint, // vkPrint
|
||||
0x2c: KeyPrint, // vkPrtScr
|
||||
0x2d: KeyInsert, // vkInsert
|
||||
0x2e: KeyDelete, // vkDelete
|
||||
0x2f: KeyHelp, // vkHelp
|
||||
0x70: KeyF1, // vkF1
|
||||
0x71: KeyF2, // vkF2
|
||||
0x72: KeyF3, // vkF3
|
||||
0x73: KeyF4, // vkF4
|
||||
0x74: KeyF5, // vkF5
|
||||
0x75: KeyF6, // vkF6
|
||||
0x76: KeyF7, // vkF7
|
||||
0x77: KeyF8, // vkF8
|
||||
0x78: KeyF9, // vkF9
|
||||
0x79: KeyF10, // vkF10
|
||||
0x7a: KeyF11, // vkF11
|
||||
0x7b: KeyF12, // vkF12
|
||||
0x7c: KeyF13, // vkF13
|
||||
0x7d: KeyF14, // vkF14
|
||||
0x7e: KeyF15, // vkF15
|
||||
0x7f: KeyF16, // vkF16
|
||||
0x80: KeyF17, // vkF17
|
||||
0x81: KeyF18, // vkF18
|
||||
0x82: KeyF19, // vkF19
|
||||
0x83: KeyF20, // vkF20
|
||||
0x84: KeyF21, // vkF21
|
||||
0x85: KeyF22, // vkF22
|
||||
0x86: KeyF23, // vkF23
|
||||
0x87: KeyF24, // vkF24
|
||||
}
|
||||
|
||||
// keys by their SS3 - used in application mode usually (legacy VT-style)
|
||||
var ss3Keys = map[rune]Key{
|
||||
'A': KeyUp,
|
||||
'B': KeyDown,
|
||||
'C': KeyRight,
|
||||
'D': KeyLeft,
|
||||
'F': KeyEnd,
|
||||
'H': KeyHome,
|
||||
'P': KeyF1,
|
||||
'Q': KeyF2,
|
||||
'R': KeyF3,
|
||||
'S': KeyF4,
|
||||
't': KeyF5,
|
||||
'u': KeyF6,
|
||||
'v': KeyF7,
|
||||
'l': KeyF8,
|
||||
'w': KeyF9,
|
||||
'x': KeyF10,
|
||||
}
|
||||
|
||||
// linux terminal uses these non ECMA keys prefixed by CSI-[
|
||||
var linuxFKeys = map[rune]Key{
|
||||
'A': KeyF1,
|
||||
'B': KeyF2,
|
||||
'C': KeyF3,
|
||||
'D': KeyF4,
|
||||
'E': KeyF5,
|
||||
}
|
||||
|
||||
func (ip *inputProcessor) scan() {
|
||||
for _, r := range ip.buf {
|
||||
ip.buf = ip.buf[1:]
|
||||
if r > 0x7F {
|
||||
// 8-bit extended Unicode we just treat as such - this will swallow anything else queued up
|
||||
ip.state = inpStateInit
|
||||
ip.post(NewEventKey(KeyRune, r, ModNone))
|
||||
continue
|
||||
}
|
||||
switch ip.state {
|
||||
case inpStateInit:
|
||||
switch r {
|
||||
case '\x1b':
|
||||
// escape.. pending
|
||||
ip.state = inpStateEsc
|
||||
if len(ip.buf) == 0 && ip.nested == nil {
|
||||
ip.expire = time.Now().Add(time.Millisecond * 50)
|
||||
ip.timer = time.AfterFunc(time.Millisecond*60, ip.escTimeout)
|
||||
}
|
||||
case '\t':
|
||||
ip.post(NewEventKey(KeyTab, 0, ModNone))
|
||||
case '\b', '\x7F':
|
||||
ip.post(NewEventKey(KeyBackspace, 0, ModNone))
|
||||
case '\r':
|
||||
ip.post(NewEventKey(KeyEnter, 0, ModNone))
|
||||
default:
|
||||
// Control keys - legacy handling
|
||||
if r < ' ' {
|
||||
ip.post(NewEventKey(KeyCtrlSpace+Key(r), 0, ModCtrl))
|
||||
} else {
|
||||
ip.post(NewEventKey(KeyRune, r, ModNone))
|
||||
}
|
||||
}
|
||||
case inpStateEsc:
|
||||
switch r {
|
||||
case '[':
|
||||
ip.state = inpStateCsi
|
||||
ip.csiInterm = nil
|
||||
ip.csiParams = nil
|
||||
case ']':
|
||||
ip.state = inpStateOsc
|
||||
ip.scratch = nil
|
||||
case 'N':
|
||||
ip.state = inpStateSs2 // no known uses
|
||||
ip.scratch = nil
|
||||
case 'O':
|
||||
ip.state = inpStateSs3
|
||||
ip.scratch = nil
|
||||
case 'X':
|
||||
ip.state = inpStateSos
|
||||
ip.scratch = nil
|
||||
case '^':
|
||||
ip.state = inpStatePm
|
||||
ip.scratch = nil
|
||||
case '_':
|
||||
ip.state = inpStateApc
|
||||
ip.scratch = nil
|
||||
case '\\':
|
||||
// string terminator reached, (orphaned?)
|
||||
ip.state = inpStateInit
|
||||
case '\t':
|
||||
// Linux console only, does not conform to ECMA
|
||||
ip.state = inpStateInit
|
||||
ip.post(NewEventKey(KeyBacktab, 0, ModNone))
|
||||
default:
|
||||
if r == '\x1b' {
|
||||
// leading ESC to capture alt
|
||||
ip.escaped = true
|
||||
} else {
|
||||
// treat as alt-key ... legacy emulators only (no CSI-u or other)
|
||||
ip.state = inpStateInit
|
||||
mod := ModAlt
|
||||
if r < ' ' {
|
||||
mod |= ModCtrl
|
||||
r += 0x60
|
||||
}
|
||||
ip.post(NewEventKey(KeyRune, r, mod))
|
||||
}
|
||||
}
|
||||
case inpStateCsi:
|
||||
// usual case for incoming keys
|
||||
if r >= 0x30 && r <= 0x3F { // parameter bytes
|
||||
ip.csiParams = append(ip.csiParams, byte(r))
|
||||
} else if r >= 0x20 && r <= 0x2F { // intermediate bytes, rarely used
|
||||
ip.csiInterm = append(ip.csiInterm, byte(r))
|
||||
} else if r >= 0x40 && r <= 0x7F { // final byte
|
||||
ip.handleCsi(r, ip.csiParams, ip.csiInterm)
|
||||
} else {
|
||||
// bad parse, just swallow it all
|
||||
ip.state = inpStateInit
|
||||
}
|
||||
case inpStateSs2:
|
||||
// No known uses for SS2
|
||||
ip.state = inpStateInit
|
||||
|
||||
case inpStateSs3: // typically application mode keys or older terminals
|
||||
ip.state = inpStateInit
|
||||
if k, ok := ss3Keys[r]; ok {
|
||||
ip.post(NewEventKey(k, 0, ModNone))
|
||||
}
|
||||
|
||||
case inpStatePm, inpStateApc, inpStateSos, inpStateDcs: // these we just eat
|
||||
switch r {
|
||||
case '\x1b':
|
||||
ip.strState = ip.state
|
||||
ip.state = inpStateSt
|
||||
case '\x07': // bell - some send this instead of ST
|
||||
ip.state = inpStateInit
|
||||
}
|
||||
|
||||
case inpStateOsc: // not sure if used
|
||||
switch r {
|
||||
case '\x1b':
|
||||
ip.strState = ip.state
|
||||
ip.state = inpStateSt
|
||||
case '\x07':
|
||||
ip.handleOsc(string(ip.scratch))
|
||||
default:
|
||||
ip.scratch = append(ip.scratch, byte(r&0x7f))
|
||||
}
|
||||
case inpStateSt:
|
||||
if r == '\\' || r == '\x07' {
|
||||
ip.state = inpStateInit
|
||||
switch ip.strState {
|
||||
case inpStateOsc:
|
||||
ip.handleOsc(string(ip.scratch))
|
||||
case inpStatePm, inpStateApc, inpStateSos, inpStateDcs:
|
||||
ip.state = inpStateInit
|
||||
}
|
||||
} else {
|
||||
ip.scratch = append(ip.scratch, '\x1b', byte(r))
|
||||
ip.state = ip.strState
|
||||
}
|
||||
case inpStateLFK:
|
||||
// linux console does not follow ECMA
|
||||
if k, ok := linuxFKeys[r]; ok {
|
||||
ip.post(NewEventKey(k, 0, ModNone))
|
||||
}
|
||||
ip.state = inpStateInit
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (ip *inputProcessor) handleOsc(str string) {
|
||||
ip.state = inpStateInit
|
||||
if content, ok := strings.CutPrefix(str, "52;c;"); ok {
|
||||
decoded := make([]byte, base64.StdEncoding.DecodedLen(len(content)))
|
||||
if count, err := base64.StdEncoding.Decode(decoded, []byte(content)); err == nil {
|
||||
ip.post(NewEventClipboard(decoded[:count]))
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func calcModifier(n int) ModMask {
|
||||
n--
|
||||
m := ModNone
|
||||
if n&1 != 0 {
|
||||
m |= ModShift
|
||||
}
|
||||
if n&2 != 0 {
|
||||
m |= ModAlt
|
||||
}
|
||||
if n&4 != 0 {
|
||||
m |= ModCtrl
|
||||
}
|
||||
if n&8 != 0 {
|
||||
m |= ModMeta // kitty calls this Super
|
||||
}
|
||||
if n&16 != 0 {
|
||||
m |= ModHyper
|
||||
}
|
||||
if n&32 != 0 {
|
||||
m |= ModMeta // for now not separating from Super
|
||||
}
|
||||
// Not doing (kitty only):
|
||||
// caps_lock 0b1000000 (64)
|
||||
// num_lock 0b10000000 (128)
|
||||
|
||||
return m
|
||||
}
|
||||
|
||||
// func (ip *inputProcessor) handleMouse(x, y, btn int, down bool) *EventMouse {
|
||||
func (ip *inputProcessor) handleMouse(mode rune, params []int) {
|
||||
|
||||
// XTerm mouse events only report at most one button at a time,
|
||||
// which may include a wheel button. Wheel motion events are
|
||||
// reported as single impulses, while other button events are reported
|
||||
// as separate press & release events.
|
||||
if len(params) < 3 {
|
||||
return
|
||||
}
|
||||
btn := params[0]
|
||||
// Some terminals will report mouse coordinates outside the
|
||||
// screen, especially with click-drag events. Clip the coordinates
|
||||
// to the screen in that case.
|
||||
x := max(min(params[1]-1, ip.cols-1), 0)
|
||||
y := max(min(params[2]-1, ip.rows-1), 0)
|
||||
motion := (btn & 0x20) != 0
|
||||
scroll := (btn & 0x42) == 0x40
|
||||
btn &^= 0x20
|
||||
if mode == 'm' {
|
||||
// mouse release, clear all buttons
|
||||
btn |= 3
|
||||
btn &^= 0x40
|
||||
ip.btnDown = false
|
||||
} else if motion {
|
||||
/*
|
||||
* Some broken terminals appear to send
|
||||
* mouse button one motion events, instead of
|
||||
* encoding 35 (no buttons) into these events.
|
||||
* We resolve these by looking for a non-motion
|
||||
* event first.
|
||||
*/
|
||||
if !ip.btnDown {
|
||||
btn |= 3
|
||||
btn &^= 0x40
|
||||
}
|
||||
} else if !scroll {
|
||||
ip.btnDown = true
|
||||
}
|
||||
|
||||
button := ButtonNone
|
||||
mod := ModNone
|
||||
|
||||
// Mouse wheel has bit 6 set, no release events. It should be noted
|
||||
// that wheel events are sometimes misdelivered as mouse button events
|
||||
// during a click-drag, so we debounce these, considering them to be
|
||||
// button press events unless we see an intervening release event.
|
||||
switch btn & 0x43 {
|
||||
case 0:
|
||||
button = Button1
|
||||
case 1:
|
||||
button = Button3 // Note we prefer to treat right as button 2
|
||||
case 2:
|
||||
button = Button2 // And the middle button as button 3
|
||||
case 3:
|
||||
button = ButtonNone
|
||||
case 0x40:
|
||||
button = WheelUp
|
||||
case 0x41:
|
||||
button = WheelDown
|
||||
case 0x42:
|
||||
button = WheelLeft
|
||||
case 0x43:
|
||||
button = WheelRight
|
||||
}
|
||||
|
||||
if btn&0x4 != 0 {
|
||||
mod |= ModShift
|
||||
}
|
||||
if btn&0x8 != 0 {
|
||||
mod |= ModAlt
|
||||
}
|
||||
if btn&0x10 != 0 {
|
||||
mod |= ModCtrl
|
||||
}
|
||||
|
||||
ip.post(NewEventMouse(x, y, button, mod))
|
||||
}
|
||||
|
||||
func (ip *inputProcessor) handleWinKey(P []int) {
|
||||
// win32-input-mode
|
||||
// ^[ [ Vk ; Sc ; Uc ; Kd ; Cs ; Rc _
|
||||
// Vk: the value of wVirtualKeyCode - any number. If omitted, defaults to '0'.
|
||||
// Sc: the value of wVirtualScanCode - any number. If omitted, defaults to '0'.
|
||||
// Uc: the decimal value of UnicodeChar - for example, NUL is "0", LF is
|
||||
// "10", the character 'A' is "65". If omitted, defaults to '0'.
|
||||
// Kd: the value of bKeyDown - either a '0' or '1'. If omitted, defaults to '0'.
|
||||
// Cs: the value of dwControlKeyState - any number. If omitted, defaults to '0'.
|
||||
// Rc: the value of wRepeatCount - any number. If omitted, defaults to '1'.
|
||||
//
|
||||
// Note that some 3rd party terminal emulators (not Terminal) suffer from a bug
|
||||
// where other events, such as mouse events, are doubly encoded, using Vk 0
|
||||
// for each character. (So a CSI-M sequence is encoded as a series of CSI-_
|
||||
// sequences.) We consider this a bug in those terminal emulators -- Windows 11
|
||||
// Terminal does not suffer this brain damage. (We've observed this with both Alacritty
|
||||
// and WezTerm.)
|
||||
for len(P) < 6 {
|
||||
P = append(P, 0) // ensure sufficient length
|
||||
}
|
||||
if P[3] == 0 {
|
||||
// key up event ignore ignore
|
||||
return
|
||||
}
|
||||
|
||||
if P[0] == 0 && P[1] == 0 && P[2] > 0 && P[2] < 0x80 { // only ASCII in win32-input-mode
|
||||
if ip.nested == nil {
|
||||
ip.nested = &inputProcessor{
|
||||
evch: ip.evch,
|
||||
rows: ip.rows,
|
||||
cols: ip.cols,
|
||||
}
|
||||
}
|
||||
|
||||
ip.nested.ScanUTF8([]byte{byte(P[2])})
|
||||
return
|
||||
}
|
||||
|
||||
key := KeyRune
|
||||
chr := rune(P[2])
|
||||
mod := ModNone
|
||||
rpt := max(1, P[5])
|
||||
if k1, ok := winKeys[P[0]]; ok {
|
||||
chr = 0
|
||||
key = k1
|
||||
} else if chr == 0 && P[0] >= 0x30 && P[0] <= 0x39 {
|
||||
chr = rune(P[0])
|
||||
} else if chr < ' ' && P[0] >= 0x41 && P[0] <= 0x5a {
|
||||
key = Key(P[0])
|
||||
chr = 0
|
||||
} else if key == 0x11 || key == 0x13 || key == 0x14 {
|
||||
// lone modifiers
|
||||
return
|
||||
}
|
||||
|
||||
// Modifiers
|
||||
if P[4]&0x010 != 0 {
|
||||
mod |= ModShift
|
||||
}
|
||||
if P[4]&0x000c != 0 {
|
||||
mod |= ModCtrl
|
||||
}
|
||||
if P[4]&0x0003 != 0 {
|
||||
mod |= ModAlt
|
||||
}
|
||||
if key == KeyRune && chr > ' ' && mod == ModShift {
|
||||
// filter out lone shift for printable chars
|
||||
mod = ModNone
|
||||
}
|
||||
if chr != 0 && mod&(ModCtrl|ModAlt) == ModCtrl|ModAlt {
|
||||
// Filter out ctrl+alt (it means AltGr)
|
||||
mod = ModNone
|
||||
}
|
||||
|
||||
for range rpt {
|
||||
if key != KeyRune || chr != 0 {
|
||||
ip.post(NewEventKey(key, chr, mod))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (ip *inputProcessor) handleCsi(mode rune, params []byte, intermediate []byte) {
|
||||
|
||||
// reset state
|
||||
ip.state = inpStateInit
|
||||
|
||||
if len(intermediate) != 0 {
|
||||
// we don't know what to do with these for now
|
||||
return
|
||||
}
|
||||
|
||||
var parts []string
|
||||
var P []int
|
||||
hasLT := false
|
||||
pstr := string(params)
|
||||
// extract numeric parameters
|
||||
if strings.HasPrefix(pstr, "<") {
|
||||
hasLT = true
|
||||
pstr = pstr[1:]
|
||||
}
|
||||
if pstr != "" && pstr[0] >= '0' && pstr[0] <= '9' {
|
||||
parts = strings.Split(pstr, ";")
|
||||
for i := range parts {
|
||||
if parts[i] != "" {
|
||||
if n, e := strconv.ParseInt(parts[i], 10, 32); e == nil {
|
||||
P = append(P, int(n))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
var P0 int
|
||||
if len(P) > 0 {
|
||||
P0 = P[0]
|
||||
}
|
||||
|
||||
if hasLT {
|
||||
switch mode {
|
||||
case 'm', 'M': // mouse event, we only do SGR tracking
|
||||
ip.handleMouse(mode, P)
|
||||
}
|
||||
}
|
||||
|
||||
switch mode {
|
||||
case 'I': // focus in
|
||||
ip.post(NewEventFocus(true))
|
||||
return
|
||||
case 'O': // focus out
|
||||
ip.post(NewEventFocus(false))
|
||||
return
|
||||
case '[':
|
||||
// linux console F-key - CSI-[ modifies next key
|
||||
ip.state = inpStateLFK
|
||||
return
|
||||
case 'u':
|
||||
// CSI-u kitty keyboard protocol
|
||||
if len(P) > 0 && !hasLT {
|
||||
mod := ModNone
|
||||
key := KeyRune
|
||||
chr := rune(0)
|
||||
if k1, ok := csiUKeys[P0]; ok {
|
||||
key = k1
|
||||
chr = 0
|
||||
} else {
|
||||
chr = rune(P0)
|
||||
}
|
||||
if len(P) > 1 {
|
||||
mod = calcModifier(P[1])
|
||||
}
|
||||
ip.post(NewEventKey(key, chr, mod))
|
||||
}
|
||||
return
|
||||
case '_':
|
||||
if len(intermediate) == 0 && len(P) > 0 {
|
||||
ip.handleWinKey(P)
|
||||
return
|
||||
}
|
||||
case '~':
|
||||
if len(intermediate) == 0 && len(P) >= 2 {
|
||||
mod := calcModifier(P[1])
|
||||
if ks, ok := csiAllKeys[csiParamMode{M: mode, P: P0}]; ok {
|
||||
ip.post(NewEventKey(ks.Key, 0, mod))
|
||||
return
|
||||
}
|
||||
if P0 == 27 && len(P) > 2 && P[2] > 0 && P[2] <= 0xff {
|
||||
if P[2] < ' ' || P[2] == 0x7F {
|
||||
ip.post(NewEventKey(Key(P[2]), 0, mod))
|
||||
} else {
|
||||
ip.post(NewEventKey(KeyRune, rune(P[2]), mod))
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ks, ok := csiAllKeys[csiParamMode{M: mode, P: P0}]; ok && !hasLT {
|
||||
if mode == '~' && len(P) > 1 && ks.Mod == ModNone {
|
||||
// apply modifiers if present
|
||||
ks.Mod = calcModifier(P[1])
|
||||
} else if mode == 'P' && os.Getenv("TERM") == "aixterm" {
|
||||
ks.Key = KeyDelete // aixterm hack - conflicts with kitty protocol
|
||||
}
|
||||
ip.post(NewEventKey(ks.Key, 0, ks.Mod))
|
||||
return
|
||||
}
|
||||
|
||||
// this might have been an SS3 style key with modifiers applied
|
||||
if k, ok := ss3Keys[mode]; ok && P0 == 1 && len(P) > 1 {
|
||||
ip.post(NewEventKey(k, 0, calcModifier(P[1])))
|
||||
return
|
||||
}
|
||||
// if we got here we just swallow the unknown sequence
|
||||
}
|
||||
|
||||
func (ip *inputProcessor) ScanUTF8(b []byte) {
|
||||
ip.l.Lock()
|
||||
defer ip.l.Unlock()
|
||||
|
||||
ip.ut8 = append(ip.ut8, b...)
|
||||
for len(ip.ut8) > 0 {
|
||||
// fast path, basic ascii
|
||||
if ip.ut8[0] < 0x7F {
|
||||
ip.buf = append(ip.buf, rune(ip.ut8[0]))
|
||||
ip.ut8 = ip.ut8[1:]
|
||||
} else {
|
||||
r, len := utf8.DecodeRune(ip.ut8)
|
||||
if r == utf8.RuneError {
|
||||
r = rune(ip.ut8[0])
|
||||
len = 1
|
||||
}
|
||||
ip.buf = append(ip.buf, r)
|
||||
ip.ut8 = ip.ut8[len:]
|
||||
}
|
||||
}
|
||||
|
||||
ip.scan()
|
||||
}
|
||||
|
||||
func (ip *inputProcessor) ScanUTF16(u []uint16) {
|
||||
ip.l.Lock()
|
||||
defer ip.l.Unlock()
|
||||
ip.ut16 = append(ip.ut16, u...)
|
||||
for len(ip.ut16) > 0 {
|
||||
if !utf16.IsSurrogate(rune(ip.ut16[0])) {
|
||||
ip.buf = append(ip.buf, rune(ip.ut16[0]))
|
||||
ip.ut16 = ip.ut16[1:]
|
||||
} else if len(ip.ut16) > 1 {
|
||||
ip.buf = append(ip.buf, utf16.DecodeRune(rune(ip.ut16[0]), rune(ip.ut16[1])))
|
||||
ip.ut16 = ip.ut16[2:]
|
||||
} else {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
81
vendor/github.com/gdamore/tcell/v2/key.go
generated
vendored
81
vendor/github.com/gdamore/tcell/v2/key.go
generated
vendored
@@ -1,4 +1,4 @@
|
||||
// Copyright 2016 The TCell Authors
|
||||
// Copyright 2025 The TCell Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use file except in compliance with the License.
|
||||
@@ -171,6 +171,11 @@ var KeyNames = map[Key]string{
|
||||
KeyF62: "F62",
|
||||
KeyF63: "F63",
|
||||
KeyF64: "F64",
|
||||
KeyMenu: "Menu",
|
||||
KeyCapsLock: "CapsLock",
|
||||
KeyScrollLock: "ScrollLock",
|
||||
KeyNumLock: "NumLock",
|
||||
KeyCtrlSpace: "Ctrl-Space",
|
||||
KeyCtrlA: "Ctrl-A",
|
||||
KeyCtrlB: "Ctrl-B",
|
||||
KeyCtrlC: "Ctrl-C",
|
||||
@@ -178,9 +183,12 @@ var KeyNames = map[Key]string{
|
||||
KeyCtrlE: "Ctrl-E",
|
||||
KeyCtrlF: "Ctrl-F",
|
||||
KeyCtrlG: "Ctrl-G",
|
||||
KeyCtrlH: "Ctrl-H",
|
||||
KeyCtrlI: "Ctrl-I",
|
||||
KeyCtrlJ: "Ctrl-J",
|
||||
KeyCtrlK: "Ctrl-K",
|
||||
KeyCtrlL: "Ctrl-L",
|
||||
KeyCtrlM: "Ctrl-M",
|
||||
KeyCtrlN: "Ctrl-N",
|
||||
KeyCtrlO: "Ctrl-O",
|
||||
KeyCtrlP: "Ctrl-P",
|
||||
@@ -194,11 +202,11 @@ var KeyNames = map[Key]string{
|
||||
KeyCtrlX: "Ctrl-X",
|
||||
KeyCtrlY: "Ctrl-Y",
|
||||
KeyCtrlZ: "Ctrl-Z",
|
||||
KeyCtrlSpace: "Ctrl-Space",
|
||||
KeyCtrlUnderscore: "Ctrl-_",
|
||||
KeyCtrlLeftSq: "Ctrl-[",
|
||||
KeyCtrlRightSq: "Ctrl-]",
|
||||
KeyCtrlBackslash: "Ctrl-\\",
|
||||
KeyCtrlCarat: "Ctrl-^",
|
||||
KeyCtrlUnderscore: "Ctrl-_",
|
||||
}
|
||||
|
||||
// Name returns a printable value or the key stroke. This can be used
|
||||
@@ -218,6 +226,9 @@ func (ev *EventKey) Name() string {
|
||||
if ev.mod&ModCtrl != 0 {
|
||||
m = append(m, "Ctrl")
|
||||
}
|
||||
if ev.mod&ModHyper != 0 {
|
||||
m = append(m, "Hyper")
|
||||
}
|
||||
|
||||
ok := false
|
||||
if s, ok = KeyNames[ev.key]; !ok {
|
||||
@@ -246,15 +257,52 @@ func NewEventKey(k Key, ch rune, mod ModMask) *EventKey {
|
||||
// control characters and the DEL.
|
||||
k = Key(ch)
|
||||
if mod == ModNone && ch < ' ' {
|
||||
switch Key(ch) {
|
||||
switch k {
|
||||
case KeyBackspace, KeyTab, KeyEsc, KeyEnter:
|
||||
// these keys are directly typeable without CTRL
|
||||
default:
|
||||
// most likely entered with a CTRL keypress
|
||||
mod = ModCtrl
|
||||
}
|
||||
ch = ch + '\x60'
|
||||
}
|
||||
}
|
||||
if k == KeyRune && ch >= 'A' && ch <= 'Z' && mod == ModCtrl {
|
||||
// We don't do Ctrl-[ or backslash or those specially.
|
||||
k = KeyCtrlA + Key(ch-'A')
|
||||
}
|
||||
|
||||
// Might be lower case
|
||||
if k == KeyRune && ch >= 'a' && ch <= 'z' && mod == ModCtrl {
|
||||
// We don't do Ctrl-[ or backslash or those specially.
|
||||
k = KeyCtrlA + Key(ch-'a')
|
||||
}
|
||||
|
||||
// Windows reports ModShift for shifted keys. This is inconsistent
|
||||
// with UNIX, lets harmonize this.
|
||||
if k == KeyRune && mod == ModShift && ch != 0 {
|
||||
mod = ModNone
|
||||
}
|
||||
|
||||
if k >= KeyCtrlA && k <= KeyCtrlZ {
|
||||
if mod&ModShift != 0 {
|
||||
ch = rune((k - KeyCtrlA) + 'A')
|
||||
} else {
|
||||
ch = rune((k - KeyCtrlA) + 'a')
|
||||
}
|
||||
}
|
||||
|
||||
// Backspace2 is just another name for backspace.
|
||||
if k == KeyBackspace2 {
|
||||
k = KeyBackspace
|
||||
}
|
||||
|
||||
// Shift-Tab should be Backtab.
|
||||
if k == KeyTab && (mod&ModShift) != 0 {
|
||||
k = KeyBacktab
|
||||
mod &^= ModShift
|
||||
}
|
||||
|
||||
return &EventKey{t: time.Now(), key: k, ch: ch, mod: mod}
|
||||
}
|
||||
|
||||
@@ -272,6 +320,7 @@ const (
|
||||
ModCtrl
|
||||
ModAlt
|
||||
ModMeta
|
||||
ModHyper
|
||||
ModNone ModMask = 0
|
||||
)
|
||||
|
||||
@@ -373,6 +422,10 @@ const (
|
||||
KeyF62
|
||||
KeyF63
|
||||
KeyF64
|
||||
KeyMenu
|
||||
KeyCapsLock
|
||||
KeyScrollLock
|
||||
KeyNumLock
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -381,10 +434,12 @@ const (
|
||||
keyPasteEnd
|
||||
)
|
||||
|
||||
// These are the control keys. Note that they overlap with other keys,
|
||||
// perhaps. For example, KeyCtrlH is the same as KeyBackspace.
|
||||
// These are the control keys, they will also be reported with the
|
||||
// rune (lower case) and control modifier. If the shift key
|
||||
// or other modifiers are present then these will *NOT* be reported,
|
||||
// but reported instead as KeyRune.
|
||||
const (
|
||||
KeyCtrlSpace Key = iota
|
||||
KeyCtrlSpace Key = iota + 64
|
||||
KeyCtrlA
|
||||
KeyCtrlB
|
||||
KeyCtrlC
|
||||
@@ -461,10 +516,12 @@ const (
|
||||
|
||||
// These keys are aliases for other names.
|
||||
const (
|
||||
KeyBackspace = KeyBS
|
||||
KeyTab = KeyTAB
|
||||
KeyEsc = KeyESC
|
||||
KeyEscape = KeyESC
|
||||
KeyEnter = KeyCR
|
||||
KeyBackspace = KeyBS
|
||||
KeyTab = KeyTAB
|
||||
KeyEsc = KeyESC
|
||||
KeyEscape = KeyESC
|
||||
KeyEnter = KeyCR
|
||||
|
||||
// NB: This key will be translated to KeyBackspace
|
||||
KeyBackspace2 = KeyDEL
|
||||
)
|
||||
|
||||
2
vendor/github.com/gdamore/tcell/v2/mouse.go
generated
vendored
2
vendor/github.com/gdamore/tcell/v2/mouse.go
generated
vendored
@@ -1,4 +1,4 @@
|
||||
// Copyright 2020 The TCell Authors
|
||||
// Copyright 2025 The TCell Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use file except in compliance with the License.
|
||||
|
||||
90
vendor/github.com/gdamore/tcell/v2/screen.go
generated
vendored
90
vendor/github.com/gdamore/tcell/v2/screen.go
generated
vendored
@@ -1,4 +1,4 @@
|
||||
// Copyright 2024 The TCell Authors
|
||||
// Copyright 2025 The TCell Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use file except in compliance with the License.
|
||||
@@ -35,17 +35,37 @@ type Screen interface {
|
||||
// is called (or Sync).
|
||||
Fill(rune, Style)
|
||||
|
||||
// SetCell is an older API, and will be removed. Please use
|
||||
// SetContent instead; SetCell is implemented in terms of SetContent.
|
||||
// Put writes the first graphme of the given string with th
|
||||
// given style at the given coordinates. (Only the first grapheme
|
||||
// occupying either one or two cells is stored.) It returns the
|
||||
// remainder of the string, and the width displayed.
|
||||
Put(x int, y int, str string, style Style) (string, int)
|
||||
|
||||
// PutStr writes a string starting at the given position, using the
|
||||
// default style. The content is clipped to the screen dimensions.
|
||||
PutStr(x int, y int, str string)
|
||||
|
||||
// PutStrStyled writes a string starting at the given position, using
|
||||
// the given style. The cont4ent is clipped to the screen dimensions.
|
||||
PutStrStyled(x int, y int, str string, style Style)
|
||||
|
||||
// SetCell is an older API, and will be removed.
|
||||
//jj
|
||||
// Deprecated: Please use Put instead.
|
||||
SetCell(x int, y int, style Style, ch ...rune)
|
||||
|
||||
// GetContent returns the contents at the given location. If the
|
||||
// Get the contents at the given location. If the
|
||||
// coordinates are out of range, then the values will be 0, nil,
|
||||
// StyleDefault. Note that the contents returned are logical contents
|
||||
// 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 and emoji require two cells.
|
||||
Get(x, y int) (str string, style Style, width int)
|
||||
|
||||
// GetContent is the old way to get cell contents.
|
||||
//
|
||||
// Deprecated: Use Get() instead.
|
||||
GetContent(x, y int) (primary rune, combining []rune, style Style, width int)
|
||||
|
||||
// SetContent sets the contents of the given cell location. If
|
||||
@@ -221,6 +241,9 @@ type Screen interface {
|
||||
// fallbacks are registered, this will return true. This will
|
||||
// also return true if the terminal can replace the glyph with
|
||||
// one that is visually indistinguishable from the one requested.
|
||||
//
|
||||
// Deprecated: This is not a particularly useful or reliable function,
|
||||
// due to limitations in fonts, etc. It will be removed in the future.
|
||||
CanDisplay(r rune, checkFallbacks bool) bool
|
||||
|
||||
// Resize does nothing, since it's generally not possible to
|
||||
@@ -228,14 +251,13 @@ type Screen interface {
|
||||
// the View interface.
|
||||
Resize(int, int, int, int)
|
||||
|
||||
// HasKey returns true if the keyboard is believed to have the
|
||||
// key. In some cases a keyboard may have keys with this name
|
||||
// but no support for them, while in others a key may be reported
|
||||
// as supported but not actually be usable (such as some emulators
|
||||
// that hijack certain keys). Its best not to depend to strictly
|
||||
// on this function, but it can be used for hinting when building
|
||||
// menus, displayed hot-keys, etc. Note that KeyRune (literal
|
||||
// runes) is always true.
|
||||
// HasKey always returns true.
|
||||
//
|
||||
// Deprecated: This function always returns true. Applications
|
||||
// cannot reliably detect whether a key is supported or not with
|
||||
// modern terminal emulators. (The intended use here was to help
|
||||
// applications determine whether a given key stroke was supported
|
||||
// by the terminal, but it was never reliable.)
|
||||
HasKey(Key) bool
|
||||
|
||||
// Suspend pauses input and output processing. It also restores the
|
||||
@@ -288,10 +310,9 @@ type Screen interface {
|
||||
// NewScreen returns a default Screen suitable for the user's terminal
|
||||
// environment.
|
||||
func NewScreen() (Screen, error) {
|
||||
// Windows is happier if we try for a console screen first.
|
||||
if s, _ := NewConsoleScreen(); s != nil {
|
||||
if s, e := NewTerminfoScreen(); s != nil {
|
||||
return s, nil
|
||||
} else if s, e := NewTerminfoScreen(); s != nil {
|
||||
} else if s, _ := NewConsoleScreen(); s != nil {
|
||||
return s, nil
|
||||
} else {
|
||||
return nil, e
|
||||
@@ -382,11 +403,37 @@ type baseScreen struct {
|
||||
screenImpl
|
||||
}
|
||||
|
||||
func (b *baseScreen) Put(x int, y int, str string, style Style) (remain string, width int) {
|
||||
cells := b.GetCells()
|
||||
b.Lock()
|
||||
defer b.Unlock()
|
||||
return cells.Put(x, y, str, style)
|
||||
}
|
||||
|
||||
func (b *baseScreen) PutStrStyled(x int, y int, str string, style Style) {
|
||||
cells := b.GetCells()
|
||||
b.Lock()
|
||||
cols, rows := cells.Size()
|
||||
width := 0
|
||||
for str != "" && x < cols && y < rows {
|
||||
str, width = cells.Put(x, y, str, style)
|
||||
if width == 0 {
|
||||
break
|
||||
}
|
||||
x += width
|
||||
}
|
||||
defer b.Unlock()
|
||||
}
|
||||
|
||||
func (b *baseScreen) PutStr(x, y int, str string) {
|
||||
b.PutStrStyled(x, y, str, StyleDefault)
|
||||
}
|
||||
|
||||
func (b *baseScreen) SetCell(x int, y int, style Style, ch ...rune) {
|
||||
if len(ch) > 0 {
|
||||
b.SetContent(x, y, ch[0], ch[1:], style)
|
||||
b.Put(x, y, string(ch), style)
|
||||
} else {
|
||||
b.SetContent(x, y, ' ', nil, style)
|
||||
b.Put(x, y, " ", style)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -401,12 +448,15 @@ func (b *baseScreen) Fill(r rune, style Style) {
|
||||
b.Unlock()
|
||||
}
|
||||
|
||||
func (b *baseScreen) SetContent(x, y int, mainc rune, combc []rune, st Style) {
|
||||
func (b *baseScreen) SetContent(x, y int, mainc rune, combc []rune, style Style) {
|
||||
b.Put(x, y, string(append([]rune{mainc}, combc...)), style)
|
||||
}
|
||||
|
||||
func (b *baseScreen) Get(x, y int) (string, Style, int) {
|
||||
cells := b.GetCells()
|
||||
b.Lock()
|
||||
cells.SetContent(x, y, mainc, combc, st)
|
||||
b.Unlock()
|
||||
defer b.Unlock()
|
||||
return cells.Get(x, y)
|
||||
}
|
||||
|
||||
func (b *baseScreen) GetContent(x, y int) (rune, []rune, Style, int) {
|
||||
|
||||
13
vendor/github.com/gdamore/tcell/v2/simulation.go
generated
vendored
13
vendor/github.com/gdamore/tcell/v2/simulation.go
generated
vendored
@@ -356,11 +356,18 @@ outer:
|
||||
}
|
||||
|
||||
if b[0] < 0x80 {
|
||||
mod := ModNone
|
||||
// No encodings start with low numbered values
|
||||
if Key(b[0]) >= KeyCtrlA && Key(b[0]) <= KeyCtrlZ {
|
||||
mod = ModCtrl
|
||||
if b[0] > 0 && b[0] < ' ' { // control keys
|
||||
switch Key(b[0]) {
|
||||
case KeyESC, KeyEnter, KeyTAB:
|
||||
s.postEvent(NewEventKey(Key(b[0]), 0, 0))
|
||||
continue;
|
||||
default:
|
||||
s.postEvent(NewEventKey(Key(b[0]), rune(b[0])+'\x60', ModCtrl))
|
||||
continue
|
||||
}
|
||||
}
|
||||
mod := ModNone
|
||||
ev := NewEventKey(Key(b[0]), 0, mod)
|
||||
s.postEvent(ev)
|
||||
b = b[1:]
|
||||
|
||||
90
vendor/github.com/gdamore/tcell/v2/terminfo/a/aixterm/term.go
generated
vendored
90
vendor/github.com/gdamore/tcell/v2/terminfo/a/aixterm/term.go
generated
vendored
@@ -8,76 +8,24 @@ func init() {
|
||||
|
||||
// IBM Aixterm Terminal Emulator
|
||||
terminfo.AddTerminfo(&terminfo.Terminfo{
|
||||
Name: "aixterm",
|
||||
Columns: 80,
|
||||
Lines: 25,
|
||||
Colors: 8,
|
||||
Bell: "\a",
|
||||
Clear: "\x1b[H\x1b[J",
|
||||
AttrOff: "\x1b[0;10m\x1b(B",
|
||||
Underline: "\x1b[4m",
|
||||
Bold: "\x1b[1m",
|
||||
Reverse: "\x1b[7m",
|
||||
SetFg: "\x1b[3%p1%dm",
|
||||
SetBg: "\x1b[4%p1%dm",
|
||||
SetFgBg: "\x1b[3%p1%d;4%p2%dm",
|
||||
ResetFgBg: "\x1b[32m\x1b[40m",
|
||||
PadChar: "\x00",
|
||||
AltChars: "jjkkllmmnnqqttuuvvwwxx",
|
||||
EnterAcs: "\x1b(0",
|
||||
ExitAcs: "\x1b(B",
|
||||
SetCursor: "\x1b[%i%p1%d;%p2%dH",
|
||||
CursorBack1: "\b",
|
||||
CursorUp1: "\x1b[A",
|
||||
KeyUp: "\x1b[A",
|
||||
KeyDown: "\x1b[B",
|
||||
KeyRight: "\x1b[C",
|
||||
KeyLeft: "\x1b[D",
|
||||
KeyInsert: "\x1b[139q",
|
||||
KeyDelete: "\x1b[P",
|
||||
KeyBackspace: "\b",
|
||||
KeyHome: "\x1b[H",
|
||||
KeyEnd: "\x1b[146q",
|
||||
KeyPgUp: "\x1b[150q",
|
||||
KeyPgDn: "\x1b[154q",
|
||||
KeyF1: "\x1b[001q",
|
||||
KeyF2: "\x1b[002q",
|
||||
KeyF3: "\x1b[003q",
|
||||
KeyF4: "\x1b[004q",
|
||||
KeyF5: "\x1b[005q",
|
||||
KeyF6: "\x1b[006q",
|
||||
KeyF7: "\x1b[007q",
|
||||
KeyF8: "\x1b[008q",
|
||||
KeyF9: "\x1b[009q",
|
||||
KeyF10: "\x1b[010q",
|
||||
KeyF11: "\x1b[011q",
|
||||
KeyF12: "\x1b[012q",
|
||||
KeyF13: "\x1b[013q",
|
||||
KeyF14: "\x1b[014q",
|
||||
KeyF15: "\x1b[015q",
|
||||
KeyF16: "\x1b[016q",
|
||||
KeyF17: "\x1b[017q",
|
||||
KeyF18: "\x1b[018q",
|
||||
KeyF19: "\x1b[019q",
|
||||
KeyF20: "\x1b[020q",
|
||||
KeyF21: "\x1b[021q",
|
||||
KeyF22: "\x1b[022q",
|
||||
KeyF23: "\x1b[023q",
|
||||
KeyF24: "\x1b[024q",
|
||||
KeyF25: "\x1b[025q",
|
||||
KeyF26: "\x1b[026q",
|
||||
KeyF27: "\x1b[027q",
|
||||
KeyF28: "\x1b[028q",
|
||||
KeyF29: "\x1b[029q",
|
||||
KeyF30: "\x1b[030q",
|
||||
KeyF31: "\x1b[031q",
|
||||
KeyF32: "\x1b[032q",
|
||||
KeyF33: "\x1b[033q",
|
||||
KeyF34: "\x1b[034q",
|
||||
KeyF35: "\x1b[035q",
|
||||
KeyF36: "\x1b[036q",
|
||||
KeyClear: "\x1b[144q",
|
||||
KeyBacktab: "\x1b[Z",
|
||||
AutoMargin: true,
|
||||
Name: "aixterm",
|
||||
Columns: 80,
|
||||
Lines: 25,
|
||||
Colors: 8,
|
||||
Clear: "\x1b[H\x1b[J",
|
||||
AttrOff: "\x1b[0;10m\x1b(B",
|
||||
Underline: "\x1b[4m",
|
||||
Bold: "\x1b[1m",
|
||||
Reverse: "\x1b[7m",
|
||||
SetFg: "\x1b[3%p1%dm",
|
||||
SetBg: "\x1b[4%p1%dm",
|
||||
SetFgBg: "\x1b[3%p1%d;4%p2%dm",
|
||||
ResetFgBg: "\x1b[32m\x1b[40m",
|
||||
PadChar: "\x00",
|
||||
AltChars: "jjkkllmmnnqqttuuvvwwxx",
|
||||
EnterAcs: "\x1b(0",
|
||||
ExitAcs: "\x1b(B",
|
||||
SetCursor: "\x1b[%i%p1%d;%p2%dH",
|
||||
AutoMargin: true,
|
||||
})
|
||||
}
|
||||
|
||||
28
vendor/github.com/gdamore/tcell/v2/terminfo/a/alacritty/direct.go
generated
vendored
28
vendor/github.com/gdamore/tcell/v2/terminfo/a/alacritty/direct.go
generated
vendored
@@ -12,7 +12,6 @@ func init() {
|
||||
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",
|
||||
@@ -36,33 +35,6 @@ func init() {
|
||||
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,
|
||||
})
|
||||
|
||||
32
vendor/github.com/gdamore/tcell/v2/terminfo/a/alacritty/term.go
generated
vendored
32
vendor/github.com/gdamore/tcell/v2/terminfo/a/alacritty/term.go
generated
vendored
@@ -12,7 +12,6 @@ func init() {
|
||||
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",
|
||||
@@ -39,38 +38,7 @@ func init() {
|
||||
StrikeThrough: "\x1b[9m",
|
||||
Mouse: "\x1b[<",
|
||||
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,
|
||||
AutoMargin: true,
|
||||
DoubleUnderline: "\x1b[4:2m",
|
||||
CurlyUnderline: "\x1b[4:3m",
|
||||
DottedUnderline: "\x1b[4:4m",
|
||||
DashedUnderline: "\x1b[4:5m",
|
||||
XTermLike: true,
|
||||
})
|
||||
}
|
||||
|
||||
51
vendor/github.com/gdamore/tcell/v2/terminfo/a/ansi/term.go
generated
vendored
51
vendor/github.com/gdamore/tcell/v2/terminfo/a/ansi/term.go
generated
vendored
@@ -8,36 +8,25 @@ func init() {
|
||||
|
||||
// ansi/pc-term compatible with color
|
||||
terminfo.AddTerminfo(&terminfo.Terminfo{
|
||||
Name: "ansi",
|
||||
Columns: 80,
|
||||
Lines: 24,
|
||||
Colors: 8,
|
||||
Bell: "\a",
|
||||
Clear: "\x1b[H\x1b[J",
|
||||
AttrOff: "\x1b[0;10m",
|
||||
Underline: "\x1b[4m",
|
||||
Bold: "\x1b[1m",
|
||||
Blink: "\x1b[5m",
|
||||
Reverse: "\x1b[7m",
|
||||
SetFg: "\x1b[3%p1%dm",
|
||||
SetBg: "\x1b[4%p1%dm",
|
||||
SetFgBg: "\x1b[3%p1%d;4%p2%dm",
|
||||
ResetFgBg: "\x1b[39;49m",
|
||||
PadChar: "\x00",
|
||||
AltChars: "+\x10,\x11-\x18.\x190\xdb`\x04a\xb1f\xf8g\xf1h\xb0j\xd9k\xbfl\xdam\xc0n\xc5o~p\xc4q\xc4r\xc4s_t\xc3u\xb4v\xc1w\xc2x\xb3y\xf3z\xf2{\xe3|\xd8}\x9c~\xfe",
|
||||
EnterAcs: "\x1b[11m",
|
||||
ExitAcs: "\x1b[10m",
|
||||
SetCursor: "\x1b[%i%p1%d;%p2%dH",
|
||||
CursorBack1: "\x1b[D",
|
||||
CursorUp1: "\x1b[A",
|
||||
KeyUp: "\x1b[A",
|
||||
KeyDown: "\x1b[B",
|
||||
KeyRight: "\x1b[C",
|
||||
KeyLeft: "\x1b[D",
|
||||
KeyInsert: "\x1b[L",
|
||||
KeyBackspace: "\b",
|
||||
KeyHome: "\x1b[H",
|
||||
KeyBacktab: "\x1b[Z",
|
||||
AutoMargin: true,
|
||||
Name: "ansi",
|
||||
Columns: 80,
|
||||
Lines: 24,
|
||||
Colors: 8,
|
||||
Clear: "\x1b[H\x1b[J",
|
||||
AttrOff: "\x1b[0;10m",
|
||||
Underline: "\x1b[4m",
|
||||
Bold: "\x1b[1m",
|
||||
Blink: "\x1b[5m",
|
||||
Reverse: "\x1b[7m",
|
||||
SetFg: "\x1b[3%p1%dm",
|
||||
SetBg: "\x1b[4%p1%dm",
|
||||
SetFgBg: "\x1b[3%p1%d;4%p2%dm",
|
||||
ResetFgBg: "\x1b[39;49m",
|
||||
PadChar: "\x00",
|
||||
AltChars: "+\x10,\x11-\x18.\x190\xdb`\x04a\xb1f\xf8g\xf1h\xb0j\xd9k\xbfl\xdam\xc0n\xc5o~p\xc4q\xc4r\xc4s_t\xc3u\xb4v\xc1w\xc2x\xb3y\xf3z\xf2{\xe3|\xd8}\x9c~\xfe",
|
||||
EnterAcs: "\x1b[11m",
|
||||
ExitAcs: "\x1b[10m",
|
||||
SetCursor: "\x1b[%i%p1%d;%p2%dH",
|
||||
AutoMargin: true,
|
||||
})
|
||||
}
|
||||
|
||||
57
vendor/github.com/gdamore/tcell/v2/terminfo/b/beterm/term.go
generated
vendored
57
vendor/github.com/gdamore/tcell/v2/terminfo/b/beterm/term.go
generated
vendored
@@ -1,57 +0,0 @@
|
||||
// Generated automatically. DO NOT HAND-EDIT.
|
||||
|
||||
package beterm
|
||||
|
||||
import "github.com/gdamore/tcell/v2/terminfo"
|
||||
|
||||
func init() {
|
||||
|
||||
// BeOS Terminal
|
||||
terminfo.AddTerminfo(&terminfo.Terminfo{
|
||||
Name: "beterm",
|
||||
Columns: 80,
|
||||
Lines: 25,
|
||||
Colors: 8,
|
||||
Bell: "\a",
|
||||
Clear: "\x1b[H\x1b[J",
|
||||
AttrOff: "\x1b[0;10m",
|
||||
Underline: "\x1b[4m",
|
||||
Bold: "\x1b[1m",
|
||||
Reverse: "\x1b[7m",
|
||||
EnterKeypad: "\x1b[?4h",
|
||||
ExitKeypad: "\x1b[?4l",
|
||||
SetFg: "\x1b[3%p1%dm",
|
||||
SetBg: "\x1b[4%p1%dm",
|
||||
SetFgBg: "\x1b[3%p1%d;4%p2%dm",
|
||||
ResetFgBg: "\x1b[m",
|
||||
PadChar: "\x00",
|
||||
SetCursor: "\x1b[%i%p1%d;%p2%dH",
|
||||
CursorBack1: "\b",
|
||||
CursorUp1: "\x1b[A",
|
||||
KeyUp: "\x1b[A",
|
||||
KeyDown: "\x1b[B",
|
||||
KeyRight: "\x1b[C",
|
||||
KeyLeft: "\x1b[D",
|
||||
KeyInsert: "\x1b[2~",
|
||||
KeyDelete: "\x1b[3~",
|
||||
KeyBackspace: "\b",
|
||||
KeyHome: "\x1b[1~",
|
||||
KeyEnd: "\x1b[4~",
|
||||
KeyPgUp: "\x1b[5~",
|
||||
KeyPgDn: "\x1b[6~",
|
||||
KeyF1: "\x1b[11~",
|
||||
KeyF2: "\x1b[12~",
|
||||
KeyF3: "\x1b[13~",
|
||||
KeyF4: "\x1b[14~",
|
||||
KeyF5: "\x1b[15~",
|
||||
KeyF6: "\x1b[16~",
|
||||
KeyF7: "\x1b[17~",
|
||||
KeyF8: "\x1b[18~",
|
||||
KeyF9: "\x1b[19~",
|
||||
KeyF10: "\x1b[20~",
|
||||
KeyF11: "\x1b[21~",
|
||||
KeyF12: "\x1b[22~",
|
||||
AutoMargin: true,
|
||||
InsertChar: "\x1b[@",
|
||||
})
|
||||
}
|
||||
74
vendor/github.com/gdamore/tcell/v2/terminfo/c/cygwin/term.go
generated
vendored
74
vendor/github.com/gdamore/tcell/v2/terminfo/c/cygwin/term.go
generated
vendored
@@ -8,59 +8,25 @@ func init() {
|
||||
|
||||
// ANSI emulation for Cygwin
|
||||
terminfo.AddTerminfo(&terminfo.Terminfo{
|
||||
Name: "cygwin",
|
||||
Colors: 8,
|
||||
Bell: "\a",
|
||||
Clear: "\x1b[H\x1b[J",
|
||||
EnterCA: "\x1b7\x1b[?47h",
|
||||
ExitCA: "\x1b[2J\x1b[?47l\x1b8",
|
||||
AttrOff: "\x1b[0;10m",
|
||||
Underline: "\x1b[4m",
|
||||
Bold: "\x1b[1m",
|
||||
Reverse: "\x1b[7m",
|
||||
SetFg: "\x1b[3%p1%dm",
|
||||
SetBg: "\x1b[4%p1%dm",
|
||||
SetFgBg: "\x1b[3%p1%d;4%p2%dm",
|
||||
ResetFgBg: "\x1b[39;49m",
|
||||
PadChar: "\x00",
|
||||
AltChars: "+\x10,\x11-\x18.\x190\xdb`\x04a\xb1f\xf8g\xf1h\xb0j\xd9k\xbfl\xdam\xc0n\xc5o~p\xc4q\xc4r\xc4s_t\xc3u\xb4v\xc1w\xc2x\xb3y\xf3z\xf2{\xe3|\xd8}\x9c~\xfe",
|
||||
EnterAcs: "\x1b[11m",
|
||||
ExitAcs: "\x1b[10m",
|
||||
SetCursor: "\x1b[%i%p1%d;%p2%dH",
|
||||
CursorBack1: "\b",
|
||||
CursorUp1: "\x1b[A",
|
||||
KeyUp: "\x1b[A",
|
||||
KeyDown: "\x1b[B",
|
||||
KeyRight: "\x1b[C",
|
||||
KeyLeft: "\x1b[D",
|
||||
KeyInsert: "\x1b[2~",
|
||||
KeyDelete: "\x1b[3~",
|
||||
KeyBackspace: "\b",
|
||||
KeyHome: "\x1b[1~",
|
||||
KeyEnd: "\x1b[4~",
|
||||
KeyPgUp: "\x1b[5~",
|
||||
KeyPgDn: "\x1b[6~",
|
||||
KeyF1: "\x1b[[A",
|
||||
KeyF2: "\x1b[[B",
|
||||
KeyF3: "\x1b[[C",
|
||||
KeyF4: "\x1b[[D",
|
||||
KeyF5: "\x1b[[E",
|
||||
KeyF6: "\x1b[17~",
|
||||
KeyF7: "\x1b[18~",
|
||||
KeyF8: "\x1b[19~",
|
||||
KeyF9: "\x1b[20~",
|
||||
KeyF10: "\x1b[21~",
|
||||
KeyF11: "\x1b[23~",
|
||||
KeyF12: "\x1b[24~",
|
||||
KeyF13: "\x1b[25~",
|
||||
KeyF14: "\x1b[26~",
|
||||
KeyF15: "\x1b[28~",
|
||||
KeyF16: "\x1b[29~",
|
||||
KeyF17: "\x1b[31~",
|
||||
KeyF18: "\x1b[32~",
|
||||
KeyF19: "\x1b[33~",
|
||||
KeyF20: "\x1b[34~",
|
||||
AutoMargin: true,
|
||||
InsertChar: "\x1b[@",
|
||||
Name: "cygwin",
|
||||
Colors: 8,
|
||||
Clear: "\x1b[H\x1b[J",
|
||||
EnterCA: "\x1b7\x1b[?47h",
|
||||
ExitCA: "\x1b[2J\x1b[?47l\x1b8",
|
||||
AttrOff: "\x1b[0;10m",
|
||||
Underline: "\x1b[4m",
|
||||
Bold: "\x1b[1m",
|
||||
Reverse: "\x1b[7m",
|
||||
SetFg: "\x1b[3%p1%dm",
|
||||
SetBg: "\x1b[4%p1%dm",
|
||||
SetFgBg: "\x1b[3%p1%d;4%p2%dm",
|
||||
ResetFgBg: "\x1b[39;49m",
|
||||
PadChar: "\x00",
|
||||
AltChars: "+\x10,\x11-\x18.\x190\xdb`\x04a\xb1f\xf8g\xf1h\xb0j\xd9k\xbfl\xdam\xc0n\xc5o~p\xc4q\xc4r\xc4s_t\xc3u\xb4v\xc1w\xc2x\xb3y\xf3z\xf2{\xe3|\xd8}\x9c~\xfe",
|
||||
EnterAcs: "\x1b[11m",
|
||||
ExitAcs: "\x1b[10m",
|
||||
SetCursor: "\x1b[%i%p1%d;%p2%dH",
|
||||
AutoMargin: true,
|
||||
InsertChar: "\x1b[@",
|
||||
})
|
||||
}
|
||||
|
||||
33
vendor/github.com/gdamore/tcell/v2/terminfo/d/dtterm/term.go
generated
vendored
33
vendor/github.com/gdamore/tcell/v2/terminfo/d/dtterm/term.go
generated
vendored
@@ -12,7 +12,6 @@ func init() {
|
||||
Columns: 80,
|
||||
Lines: 24,
|
||||
Colors: 8,
|
||||
Bell: "\a",
|
||||
Clear: "\x1b[H\x1b[J",
|
||||
ShowCursor: "\x1b[?25h",
|
||||
HideCursor: "\x1b[?25l",
|
||||
@@ -34,38 +33,6 @@ func init() {
|
||||
EnableAutoMargin: "\x1b[?7h",
|
||||
DisableAutoMargin: "\x1b[?7l",
|
||||
SetCursor: "\x1b[%i%p1%d;%p2%dH",
|
||||
CursorBack1: "\b",
|
||||
CursorUp1: "\x1b[A",
|
||||
KeyUp: "\x1b[A",
|
||||
KeyDown: "\x1b[B",
|
||||
KeyRight: "\x1b[C",
|
||||
KeyLeft: "\x1b[D",
|
||||
KeyInsert: "\x1b[2~",
|
||||
KeyDelete: "\x1b[3~",
|
||||
KeyBackspace: "\b",
|
||||
KeyPgUp: "\x1b[5~",
|
||||
KeyPgDn: "\x1b[6~",
|
||||
KeyF1: "\x1b[11~",
|
||||
KeyF2: "\x1b[12~",
|
||||
KeyF3: "\x1b[13~",
|
||||
KeyF4: "\x1b[14~",
|
||||
KeyF5: "\x1b[15~",
|
||||
KeyF6: "\x1b[17~",
|
||||
KeyF7: "\x1b[18~",
|
||||
KeyF8: "\x1b[19~",
|
||||
KeyF9: "\x1b[20~",
|
||||
KeyF10: "\x1b[21~",
|
||||
KeyF11: "\x1b[23~",
|
||||
KeyF12: "\x1b[24~",
|
||||
KeyF13: "\x1b[25~",
|
||||
KeyF14: "\x1b[26~",
|
||||
KeyF15: "\x1b[28~",
|
||||
KeyF16: "\x1b[29~",
|
||||
KeyF17: "\x1b[31~",
|
||||
KeyF18: "\x1b[32~",
|
||||
KeyF19: "\x1b[33~",
|
||||
KeyF20: "\x1b[34~",
|
||||
KeyHelp: "\x1b[28~",
|
||||
AutoMargin: true,
|
||||
})
|
||||
}
|
||||
|
||||
163
vendor/github.com/gdamore/tcell/v2/terminfo/dynamic/dynamic.go
generated
vendored
163
vendor/github.com/gdamore/tcell/v2/terminfo/dynamic/dynamic.go
generated
vendored
@@ -24,6 +24,7 @@ package dynamic
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"os/exec"
|
||||
"regexp"
|
||||
"strconv"
|
||||
@@ -126,7 +127,7 @@ func (tc *termcap) setupterm(name string) error {
|
||||
tc.nums = make(map[string]int)
|
||||
|
||||
if err := cmd.Run(); err != nil {
|
||||
return err
|
||||
return fmt.Errorf("couldn't open terminfo ($TERM) file for %s: %w", name, err)
|
||||
}
|
||||
|
||||
// Now parse the output.
|
||||
@@ -144,9 +145,7 @@ func (tc *termcap) setupterm(name string) error {
|
||||
lines = lines[:len(lines)-1]
|
||||
}
|
||||
header := lines[0]
|
||||
if strings.HasSuffix(header, ",") {
|
||||
header = header[:len(header)-1]
|
||||
}
|
||||
header = strings.TrimSuffix(header, ",")
|
||||
names := strings.Split(header, "|")
|
||||
tc.name = names[0]
|
||||
names = names[1:]
|
||||
@@ -193,7 +192,6 @@ func LoadTerminfo(name string) (*terminfo.Terminfo, string, error) {
|
||||
t.Colors = tc.getnum("colors")
|
||||
t.Columns = tc.getnum("cols")
|
||||
t.Lines = tc.getnum("lines")
|
||||
t.Bell = tc.getstr("bel")
|
||||
t.Clear = tc.getstr("clear")
|
||||
t.EnterCA = tc.getstr("smcup")
|
||||
t.ExitCA = tc.getstr("rmcup")
|
||||
@@ -211,166 +209,11 @@ func LoadTerminfo(name string) (*terminfo.Terminfo, string, error) {
|
||||
t.SetFg = tc.getstr("setaf")
|
||||
t.SetBg = tc.getstr("setab")
|
||||
t.SetCursor = tc.getstr("cup")
|
||||
t.CursorBack1 = tc.getstr("cub1")
|
||||
t.CursorUp1 = tc.getstr("cuu1")
|
||||
t.KeyF1 = tc.getstr("kf1")
|
||||
t.KeyF2 = tc.getstr("kf2")
|
||||
t.KeyF3 = tc.getstr("kf3")
|
||||
t.KeyF4 = tc.getstr("kf4")
|
||||
t.KeyF5 = tc.getstr("kf5")
|
||||
t.KeyF6 = tc.getstr("kf6")
|
||||
t.KeyF7 = tc.getstr("kf7")
|
||||
t.KeyF8 = tc.getstr("kf8")
|
||||
t.KeyF9 = tc.getstr("kf9")
|
||||
t.KeyF10 = tc.getstr("kf10")
|
||||
t.KeyF11 = tc.getstr("kf11")
|
||||
t.KeyF12 = tc.getstr("kf12")
|
||||
t.KeyF13 = tc.getstr("kf13")
|
||||
t.KeyF14 = tc.getstr("kf14")
|
||||
t.KeyF15 = tc.getstr("kf15")
|
||||
t.KeyF16 = tc.getstr("kf16")
|
||||
t.KeyF17 = tc.getstr("kf17")
|
||||
t.KeyF18 = tc.getstr("kf18")
|
||||
t.KeyF19 = tc.getstr("kf19")
|
||||
t.KeyF20 = tc.getstr("kf20")
|
||||
t.KeyF21 = tc.getstr("kf21")
|
||||
t.KeyF22 = tc.getstr("kf22")
|
||||
t.KeyF23 = tc.getstr("kf23")
|
||||
t.KeyF24 = tc.getstr("kf24")
|
||||
t.KeyF25 = tc.getstr("kf25")
|
||||
t.KeyF26 = tc.getstr("kf26")
|
||||
t.KeyF27 = tc.getstr("kf27")
|
||||
t.KeyF28 = tc.getstr("kf28")
|
||||
t.KeyF29 = tc.getstr("kf29")
|
||||
t.KeyF30 = tc.getstr("kf30")
|
||||
t.KeyF31 = tc.getstr("kf31")
|
||||
t.KeyF32 = tc.getstr("kf32")
|
||||
t.KeyF33 = tc.getstr("kf33")
|
||||
t.KeyF34 = tc.getstr("kf34")
|
||||
t.KeyF35 = tc.getstr("kf35")
|
||||
t.KeyF36 = tc.getstr("kf36")
|
||||
t.KeyF37 = tc.getstr("kf37")
|
||||
t.KeyF38 = tc.getstr("kf38")
|
||||
t.KeyF39 = tc.getstr("kf39")
|
||||
t.KeyF40 = tc.getstr("kf40")
|
||||
t.KeyF41 = tc.getstr("kf41")
|
||||
t.KeyF42 = tc.getstr("kf42")
|
||||
t.KeyF43 = tc.getstr("kf43")
|
||||
t.KeyF44 = tc.getstr("kf44")
|
||||
t.KeyF45 = tc.getstr("kf45")
|
||||
t.KeyF46 = tc.getstr("kf46")
|
||||
t.KeyF47 = tc.getstr("kf47")
|
||||
t.KeyF48 = tc.getstr("kf48")
|
||||
t.KeyF49 = tc.getstr("kf49")
|
||||
t.KeyF50 = tc.getstr("kf50")
|
||||
t.KeyF51 = tc.getstr("kf51")
|
||||
t.KeyF52 = tc.getstr("kf52")
|
||||
t.KeyF53 = tc.getstr("kf53")
|
||||
t.KeyF54 = tc.getstr("kf54")
|
||||
t.KeyF55 = tc.getstr("kf55")
|
||||
t.KeyF56 = tc.getstr("kf56")
|
||||
t.KeyF57 = tc.getstr("kf57")
|
||||
t.KeyF58 = tc.getstr("kf58")
|
||||
t.KeyF59 = tc.getstr("kf59")
|
||||
t.KeyF60 = tc.getstr("kf60")
|
||||
t.KeyF61 = tc.getstr("kf61")
|
||||
t.KeyF62 = tc.getstr("kf62")
|
||||
t.KeyF63 = tc.getstr("kf63")
|
||||
t.KeyF64 = tc.getstr("kf64")
|
||||
t.KeyInsert = tc.getstr("kich1")
|
||||
t.KeyDelete = tc.getstr("kdch1")
|
||||
t.KeyBackspace = tc.getstr("kbs")
|
||||
t.KeyHome = tc.getstr("khome")
|
||||
t.KeyEnd = tc.getstr("kend")
|
||||
t.KeyUp = tc.getstr("kcuu1")
|
||||
t.KeyDown = tc.getstr("kcud1")
|
||||
t.KeyRight = tc.getstr("kcuf1")
|
||||
t.KeyLeft = tc.getstr("kcub1")
|
||||
t.KeyPgDn = tc.getstr("knp")
|
||||
t.KeyPgUp = tc.getstr("kpp")
|
||||
t.KeyBacktab = tc.getstr("kcbt")
|
||||
t.KeyExit = tc.getstr("kext")
|
||||
t.KeyCancel = tc.getstr("kcan")
|
||||
t.KeyPrint = tc.getstr("kprt")
|
||||
t.KeyHelp = tc.getstr("khlp")
|
||||
t.KeyClear = tc.getstr("kclr")
|
||||
t.AltChars = tc.getstr("acsc")
|
||||
t.EnterAcs = tc.getstr("smacs")
|
||||
t.ExitAcs = tc.getstr("rmacs")
|
||||
t.EnableAcs = tc.getstr("enacs")
|
||||
t.Mouse = tc.getstr("kmous")
|
||||
t.KeyShfRight = tc.getstr("kRIT")
|
||||
t.KeyShfLeft = tc.getstr("kLFT")
|
||||
t.KeyShfHome = tc.getstr("kHOM")
|
||||
t.KeyShfEnd = tc.getstr("kEND")
|
||||
|
||||
// Terminfo lacks descriptions for a bunch of modified keys,
|
||||
// but modern XTerm and emulators often have them. Let's add them,
|
||||
// if the shifted right and left arrows are defined.
|
||||
if t.KeyShfRight == "\x1b[1;2C" && t.KeyShfLeft == "\x1b[1;2D" {
|
||||
t.Modifiers = terminfo.ModifiersXTerm
|
||||
|
||||
t.KeyShfUp = "\x1b[1;2A"
|
||||
t.KeyShfDown = "\x1b[1;2B"
|
||||
t.KeyMetaUp = "\x1b[1;9A"
|
||||
t.KeyMetaDown = "\x1b[1;9B"
|
||||
t.KeyMetaRight = "\x1b[1;9C"
|
||||
t.KeyMetaLeft = "\x1b[1;9D"
|
||||
t.KeyAltUp = "\x1b[1;3A"
|
||||
t.KeyAltDown = "\x1b[1;3B"
|
||||
t.KeyAltRight = "\x1b[1;3C"
|
||||
t.KeyAltLeft = "\x1b[1;3D"
|
||||
t.KeyCtrlUp = "\x1b[1;5A"
|
||||
t.KeyCtrlDown = "\x1b[1;5B"
|
||||
t.KeyCtrlRight = "\x1b[1;5C"
|
||||
t.KeyCtrlLeft = "\x1b[1;5D"
|
||||
t.KeyAltShfUp = "\x1b[1;4A"
|
||||
t.KeyAltShfDown = "\x1b[1;4B"
|
||||
t.KeyAltShfRight = "\x1b[1;4C"
|
||||
t.KeyAltShfLeft = "\x1b[1;4D"
|
||||
|
||||
t.KeyMetaShfUp = "\x1b[1;10A"
|
||||
t.KeyMetaShfDown = "\x1b[1;10B"
|
||||
t.KeyMetaShfRight = "\x1b[1;10C"
|
||||
t.KeyMetaShfLeft = "\x1b[1;10D"
|
||||
|
||||
t.KeyCtrlShfUp = "\x1b[1;6A"
|
||||
t.KeyCtrlShfDown = "\x1b[1;6B"
|
||||
t.KeyCtrlShfRight = "\x1b[1;6C"
|
||||
t.KeyCtrlShfLeft = "\x1b[1;6D"
|
||||
|
||||
t.KeyShfPgUp = "\x1b[5;2~"
|
||||
t.KeyShfPgDn = "\x1b[6;2~"
|
||||
}
|
||||
// And also for Home and End
|
||||
if t.KeyShfHome == "\x1b[1;2H" && t.KeyShfEnd == "\x1b[1;2F" {
|
||||
t.KeyCtrlHome = "\x1b[1;5H"
|
||||
t.KeyCtrlEnd = "\x1b[1;5F"
|
||||
t.KeyAltHome = "\x1b[1;9H"
|
||||
t.KeyAltEnd = "\x1b[1;9F"
|
||||
t.KeyCtrlShfHome = "\x1b[1;6H"
|
||||
t.KeyCtrlShfEnd = "\x1b[1;6F"
|
||||
t.KeyAltShfHome = "\x1b[1;4H"
|
||||
t.KeyAltShfEnd = "\x1b[1;4F"
|
||||
t.KeyMetaShfHome = "\x1b[1;10H"
|
||||
t.KeyMetaShfEnd = "\x1b[1;10F"
|
||||
}
|
||||
|
||||
// And the same thing for rxvt and workalikes (Eterm, aterm, etc.)
|
||||
// It seems that urxvt at least send escaped as ALT prefix for these,
|
||||
// although some places seem to indicate a separate ALT key sesquence.
|
||||
if t.KeyShfRight == "\x1b[c" && t.KeyShfLeft == "\x1b[d" {
|
||||
t.KeyShfUp = "\x1b[a"
|
||||
t.KeyShfDown = "\x1b[b"
|
||||
t.KeyCtrlUp = "\x1b[Oa"
|
||||
t.KeyCtrlDown = "\x1b[Ob"
|
||||
t.KeyCtrlRight = "\x1b[Oc"
|
||||
t.KeyCtrlLeft = "\x1b[Od"
|
||||
}
|
||||
if t.KeyShfHome == "\x1b[7$" && t.KeyShfEnd == "\x1b[8$" {
|
||||
t.KeyCtrlHome = "\x1b[7^"
|
||||
t.KeyCtrlEnd = "\x1b[8^"
|
||||
}
|
||||
|
||||
// Technically the RGB flag that is provided for xterm-direct is not
|
||||
// quite right. The problem is that the -direct flag that was introduced
|
||||
|
||||
81
vendor/github.com/gdamore/tcell/v2/terminfo/e/emacs/term.go
generated
vendored
81
vendor/github.com/gdamore/tcell/v2/terminfo/e/emacs/term.go
generated
vendored
@@ -8,58 +8,41 @@ func init() {
|
||||
|
||||
// GNU Emacs term.el terminal emulation
|
||||
terminfo.AddTerminfo(&terminfo.Terminfo{
|
||||
Name: "eterm",
|
||||
Columns: 80,
|
||||
Lines: 24,
|
||||
Bell: "\a",
|
||||
Clear: "\x1b[H\x1b[J",
|
||||
EnterCA: "\x1b7\x1b[?47h",
|
||||
ExitCA: "\x1b[2J\x1b[?47l\x1b8",
|
||||
AttrOff: "\x1b[m",
|
||||
Underline: "\x1b[4m",
|
||||
Bold: "\x1b[1m",
|
||||
Reverse: "\x1b[7m",
|
||||
PadChar: "\x00",
|
||||
SetCursor: "\x1b[%i%p1%d;%p2%dH",
|
||||
CursorBack1: "\b",
|
||||
CursorUp1: "\x1b[A",
|
||||
AutoMargin: true,
|
||||
Name: "eterm",
|
||||
Columns: 80,
|
||||
Lines: 24,
|
||||
Clear: "\x1b[H\x1b[J",
|
||||
EnterCA: "\x1b7\x1b[?47h",
|
||||
ExitCA: "\x1b[2J\x1b[?47l\x1b8",
|
||||
AttrOff: "\x1b[m",
|
||||
Underline: "\x1b[4m",
|
||||
Bold: "\x1b[1m",
|
||||
Reverse: "\x1b[7m",
|
||||
PadChar: "\x00",
|
||||
SetCursor: "\x1b[%i%p1%d;%p2%dH",
|
||||
AutoMargin: true,
|
||||
})
|
||||
|
||||
// Emacs term.el terminal emulator term-protocol-version 0.96
|
||||
terminfo.AddTerminfo(&terminfo.Terminfo{
|
||||
Name: "eterm-color",
|
||||
Columns: 80,
|
||||
Lines: 24,
|
||||
Colors: 8,
|
||||
Bell: "\a",
|
||||
Clear: "\x1b[H\x1b[J",
|
||||
EnterCA: "\x1b7\x1b[?47h",
|
||||
ExitCA: "\x1b[2J\x1b[?47l\x1b8",
|
||||
AttrOff: "\x1b[m",
|
||||
Underline: "\x1b[4m",
|
||||
Bold: "\x1b[1m",
|
||||
Blink: "\x1b[5m",
|
||||
Reverse: "\x1b[7m",
|
||||
SetFg: "\x1b[%p1%{30}%+%dm",
|
||||
SetBg: "\x1b[%p1%'('%+%dm",
|
||||
SetFgBg: "\x1b[%p1%{30}%+%d;%p2%'('%+%dm",
|
||||
ResetFgBg: "\x1b[39;49m",
|
||||
PadChar: "\x00",
|
||||
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: "\x1b[1~",
|
||||
KeyEnd: "\x1b[4~",
|
||||
KeyPgUp: "\x1b[5~",
|
||||
KeyPgDn: "\x1b[6~",
|
||||
AutoMargin: true,
|
||||
Name: "eterm-color",
|
||||
Columns: 80,
|
||||
Lines: 24,
|
||||
Colors: 8,
|
||||
Clear: "\x1b[H\x1b[J",
|
||||
EnterCA: "\x1b7\x1b[?47h",
|
||||
ExitCA: "\x1b[2J\x1b[?47l\x1b8",
|
||||
AttrOff: "\x1b[m",
|
||||
Underline: "\x1b[4m",
|
||||
Bold: "\x1b[1m",
|
||||
Blink: "\x1b[5m",
|
||||
Reverse: "\x1b[7m",
|
||||
SetFg: "\x1b[%p1%{30}%+%dm",
|
||||
SetBg: "\x1b[%p1%'('%+%dm",
|
||||
SetFgBg: "\x1b[%p1%{30}%+%d;%p2%'('%+%dm",
|
||||
ResetFgBg: "\x1b[39;49m",
|
||||
PadChar: "\x00",
|
||||
SetCursor: "\x1b[%i%p1%d;%p2%dH",
|
||||
AutoMargin: true,
|
||||
})
|
||||
}
|
||||
|
||||
6
vendor/github.com/gdamore/tcell/v2/terminfo/extended/extended.go
generated
vendored
6
vendor/github.com/gdamore/tcell/v2/terminfo/extended/extended.go
generated
vendored
@@ -24,13 +24,11 @@ import (
|
||||
_ "github.com/gdamore/tcell/v2/terminfo/a/aixterm"
|
||||
_ "github.com/gdamore/tcell/v2/terminfo/a/alacritty"
|
||||
_ "github.com/gdamore/tcell/v2/terminfo/a/ansi"
|
||||
_ "github.com/gdamore/tcell/v2/terminfo/b/beterm"
|
||||
_ "github.com/gdamore/tcell/v2/terminfo/c/cygwin"
|
||||
_ "github.com/gdamore/tcell/v2/terminfo/d/dtterm"
|
||||
_ "github.com/gdamore/tcell/v2/terminfo/e/emacs"
|
||||
_ "github.com/gdamore/tcell/v2/terminfo/f/foot"
|
||||
_ "github.com/gdamore/tcell/v2/terminfo/g/gnome"
|
||||
_ "github.com/gdamore/tcell/v2/terminfo/h/hpterm"
|
||||
_ "github.com/gdamore/tcell/v2/terminfo/k/konsole"
|
||||
_ "github.com/gdamore/tcell/v2/terminfo/k/kterm"
|
||||
_ "github.com/gdamore/tcell/v2/terminfo/l/linux"
|
||||
@@ -46,10 +44,6 @@ import (
|
||||
_ "github.com/gdamore/tcell/v2/terminfo/v/vt320"
|
||||
_ "github.com/gdamore/tcell/v2/terminfo/v/vt400"
|
||||
_ "github.com/gdamore/tcell/v2/terminfo/v/vt420"
|
||||
_ "github.com/gdamore/tcell/v2/terminfo/v/vt52"
|
||||
_ "github.com/gdamore/tcell/v2/terminfo/w/wy50"
|
||||
_ "github.com/gdamore/tcell/v2/terminfo/w/wy60"
|
||||
_ "github.com/gdamore/tcell/v2/terminfo/w/wy99_ansi"
|
||||
_ "github.com/gdamore/tcell/v2/terminfo/x/xfce"
|
||||
_ "github.com/gdamore/tcell/v2/terminfo/x/xterm"
|
||||
_ "github.com/gdamore/tcell/v2/terminfo/x/xterm_ghostty"
|
||||
|
||||
28
vendor/github.com/gdamore/tcell/v2/terminfo/f/foot/foot.go
generated
vendored
28
vendor/github.com/gdamore/tcell/v2/terminfo/f/foot/foot.go
generated
vendored
@@ -13,7 +13,6 @@ func init() {
|
||||
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",
|
||||
@@ -38,33 +37,6 @@ func init() {
|
||||
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,
|
||||
})
|
||||
}
|
||||
|
||||
56
vendor/github.com/gdamore/tcell/v2/terminfo/g/gnome/term.go
generated
vendored
56
vendor/github.com/gdamore/tcell/v2/terminfo/g/gnome/term.go
generated
vendored
@@ -12,7 +12,6 @@ func init() {
|
||||
Columns: 80,
|
||||
Lines: 24,
|
||||
Colors: 8,
|
||||
Bell: "\a",
|
||||
Clear: "\x1b[H\x1b[2J",
|
||||
EnterCA: "\x1b7\x1b[?47h",
|
||||
ExitCA: "\x1b[2J\x1b[?47l\x1b8",
|
||||
@@ -39,33 +38,6 @@ func init() {
|
||||
DisableAutoMargin: "\x1b[?7l",
|
||||
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,
|
||||
AutoMargin: true,
|
||||
XTermLike: true,
|
||||
})
|
||||
@@ -76,7 +48,6 @@ func init() {
|
||||
Columns: 80,
|
||||
Lines: 24,
|
||||
Colors: 256,
|
||||
Bell: "\a",
|
||||
Clear: "\x1b[H\x1b[2J",
|
||||
EnterCA: "\x1b7\x1b[?47h",
|
||||
ExitCA: "\x1b[2J\x1b[?47l\x1b8",
|
||||
@@ -103,33 +74,6 @@ func init() {
|
||||
DisableAutoMargin: "\x1b[?7l",
|
||||
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,
|
||||
AutoMargin: true,
|
||||
XTermLike: true,
|
||||
})
|
||||
|
||||
51
vendor/github.com/gdamore/tcell/v2/terminfo/h/hpterm/term.go
generated
vendored
51
vendor/github.com/gdamore/tcell/v2/terminfo/h/hpterm/term.go
generated
vendored
@@ -1,51 +0,0 @@
|
||||
// Generated automatically. DO NOT HAND-EDIT.
|
||||
|
||||
package hpterm
|
||||
|
||||
import "github.com/gdamore/tcell/v2/terminfo"
|
||||
|
||||
func init() {
|
||||
|
||||
// HP X11 terminal emulator (old)
|
||||
terminfo.AddTerminfo(&terminfo.Terminfo{
|
||||
Name: "hpterm",
|
||||
Aliases: []string{"X-hpterm"},
|
||||
Columns: 80,
|
||||
Lines: 24,
|
||||
Bell: "\a",
|
||||
Clear: "\x1b&a0y0C\x1bJ",
|
||||
AttrOff: "\x1b&d@\x0f",
|
||||
Underline: "\x1b&dD",
|
||||
Bold: "\x1b&dB",
|
||||
Dim: "\x1b&dH",
|
||||
Reverse: "\x1b&dB",
|
||||
EnterKeypad: "\x1b&s1A",
|
||||
ExitKeypad: "\x1b&s0A",
|
||||
PadChar: "\x00",
|
||||
EnterAcs: "\x0e",
|
||||
ExitAcs: "\x0f",
|
||||
SetCursor: "\x1b&a%p1%dy%p2%dC",
|
||||
CursorBack1: "\b",
|
||||
CursorUp1: "\x1bA",
|
||||
KeyUp: "\x1bA",
|
||||
KeyDown: "\x1bB",
|
||||
KeyRight: "\x1bC",
|
||||
KeyLeft: "\x1bD",
|
||||
KeyInsert: "\x1bQ",
|
||||
KeyDelete: "\x1bP",
|
||||
KeyBackspace: "\b",
|
||||
KeyHome: "\x1bh",
|
||||
KeyPgUp: "\x1bV",
|
||||
KeyPgDn: "\x1bU",
|
||||
KeyF1: "\x1bp",
|
||||
KeyF2: "\x1bq",
|
||||
KeyF3: "\x1br",
|
||||
KeyF4: "\x1bs",
|
||||
KeyF5: "\x1bt",
|
||||
KeyF6: "\x1bu",
|
||||
KeyF7: "\x1bv",
|
||||
KeyF8: "\x1bw",
|
||||
KeyClear: "\x1bJ",
|
||||
AutoMargin: true,
|
||||
})
|
||||
}
|
||||
56
vendor/github.com/gdamore/tcell/v2/terminfo/k/konsole/term.go
generated
vendored
56
vendor/github.com/gdamore/tcell/v2/terminfo/k/konsole/term.go
generated
vendored
@@ -12,7 +12,6 @@ func init() {
|
||||
Columns: 80,
|
||||
Lines: 24,
|
||||
Colors: 8,
|
||||
Bell: "\a",
|
||||
Clear: "\x1b[H\x1b[2J",
|
||||
EnterCA: "\x1b7\x1b[?47h",
|
||||
ExitCA: "\x1b[2J\x1b[?47l\x1b8",
|
||||
@@ -40,33 +39,6 @@ func init() {
|
||||
StrikeThrough: "\x1b[9m",
|
||||
Mouse: "\x1b[<",
|
||||
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,
|
||||
AutoMargin: true,
|
||||
XTermLike: true,
|
||||
})
|
||||
@@ -77,7 +49,6 @@ func init() {
|
||||
Columns: 80,
|
||||
Lines: 24,
|
||||
Colors: 256,
|
||||
Bell: "\a",
|
||||
Clear: "\x1b[H\x1b[2J",
|
||||
EnterCA: "\x1b7\x1b[?47h",
|
||||
ExitCA: "\x1b[2J\x1b[?47l\x1b8",
|
||||
@@ -105,33 +76,6 @@ func init() {
|
||||
StrikeThrough: "\x1b[9m",
|
||||
Mouse: "\x1b[<",
|
||||
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,
|
||||
AutoMargin: true,
|
||||
XTermLike: true,
|
||||
})
|
||||
|
||||
32
vendor/github.com/gdamore/tcell/v2/terminfo/k/kterm/term.go
generated
vendored
32
vendor/github.com/gdamore/tcell/v2/terminfo/k/kterm/term.go
generated
vendored
@@ -12,7 +12,6 @@ func init() {
|
||||
Columns: 80,
|
||||
Lines: 24,
|
||||
Colors: 8,
|
||||
Bell: "\a",
|
||||
Clear: "\x1b[H\x1b[2J",
|
||||
EnterCA: "\x1b7\x1b[?47h",
|
||||
ExitCA: "\x1b[2J\x1b[?47l\x1b8",
|
||||
@@ -34,37 +33,6 @@ func init() {
|
||||
DisableAutoMargin: "\x1b[?7l",
|
||||
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",
|
||||
KeyPgUp: "\x1b[5~",
|
||||
KeyPgDn: "\x1b[6~",
|
||||
KeyF1: "\x1b[11~",
|
||||
KeyF2: "\x1b[12~",
|
||||
KeyF3: "\x1b[13~",
|
||||
KeyF4: "\x1b[14~",
|
||||
KeyF5: "\x1b[15~",
|
||||
KeyF6: "\x1b[17~",
|
||||
KeyF7: "\x1b[18~",
|
||||
KeyF8: "\x1b[19~",
|
||||
KeyF9: "\x1b[20~",
|
||||
KeyF10: "\x1b[21~",
|
||||
KeyF11: "\x1b[23~",
|
||||
KeyF12: "\x1b[24~",
|
||||
KeyF13: "\x1b[25~",
|
||||
KeyF14: "\x1b[26~",
|
||||
KeyF15: "\x1b[28~",
|
||||
KeyF16: "\x1b[29~",
|
||||
KeyF17: "\x1b[31~",
|
||||
KeyF18: "\x1b[32~",
|
||||
KeyF19: "\x1b[33~",
|
||||
KeyF20: "\x1b[34~",
|
||||
AutoMargin: true,
|
||||
XTermLike: true,
|
||||
})
|
||||
|
||||
35
vendor/github.com/gdamore/tcell/v2/terminfo/l/linux/term.go
generated
vendored
35
vendor/github.com/gdamore/tcell/v2/terminfo/l/linux/term.go
generated
vendored
@@ -10,7 +10,6 @@ func init() {
|
||||
terminfo.AddTerminfo(&terminfo.Terminfo{
|
||||
Name: "linux",
|
||||
Colors: 8,
|
||||
Bell: "\a",
|
||||
Clear: "\x1b[H\x1b[J",
|
||||
ShowCursor: "\x1b[?25h\x1b[?0c",
|
||||
HideCursor: "\x1b[?25l\x1b[?1c",
|
||||
@@ -33,40 +32,6 @@ func init() {
|
||||
DisableAutoMargin: "\x1b[?7l",
|
||||
Mouse: "\x1b[M",
|
||||
SetCursor: "\x1b[%i%p1%d;%p2%dH",
|
||||
CursorBack1: "\b",
|
||||
CursorUp1: "\x1b[A",
|
||||
KeyUp: "\x1b[A",
|
||||
KeyDown: "\x1b[B",
|
||||
KeyRight: "\x1b[C",
|
||||
KeyLeft: "\x1b[D",
|
||||
KeyInsert: "\x1b[2~",
|
||||
KeyDelete: "\x1b[3~",
|
||||
KeyBackspace: "\x7f",
|
||||
KeyHome: "\x1b[1~",
|
||||
KeyEnd: "\x1b[4~",
|
||||
KeyPgUp: "\x1b[5~",
|
||||
KeyPgDn: "\x1b[6~",
|
||||
KeyF1: "\x1b[[A",
|
||||
KeyF2: "\x1b[[B",
|
||||
KeyF3: "\x1b[[C",
|
||||
KeyF4: "\x1b[[D",
|
||||
KeyF5: "\x1b[[E",
|
||||
KeyF6: "\x1b[17~",
|
||||
KeyF7: "\x1b[18~",
|
||||
KeyF8: "\x1b[19~",
|
||||
KeyF9: "\x1b[20~",
|
||||
KeyF10: "\x1b[21~",
|
||||
KeyF11: "\x1b[23~",
|
||||
KeyF12: "\x1b[24~",
|
||||
KeyF13: "\x1b[25~",
|
||||
KeyF14: "\x1b[26~",
|
||||
KeyF15: "\x1b[28~",
|
||||
KeyF16: "\x1b[29~",
|
||||
KeyF17: "\x1b[31~",
|
||||
KeyF18: "\x1b[32~",
|
||||
KeyF19: "\x1b[33~",
|
||||
KeyF20: "\x1b[34~",
|
||||
KeyBacktab: "\x1b\t",
|
||||
AutoMargin: true,
|
||||
InsertChar: "\x1b[@",
|
||||
})
|
||||
|
||||
2
vendor/github.com/gdamore/tcell/v2/terminfo/models.txt
generated
vendored
2
vendor/github.com/gdamore/tcell/v2/terminfo/models.txt
generated
vendored
@@ -1,7 +1,6 @@
|
||||
aixterm
|
||||
alacritty
|
||||
ansi
|
||||
beterm
|
||||
cygwin
|
||||
dtterm
|
||||
eterm,eterm-color|emacs
|
||||
@@ -15,7 +14,6 @@ rxvt,rxvt-256color,rxvt-88color,rxvt-unicode,rxvt-unicode-256color
|
||||
screen,screen-256color
|
||||
st,st-256color|simpleterm
|
||||
tmux,tmux-256color
|
||||
vt52
|
||||
vt100
|
||||
vt102
|
||||
vt220
|
||||
|
||||
49
vendor/github.com/gdamore/tcell/v2/terminfo/p/pcansi/term.go
generated
vendored
49
vendor/github.com/gdamore/tcell/v2/terminfo/p/pcansi/term.go
generated
vendored
@@ -8,34 +8,25 @@ func init() {
|
||||
|
||||
// ibm-pc terminal programs claiming to be ANSI
|
||||
terminfo.AddTerminfo(&terminfo.Terminfo{
|
||||
Name: "pcansi",
|
||||
Columns: 80,
|
||||
Lines: 24,
|
||||
Colors: 8,
|
||||
Bell: "\a",
|
||||
Clear: "\x1b[H\x1b[J",
|
||||
AttrOff: "\x1b[0;10m",
|
||||
Underline: "\x1b[4m",
|
||||
Bold: "\x1b[1m",
|
||||
Blink: "\x1b[5m",
|
||||
Reverse: "\x1b[7m",
|
||||
SetFg: "\x1b[3%p1%dm",
|
||||
SetBg: "\x1b[4%p1%dm",
|
||||
SetFgBg: "\x1b[3%p1%d;4%p2%dm",
|
||||
ResetFgBg: "\x1b[37;40m",
|
||||
PadChar: "\x00",
|
||||
AltChars: "+\x10,\x11-\x18.\x190\xdb`\x04a\xb1f\xf8g\xf1h\xb0j\xd9k\xbfl\xdam\xc0n\xc5o~p\xc4q\xc4r\xc4s_t\xc3u\xb4v\xc1w\xc2x\xb3y\xf3z\xf2{\xe3|\xd8}\x9c~\xfe",
|
||||
EnterAcs: "\x1b[12m",
|
||||
ExitAcs: "\x1b[10m",
|
||||
SetCursor: "\x1b[%i%p1%d;%p2%dH",
|
||||
CursorBack1: "\x1b[D",
|
||||
CursorUp1: "\x1b[A",
|
||||
KeyUp: "\x1b[A",
|
||||
KeyDown: "\x1b[B",
|
||||
KeyRight: "\x1b[C",
|
||||
KeyLeft: "\x1b[D",
|
||||
KeyBackspace: "\b",
|
||||
KeyHome: "\x1b[H",
|
||||
AutoMargin: true,
|
||||
Name: "pcansi",
|
||||
Columns: 80,
|
||||
Lines: 24,
|
||||
Colors: 8,
|
||||
Clear: "\x1b[H\x1b[J",
|
||||
AttrOff: "\x1b[0;10m",
|
||||
Underline: "\x1b[4m",
|
||||
Bold: "\x1b[1m",
|
||||
Blink: "\x1b[5m",
|
||||
Reverse: "\x1b[7m",
|
||||
SetFg: "\x1b[3%p1%dm",
|
||||
SetBg: "\x1b[4%p1%dm",
|
||||
SetFgBg: "\x1b[3%p1%d;4%p2%dm",
|
||||
ResetFgBg: "\x1b[37;40m",
|
||||
PadChar: "\x00",
|
||||
AltChars: "+\x10,\x11-\x18.\x190\xdb`\x04a\xb1f\xf8g\xf1h\xb0j\xd9k\xbfl\xdam\xc0n\xc5o~p\xc4q\xc4r\xc4s_t\xc3u\xb4v\xc1w\xc2x\xb3y\xf3z\xf2{\xe3|\xd8}\x9c~\xfe",
|
||||
EnterAcs: "\x1b[12m",
|
||||
ExitAcs: "\x1b[10m",
|
||||
SetCursor: "\x1b[%i%p1%d;%p2%dH",
|
||||
AutoMargin: true,
|
||||
})
|
||||
}
|
||||
|
||||
493
vendor/github.com/gdamore/tcell/v2/terminfo/r/rxvt/term.go
generated
vendored
493
vendor/github.com/gdamore/tcell/v2/terminfo/r/rxvt/term.go
generated
vendored
@@ -8,321 +8,102 @@ func init() {
|
||||
|
||||
// rxvt terminal emulator (X Window System)
|
||||
terminfo.AddTerminfo(&terminfo.Terminfo{
|
||||
Name: "rxvt",
|
||||
Aliases: []string{"rxvt-color"},
|
||||
Columns: 80,
|
||||
Lines: 24,
|
||||
Colors: 8,
|
||||
Bell: "\a",
|
||||
Clear: "\x1b[H\x1b[2J",
|
||||
EnterCA: "\x1b7\x1b[?47h",
|
||||
ExitCA: "\x1b[2J\x1b[?47l\x1b8",
|
||||
ShowCursor: "\x1b[?25h",
|
||||
HideCursor: "\x1b[?25l",
|
||||
AttrOff: "\x1b[m\x0f",
|
||||
Underline: "\x1b[4m",
|
||||
Bold: "\x1b[1m",
|
||||
Blink: "\x1b[5m",
|
||||
Reverse: "\x1b[7m",
|
||||
EnterKeypad: "\x1b=",
|
||||
ExitKeypad: "\x1b>",
|
||||
SetFg: "\x1b[3%p1%dm",
|
||||
SetBg: "\x1b[4%p1%dm",
|
||||
SetFgBg: "\x1b[3%p1%d;4%p2%dm",
|
||||
ResetFgBg: "\x1b[39;49m",
|
||||
PadChar: "\x00",
|
||||
AltChars: "``aaffggjjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~",
|
||||
EnterAcs: "\x0e",
|
||||
ExitAcs: "\x0f",
|
||||
EnableAcs: "\x1b(B\x1b)0",
|
||||
Mouse: "\x1b[M",
|
||||
SetCursor: "\x1b[%i%p1%d;%p2%dH",
|
||||
CursorBack1: "\b",
|
||||
CursorUp1: "\x1b[A",
|
||||
KeyUp: "\x1b[A",
|
||||
KeyDown: "\x1b[B",
|
||||
KeyRight: "\x1b[C",
|
||||
KeyLeft: "\x1b[D",
|
||||
KeyInsert: "\x1b[2~",
|
||||
KeyDelete: "\x1b[3~",
|
||||
KeyBackspace: "\x7f",
|
||||
KeyHome: "\x1b[7~",
|
||||
KeyEnd: "\x1b[8~",
|
||||
KeyPgUp: "\x1b[5~",
|
||||
KeyPgDn: "\x1b[6~",
|
||||
KeyF1: "\x1b[11~",
|
||||
KeyF2: "\x1b[12~",
|
||||
KeyF3: "\x1b[13~",
|
||||
KeyF4: "\x1b[14~",
|
||||
KeyF5: "\x1b[15~",
|
||||
KeyF6: "\x1b[17~",
|
||||
KeyF7: "\x1b[18~",
|
||||
KeyF8: "\x1b[19~",
|
||||
KeyF9: "\x1b[20~",
|
||||
KeyF10: "\x1b[21~",
|
||||
KeyF11: "\x1b[23~",
|
||||
KeyF12: "\x1b[24~",
|
||||
KeyF13: "\x1b[25~",
|
||||
KeyF14: "\x1b[26~",
|
||||
KeyF15: "\x1b[28~",
|
||||
KeyF16: "\x1b[29~",
|
||||
KeyF17: "\x1b[31~",
|
||||
KeyF18: "\x1b[32~",
|
||||
KeyF19: "\x1b[33~",
|
||||
KeyF20: "\x1b[34~",
|
||||
KeyF21: "\x1b[23$",
|
||||
KeyF22: "\x1b[24$",
|
||||
KeyF23: "\x1b[11^",
|
||||
KeyF24: "\x1b[12^",
|
||||
KeyF25: "\x1b[13^",
|
||||
KeyF26: "\x1b[14^",
|
||||
KeyF27: "\x1b[15^",
|
||||
KeyF28: "\x1b[17^",
|
||||
KeyF29: "\x1b[18^",
|
||||
KeyF30: "\x1b[19^",
|
||||
KeyF31: "\x1b[20^",
|
||||
KeyF32: "\x1b[21^",
|
||||
KeyF33: "\x1b[23^",
|
||||
KeyF34: "\x1b[24^",
|
||||
KeyF35: "\x1b[25^",
|
||||
KeyF36: "\x1b[26^",
|
||||
KeyF37: "\x1b[28^",
|
||||
KeyF38: "\x1b[29^",
|
||||
KeyF39: "\x1b[31^",
|
||||
KeyF40: "\x1b[32^",
|
||||
KeyF41: "\x1b[33^",
|
||||
KeyF42: "\x1b[34^",
|
||||
KeyF43: "\x1b[23@",
|
||||
KeyF44: "\x1b[24@",
|
||||
KeyBacktab: "\x1b[Z",
|
||||
KeyShfLeft: "\x1b[d",
|
||||
KeyShfRight: "\x1b[c",
|
||||
KeyShfUp: "\x1b[a",
|
||||
KeyShfDown: "\x1b[b",
|
||||
KeyShfHome: "\x1b[7$",
|
||||
KeyShfEnd: "\x1b[8$",
|
||||
KeyShfInsert: "\x1b[2$",
|
||||
KeyShfDelete: "\x1b[3$",
|
||||
KeyCtrlUp: "\x1b[Oa",
|
||||
KeyCtrlDown: "\x1b[Ob",
|
||||
KeyCtrlRight: "\x1b[Oc",
|
||||
KeyCtrlLeft: "\x1b[Od",
|
||||
KeyCtrlHome: "\x1b[7^",
|
||||
KeyCtrlEnd: "\x1b[8^",
|
||||
AutoMargin: true,
|
||||
XTermLike: true,
|
||||
Name: "rxvt",
|
||||
Aliases: []string{"rxvt-color"},
|
||||
Columns: 80,
|
||||
Lines: 24,
|
||||
Colors: 8,
|
||||
Clear: "\x1b[H\x1b[2J",
|
||||
EnterCA: "\x1b7\x1b[?47h",
|
||||
ExitCA: "\x1b[2J\x1b[?47l\x1b8",
|
||||
ShowCursor: "\x1b[?25h",
|
||||
HideCursor: "\x1b[?25l",
|
||||
AttrOff: "\x1b[m\x0f",
|
||||
Underline: "\x1b[4m",
|
||||
Bold: "\x1b[1m",
|
||||
Blink: "\x1b[5m",
|
||||
Reverse: "\x1b[7m",
|
||||
EnterKeypad: "\x1b=",
|
||||
ExitKeypad: "\x1b>",
|
||||
SetFg: "\x1b[3%p1%dm",
|
||||
SetBg: "\x1b[4%p1%dm",
|
||||
SetFgBg: "\x1b[3%p1%d;4%p2%dm",
|
||||
ResetFgBg: "\x1b[39;49m",
|
||||
PadChar: "\x00",
|
||||
AltChars: "``aaffggjjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~",
|
||||
EnterAcs: "\x0e",
|
||||
ExitAcs: "\x0f",
|
||||
EnableAcs: "\x1b(B\x1b)0",
|
||||
Mouse: "\x1b[M",
|
||||
SetCursor: "\x1b[%i%p1%d;%p2%dH",
|
||||
AutoMargin: true,
|
||||
XTermLike: true,
|
||||
})
|
||||
|
||||
// rxvt 2.7.9 with xterm 256-colors
|
||||
terminfo.AddTerminfo(&terminfo.Terminfo{
|
||||
Name: "rxvt-256color",
|
||||
Columns: 80,
|
||||
Lines: 24,
|
||||
Colors: 256,
|
||||
Bell: "\a",
|
||||
Clear: "\x1b[H\x1b[2J",
|
||||
EnterCA: "\x1b7\x1b[?47h",
|
||||
ExitCA: "\x1b[2J\x1b[?47l\x1b8",
|
||||
ShowCursor: "\x1b[?25h",
|
||||
HideCursor: "\x1b[?25l",
|
||||
AttrOff: "\x1b[m\x0f",
|
||||
Underline: "\x1b[4m",
|
||||
Bold: "\x1b[1m",
|
||||
Blink: "\x1b[5m",
|
||||
Reverse: "\x1b[7m",
|
||||
EnterKeypad: "\x1b=",
|
||||
ExitKeypad: "\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",
|
||||
PadChar: "\x00",
|
||||
AltChars: "``aaffggjjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~",
|
||||
EnterAcs: "\x0e",
|
||||
ExitAcs: "\x0f",
|
||||
EnableAcs: "\x1b(B\x1b)0",
|
||||
Mouse: "\x1b[M",
|
||||
SetCursor: "\x1b[%i%p1%d;%p2%dH",
|
||||
CursorBack1: "\b",
|
||||
CursorUp1: "\x1b[A",
|
||||
KeyUp: "\x1b[A",
|
||||
KeyDown: "\x1b[B",
|
||||
KeyRight: "\x1b[C",
|
||||
KeyLeft: "\x1b[D",
|
||||
KeyInsert: "\x1b[2~",
|
||||
KeyDelete: "\x1b[3~",
|
||||
KeyBackspace: "\x7f",
|
||||
KeyHome: "\x1b[7~",
|
||||
KeyEnd: "\x1b[8~",
|
||||
KeyPgUp: "\x1b[5~",
|
||||
KeyPgDn: "\x1b[6~",
|
||||
KeyF1: "\x1b[11~",
|
||||
KeyF2: "\x1b[12~",
|
||||
KeyF3: "\x1b[13~",
|
||||
KeyF4: "\x1b[14~",
|
||||
KeyF5: "\x1b[15~",
|
||||
KeyF6: "\x1b[17~",
|
||||
KeyF7: "\x1b[18~",
|
||||
KeyF8: "\x1b[19~",
|
||||
KeyF9: "\x1b[20~",
|
||||
KeyF10: "\x1b[21~",
|
||||
KeyF11: "\x1b[23~",
|
||||
KeyF12: "\x1b[24~",
|
||||
KeyF13: "\x1b[25~",
|
||||
KeyF14: "\x1b[26~",
|
||||
KeyF15: "\x1b[28~",
|
||||
KeyF16: "\x1b[29~",
|
||||
KeyF17: "\x1b[31~",
|
||||
KeyF18: "\x1b[32~",
|
||||
KeyF19: "\x1b[33~",
|
||||
KeyF20: "\x1b[34~",
|
||||
KeyF21: "\x1b[23$",
|
||||
KeyF22: "\x1b[24$",
|
||||
KeyF23: "\x1b[11^",
|
||||
KeyF24: "\x1b[12^",
|
||||
KeyF25: "\x1b[13^",
|
||||
KeyF26: "\x1b[14^",
|
||||
KeyF27: "\x1b[15^",
|
||||
KeyF28: "\x1b[17^",
|
||||
KeyF29: "\x1b[18^",
|
||||
KeyF30: "\x1b[19^",
|
||||
KeyF31: "\x1b[20^",
|
||||
KeyF32: "\x1b[21^",
|
||||
KeyF33: "\x1b[23^",
|
||||
KeyF34: "\x1b[24^",
|
||||
KeyF35: "\x1b[25^",
|
||||
KeyF36: "\x1b[26^",
|
||||
KeyF37: "\x1b[28^",
|
||||
KeyF38: "\x1b[29^",
|
||||
KeyF39: "\x1b[31^",
|
||||
KeyF40: "\x1b[32^",
|
||||
KeyF41: "\x1b[33^",
|
||||
KeyF42: "\x1b[34^",
|
||||
KeyF43: "\x1b[23@",
|
||||
KeyF44: "\x1b[24@",
|
||||
KeyBacktab: "\x1b[Z",
|
||||
KeyShfLeft: "\x1b[d",
|
||||
KeyShfRight: "\x1b[c",
|
||||
KeyShfUp: "\x1b[a",
|
||||
KeyShfDown: "\x1b[b",
|
||||
KeyShfHome: "\x1b[7$",
|
||||
KeyShfEnd: "\x1b[8$",
|
||||
KeyShfInsert: "\x1b[2$",
|
||||
KeyShfDelete: "\x1b[3$",
|
||||
KeyCtrlUp: "\x1b[Oa",
|
||||
KeyCtrlDown: "\x1b[Ob",
|
||||
KeyCtrlRight: "\x1b[Oc",
|
||||
KeyCtrlLeft: "\x1b[Od",
|
||||
KeyCtrlHome: "\x1b[7^",
|
||||
KeyCtrlEnd: "\x1b[8^",
|
||||
AutoMargin: true,
|
||||
XTermLike: true,
|
||||
Name: "rxvt-256color",
|
||||
Columns: 80,
|
||||
Lines: 24,
|
||||
Colors: 256,
|
||||
Clear: "\x1b[H\x1b[2J",
|
||||
EnterCA: "\x1b7\x1b[?47h",
|
||||
ExitCA: "\x1b[2J\x1b[?47l\x1b8",
|
||||
ShowCursor: "\x1b[?25h",
|
||||
HideCursor: "\x1b[?25l",
|
||||
AttrOff: "\x1b[m\x0f",
|
||||
Underline: "\x1b[4m",
|
||||
Bold: "\x1b[1m",
|
||||
Blink: "\x1b[5m",
|
||||
Reverse: "\x1b[7m",
|
||||
EnterKeypad: "\x1b=",
|
||||
ExitKeypad: "\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",
|
||||
PadChar: "\x00",
|
||||
AltChars: "``aaffggjjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~",
|
||||
EnterAcs: "\x0e",
|
||||
ExitAcs: "\x0f",
|
||||
EnableAcs: "\x1b(B\x1b)0",
|
||||
Mouse: "\x1b[M",
|
||||
SetCursor: "\x1b[%i%p1%d;%p2%dH",
|
||||
AutoMargin: true,
|
||||
XTermLike: true,
|
||||
})
|
||||
|
||||
// rxvt 2.7.9 with xterm 88-colors
|
||||
terminfo.AddTerminfo(&terminfo.Terminfo{
|
||||
Name: "rxvt-88color",
|
||||
Columns: 80,
|
||||
Lines: 24,
|
||||
Colors: 88,
|
||||
Bell: "\a",
|
||||
Clear: "\x1b[H\x1b[2J",
|
||||
EnterCA: "\x1b7\x1b[?47h",
|
||||
ExitCA: "\x1b[2J\x1b[?47l\x1b8",
|
||||
ShowCursor: "\x1b[?25h",
|
||||
HideCursor: "\x1b[?25l",
|
||||
AttrOff: "\x1b[m\x0f",
|
||||
Underline: "\x1b[4m",
|
||||
Bold: "\x1b[1m",
|
||||
Blink: "\x1b[5m",
|
||||
Reverse: "\x1b[7m",
|
||||
EnterKeypad: "\x1b=",
|
||||
ExitKeypad: "\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",
|
||||
PadChar: "\x00",
|
||||
AltChars: "``aaffggjjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~",
|
||||
EnterAcs: "\x0e",
|
||||
ExitAcs: "\x0f",
|
||||
EnableAcs: "\x1b(B\x1b)0",
|
||||
Mouse: "\x1b[M",
|
||||
SetCursor: "\x1b[%i%p1%d;%p2%dH",
|
||||
CursorBack1: "\b",
|
||||
CursorUp1: "\x1b[A",
|
||||
KeyUp: "\x1b[A",
|
||||
KeyDown: "\x1b[B",
|
||||
KeyRight: "\x1b[C",
|
||||
KeyLeft: "\x1b[D",
|
||||
KeyInsert: "\x1b[2~",
|
||||
KeyDelete: "\x1b[3~",
|
||||
KeyBackspace: "\x7f",
|
||||
KeyHome: "\x1b[7~",
|
||||
KeyEnd: "\x1b[8~",
|
||||
KeyPgUp: "\x1b[5~",
|
||||
KeyPgDn: "\x1b[6~",
|
||||
KeyF1: "\x1b[11~",
|
||||
KeyF2: "\x1b[12~",
|
||||
KeyF3: "\x1b[13~",
|
||||
KeyF4: "\x1b[14~",
|
||||
KeyF5: "\x1b[15~",
|
||||
KeyF6: "\x1b[17~",
|
||||
KeyF7: "\x1b[18~",
|
||||
KeyF8: "\x1b[19~",
|
||||
KeyF9: "\x1b[20~",
|
||||
KeyF10: "\x1b[21~",
|
||||
KeyF11: "\x1b[23~",
|
||||
KeyF12: "\x1b[24~",
|
||||
KeyF13: "\x1b[25~",
|
||||
KeyF14: "\x1b[26~",
|
||||
KeyF15: "\x1b[28~",
|
||||
KeyF16: "\x1b[29~",
|
||||
KeyF17: "\x1b[31~",
|
||||
KeyF18: "\x1b[32~",
|
||||
KeyF19: "\x1b[33~",
|
||||
KeyF20: "\x1b[34~",
|
||||
KeyF21: "\x1b[23$",
|
||||
KeyF22: "\x1b[24$",
|
||||
KeyF23: "\x1b[11^",
|
||||
KeyF24: "\x1b[12^",
|
||||
KeyF25: "\x1b[13^",
|
||||
KeyF26: "\x1b[14^",
|
||||
KeyF27: "\x1b[15^",
|
||||
KeyF28: "\x1b[17^",
|
||||
KeyF29: "\x1b[18^",
|
||||
KeyF30: "\x1b[19^",
|
||||
KeyF31: "\x1b[20^",
|
||||
KeyF32: "\x1b[21^",
|
||||
KeyF33: "\x1b[23^",
|
||||
KeyF34: "\x1b[24^",
|
||||
KeyF35: "\x1b[25^",
|
||||
KeyF36: "\x1b[26^",
|
||||
KeyF37: "\x1b[28^",
|
||||
KeyF38: "\x1b[29^",
|
||||
KeyF39: "\x1b[31^",
|
||||
KeyF40: "\x1b[32^",
|
||||
KeyF41: "\x1b[33^",
|
||||
KeyF42: "\x1b[34^",
|
||||
KeyF43: "\x1b[23@",
|
||||
KeyF44: "\x1b[24@",
|
||||
KeyBacktab: "\x1b[Z",
|
||||
KeyShfLeft: "\x1b[d",
|
||||
KeyShfRight: "\x1b[c",
|
||||
KeyShfUp: "\x1b[a",
|
||||
KeyShfDown: "\x1b[b",
|
||||
KeyShfHome: "\x1b[7$",
|
||||
KeyShfEnd: "\x1b[8$",
|
||||
KeyShfInsert: "\x1b[2$",
|
||||
KeyShfDelete: "\x1b[3$",
|
||||
KeyCtrlUp: "\x1b[Oa",
|
||||
KeyCtrlDown: "\x1b[Ob",
|
||||
KeyCtrlRight: "\x1b[Oc",
|
||||
KeyCtrlLeft: "\x1b[Od",
|
||||
KeyCtrlHome: "\x1b[7^",
|
||||
KeyCtrlEnd: "\x1b[8^",
|
||||
AutoMargin: true,
|
||||
XTermLike: true,
|
||||
Name: "rxvt-88color",
|
||||
Columns: 80,
|
||||
Lines: 24,
|
||||
Colors: 88,
|
||||
Clear: "\x1b[H\x1b[2J",
|
||||
EnterCA: "\x1b7\x1b[?47h",
|
||||
ExitCA: "\x1b[2J\x1b[?47l\x1b8",
|
||||
ShowCursor: "\x1b[?25h",
|
||||
HideCursor: "\x1b[?25l",
|
||||
AttrOff: "\x1b[m\x0f",
|
||||
Underline: "\x1b[4m",
|
||||
Bold: "\x1b[1m",
|
||||
Blink: "\x1b[5m",
|
||||
Reverse: "\x1b[7m",
|
||||
EnterKeypad: "\x1b=",
|
||||
ExitKeypad: "\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",
|
||||
PadChar: "\x00",
|
||||
AltChars: "``aaffggjjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~",
|
||||
EnterAcs: "\x0e",
|
||||
ExitAcs: "\x0f",
|
||||
EnableAcs: "\x1b(B\x1b)0",
|
||||
Mouse: "\x1b[M",
|
||||
SetCursor: "\x1b[%i%p1%d;%p2%dH",
|
||||
AutoMargin: true,
|
||||
XTermLike: true,
|
||||
})
|
||||
|
||||
// rxvt-unicode terminal (X Window System)
|
||||
@@ -331,7 +112,6 @@ func init() {
|
||||
Columns: 80,
|
||||
Lines: 24,
|
||||
Colors: 88,
|
||||
Bell: "\a",
|
||||
Clear: "\x1b[H\x1b[2J",
|
||||
EnterCA: "\x1b[?1049h",
|
||||
ExitCA: "\x1b[r\x1b[?1049l",
|
||||
@@ -356,54 +136,6 @@ func init() {
|
||||
DisableAutoMargin: "\x1b[?7l",
|
||||
Mouse: "\x1b[M",
|
||||
SetCursor: "\x1b[%i%p1%d;%p2%dH",
|
||||
CursorBack1: "\b",
|
||||
CursorUp1: "\x1b[A",
|
||||
KeyUp: "\x1b[A",
|
||||
KeyDown: "\x1b[B",
|
||||
KeyRight: "\x1b[C",
|
||||
KeyLeft: "\x1b[D",
|
||||
KeyInsert: "\x1b[2~",
|
||||
KeyDelete: "\x1b[3~",
|
||||
KeyBackspace: "\x7f",
|
||||
KeyHome: "\x1b[7~",
|
||||
KeyEnd: "\x1b[8~",
|
||||
KeyPgUp: "\x1b[5~",
|
||||
KeyPgDn: "\x1b[6~",
|
||||
KeyF1: "\x1b[11~",
|
||||
KeyF2: "\x1b[12~",
|
||||
KeyF3: "\x1b[13~",
|
||||
KeyF4: "\x1b[14~",
|
||||
KeyF5: "\x1b[15~",
|
||||
KeyF6: "\x1b[17~",
|
||||
KeyF7: "\x1b[18~",
|
||||
KeyF8: "\x1b[19~",
|
||||
KeyF9: "\x1b[20~",
|
||||
KeyF10: "\x1b[21~",
|
||||
KeyF11: "\x1b[23~",
|
||||
KeyF12: "\x1b[24~",
|
||||
KeyF13: "\x1b[25~",
|
||||
KeyF14: "\x1b[26~",
|
||||
KeyF15: "\x1b[28~",
|
||||
KeyF16: "\x1b[29~",
|
||||
KeyF17: "\x1b[31~",
|
||||
KeyF18: "\x1b[32~",
|
||||
KeyF19: "\x1b[33~",
|
||||
KeyF20: "\x1b[34~",
|
||||
KeyBacktab: "\x1b[Z",
|
||||
KeyShfLeft: "\x1b[d",
|
||||
KeyShfRight: "\x1b[c",
|
||||
KeyShfUp: "\x1b[a",
|
||||
KeyShfDown: "\x1b[b",
|
||||
KeyShfHome: "\x1b[7$",
|
||||
KeyShfEnd: "\x1b[8$",
|
||||
KeyShfInsert: "\x1b[2$",
|
||||
KeyShfDelete: "\x1b[3$",
|
||||
KeyCtrlUp: "\x1b[Oa",
|
||||
KeyCtrlDown: "\x1b[Ob",
|
||||
KeyCtrlRight: "\x1b[Oc",
|
||||
KeyCtrlLeft: "\x1b[Od",
|
||||
KeyCtrlHome: "\x1b[7^",
|
||||
KeyCtrlEnd: "\x1b[8^",
|
||||
AutoMargin: true,
|
||||
InsertChar: "\x1b[@",
|
||||
})
|
||||
@@ -414,7 +146,6 @@ func init() {
|
||||
Columns: 80,
|
||||
Lines: 24,
|
||||
Colors: 256,
|
||||
Bell: "\a",
|
||||
Clear: "\x1b[H\x1b[2J",
|
||||
EnterCA: "\x1b[?1049h",
|
||||
ExitCA: "\x1b[r\x1b[?1049l",
|
||||
@@ -439,54 +170,6 @@ func init() {
|
||||
DisableAutoMargin: "\x1b[?7l",
|
||||
Mouse: "\x1b[M",
|
||||
SetCursor: "\x1b[%i%p1%d;%p2%dH",
|
||||
CursorBack1: "\b",
|
||||
CursorUp1: "\x1b[A",
|
||||
KeyUp: "\x1b[A",
|
||||
KeyDown: "\x1b[B",
|
||||
KeyRight: "\x1b[C",
|
||||
KeyLeft: "\x1b[D",
|
||||
KeyInsert: "\x1b[2~",
|
||||
KeyDelete: "\x1b[3~",
|
||||
KeyBackspace: "\x7f",
|
||||
KeyHome: "\x1b[7~",
|
||||
KeyEnd: "\x1b[8~",
|
||||
KeyPgUp: "\x1b[5~",
|
||||
KeyPgDn: "\x1b[6~",
|
||||
KeyF1: "\x1b[11~",
|
||||
KeyF2: "\x1b[12~",
|
||||
KeyF3: "\x1b[13~",
|
||||
KeyF4: "\x1b[14~",
|
||||
KeyF5: "\x1b[15~",
|
||||
KeyF6: "\x1b[17~",
|
||||
KeyF7: "\x1b[18~",
|
||||
KeyF8: "\x1b[19~",
|
||||
KeyF9: "\x1b[20~",
|
||||
KeyF10: "\x1b[21~",
|
||||
KeyF11: "\x1b[23~",
|
||||
KeyF12: "\x1b[24~",
|
||||
KeyF13: "\x1b[25~",
|
||||
KeyF14: "\x1b[26~",
|
||||
KeyF15: "\x1b[28~",
|
||||
KeyF16: "\x1b[29~",
|
||||
KeyF17: "\x1b[31~",
|
||||
KeyF18: "\x1b[32~",
|
||||
KeyF19: "\x1b[33~",
|
||||
KeyF20: "\x1b[34~",
|
||||
KeyBacktab: "\x1b[Z",
|
||||
KeyShfLeft: "\x1b[d",
|
||||
KeyShfRight: "\x1b[c",
|
||||
KeyShfUp: "\x1b[a",
|
||||
KeyShfDown: "\x1b[b",
|
||||
KeyShfHome: "\x1b[7$",
|
||||
KeyShfEnd: "\x1b[8$",
|
||||
KeyShfInsert: "\x1b[2$",
|
||||
KeyShfDelete: "\x1b[3$",
|
||||
KeyCtrlUp: "\x1b[Oa",
|
||||
KeyCtrlDown: "\x1b[Ob",
|
||||
KeyCtrlRight: "\x1b[Oc",
|
||||
KeyCtrlLeft: "\x1b[Od",
|
||||
KeyCtrlHome: "\x1b[7^",
|
||||
KeyCtrlEnd: "\x1b[8^",
|
||||
AutoMargin: true,
|
||||
InsertChar: "\x1b[@",
|
||||
})
|
||||
|
||||
170
vendor/github.com/gdamore/tcell/v2/terminfo/s/screen/term.go
generated
vendored
170
vendor/github.com/gdamore/tcell/v2/terminfo/s/screen/term.go
generated
vendored
@@ -8,121 +8,67 @@ func init() {
|
||||
|
||||
// VT 100/ANSI X3.64 virtual terminal
|
||||
terminfo.AddTerminfo(&terminfo.Terminfo{
|
||||
Name: "screen",
|
||||
Columns: 80,
|
||||
Lines: 24,
|
||||
Colors: 8,
|
||||
Bell: "\a",
|
||||
Clear: "\x1b[H\x1b[J",
|
||||
EnterCA: "\x1b[?1049h",
|
||||
ExitCA: "\x1b[?1049l",
|
||||
ShowCursor: "\x1b[34h\x1b[?25h",
|
||||
HideCursor: "\x1b[?25l",
|
||||
AttrOff: "\x1b[m\x0f",
|
||||
Underline: "\x1b[4m",
|
||||
Bold: "\x1b[1m",
|
||||
Dim: "\x1b[2m",
|
||||
Blink: "\x1b[5m",
|
||||
Reverse: "\x1b[7m",
|
||||
EnterKeypad: "\x1b[?1h\x1b=",
|
||||
ExitKeypad: "\x1b[?1l\x1b>",
|
||||
SetFg: "\x1b[3%p1%dm",
|
||||
SetBg: "\x1b[4%p1%dm",
|
||||
SetFgBg: "\x1b[3%p1%d;4%p2%dm",
|
||||
ResetFgBg: "\x1b[39;49m",
|
||||
PadChar: "\x00",
|
||||
AltChars: "++,,--..00``aaffgghhiijjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~",
|
||||
EnterAcs: "\x0e",
|
||||
ExitAcs: "\x0f",
|
||||
EnableAcs: "\x1b(B\x1b)0",
|
||||
Mouse: "\x1b[M",
|
||||
SetCursor: "\x1b[%i%p1%d;%p2%dH",
|
||||
CursorBack1: "\b",
|
||||
CursorUp1: "\x1bM",
|
||||
KeyUp: "\x1bOA",
|
||||
KeyDown: "\x1bOB",
|
||||
KeyRight: "\x1bOC",
|
||||
KeyLeft: "\x1bOD",
|
||||
KeyInsert: "\x1b[2~",
|
||||
KeyDelete: "\x1b[3~",
|
||||
KeyBackspace: "\x7f",
|
||||
KeyHome: "\x1b[1~",
|
||||
KeyEnd: "\x1b[4~",
|
||||
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",
|
||||
AutoMargin: true,
|
||||
Name: "screen",
|
||||
Columns: 80,
|
||||
Lines: 24,
|
||||
Colors: 8,
|
||||
Clear: "\x1b[H\x1b[J",
|
||||
EnterCA: "\x1b[?1049h",
|
||||
ExitCA: "\x1b[?1049l",
|
||||
ShowCursor: "\x1b[34h\x1b[?25h",
|
||||
HideCursor: "\x1b[?25l",
|
||||
AttrOff: "\x1b[m\x0f",
|
||||
Underline: "\x1b[4m",
|
||||
Bold: "\x1b[1m",
|
||||
Dim: "\x1b[2m",
|
||||
Blink: "\x1b[5m",
|
||||
Reverse: "\x1b[7m",
|
||||
EnterKeypad: "\x1b[?1h\x1b=",
|
||||
ExitKeypad: "\x1b[?1l\x1b>",
|
||||
SetFg: "\x1b[3%p1%dm",
|
||||
SetBg: "\x1b[4%p1%dm",
|
||||
SetFgBg: "\x1b[3%p1%d;4%p2%dm",
|
||||
ResetFgBg: "\x1b[39;49m",
|
||||
PadChar: "\x00",
|
||||
AltChars: "++,,--..00``aaffgghhiijjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~",
|
||||
EnterAcs: "\x0e",
|
||||
ExitAcs: "\x0f",
|
||||
EnableAcs: "\x1b(B\x1b)0",
|
||||
Mouse: "\x1b[M",
|
||||
SetCursor: "\x1b[%i%p1%d;%p2%dH",
|
||||
AutoMargin: true,
|
||||
})
|
||||
|
||||
// GNU Screen with 256 colors
|
||||
terminfo.AddTerminfo(&terminfo.Terminfo{
|
||||
Name: "screen-256color",
|
||||
Columns: 80,
|
||||
Lines: 24,
|
||||
Colors: 256,
|
||||
Bell: "\a",
|
||||
Clear: "\x1b[H\x1b[J",
|
||||
EnterCA: "\x1b[?1049h",
|
||||
ExitCA: "\x1b[?1049l",
|
||||
ShowCursor: "\x1b[34h\x1b[?25h",
|
||||
HideCursor: "\x1b[?25l",
|
||||
AttrOff: "\x1b[m\x0f",
|
||||
Underline: "\x1b[4m",
|
||||
Bold: "\x1b[1m",
|
||||
Dim: "\x1b[2m",
|
||||
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",
|
||||
PadChar: "\x00",
|
||||
AltChars: "++,,--..00``aaffgghhiijjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~",
|
||||
EnterAcs: "\x0e",
|
||||
ExitAcs: "\x0f",
|
||||
EnableAcs: "\x1b(B\x1b)0",
|
||||
Mouse: "\x1b[M",
|
||||
SetCursor: "\x1b[%i%p1%d;%p2%dH",
|
||||
CursorBack1: "\b",
|
||||
CursorUp1: "\x1bM",
|
||||
KeyUp: "\x1bOA",
|
||||
KeyDown: "\x1bOB",
|
||||
KeyRight: "\x1bOC",
|
||||
KeyLeft: "\x1bOD",
|
||||
KeyInsert: "\x1b[2~",
|
||||
KeyDelete: "\x1b[3~",
|
||||
KeyBackspace: "\x7f",
|
||||
KeyHome: "\x1b[1~",
|
||||
KeyEnd: "\x1b[4~",
|
||||
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",
|
||||
AutoMargin: true,
|
||||
Name: "screen-256color",
|
||||
Columns: 80,
|
||||
Lines: 24,
|
||||
Colors: 256,
|
||||
Clear: "\x1b[H\x1b[J",
|
||||
EnterCA: "\x1b[?1049h",
|
||||
ExitCA: "\x1b[?1049l",
|
||||
ShowCursor: "\x1b[34h\x1b[?25h",
|
||||
HideCursor: "\x1b[?25l",
|
||||
AttrOff: "\x1b[m\x0f",
|
||||
Underline: "\x1b[4m",
|
||||
Bold: "\x1b[1m",
|
||||
Dim: "\x1b[2m",
|
||||
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",
|
||||
PadChar: "\x00",
|
||||
AltChars: "++,,--..00``aaffgghhiijjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~",
|
||||
EnterAcs: "\x0e",
|
||||
ExitAcs: "\x0f",
|
||||
EnableAcs: "\x1b(B\x1b)0",
|
||||
Mouse: "\x1b[M",
|
||||
SetCursor: "\x1b[%i%p1%d;%p2%dH",
|
||||
AutoMargin: true,
|
||||
})
|
||||
}
|
||||
|
||||
56
vendor/github.com/gdamore/tcell/v2/terminfo/s/simpleterm/term.go
generated
vendored
56
vendor/github.com/gdamore/tcell/v2/terminfo/s/simpleterm/term.go
generated
vendored
@@ -13,7 +13,6 @@ func init() {
|
||||
Columns: 80,
|
||||
Lines: 24,
|
||||
Colors: 8,
|
||||
Bell: "\a",
|
||||
Clear: "\x1b[H\x1b[2J",
|
||||
EnterCA: "\x1b[?1049h",
|
||||
ExitCA: "\x1b[?1049l",
|
||||
@@ -39,33 +38,6 @@ func init() {
|
||||
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: "\x1b[1~",
|
||||
KeyEnd: "\x1b[4~",
|
||||
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~",
|
||||
KeyClear: "\x1b[3;5~",
|
||||
Modifiers: 1,
|
||||
AutoMargin: true,
|
||||
XTermLike: true,
|
||||
})
|
||||
@@ -77,7 +49,6 @@ func init() {
|
||||
Columns: 80,
|
||||
Lines: 24,
|
||||
Colors: 256,
|
||||
Bell: "\a",
|
||||
Clear: "\x1b[H\x1b[2J",
|
||||
EnterCA: "\x1b[?1049h",
|
||||
ExitCA: "\x1b[?1049l",
|
||||
@@ -103,33 +74,6 @@ func init() {
|
||||
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: "\x1b[1~",
|
||||
KeyEnd: "\x1b[4~",
|
||||
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~",
|
||||
KeyClear: "\x1b[3;5~",
|
||||
Modifiers: 1,
|
||||
AutoMargin: true,
|
||||
XTermLike: true,
|
||||
})
|
||||
|
||||
104
vendor/github.com/gdamore/tcell/v2/terminfo/s/sun/term.go
generated
vendored
104
vendor/github.com/gdamore/tcell/v2/terminfo/s/sun/term.go
generated
vendored
@@ -26,87 +26,35 @@ func init() {
|
||||
|
||||
// Sun Microsystems Inc. workstation console
|
||||
terminfo.AddTerminfo(&terminfo.Terminfo{
|
||||
Name: "sun",
|
||||
Aliases: []string{"sun1", "sun2"},
|
||||
Columns: 80,
|
||||
Lines: 34,
|
||||
Bell: "\a",
|
||||
Clear: "\f",
|
||||
AttrOff: "\x1b[m",
|
||||
Reverse: "\x1b[7m",
|
||||
PadChar: "\x00",
|
||||
SetCursor: "\x1b[%i%p1%d;%p2%dH",
|
||||
CursorBack1: "\b",
|
||||
CursorUp1: "\x1b[A",
|
||||
KeyUp: "\x1b[A",
|
||||
KeyDown: "\x1b[B",
|
||||
KeyRight: "\x1b[C",
|
||||
KeyLeft: "\x1b[D",
|
||||
KeyInsert: "\x1b[247z",
|
||||
KeyDelete: "\u007f",
|
||||
KeyBackspace: "\b",
|
||||
KeyHome: "\x1b[214z",
|
||||
KeyEnd: "\x1b[220z",
|
||||
KeyPgUp: "\x1b[216z",
|
||||
KeyPgDn: "\x1b[222z",
|
||||
KeyF1: "\x1b[224z",
|
||||
KeyF2: "\x1b[225z",
|
||||
KeyF3: "\x1b[226z",
|
||||
KeyF4: "\x1b[227z",
|
||||
KeyF5: "\x1b[228z",
|
||||
KeyF6: "\x1b[229z",
|
||||
KeyF7: "\x1b[230z",
|
||||
KeyF8: "\x1b[231z",
|
||||
KeyF9: "\x1b[232z",
|
||||
KeyF10: "\x1b[233z",
|
||||
KeyF11: "\x1b[234z",
|
||||
KeyF12: "\x1b[235z",
|
||||
AutoMargin: true,
|
||||
InsertChar: "\x1b[@",
|
||||
Name: "sun",
|
||||
Aliases: []string{"sun1", "sun2"},
|
||||
Columns: 80,
|
||||
Lines: 34,
|
||||
Clear: "\f",
|
||||
AttrOff: "\x1b[m",
|
||||
Reverse: "\x1b[7m",
|
||||
PadChar: "\x00",
|
||||
SetCursor: "\x1b[%i%p1%d;%p2%dH",
|
||||
AutoMargin: true,
|
||||
InsertChar: "\x1b[@",
|
||||
})
|
||||
|
||||
// Sun Microsystems Workstation console with color support (IA systems)
|
||||
terminfo.AddTerminfo(&terminfo.Terminfo{
|
||||
Name: "sun-color",
|
||||
Columns: 80,
|
||||
Lines: 34,
|
||||
Colors: 256,
|
||||
Bell: "\a",
|
||||
Clear: "\f",
|
||||
AttrOff: "\x1b[m",
|
||||
Bold: "\x1b[1m",
|
||||
Reverse: "\x1b[7m",
|
||||
SetFg: "\x1b[38;5;%p1%dm",
|
||||
SetBg: "\x1b[48;5;%p1%dm",
|
||||
ResetFgBg: "\x1b[0m",
|
||||
PadChar: "\x00",
|
||||
SetCursor: "\x1b[%i%p1%d;%p2%dH",
|
||||
CursorBack1: "\b",
|
||||
CursorUp1: "\x1b[A",
|
||||
KeyUp: "\x1b[A",
|
||||
KeyDown: "\x1b[B",
|
||||
KeyRight: "\x1b[C",
|
||||
KeyLeft: "\x1b[D",
|
||||
KeyInsert: "\x1b[247z",
|
||||
KeyDelete: "\u007f",
|
||||
KeyBackspace: "\b",
|
||||
KeyHome: "\x1b[214z",
|
||||
KeyEnd: "\x1b[220z",
|
||||
KeyPgUp: "\x1b[216z",
|
||||
KeyPgDn: "\x1b[222z",
|
||||
KeyF1: "\x1b[224z",
|
||||
KeyF2: "\x1b[225z",
|
||||
KeyF3: "\x1b[226z",
|
||||
KeyF4: "\x1b[227z",
|
||||
KeyF5: "\x1b[228z",
|
||||
KeyF6: "\x1b[229z",
|
||||
KeyF7: "\x1b[230z",
|
||||
KeyF8: "\x1b[231z",
|
||||
KeyF9: "\x1b[232z",
|
||||
KeyF10: "\x1b[233z",
|
||||
KeyF11: "\x1b[234z",
|
||||
KeyF12: "\x1b[235z",
|
||||
AutoMargin: true,
|
||||
InsertChar: "\x1b[@",
|
||||
Name: "sun-color",
|
||||
Columns: 80,
|
||||
Lines: 34,
|
||||
Colors: 256,
|
||||
Clear: "\f",
|
||||
AttrOff: "\x1b[m",
|
||||
Bold: "\x1b[1m",
|
||||
Reverse: "\x1b[7m",
|
||||
SetFg: "\x1b[38;5;%p1%dm",
|
||||
SetBg: "\x1b[48;5;%p1%dm",
|
||||
ResetFgBg: "\x1b[0m",
|
||||
PadChar: "\x00",
|
||||
SetCursor: "\x1b[%i%p1%d;%p2%dH",
|
||||
AutoMargin: true,
|
||||
InsertChar: "\x1b[@",
|
||||
})
|
||||
}
|
||||
|
||||
190
vendor/github.com/gdamore/tcell/v2/terminfo/t/tmux/term.go
generated
vendored
190
vendor/github.com/gdamore/tcell/v2/terminfo/t/tmux/term.go
generated
vendored
@@ -8,135 +8,73 @@ func init() {
|
||||
|
||||
// tmux terminal multiplexer
|
||||
terminfo.AddTerminfo(&terminfo.Terminfo{
|
||||
Name: "tmux",
|
||||
Columns: 80,
|
||||
Lines: 24,
|
||||
Colors: 8,
|
||||
Bell: "\a",
|
||||
Clear: "\x1b[H\x1b[J",
|
||||
EnterCA: "\x1b[?1049h",
|
||||
ExitCA: "\x1b[?1049l",
|
||||
ShowCursor: "\x1b[34h\x1b[?25h",
|
||||
HideCursor: "\x1b[?25l",
|
||||
AttrOff: "\x1b[m\x0f",
|
||||
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[3%p1%dm",
|
||||
SetBg: "\x1b[4%p1%dm",
|
||||
SetFgBg: "\x1b[3%p1%d;4%p2%dm",
|
||||
ResetFgBg: "\x1b[39;49m",
|
||||
PadChar: "\x00",
|
||||
AltChars: "++,,--..00``aaffgghhiijjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~",
|
||||
EnterAcs: "\x0e",
|
||||
ExitAcs: "\x0f",
|
||||
EnableAcs: "\x1b(B\x1b)0",
|
||||
StrikeThrough: "\x1b[9m",
|
||||
Mouse: "\x1b[M",
|
||||
SetCursor: "\x1b[%i%p1%d;%p2%dH",
|
||||
CursorBack1: "\b",
|
||||
CursorUp1: "\x1bM",
|
||||
KeyUp: "\x1bOA",
|
||||
KeyDown: "\x1bOB",
|
||||
KeyRight: "\x1bOC",
|
||||
KeyLeft: "\x1bOD",
|
||||
KeyInsert: "\x1b[2~",
|
||||
KeyDelete: "\x1b[3~",
|
||||
KeyBackspace: "\x7f",
|
||||
KeyHome: "\x1b[1~",
|
||||
KeyEnd: "\x1b[4~",
|
||||
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,
|
||||
DoubleUnderline: "\x1b[4:2m",
|
||||
CurlyUnderline: "\x1b[4:3m",
|
||||
DottedUnderline: "\x1b[4:4m",
|
||||
DashedUnderline: "\x1b[4:5m",
|
||||
Name: "tmux",
|
||||
Columns: 80,
|
||||
Lines: 24,
|
||||
Colors: 8,
|
||||
Clear: "\x1b[H\x1b[J",
|
||||
EnterCA: "\x1b[?1049h",
|
||||
ExitCA: "\x1b[?1049l",
|
||||
ShowCursor: "\x1b[34h\x1b[?25h",
|
||||
HideCursor: "\x1b[?25l",
|
||||
AttrOff: "\x1b[m\x0f",
|
||||
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[3%p1%dm",
|
||||
SetBg: "\x1b[4%p1%dm",
|
||||
SetFgBg: "\x1b[3%p1%d;4%p2%dm",
|
||||
ResetFgBg: "\x1b[39;49m",
|
||||
PadChar: "\x00",
|
||||
AltChars: "++,,--..00``aaffgghhiijjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~",
|
||||
EnterAcs: "\x0e",
|
||||
ExitAcs: "\x0f",
|
||||
EnableAcs: "\x1b(B\x1b)0",
|
||||
StrikeThrough: "\x1b[9m",
|
||||
Mouse: "\x1b[M",
|
||||
SetCursor: "\x1b[%i%p1%d;%p2%dH",
|
||||
AutoMargin: true,
|
||||
XTermLike: true,
|
||||
})
|
||||
|
||||
// tmux with 256 colors
|
||||
terminfo.AddTerminfo(&terminfo.Terminfo{
|
||||
Name: "tmux-256color",
|
||||
Columns: 80,
|
||||
Lines: 24,
|
||||
Colors: 256,
|
||||
Bell: "\a",
|
||||
Clear: "\x1b[H\x1b[J",
|
||||
EnterCA: "\x1b[?1049h",
|
||||
ExitCA: "\x1b[?1049l",
|
||||
ShowCursor: "\x1b[34h\x1b[?25h",
|
||||
HideCursor: "\x1b[?25l",
|
||||
AttrOff: "\x1b[m\x0f",
|
||||
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",
|
||||
PadChar: "\x00",
|
||||
AltChars: "++,,--..00``aaffgghhiijjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~",
|
||||
EnterAcs: "\x0e",
|
||||
ExitAcs: "\x0f",
|
||||
EnableAcs: "\x1b(B\x1b)0",
|
||||
StrikeThrough: "\x1b[9m",
|
||||
Mouse: "\x1b[M",
|
||||
SetCursor: "\x1b[%i%p1%d;%p2%dH",
|
||||
CursorBack1: "\b",
|
||||
CursorUp1: "\x1bM",
|
||||
KeyUp: "\x1bOA",
|
||||
KeyDown: "\x1bOB",
|
||||
KeyRight: "\x1bOC",
|
||||
KeyLeft: "\x1bOD",
|
||||
KeyInsert: "\x1b[2~",
|
||||
KeyDelete: "\x1b[3~",
|
||||
KeyBackspace: "\x7f",
|
||||
KeyHome: "\x1b[1~",
|
||||
KeyEnd: "\x1b[4~",
|
||||
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,
|
||||
DoubleUnderline: "\x1b[4:2m",
|
||||
CurlyUnderline: "\x1b[4:3m",
|
||||
DottedUnderline: "\x1b[4:4m",
|
||||
DashedUnderline: "\x1b[4:5m",
|
||||
Name: "tmux-256color",
|
||||
Columns: 80,
|
||||
Lines: 24,
|
||||
Colors: 256,
|
||||
Clear: "\x1b[H\x1b[J",
|
||||
EnterCA: "\x1b[?1049h",
|
||||
ExitCA: "\x1b[?1049l",
|
||||
ShowCursor: "\x1b[34h\x1b[?25h",
|
||||
HideCursor: "\x1b[?25l",
|
||||
AttrOff: "\x1b[m\x0f",
|
||||
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",
|
||||
PadChar: "\x00",
|
||||
AltChars: "++,,--..00``aaffgghhiijjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~",
|
||||
EnterAcs: "\x0e",
|
||||
ExitAcs: "\x0f",
|
||||
EnableAcs: "\x1b(B\x1b)0",
|
||||
StrikeThrough: "\x1b[9m",
|
||||
Mouse: "\x1b[M",
|
||||
SetCursor: "\x1b[%i%p1%d;%p2%dH",
|
||||
AutoMargin: true,
|
||||
XTermLike: true,
|
||||
})
|
||||
}
|
||||
|
||||
263
vendor/github.com/gdamore/tcell/v2/terminfo/terminfo.go
generated
vendored
263
vendor/github.com/gdamore/tcell/v2/terminfo/terminfo.go
generated
vendored
@@ -1,4 +1,4 @@
|
||||
// Copyright 2024 The TCell Authors
|
||||
// Copyright 2025 The TCell Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use file except in compliance with the License.
|
||||
@@ -41,125 +41,35 @@ var (
|
||||
// in Go, but when we write out JSON, we use the same names as terminfo.
|
||||
// The name, aliases and smous, rmous fields do not come from terminfo directly.
|
||||
type Terminfo struct {
|
||||
Name string
|
||||
Aliases []string
|
||||
Columns int // cols
|
||||
Lines int // lines
|
||||
Colors int // colors
|
||||
Bell string // bell
|
||||
Clear string // clear
|
||||
EnterCA string // smcup
|
||||
ExitCA string // rmcup
|
||||
ShowCursor string // cnorm
|
||||
HideCursor string // civis
|
||||
AttrOff string // sgr0
|
||||
Underline string // smul
|
||||
Bold string // bold
|
||||
Blink string // blink
|
||||
Reverse string // rev
|
||||
Dim string // dim
|
||||
Italic string // sitm
|
||||
EnterKeypad string // smkx
|
||||
ExitKeypad string // rmkx
|
||||
SetFg string // setaf
|
||||
SetBg string // setab
|
||||
ResetFgBg string // op
|
||||
SetCursor string // cup
|
||||
CursorBack1 string // cub1
|
||||
CursorUp1 string // cuu1
|
||||
PadChar string // pad
|
||||
KeyBackspace string // kbs
|
||||
KeyF1 string // kf1
|
||||
KeyF2 string // kf2
|
||||
KeyF3 string // kf3
|
||||
KeyF4 string // kf4
|
||||
KeyF5 string // kf5
|
||||
KeyF6 string // kf6
|
||||
KeyF7 string // kf7
|
||||
KeyF8 string // kf8
|
||||
KeyF9 string // kf9
|
||||
KeyF10 string // kf10
|
||||
KeyF11 string // kf11
|
||||
KeyF12 string // kf12
|
||||
KeyF13 string // kf13
|
||||
KeyF14 string // kf14
|
||||
KeyF15 string // kf15
|
||||
KeyF16 string // kf16
|
||||
KeyF17 string // kf17
|
||||
KeyF18 string // kf18
|
||||
KeyF19 string // kf19
|
||||
KeyF20 string // kf20
|
||||
KeyF21 string // kf21
|
||||
KeyF22 string // kf22
|
||||
KeyF23 string // kf23
|
||||
KeyF24 string // kf24
|
||||
KeyF25 string // kf25
|
||||
KeyF26 string // kf26
|
||||
KeyF27 string // kf27
|
||||
KeyF28 string // kf28
|
||||
KeyF29 string // kf29
|
||||
KeyF30 string // kf30
|
||||
KeyF31 string // kf31
|
||||
KeyF32 string // kf32
|
||||
KeyF33 string // kf33
|
||||
KeyF34 string // kf34
|
||||
KeyF35 string // kf35
|
||||
KeyF36 string // kf36
|
||||
KeyF37 string // kf37
|
||||
KeyF38 string // kf38
|
||||
KeyF39 string // kf39
|
||||
KeyF40 string // kf40
|
||||
KeyF41 string // kf41
|
||||
KeyF42 string // kf42
|
||||
KeyF43 string // kf43
|
||||
KeyF44 string // kf44
|
||||
KeyF45 string // kf45
|
||||
KeyF46 string // kf46
|
||||
KeyF47 string // kf47
|
||||
KeyF48 string // kf48
|
||||
KeyF49 string // kf49
|
||||
KeyF50 string // kf50
|
||||
KeyF51 string // kf51
|
||||
KeyF52 string // kf52
|
||||
KeyF53 string // kf53
|
||||
KeyF54 string // kf54
|
||||
KeyF55 string // kf55
|
||||
KeyF56 string // kf56
|
||||
KeyF57 string // kf57
|
||||
KeyF58 string // kf58
|
||||
KeyF59 string // kf59
|
||||
KeyF60 string // kf60
|
||||
KeyF61 string // kf61
|
||||
KeyF62 string // kf62
|
||||
KeyF63 string // kf63
|
||||
KeyF64 string // kf64
|
||||
KeyInsert string // kich1
|
||||
KeyDelete string // kdch1
|
||||
KeyHome string // khome
|
||||
KeyEnd string // kend
|
||||
KeyHelp string // khlp
|
||||
KeyPgUp string // kpp
|
||||
KeyPgDn string // knp
|
||||
KeyUp string // kcuu1
|
||||
KeyDown string // kcud1
|
||||
KeyLeft string // kcub1
|
||||
KeyRight string // kcuf1
|
||||
KeyBacktab string // kcbt
|
||||
KeyExit string // kext
|
||||
KeyClear string // kclr
|
||||
KeyPrint string // kprt
|
||||
KeyCancel string // kcan
|
||||
Mouse string // kmous
|
||||
AltChars string // acsc
|
||||
EnterAcs string // smacs
|
||||
ExitAcs string // rmacs
|
||||
EnableAcs string // enacs
|
||||
KeyShfRight string // kRIT
|
||||
KeyShfLeft string // kLFT
|
||||
KeyShfHome string // kHOM
|
||||
KeyShfEnd string // kEND
|
||||
KeyShfInsert string // kIC
|
||||
KeyShfDelete string // kDC
|
||||
Name string
|
||||
Aliases []string
|
||||
Columns int // cols
|
||||
Lines int // lines
|
||||
Colors int // colors
|
||||
Clear string // clear
|
||||
EnterCA string // smcup
|
||||
ExitCA string // rmcup
|
||||
ShowCursor string // cnorm
|
||||
HideCursor string // civis
|
||||
AttrOff string // sgr0
|
||||
Underline string // smul
|
||||
Bold string // bold
|
||||
Blink string // blink
|
||||
Reverse string // rev
|
||||
Dim string // dim
|
||||
Italic string // sitm
|
||||
EnterKeypad string // smkx
|
||||
ExitKeypad string // rmkx
|
||||
SetFg string // setaf
|
||||
SetBg string // setab
|
||||
ResetFgBg string // op
|
||||
SetCursor string // cup
|
||||
PadChar string // pad
|
||||
Mouse string // kmous
|
||||
AltChars string // acsc
|
||||
EnterAcs string // smacs
|
||||
ExitAcs string // rmacs
|
||||
EnableAcs string // enacs
|
||||
|
||||
// These are non-standard extensions to terminfo. This includes
|
||||
// true color support, and some additional keys. Its kind of bizarre
|
||||
@@ -167,95 +77,22 @@ type Terminfo struct {
|
||||
// Terminal support for these are going to vary amongst XTerm
|
||||
// emulations, so don't depend too much on them in your application.
|
||||
|
||||
StrikeThrough string // smxx
|
||||
SetFgBg string // setfgbg
|
||||
SetFgBgRGB string // setfgbgrgb
|
||||
SetFgRGB string // setfrgb
|
||||
SetBgRGB string // setbrgb
|
||||
KeyShfUp string // shift-up
|
||||
KeyShfDown string // shift-down
|
||||
KeyShfPgUp string // shift-kpp
|
||||
KeyShfPgDn string // shift-knp
|
||||
KeyCtrlUp string // ctrl-up
|
||||
KeyCtrlDown string // ctrl-left
|
||||
KeyCtrlRight string // ctrl-right
|
||||
KeyCtrlLeft string // ctrl-left
|
||||
KeyMetaUp string // meta-up
|
||||
KeyMetaDown string // meta-left
|
||||
KeyMetaRight string // meta-right
|
||||
KeyMetaLeft string // meta-left
|
||||
KeyAltUp string // alt-up
|
||||
KeyAltDown string // alt-left
|
||||
KeyAltRight string // alt-right
|
||||
KeyAltLeft string // alt-left
|
||||
KeyCtrlHome string
|
||||
KeyCtrlEnd string
|
||||
KeyMetaHome string
|
||||
KeyMetaEnd string
|
||||
KeyAltHome string
|
||||
KeyAltEnd string
|
||||
KeyAltShfUp string
|
||||
KeyAltShfDown string
|
||||
KeyAltShfLeft string
|
||||
KeyAltShfRight string
|
||||
KeyMetaShfUp string
|
||||
KeyMetaShfDown string
|
||||
KeyMetaShfLeft string
|
||||
KeyMetaShfRight string
|
||||
KeyCtrlShfUp string
|
||||
KeyCtrlShfDown string
|
||||
KeyCtrlShfLeft string
|
||||
KeyCtrlShfRight string
|
||||
KeyCtrlShfHome string
|
||||
KeyCtrlShfEnd string
|
||||
KeyAltShfHome string
|
||||
KeyAltShfEnd string
|
||||
KeyMetaShfHome string
|
||||
KeyMetaShfEnd string
|
||||
EnablePaste string // bracketed paste mode
|
||||
DisablePaste string
|
||||
PasteStart string
|
||||
PasteEnd string
|
||||
Modifiers int
|
||||
InsertChar string // string to insert a character (ich1)
|
||||
AutoMargin bool // true if writing to last cell in line advances
|
||||
TrueColor bool // true if the terminal supports direct color
|
||||
CursorDefault string
|
||||
CursorBlinkingBlock string
|
||||
CursorSteadyBlock string
|
||||
CursorBlinkingUnderline string
|
||||
CursorSteadyUnderline string
|
||||
CursorBlinkingBar string
|
||||
CursorSteadyBar string
|
||||
CursorColor string // nothing uses it yet
|
||||
CursorColorRGB string // Cs (but not really because Cs uses X11 color string)
|
||||
CursorColorReset string // Cr
|
||||
EnterUrl string
|
||||
ExitUrl string
|
||||
SetWindowSize string
|
||||
SetWindowTitle string // no terminfo extension
|
||||
EnableFocusReporting string
|
||||
DisableFocusReporting string
|
||||
DisableAutoMargin string // smam
|
||||
EnableAutoMargin string // rmam
|
||||
DoubleUnderline string // Smulx with param 2
|
||||
CurlyUnderline string // Smulx with param 3
|
||||
DottedUnderline string // Smulx with param 4
|
||||
DashedUnderline string // Smulx with param 5
|
||||
UnderlineColor string // Setuc1
|
||||
UnderlineColorRGB string // Setulc
|
||||
UnderlineColorReset string // ol
|
||||
XTermLike bool // (XT) has XTerm extensions
|
||||
StrikeThrough string // smxx
|
||||
SetFgBg string // setfgbg
|
||||
SetFgBgRGB string // setfgbgrgb
|
||||
SetFgRGB string // setfrgb
|
||||
SetBgRGB string // setbrgb
|
||||
InsertChar string // string to insert a character (ich1)
|
||||
AutoMargin bool // true if writing to last cell in line advances
|
||||
TrueColor bool // true if the terminal supports direct color
|
||||
DisableAutoMargin string // smam
|
||||
EnableAutoMargin string // rmam
|
||||
XTermLike bool // (XT) has XTerm extensions
|
||||
}
|
||||
|
||||
const (
|
||||
ModifiersNone = 0
|
||||
ModifiersXTerm = 1
|
||||
)
|
||||
type stack []any
|
||||
|
||||
type stack []interface{}
|
||||
|
||||
func (st stack) Push(v interface{}) stack {
|
||||
func (st stack) Push(v any) stack {
|
||||
if b, ok := v.(bool); ok {
|
||||
if b {
|
||||
return append(st, 1)
|
||||
@@ -337,12 +174,12 @@ func (pb *paramsBuffer) PutString(s string) {
|
||||
// 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 {
|
||||
func (t *Terminfo) TParm(s string, p ...any) string {
|
||||
var stk stack
|
||||
var a string
|
||||
var ai, bi int
|
||||
var dvars [26]string
|
||||
var params [9]interface{}
|
||||
var params [9]any
|
||||
var pb = ¶msBuffer{}
|
||||
|
||||
pb.Start(s)
|
||||
@@ -682,6 +519,7 @@ var (
|
||||
// AddTerminfo can be called to register a new Terminfo entry.
|
||||
func AddTerminfo(t *Terminfo) {
|
||||
dblock.Lock()
|
||||
|
||||
terminfos[t.Name] = t
|
||||
for _, x := range t.Aliases {
|
||||
terminfos[x] = t
|
||||
@@ -777,5 +615,14 @@ func LookupTerminfo(name string) (*Terminfo, error) {
|
||||
t.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"
|
||||
t.ResetFgBg = "\x1b[39;49m"
|
||||
}
|
||||
|
||||
return t, nil
|
||||
}
|
||||
|
||||
func TerminfoNames() []string {
|
||||
res := make([]string, 0, len(terminfos))
|
||||
for m := range terminfos {
|
||||
res = append(res, m)
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
18
vendor/github.com/gdamore/tcell/v2/terminfo/v/vt100/term.go
generated
vendored
18
vendor/github.com/gdamore/tcell/v2/terminfo/v/vt100/term.go
generated
vendored
@@ -12,7 +12,6 @@ func init() {
|
||||
Aliases: []string{"vt100-am"},
|
||||
Columns: 80,
|
||||
Lines: 24,
|
||||
Bell: "\a",
|
||||
Clear: "\x1b[H\x1b[J$<50>",
|
||||
AttrOff: "\x1b[m\x0f$<2>",
|
||||
Underline: "\x1b[4m$<2>",
|
||||
@@ -29,23 +28,6 @@ func init() {
|
||||
EnableAutoMargin: "\x1b[?7h",
|
||||
DisableAutoMargin: "\x1b[?7l",
|
||||
SetCursor: "\x1b[%i%p1%d;%p2%dH$<5>",
|
||||
CursorBack1: "\b",
|
||||
CursorUp1: "\x1b[A$<2>",
|
||||
KeyUp: "\x1bOA",
|
||||
KeyDown: "\x1bOB",
|
||||
KeyRight: "\x1bOC",
|
||||
KeyLeft: "\x1bOD",
|
||||
KeyBackspace: "\b",
|
||||
KeyF1: "\x1bOP",
|
||||
KeyF2: "\x1bOQ",
|
||||
KeyF3: "\x1bOR",
|
||||
KeyF4: "\x1bOS",
|
||||
KeyF5: "\x1bOt",
|
||||
KeyF6: "\x1bOu",
|
||||
KeyF7: "\x1bOv",
|
||||
KeyF8: "\x1bOl",
|
||||
KeyF9: "\x1bOw",
|
||||
KeyF10: "\x1bOx",
|
||||
AutoMargin: true,
|
||||
})
|
||||
}
|
||||
|
||||
18
vendor/github.com/gdamore/tcell/v2/terminfo/v/vt102/term.go
generated
vendored
18
vendor/github.com/gdamore/tcell/v2/terminfo/v/vt102/term.go
generated
vendored
@@ -11,7 +11,6 @@ func init() {
|
||||
Name: "vt102",
|
||||
Columns: 80,
|
||||
Lines: 24,
|
||||
Bell: "\a",
|
||||
Clear: "\x1b[H\x1b[J$<50>",
|
||||
AttrOff: "\x1b[m\x0f$<2>",
|
||||
Underline: "\x1b[4m$<2>",
|
||||
@@ -28,23 +27,6 @@ func init() {
|
||||
EnableAutoMargin: "\x1b[?7h",
|
||||
DisableAutoMargin: "\x1b[?7l",
|
||||
SetCursor: "\x1b[%i%p1%d;%p2%dH$<5>",
|
||||
CursorBack1: "\b",
|
||||
CursorUp1: "\x1b[A$<2>",
|
||||
KeyUp: "\x1bOA",
|
||||
KeyDown: "\x1bOB",
|
||||
KeyRight: "\x1bOC",
|
||||
KeyLeft: "\x1bOD",
|
||||
KeyBackspace: "\b",
|
||||
KeyF1: "\x1bOP",
|
||||
KeyF2: "\x1bOQ",
|
||||
KeyF3: "\x1bOR",
|
||||
KeyF4: "\x1bOS",
|
||||
KeyF5: "\x1bOt",
|
||||
KeyF6: "\x1bOu",
|
||||
KeyF7: "\x1bOv",
|
||||
KeyF8: "\x1bOl",
|
||||
KeyF9: "\x1bOw",
|
||||
KeyF10: "\x1bOx",
|
||||
AutoMargin: true,
|
||||
})
|
||||
}
|
||||
|
||||
30
vendor/github.com/gdamore/tcell/v2/terminfo/v/vt220/term.go
generated
vendored
30
vendor/github.com/gdamore/tcell/v2/terminfo/v/vt220/term.go
generated
vendored
@@ -12,7 +12,6 @@ func init() {
|
||||
Aliases: []string{"vt200"},
|
||||
Columns: 80,
|
||||
Lines: 24,
|
||||
Bell: "\a",
|
||||
Clear: "\x1b[H\x1b[J",
|
||||
ShowCursor: "\x1b[?25h",
|
||||
HideCursor: "\x1b[?25l",
|
||||
@@ -29,35 +28,6 @@ func init() {
|
||||
EnableAutoMargin: "\x1b[?7h",
|
||||
DisableAutoMargin: "\x1b[?7l",
|
||||
SetCursor: "\x1b[%i%p1%d;%p2%dH",
|
||||
CursorBack1: "\b",
|
||||
CursorUp1: "\x1b[A",
|
||||
KeyUp: "\x1b[A",
|
||||
KeyDown: "\x1b[B",
|
||||
KeyRight: "\x1b[C",
|
||||
KeyLeft: "\x1b[D",
|
||||
KeyInsert: "\x1b[2~",
|
||||
KeyDelete: "\x1b[3~",
|
||||
KeyBackspace: "\b",
|
||||
KeyPgUp: "\x1b[5~",
|
||||
KeyPgDn: "\x1b[6~",
|
||||
KeyF1: "\x1bOP",
|
||||
KeyF2: "\x1bOQ",
|
||||
KeyF3: "\x1bOR",
|
||||
KeyF4: "\x1bOS",
|
||||
KeyF6: "\x1b[17~",
|
||||
KeyF7: "\x1b[18~",
|
||||
KeyF8: "\x1b[19~",
|
||||
KeyF9: "\x1b[20~",
|
||||
KeyF10: "\x1b[21~",
|
||||
KeyF11: "\x1b[23~",
|
||||
KeyF12: "\x1b[24~",
|
||||
KeyF13: "\x1b[25~",
|
||||
KeyF14: "\x1b[26~",
|
||||
KeyF17: "\x1b[31~",
|
||||
KeyF18: "\x1b[32~",
|
||||
KeyF19: "\x1b[33~",
|
||||
KeyF20: "\x1b[34~",
|
||||
KeyHelp: "\x1b[28~",
|
||||
AutoMargin: true,
|
||||
})
|
||||
}
|
||||
|
||||
32
vendor/github.com/gdamore/tcell/v2/terminfo/v/vt320/term.go
generated
vendored
32
vendor/github.com/gdamore/tcell/v2/terminfo/v/vt320/term.go
generated
vendored
@@ -12,7 +12,6 @@ func init() {
|
||||
Aliases: []string{"vt300"},
|
||||
Columns: 80,
|
||||
Lines: 24,
|
||||
Bell: "\a",
|
||||
Clear: "\x1b[H\x1b[2J",
|
||||
ShowCursor: "\x1b[?25h",
|
||||
HideCursor: "\x1b[?25l",
|
||||
@@ -30,37 +29,6 @@ func init() {
|
||||
EnableAutoMargin: "\x1b[?7h",
|
||||
DisableAutoMargin: "\x1b[?7l",
|
||||
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: "\x1b[1~",
|
||||
KeyPgUp: "\x1b[5~",
|
||||
KeyPgDn: "\x1b[6~",
|
||||
KeyF1: "\x1bOP",
|
||||
KeyF2: "\x1bOQ",
|
||||
KeyF3: "\x1bOR",
|
||||
KeyF4: "\x1bOS",
|
||||
KeyF6: "\x1b[17~",
|
||||
KeyF7: "\x1b[18~",
|
||||
KeyF8: "\x1b[19~",
|
||||
KeyF9: "\x1b[20~",
|
||||
KeyF10: "\x1b[21~",
|
||||
KeyF11: "\x1b[23~",
|
||||
KeyF12: "\x1b[24~",
|
||||
KeyF13: "\x1b[25~",
|
||||
KeyF14: "\x1b[26~",
|
||||
KeyF15: "\x1b[28~",
|
||||
KeyF16: "\x1b[29~",
|
||||
KeyF17: "\x1b[31~",
|
||||
KeyF18: "\x1b[32~",
|
||||
KeyF19: "\x1b[33~",
|
||||
KeyF20: "\x1b[34~",
|
||||
AutoMargin: true,
|
||||
})
|
||||
}
|
||||
|
||||
15
vendor/github.com/gdamore/tcell/v2/terminfo/v/vt400/term.go
generated
vendored
15
vendor/github.com/gdamore/tcell/v2/terminfo/v/vt400/term.go
generated
vendored
@@ -29,21 +29,6 @@ func init() {
|
||||
EnableAutoMargin: "\x1b[?7h",
|
||||
DisableAutoMargin: "\x1b[?7l",
|
||||
SetCursor: "\x1b[%i%p1%d;%p2%dH",
|
||||
CursorBack1: "\b",
|
||||
CursorUp1: "\x1b[A",
|
||||
KeyUp: "\x1bOA",
|
||||
KeyDown: "\x1bOB",
|
||||
KeyRight: "\x1bOC",
|
||||
KeyLeft: "\x1bOD",
|
||||
KeyBackspace: "\b",
|
||||
KeyF1: "\x1bOP",
|
||||
KeyF2: "\x1bOQ",
|
||||
KeyF3: "\x1bOR",
|
||||
KeyF4: "\x1bOS",
|
||||
KeyF6: "\x1b[17~",
|
||||
KeyF7: "\x1b[18~",
|
||||
KeyF8: "\x1b[19~",
|
||||
KeyF9: "\x1b[20~",
|
||||
AutoMargin: true,
|
||||
InsertChar: "\x1b[@",
|
||||
})
|
||||
|
||||
27
vendor/github.com/gdamore/tcell/v2/terminfo/v/vt420/term.go
generated
vendored
27
vendor/github.com/gdamore/tcell/v2/terminfo/v/vt420/term.go
generated
vendored
@@ -1,4 +1,7 @@
|
||||
// Generated automatically. DO NOT HAND-EDIT.
|
||||
// This file was originally generated automatically,
|
||||
// but it is edited to correct for errors in the VT420
|
||||
// terminfo data. Additionally we have added extended
|
||||
// information for the extended F-keys.
|
||||
|
||||
package vt420
|
||||
|
||||
@@ -11,7 +14,6 @@ func init() {
|
||||
Name: "vt420",
|
||||
Columns: 80,
|
||||
Lines: 24,
|
||||
Bell: "\a",
|
||||
Clear: "\x1b[H\x1b[2J$<50>",
|
||||
ShowCursor: "\x1b[?25h",
|
||||
HideCursor: "\x1b[?25l",
|
||||
@@ -30,27 +32,6 @@ func init() {
|
||||
EnableAutoMargin: "\x1b[?7h",
|
||||
DisableAutoMargin: "\x1b[?7l",
|
||||
SetCursor: "\x1b[%i%p1%d;%p2%dH$<10>",
|
||||
CursorBack1: "\b",
|
||||
CursorUp1: "\x1b[A",
|
||||
KeyUp: "\x1b[A",
|
||||
KeyDown: "\x1b[B",
|
||||
KeyRight: "\x1b[C",
|
||||
KeyLeft: "\x1b[D",
|
||||
KeyInsert: "\x1b[2~",
|
||||
KeyDelete: "\x1b[3~",
|
||||
KeyBackspace: "\b",
|
||||
KeyPgUp: "\x1b[5~",
|
||||
KeyPgDn: "\x1b[6~",
|
||||
KeyF1: "\x1bOP",
|
||||
KeyF2: "\x1bOQ",
|
||||
KeyF3: "\x1bOR",
|
||||
KeyF4: "\x1bOS",
|
||||
KeyF5: "\x1b[17~",
|
||||
KeyF6: "\x1b[18~",
|
||||
KeyF7: "\x1b[19~",
|
||||
KeyF8: "\x1b[20~",
|
||||
KeyF9: "\x1b[21~",
|
||||
KeyF10: "\x1b[29~",
|
||||
AutoMargin: true,
|
||||
})
|
||||
}
|
||||
|
||||
39
vendor/github.com/gdamore/tcell/v2/terminfo/v/vt52/term.go
generated
vendored
39
vendor/github.com/gdamore/tcell/v2/terminfo/v/vt52/term.go
generated
vendored
@@ -1,39 +0,0 @@
|
||||
// Generated automatically. DO NOT HAND-EDIT.
|
||||
|
||||
package vt52
|
||||
|
||||
import "github.com/gdamore/tcell/v2/terminfo"
|
||||
|
||||
func init() {
|
||||
|
||||
// DEC VT52
|
||||
terminfo.AddTerminfo(&terminfo.Terminfo{
|
||||
Name: "vt52",
|
||||
Columns: 80,
|
||||
Lines: 24,
|
||||
Bell: "\a",
|
||||
Clear: "\x1bH\x1bJ",
|
||||
EnterKeypad: "\x1b=",
|
||||
ExitKeypad: "\x1b>",
|
||||
PadChar: "\x00",
|
||||
AltChars: "+h.k0affggolpnqprrss",
|
||||
EnterAcs: "\x1bF",
|
||||
ExitAcs: "\x1bG",
|
||||
SetCursor: "\x1bY%p1%' '%+%c%p2%' '%+%c",
|
||||
CursorBack1: "\x1bD",
|
||||
CursorUp1: "\x1bA",
|
||||
KeyUp: "\x1bA",
|
||||
KeyDown: "\x1bB",
|
||||
KeyRight: "\x1bC",
|
||||
KeyLeft: "\x1bD",
|
||||
KeyBackspace: "\b",
|
||||
KeyF1: "\x1bP",
|
||||
KeyF2: "\x1bQ",
|
||||
KeyF3: "\x1bR",
|
||||
KeyF5: "\x1b?t",
|
||||
KeyF6: "\x1b?u",
|
||||
KeyF7: "\x1b?v",
|
||||
KeyF8: "\x1b?w",
|
||||
KeyF9: "\x1b?x",
|
||||
})
|
||||
}
|
||||
60
vendor/github.com/gdamore/tcell/v2/terminfo/w/wy50/term.go
generated
vendored
60
vendor/github.com/gdamore/tcell/v2/terminfo/w/wy50/term.go
generated
vendored
@@ -1,60 +0,0 @@
|
||||
// Generated automatically. DO NOT HAND-EDIT.
|
||||
|
||||
package wy50
|
||||
|
||||
import "github.com/gdamore/tcell/v2/terminfo"
|
||||
|
||||
func init() {
|
||||
|
||||
// Wyse 50
|
||||
terminfo.AddTerminfo(&terminfo.Terminfo{
|
||||
Name: "wy50",
|
||||
Aliases: []string{"wyse50"},
|
||||
Columns: 80,
|
||||
Lines: 24,
|
||||
Bell: "\a",
|
||||
Clear: "\x1b+$<20>",
|
||||
ShowCursor: "\x1b`1",
|
||||
HideCursor: "\x1b`0",
|
||||
AttrOff: "\x1b(\x1bH\x03",
|
||||
Dim: "\x1b`7\x1b)",
|
||||
Reverse: "\x1b`6\x1b)",
|
||||
PadChar: "\x00",
|
||||
AltChars: "a;j5k3l2m1n8q:t4u9v=w0x6",
|
||||
EnterAcs: "\x1bH\x02",
|
||||
ExitAcs: "\x1bH\x03",
|
||||
SetCursor: "\x1b=%p1%' '%+%c%p2%' '%+%c",
|
||||
CursorBack1: "\b",
|
||||
CursorUp1: "\v",
|
||||
KeyUp: "\v",
|
||||
KeyDown: "\n",
|
||||
KeyRight: "\f",
|
||||
KeyLeft: "\b",
|
||||
KeyInsert: "\x1bQ",
|
||||
KeyDelete: "\x1bW",
|
||||
KeyBackspace: "\b",
|
||||
KeyHome: "\x1e",
|
||||
KeyPgUp: "\x1bJ",
|
||||
KeyPgDn: "\x1bK",
|
||||
KeyF1: "\x01@\r",
|
||||
KeyF2: "\x01A\r",
|
||||
KeyF3: "\x01B\r",
|
||||
KeyF4: "\x01C\r",
|
||||
KeyF5: "\x01D\r",
|
||||
KeyF6: "\x01E\r",
|
||||
KeyF7: "\x01F\r",
|
||||
KeyF8: "\x01G\r",
|
||||
KeyF9: "\x01H\r",
|
||||
KeyF10: "\x01I\r",
|
||||
KeyF11: "\x01J\r",
|
||||
KeyF12: "\x01K\r",
|
||||
KeyF13: "\x01L\r",
|
||||
KeyF14: "\x01M\r",
|
||||
KeyF15: "\x01N\r",
|
||||
KeyF16: "\x01O\r",
|
||||
KeyPrint: "\x1bP",
|
||||
KeyBacktab: "\x1bI",
|
||||
KeyShfHome: "\x1b{",
|
||||
AutoMargin: true,
|
||||
})
|
||||
}
|
||||
66
vendor/github.com/gdamore/tcell/v2/terminfo/w/wy60/term.go
generated
vendored
66
vendor/github.com/gdamore/tcell/v2/terminfo/w/wy60/term.go
generated
vendored
@@ -1,66 +0,0 @@
|
||||
// Generated automatically. DO NOT HAND-EDIT.
|
||||
|
||||
package wy60
|
||||
|
||||
import "github.com/gdamore/tcell/v2/terminfo"
|
||||
|
||||
func init() {
|
||||
|
||||
// Wyse 60
|
||||
terminfo.AddTerminfo(&terminfo.Terminfo{
|
||||
Name: "wy60",
|
||||
Aliases: []string{"wyse60"},
|
||||
Columns: 80,
|
||||
Lines: 24,
|
||||
Bell: "\a",
|
||||
Clear: "\x1b+$<100>",
|
||||
EnterCA: "\x1bw0",
|
||||
ExitCA: "\x1bw1",
|
||||
ShowCursor: "\x1b`1",
|
||||
HideCursor: "\x1b`0",
|
||||
AttrOff: "\x1b(\x1bH\x03\x1bG0\x1bcD",
|
||||
Underline: "\x1bG8",
|
||||
Dim: "\x1bGp",
|
||||
Blink: "\x1bG2",
|
||||
Reverse: "\x1bG4",
|
||||
PadChar: "\x00",
|
||||
AltChars: "+/,.0[a2fxgqh1ihjYk?lZm@nEqDtCu4vAwBx3yszr{c~~",
|
||||
EnterAcs: "\x1bcE",
|
||||
ExitAcs: "\x1bcD",
|
||||
EnableAutoMargin: "\x1bd/",
|
||||
DisableAutoMargin: "\x1bd.",
|
||||
SetCursor: "\x1b=%p1%' '%+%c%p2%' '%+%c",
|
||||
CursorBack1: "\b",
|
||||
CursorUp1: "\v",
|
||||
KeyUp: "\v",
|
||||
KeyDown: "\n",
|
||||
KeyRight: "\f",
|
||||
KeyLeft: "\b",
|
||||
KeyInsert: "\x1bQ",
|
||||
KeyDelete: "\x1bW",
|
||||
KeyBackspace: "\b",
|
||||
KeyHome: "\x1e",
|
||||
KeyPgUp: "\x1bJ",
|
||||
KeyPgDn: "\x1bK",
|
||||
KeyF1: "\x01@\r",
|
||||
KeyF2: "\x01A\r",
|
||||
KeyF3: "\x01B\r",
|
||||
KeyF4: "\x01C\r",
|
||||
KeyF5: "\x01D\r",
|
||||
KeyF6: "\x01E\r",
|
||||
KeyF7: "\x01F\r",
|
||||
KeyF8: "\x01G\r",
|
||||
KeyF9: "\x01H\r",
|
||||
KeyF10: "\x01I\r",
|
||||
KeyF11: "\x01J\r",
|
||||
KeyF12: "\x01K\r",
|
||||
KeyF13: "\x01L\r",
|
||||
KeyF14: "\x01M\r",
|
||||
KeyF15: "\x01N\r",
|
||||
KeyF16: "\x01O\r",
|
||||
KeyPrint: "\x1bP",
|
||||
KeyBacktab: "\x1bI",
|
||||
KeyShfHome: "\x1b{",
|
||||
AutoMargin: true,
|
||||
})
|
||||
}
|
||||
120
vendor/github.com/gdamore/tcell/v2/terminfo/w/wy99_ansi/term.go
generated
vendored
120
vendor/github.com/gdamore/tcell/v2/terminfo/w/wy99_ansi/term.go
generated
vendored
@@ -1,120 +0,0 @@
|
||||
// Generated automatically. DO NOT HAND-EDIT.
|
||||
|
||||
package wy99_ansi
|
||||
|
||||
import "github.com/gdamore/tcell/v2/terminfo"
|
||||
|
||||
func init() {
|
||||
|
||||
// Wyse WY-99GT in ANSI mode (int'l PC keyboard)
|
||||
terminfo.AddTerminfo(&terminfo.Terminfo{
|
||||
Name: "wy99-ansi",
|
||||
Columns: 80,
|
||||
Lines: 25,
|
||||
Bell: "\a",
|
||||
Clear: "\x1b[H\x1b[J$<200>",
|
||||
ShowCursor: "\x1b[34h\x1b[?25h",
|
||||
HideCursor: "\x1b[?25l",
|
||||
AttrOff: "\x1b[m\x0f\x1b[\"q",
|
||||
Underline: "\x1b[4m",
|
||||
Bold: "\x1b[1m",
|
||||
Dim: "\x1b[2m",
|
||||
Blink: "\x1b[5m",
|
||||
Reverse: "\x1b[7m",
|
||||
EnterKeypad: "\x1b[?1h",
|
||||
ExitKeypad: "\x1b[?1l",
|
||||
PadChar: "\x00",
|
||||
AltChars: "``aaffggjjkkllmmnnooqqssttuuvvwwxx{{||}}~~",
|
||||
EnterAcs: "\x0e",
|
||||
ExitAcs: "\x0f",
|
||||
EnableAcs: "\x1b)0",
|
||||
EnableAutoMargin: "\x1b[?7h",
|
||||
DisableAutoMargin: "\x1b[?7l",
|
||||
SetCursor: "\x1b[%i%p1%d;%p2%dH",
|
||||
CursorBack1: "\b$<1>",
|
||||
CursorUp1: "\x1bM",
|
||||
KeyUp: "\x1bOA",
|
||||
KeyDown: "\x1bOB",
|
||||
KeyRight: "\x1bOC",
|
||||
KeyLeft: "\x1bOD",
|
||||
KeyBackspace: "\b",
|
||||
KeyF1: "\x1bOP",
|
||||
KeyF2: "\x1bOQ",
|
||||
KeyF3: "\x1bOR",
|
||||
KeyF4: "\x1bOS",
|
||||
KeyF5: "\x1b[M",
|
||||
KeyF6: "\x1b[17~",
|
||||
KeyF7: "\x1b[18~",
|
||||
KeyF8: "\x1b[19~",
|
||||
KeyF9: "\x1b[20~",
|
||||
KeyF10: "\x1b[21~",
|
||||
KeyF11: "\x1b[23~",
|
||||
KeyF12: "\x1b[24~",
|
||||
KeyF17: "\x1b[K",
|
||||
KeyF18: "\x1b[31~",
|
||||
KeyF19: "\x1b[32~",
|
||||
KeyF20: "\x1b[33~",
|
||||
KeyF21: "\x1b[34~",
|
||||
KeyF22: "\x1b[35~",
|
||||
KeyF23: "\x1b[1~",
|
||||
KeyF24: "\x1b[2~",
|
||||
KeyBacktab: "\x1b[z",
|
||||
AutoMargin: true,
|
||||
})
|
||||
|
||||
// Wyse WY-99GT in ANSI mode (US PC keyboard)
|
||||
terminfo.AddTerminfo(&terminfo.Terminfo{
|
||||
Name: "wy99a-ansi",
|
||||
Columns: 80,
|
||||
Lines: 25,
|
||||
Bell: "\a",
|
||||
Clear: "\x1b[H\x1b[J$<200>",
|
||||
ShowCursor: "\x1b[34h\x1b[?25h",
|
||||
HideCursor: "\x1b[?25l",
|
||||
AttrOff: "\x1b[m\x0f\x1b[\"q",
|
||||
Underline: "\x1b[4m",
|
||||
Bold: "\x1b[1m",
|
||||
Dim: "\x1b[2m",
|
||||
Blink: "\x1b[5m",
|
||||
Reverse: "\x1b[7m",
|
||||
EnterKeypad: "\x1b[?1h",
|
||||
ExitKeypad: "\x1b[?1l",
|
||||
PadChar: "\x00",
|
||||
AltChars: "``aaffggjjkkllmmnnooqqssttuuvvwwxx{{||}}~~",
|
||||
EnterAcs: "\x0e",
|
||||
ExitAcs: "\x0f",
|
||||
EnableAcs: "\x1b)0",
|
||||
EnableAutoMargin: "\x1b[?7h",
|
||||
DisableAutoMargin: "\x1b[?7l",
|
||||
SetCursor: "\x1b[%i%p1%d;%p2%dH",
|
||||
CursorBack1: "\b$<1>",
|
||||
CursorUp1: "\x1bM",
|
||||
KeyUp: "\x1bOA",
|
||||
KeyDown: "\x1bOB",
|
||||
KeyRight: "\x1bOC",
|
||||
KeyLeft: "\x1bOD",
|
||||
KeyBackspace: "\b",
|
||||
KeyF1: "\x1bOP",
|
||||
KeyF2: "\x1bOQ",
|
||||
KeyF3: "\x1bOR",
|
||||
KeyF4: "\x1bOS",
|
||||
KeyF5: "\x1b[M",
|
||||
KeyF6: "\x1b[17~",
|
||||
KeyF7: "\x1b[18~",
|
||||
KeyF8: "\x1b[19~",
|
||||
KeyF9: "\x1b[20~",
|
||||
KeyF10: "\x1b[21~",
|
||||
KeyF11: "\x1b[23~",
|
||||
KeyF12: "\x1b[24~",
|
||||
KeyF17: "\x1b[K",
|
||||
KeyF18: "\x1b[31~",
|
||||
KeyF19: "\x1b[32~",
|
||||
KeyF20: "\x1b[33~",
|
||||
KeyF21: "\x1b[34~",
|
||||
KeyF22: "\x1b[35~",
|
||||
KeyF23: "\x1b[1~",
|
||||
KeyF24: "\x1b[2~",
|
||||
KeyBacktab: "\x1b[z",
|
||||
AutoMargin: true,
|
||||
})
|
||||
}
|
||||
28
vendor/github.com/gdamore/tcell/v2/terminfo/x/xfce/term.go
generated
vendored
28
vendor/github.com/gdamore/tcell/v2/terminfo/x/xfce/term.go
generated
vendored
@@ -12,7 +12,6 @@ func init() {
|
||||
Columns: 80,
|
||||
Lines: 24,
|
||||
Colors: 8,
|
||||
Bell: "\a",
|
||||
Clear: "\x1b[H\x1b[2J",
|
||||
EnterCA: "\x1b7\x1b[?47h",
|
||||
ExitCA: "\x1b[2J\x1b[?47l\x1b8",
|
||||
@@ -37,33 +36,6 @@ func init() {
|
||||
DisableAutoMargin: "\x1b[?7l",
|
||||
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,
|
||||
AutoMargin: true,
|
||||
XTermLike: true,
|
||||
})
|
||||
|
||||
28
vendor/github.com/gdamore/tcell/v2/terminfo/x/xterm/direct.go
generated
vendored
28
vendor/github.com/gdamore/tcell/v2/terminfo/x/xterm/direct.go
generated
vendored
@@ -31,7 +31,6 @@ func init() {
|
||||
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",
|
||||
@@ -59,33 +58,6 @@ func init() {
|
||||
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,
|
||||
TrueColor: true,
|
||||
})
|
||||
|
||||
84
vendor/github.com/gdamore/tcell/v2/terminfo/x/xterm/term.go
generated
vendored
84
vendor/github.com/gdamore/tcell/v2/terminfo/x/xterm/term.go
generated
vendored
@@ -13,7 +13,6 @@ func init() {
|
||||
Columns: 80,
|
||||
Lines: 24,
|
||||
Colors: 8,
|
||||
Bell: "\a",
|
||||
Clear: "\x1b[H\x1b[2J",
|
||||
EnterCA: "\x1b[?1049h\x1b[22;0;0t",
|
||||
ExitCA: "\x1b[?1049l\x1b[23;0;0t",
|
||||
@@ -40,33 +39,6 @@ func init() {
|
||||
StrikeThrough: "\x1b[9m",
|
||||
Mouse: "\x1b[<",
|
||||
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,
|
||||
AutoMargin: true,
|
||||
XTermLike: true,
|
||||
})
|
||||
@@ -77,7 +49,6 @@ func init() {
|
||||
Columns: 80,
|
||||
Lines: 24,
|
||||
Colors: 88,
|
||||
Bell: "\a",
|
||||
Clear: "\x1b[H\x1b[2J",
|
||||
EnterCA: "\x1b[?1049h\x1b[22;0;0t",
|
||||
ExitCA: "\x1b[?1049l\x1b[23;0;0t",
|
||||
@@ -104,33 +75,6 @@ func init() {
|
||||
StrikeThrough: "\x1b[9m",
|
||||
Mouse: "\x1b[<",
|
||||
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,
|
||||
AutoMargin: true,
|
||||
XTermLike: true,
|
||||
})
|
||||
@@ -141,7 +85,6 @@ func init() {
|
||||
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",
|
||||
@@ -168,33 +111,6 @@ func init() {
|
||||
StrikeThrough: "\x1b[9m",
|
||||
Mouse: "\x1b[<",
|
||||
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,
|
||||
AutoMargin: true,
|
||||
XTermLike: true,
|
||||
})
|
||||
|
||||
32
vendor/github.com/gdamore/tcell/v2/terminfo/x/xterm_ghostty/term.go
generated
vendored
32
vendor/github.com/gdamore/tcell/v2/terminfo/x/xterm_ghostty/term.go
generated
vendored
@@ -13,7 +13,6 @@ func init() {
|
||||
Columns: 80,
|
||||
Lines: 24,
|
||||
Colors: 256,
|
||||
Bell: "\a",
|
||||
Clear: "\x1b[H\x1b[2J",
|
||||
EnterCA: "\x1b[?1049h",
|
||||
ExitCA: "\x1b[?1049l",
|
||||
@@ -40,40 +39,9 @@ func init() {
|
||||
StrikeThrough: "\x1b[9m",
|
||||
Mouse: "\x1b[<",
|
||||
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,
|
||||
InsertChar: "\x1b[@",
|
||||
DoubleUnderline: "\x1b[4:2m",
|
||||
CurlyUnderline: "\x1b[4:3m",
|
||||
DottedUnderline: "\x1b[4:4m",
|
||||
DashedUnderline: "\x1b[4:5m",
|
||||
XTermLike: true,
|
||||
})
|
||||
}
|
||||
|
||||
33
vendor/github.com/gdamore/tcell/v2/terminfo/x/xterm_kitty/term.go
generated
vendored
33
vendor/github.com/gdamore/tcell/v2/terminfo/x/xterm_kitty/term.go
generated
vendored
@@ -12,7 +12,6 @@ func init() {
|
||||
Columns: 80,
|
||||
Lines: 24,
|
||||
Colors: 256,
|
||||
Bell: "\a",
|
||||
Clear: "\x1b[H\x1b[2J",
|
||||
EnterCA: "\x1b[?1049h",
|
||||
ExitCA: "\x1b[?1049l",
|
||||
@@ -38,38 +37,8 @@ func init() {
|
||||
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,
|
||||
DoubleUnderline: "\x1b[4:2m",
|
||||
CurlyUnderline: "\x1b[4:3m",
|
||||
DottedUnderline: "\x1b[4:4m",
|
||||
DashedUnderline: "\x1b[4:5m",
|
||||
XTermLike: true,
|
||||
})
|
||||
}
|
||||
|
||||
1171
vendor/github.com/gdamore/tcell/v2/tscreen.go
generated
vendored
1171
vendor/github.com/gdamore/tcell/v2/tscreen.go
generated
vendored
File diff suppressed because it is too large
Load Diff
@@ -1,7 +1,4 @@
|
||||
//go:build windows
|
||||
// +build windows
|
||||
|
||||
// Copyright 2022 The TCell Authors
|
||||
// Copyright 2025 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,18 +12,30 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
//go:build windows
|
||||
// +build windows
|
||||
|
||||
package tcell
|
||||
|
||||
// NB: We might someday wish to move Windows to this model. However,
|
||||
// that would probably mean sacrificing some of the richer key reporting
|
||||
// that we can obtain with the console API present on Windows.
|
||||
import (
|
||||
// import the stock terminals
|
||||
_ "github.com/gdamore/tcell/v2/terminfo/base"
|
||||
)
|
||||
|
||||
// initialize is used at application startup, and sets up the initial values
|
||||
// including file descriptors used for terminals and saving the initial state
|
||||
// so that it can be restored when the application terminates.
|
||||
func (t *tScreen) initialize() error {
|
||||
var err error
|
||||
if t.tty == nil {
|
||||
return ErrNoScreen
|
||||
t.tty, err = NewDevTty()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
// 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
|
||||
}
|
||||
|
||||
func init() {
|
||||
defaultTerm = "xterm-truecolor"
|
||||
}
|
||||
278
vendor/github.com/gdamore/tcell/v2/tty_win.go
generated
vendored
Normal file
278
vendor/github.com/gdamore/tcell/v2/tty_win.go
generated
vendored
Normal file
@@ -0,0 +1,278 @@
|
||||
// Copyright 2025 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 windows
|
||||
// +build windows
|
||||
|
||||
package tcell
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"sync"
|
||||
"syscall"
|
||||
"time"
|
||||
"unicode/utf16"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
var (
|
||||
k32 = syscall.NewLazyDLL("kernel32.dll")
|
||||
)
|
||||
|
||||
var (
|
||||
procReadConsoleInput = k32.NewProc("ReadConsoleInputW")
|
||||
procGetNumberOfConsoleInputEvents = k32.NewProc("GetNumberOfConsoleInputEvents")
|
||||
procFlushConsoleInputBuffer = k32.NewProc("FlushConsoleInputBuffer")
|
||||
procWaitForMultipleObjects = k32.NewProc("WaitForMultipleObjects")
|
||||
procSetConsoleMode = k32.NewProc("SetConsoleMode")
|
||||
procGetConsoleMode = k32.NewProc("GetConsoleMode")
|
||||
procGetConsoleScreenBufferInfo = k32.NewProc("GetConsoleScreenBufferInfo")
|
||||
procCreateEvent = k32.NewProc("CreateEventW")
|
||||
procSetEvent = k32.NewProc("SetEvent")
|
||||
)
|
||||
|
||||
const (
|
||||
keyEvent uint16 = 1
|
||||
mouseEvent uint16 = 2
|
||||
resizeEvent uint16 = 4
|
||||
menuEvent uint16 = 8 // don't use
|
||||
focusEvent uint16 = 16
|
||||
)
|
||||
|
||||
type inputRecord struct {
|
||||
typ uint16
|
||||
_ uint16
|
||||
data [16]byte
|
||||
}
|
||||
|
||||
type winTty struct {
|
||||
buf chan byte
|
||||
out syscall.Handle
|
||||
in syscall.Handle
|
||||
cancelFlag syscall.Handle
|
||||
running bool
|
||||
stopQ chan struct{}
|
||||
resizeCb func()
|
||||
cols uint16
|
||||
rows uint16
|
||||
pair []uint16 // for surrogate pairs (UTF-16)
|
||||
oimode uint32 // original input mode
|
||||
oomode uint32 // original output mode
|
||||
oscreen consoleInfo
|
||||
wg sync.WaitGroup
|
||||
sync.Mutex
|
||||
}
|
||||
|
||||
func (w *winTty) Read(b []byte) (int, error) {
|
||||
// first character read blocks
|
||||
var num int
|
||||
select {
|
||||
case c := <-w.buf:
|
||||
b[0] = c
|
||||
num++
|
||||
case <-w.stopQ:
|
||||
// stopping, so make sure we eat everything, which might require
|
||||
// very short sleeps to ensure all buffered data is consumed.
|
||||
break
|
||||
}
|
||||
|
||||
// second character read is non-blocking
|
||||
for ; num < len(b); num++ {
|
||||
select {
|
||||
case c := <-w.buf:
|
||||
b[num] = c
|
||||
case <-time.After(time.Millisecond * 10):
|
||||
return num, nil
|
||||
}
|
||||
}
|
||||
return num, nil
|
||||
}
|
||||
|
||||
func (w *winTty) Write(b []byte) (int, error) {
|
||||
esc := utf16.Encode([]rune(string(b)))
|
||||
if len(esc) > 0 {
|
||||
err := syscall.WriteConsole(w.out, &esc[0], uint32(len(esc)), nil, nil)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
}
|
||||
return len(b), nil
|
||||
}
|
||||
|
||||
func (w *winTty) Close() error {
|
||||
_ = syscall.Close(w.in)
|
||||
_ = syscall.Close(w.out)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (w *winTty) Drain() error {
|
||||
close(w.stopQ)
|
||||
time.Sleep(time.Millisecond * 10)
|
||||
_, _, _ = procSetEvent.Call(uintptr(w.cancelFlag))
|
||||
return nil
|
||||
}
|
||||
|
||||
func (w *winTty) getConsoleInput() error {
|
||||
// cancelFlag comes first as WaitForMultipleObjects returns the lowest index
|
||||
// in the event that both events are signalled.
|
||||
waitObjects := []syscall.Handle{w.cancelFlag, w.in}
|
||||
|
||||
// As arrays are contiguous in memory, a pointer to the first object is the
|
||||
// same as a pointer to the array itself.
|
||||
pWaitObjects := unsafe.Pointer(&waitObjects[0])
|
||||
|
||||
rv, _, er := procWaitForMultipleObjects.Call(
|
||||
uintptr(len(waitObjects)),
|
||||
uintptr(pWaitObjects),
|
||||
uintptr(0),
|
||||
w32Infinite)
|
||||
|
||||
// WaitForMultipleObjects returns WAIT_OBJECT_0 + the index.
|
||||
switch rv {
|
||||
case w32WaitObject0: // w.cancelFlag
|
||||
return errors.New("cancelled")
|
||||
case w32WaitObject0 + 1: // w.in
|
||||
// rec := &inputRecord{}
|
||||
var nrec int32
|
||||
rv, _, er := procGetNumberOfConsoleInputEvents.Call(
|
||||
uintptr(w.in),
|
||||
uintptr(unsafe.Pointer(&nrec)))
|
||||
rec := make([]inputRecord, nrec)
|
||||
rv, _, er = procReadConsoleInput.Call(
|
||||
uintptr(w.in),
|
||||
uintptr(unsafe.Pointer(&rec[0])),
|
||||
uintptr(nrec),
|
||||
uintptr(unsafe.Pointer(&nrec)))
|
||||
if rv == 0 {
|
||||
return er
|
||||
}
|
||||
for i := range nrec {
|
||||
ir := rec[i]
|
||||
switch ir.typ {
|
||||
case keyEvent:
|
||||
chr := ir.data[10] // we only see ASCII, key down events in VT mode
|
||||
|
||||
// because we use win32-input-mode, we will only
|
||||
// see US-ASCII characters - (Q: will they be
|
||||
// 16-bit values with possible surrogate pairs?)
|
||||
select {
|
||||
case w.buf <- chr:
|
||||
case <-w.stopQ:
|
||||
break
|
||||
}
|
||||
|
||||
case resizeEvent:
|
||||
w.Lock()
|
||||
w.cols = binary.LittleEndian.Uint16(ir.data[0:])
|
||||
w.rows = binary.LittleEndian.Uint16(ir.data[2:])
|
||||
cb := w.resizeCb
|
||||
w.Unlock()
|
||||
if cb != nil {
|
||||
cb()
|
||||
}
|
||||
|
||||
default:
|
||||
}
|
||||
}
|
||||
return nil
|
||||
default:
|
||||
return er
|
||||
}
|
||||
}
|
||||
|
||||
func (w *winTty) scanInput() {
|
||||
defer w.wg.Done()
|
||||
for {
|
||||
if e := w.getConsoleInput(); e != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (w *winTty) Start() error {
|
||||
|
||||
w.Lock()
|
||||
defer w.Unlock()
|
||||
|
||||
if w.running {
|
||||
return errors.New("already engaged")
|
||||
}
|
||||
_, _, _ = procFlushConsoleInputBuffer.Call(uintptr(w.in))
|
||||
w.stopQ = make(chan struct{})
|
||||
cf, _, err := procCreateEvent.Call(
|
||||
uintptr(0),
|
||||
uintptr(1),
|
||||
uintptr(0),
|
||||
uintptr(0))
|
||||
if cf == uintptr(0) {
|
||||
return err
|
||||
}
|
||||
w.running = true
|
||||
w.cancelFlag = syscall.Handle(cf)
|
||||
|
||||
_, _, _ = procSetConsoleMode.Call(uintptr(w.in),
|
||||
uintptr(modeVtInput|modeResizeEn|modeExtendFlg))
|
||||
_, _, _ = procSetConsoleMode.Call(uintptr(w.out),
|
||||
uintptr(modeVtOutput|modeNoAutoNL|modeCookedOut|modeUnderline))
|
||||
|
||||
w.wg.Add(1)
|
||||
go w.scanInput()
|
||||
return nil
|
||||
}
|
||||
|
||||
func (w *winTty) Stop() error {
|
||||
w.wg.Wait()
|
||||
w.Lock()
|
||||
defer w.Unlock()
|
||||
_, _, _ = procSetConsoleMode.Call(uintptr(w.in), uintptr(w.oimode))
|
||||
_, _, _ = procSetConsoleMode.Call(uintptr(w.out), uintptr(w.oomode))
|
||||
_, _, _ = procFlushConsoleInputBuffer.Call(uintptr(w.in))
|
||||
w.running = false
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (w *winTty) NotifyResize(cb func()) {
|
||||
w.resizeCb = cb
|
||||
}
|
||||
|
||||
func (w *winTty) WindowSize() (WindowSize, error) {
|
||||
w.Lock()
|
||||
defer w.Unlock()
|
||||
return WindowSize{Width: int(w.cols), Height: int(w.rows)}, nil
|
||||
}
|
||||
|
||||
func NewDevTty() (Tty, error) {
|
||||
w := &winTty{}
|
||||
var err error
|
||||
w.in, err = syscall.Open("CONIN$", syscall.O_RDWR, 0)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
w.out, err = syscall.Open("CONOUT$", syscall.O_RDWR, 0)
|
||||
if err != nil {
|
||||
_ = syscall.Close(w.in)
|
||||
return nil, err
|
||||
}
|
||||
w.buf = make(chan byte, 128)
|
||||
|
||||
_, _, _ = procGetConsoleScreenBufferInfo.Call(uintptr(w.out), uintptr(unsafe.Pointer(&w.oscreen)))
|
||||
_, _, _ = procGetConsoleMode.Call(uintptr(w.out), uintptr(unsafe.Pointer(&w.oomode)))
|
||||
_, _, _ = procGetConsoleMode.Call(uintptr(w.in), uintptr(unsafe.Pointer(&w.oimode)))
|
||||
w.rows = uint16(w.oscreen.size.y)
|
||||
w.cols = uint16(w.oscreen.size.x)
|
||||
|
||||
return w, nil
|
||||
}
|
||||
51
vendor/github.com/gdamore/tcell/v2/wscreen.go
generated
vendored
51
vendor/github.com/gdamore/tcell/v2/wscreen.go
generated
vendored
@@ -20,7 +20,6 @@ package tcell
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
"sync"
|
||||
"syscall/js"
|
||||
"unicode/utf8"
|
||||
@@ -121,7 +120,7 @@ func paletteColor(c Color) int32 {
|
||||
}
|
||||
|
||||
func (t *wScreen) drawCell(x, y int) int {
|
||||
mainc, combc, style, width := t.cells.GetContent(x, y)
|
||||
str, style, width := t.cells.Get(x, y)
|
||||
|
||||
if !t.cells.Dirty(x, y) {
|
||||
return width
|
||||
@@ -143,18 +142,8 @@ func (t *wScreen) drawCell(x, y int) int {
|
||||
uc = 0x000000
|
||||
}
|
||||
|
||||
s := ""
|
||||
if len(combc) > 0 {
|
||||
b := make([]rune, 0, 1+len(combc))
|
||||
b = append(b, mainc)
|
||||
b = append(b, combc...)
|
||||
s = string(b)
|
||||
} else {
|
||||
s = string(mainc)
|
||||
}
|
||||
|
||||
t.cells.SetDirty(x, y, false)
|
||||
js.Global().Call("drawCell", x, y, s, fg, bg, int(style.attrs), int(us), int(uc))
|
||||
js.Global().Call("drawCell", x, y, str, fg, bg, int(style.attrs), int(us), int(uc))
|
||||
|
||||
return width
|
||||
}
|
||||
@@ -382,14 +371,6 @@ func (t *wScreen) onKeyEvent(this js.Value, args []js.Value) interface{} {
|
||||
mod |= ModMeta
|
||||
}
|
||||
|
||||
// check for special case of Ctrl + key
|
||||
if mod == ModCtrl {
|
||||
if k, ok := WebKeyNames["Ctrl-"+strings.ToLower(key)]; ok {
|
||||
t.postEvent(NewEventKey(k, 0, mod))
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// next try function keys
|
||||
if k, ok := WebKeyNames[key]; ok {
|
||||
t.postEvent(NewEventKey(k, 0, mod))
|
||||
@@ -631,34 +612,6 @@ var WebKeyNames = map[string]Key{
|
||||
"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{
|
||||
|
||||
19
vendor/github.com/jesseduffield/gocui/edit.go
generated
vendored
19
vendor/github.com/jesseduffield/gocui/edit.go
generated
vendored
@@ -4,10 +4,6 @@
|
||||
|
||||
package gocui
|
||||
|
||||
import (
|
||||
"unicode"
|
||||
)
|
||||
|
||||
// Editor interface must be satisfied by gocui editors.
|
||||
type Editor interface {
|
||||
Edit(v *View, key Key, ch rune, mod Modifier) bool
|
||||
@@ -29,6 +25,9 @@ var DefaultEditor Editor = EditorFunc(SimpleEditor)
|
||||
// SimpleEditor is used as the default gocui editor.
|
||||
func SimpleEditor(v *View, key Key, ch rune, mod Modifier) bool {
|
||||
switch {
|
||||
case (key == KeyBackspace || key == KeyBackspace2) && (mod&ModAlt) != 0,
|
||||
key == KeyCtrlW:
|
||||
v.TextArea.BackSpaceWord()
|
||||
case key == KeyBackspace || key == KeyBackspace2:
|
||||
v.TextArea.BackSpaceChar()
|
||||
case key == KeyCtrlD || key == KeyDelete:
|
||||
@@ -37,18 +36,18 @@ func SimpleEditor(v *View, key Key, ch rune, mod Modifier) bool {
|
||||
v.TextArea.MoveCursorDown()
|
||||
case key == KeyArrowUp:
|
||||
v.TextArea.MoveCursorUp()
|
||||
case key == KeyArrowLeft && (mod&ModAlt) != 0:
|
||||
case (key == KeyArrowLeft || ch == 'b') && (mod&ModAlt) != 0:
|
||||
v.TextArea.MoveLeftWord()
|
||||
case key == KeyArrowLeft:
|
||||
v.TextArea.MoveCursorLeft()
|
||||
case key == KeyArrowRight && (mod&ModAlt) != 0:
|
||||
case (key == KeyArrowRight || ch == 'f') && (mod&ModAlt) != 0:
|
||||
v.TextArea.MoveRightWord()
|
||||
case key == KeyArrowRight:
|
||||
v.TextArea.MoveCursorRight()
|
||||
case key == KeyEnter:
|
||||
v.TextArea.TypeRune('\n')
|
||||
v.TextArea.TypeCharacter("\n")
|
||||
case key == KeySpace:
|
||||
v.TextArea.TypeRune(' ')
|
||||
v.TextArea.TypeCharacter(" ")
|
||||
case key == KeyInsert:
|
||||
v.TextArea.ToggleOverwrite()
|
||||
case key == KeyCtrlU:
|
||||
@@ -63,8 +62,8 @@ func SimpleEditor(v *View, key Key, ch rune, mod Modifier) bool {
|
||||
v.TextArea.BackSpaceWord()
|
||||
case key == KeyCtrlY:
|
||||
v.TextArea.Yank()
|
||||
case unicode.IsPrint(ch):
|
||||
v.TextArea.TypeRune(ch)
|
||||
case ch != 0:
|
||||
v.TextArea.TypeCharacter(string(ch))
|
||||
default:
|
||||
return false
|
||||
}
|
||||
|
||||
75
vendor/github.com/jesseduffield/gocui/escape.go
generated
vendored
75
vendor/github.com/jesseduffield/gocui/escape.go
generated
vendored
@@ -6,18 +6,19 @@ package gocui
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/go-errors/errors"
|
||||
)
|
||||
|
||||
type escapeInterpreter struct {
|
||||
state escapeState
|
||||
curch rune
|
||||
curch string
|
||||
csiParam []string
|
||||
curFgColor, curBgColor Attribute
|
||||
mode OutputMode
|
||||
instruction instruction
|
||||
hyperlink string
|
||||
hyperlink strings.Builder
|
||||
}
|
||||
|
||||
type (
|
||||
@@ -68,20 +69,20 @@ var (
|
||||
errOSCParseError = errors.New("OSC escape sequence parsing error")
|
||||
)
|
||||
|
||||
// runes in case of error will output the non-parsed runes as a string.
|
||||
func (ei *escapeInterpreter) runes() []rune {
|
||||
// characters in case of error will output the non-parsed characters as a string.
|
||||
func (ei *escapeInterpreter) characters() []string {
|
||||
switch ei.state {
|
||||
case stateNone:
|
||||
return []rune{0x1b}
|
||||
return []string{"\x1b"}
|
||||
case stateEscape:
|
||||
return []rune{0x1b, ei.curch}
|
||||
return []string{"\x1b", ei.curch}
|
||||
case stateCSI:
|
||||
return []rune{0x1b, '[', ei.curch}
|
||||
return []string{"\x1b", "[", ei.curch}
|
||||
case stateParams:
|
||||
ret := []rune{0x1b, '['}
|
||||
ret := []string{"\x1b", "["}
|
||||
for _, s := range ei.csiParam {
|
||||
ret = append(ret, []rune(s)...)
|
||||
ret = append(ret, ';')
|
||||
ret = append(ret, s)
|
||||
ret = append(ret, ";")
|
||||
}
|
||||
return append(ret, ei.curch)
|
||||
default:
|
||||
@@ -114,10 +115,10 @@ func (ei *escapeInterpreter) instructionRead() {
|
||||
ei.instruction = noInstruction{}
|
||||
}
|
||||
|
||||
// parseOne parses a rune. If isEscape is true, it means that the rune is part
|
||||
// of an escape sequence, and as such should not be printed verbatim. Otherwise,
|
||||
// it's not an escape sequence.
|
||||
func (ei *escapeInterpreter) parseOne(ch rune) (isEscape bool, err error) {
|
||||
// parseOne parses a character (grapheme cluster). If isEscape is true, it means that the character
|
||||
// is part of an escape sequence, and as such should not be printed verbatim. Otherwise, it's not an
|
||||
// escape sequence.
|
||||
func (ei *escapeInterpreter) parseOne(ch []byte) (isEscape bool, err error) {
|
||||
// Sanity checks
|
||||
if len(ei.csiParam) > 20 {
|
||||
return false, errCSITooLong
|
||||
@@ -126,21 +127,21 @@ func (ei *escapeInterpreter) parseOne(ch rune) (isEscape bool, err error) {
|
||||
return false, errCSITooLong
|
||||
}
|
||||
|
||||
ei.curch = ch
|
||||
ei.curch = string(ch)
|
||||
|
||||
switch ei.state {
|
||||
case stateNone:
|
||||
if ch == 0x1b {
|
||||
if characterEquals(ch, 0x1b) {
|
||||
ei.state = stateEscape
|
||||
return true, nil
|
||||
}
|
||||
return false, nil
|
||||
case stateEscape:
|
||||
switch ch {
|
||||
case '[':
|
||||
switch {
|
||||
case characterEquals(ch, '['):
|
||||
ei.state = stateCSI
|
||||
return true, nil
|
||||
case ']':
|
||||
case characterEquals(ch, ']'):
|
||||
ei.state = stateOSC
|
||||
return true, nil
|
||||
default:
|
||||
@@ -148,11 +149,11 @@ func (ei *escapeInterpreter) parseOne(ch rune) (isEscape bool, err error) {
|
||||
}
|
||||
case stateCSI:
|
||||
switch {
|
||||
case ch >= '0' && ch <= '9':
|
||||
case len(ch) == 1 && ch[0] >= '0' && ch[0] <= '9':
|
||||
ei.csiParam = append(ei.csiParam, "")
|
||||
case ch == 'm':
|
||||
case characterEquals(ch, 'm'):
|
||||
ei.csiParam = append(ei.csiParam, "0")
|
||||
case ch == 'K':
|
||||
case characterEquals(ch, 'K'):
|
||||
// fall through
|
||||
default:
|
||||
return false, errCSIParseError
|
||||
@@ -161,13 +162,13 @@ func (ei *escapeInterpreter) parseOne(ch rune) (isEscape bool, err error) {
|
||||
fallthrough
|
||||
case stateParams:
|
||||
switch {
|
||||
case ch >= '0' && ch <= '9':
|
||||
case len(ch) == 1 && ch[0] >= '0' && ch[0] <= '9':
|
||||
ei.csiParam[len(ei.csiParam)-1] += string(ch)
|
||||
return true, nil
|
||||
case ch == ';':
|
||||
case characterEquals(ch, ';'):
|
||||
ei.csiParam = append(ei.csiParam, "")
|
||||
return true, nil
|
||||
case ch == 'm':
|
||||
case characterEquals(ch, 'm'):
|
||||
if err := ei.outputCSI(); err != nil {
|
||||
return false, errCSIParseError
|
||||
}
|
||||
@@ -175,7 +176,7 @@ func (ei *escapeInterpreter) parseOne(ch rune) (isEscape bool, err error) {
|
||||
ei.state = stateNone
|
||||
ei.csiParam = nil
|
||||
return true, nil
|
||||
case ch == 'K':
|
||||
case characterEquals(ch, 'K'):
|
||||
p := 0
|
||||
if len(ei.csiParam) != 0 && ei.csiParam[0] != "" {
|
||||
p, err = strconv.Atoi(ei.csiParam[0])
|
||||
@@ -198,44 +199,44 @@ func (ei *escapeInterpreter) parseOne(ch rune) (isEscape bool, err error) {
|
||||
return false, errCSIParseError
|
||||
}
|
||||
case stateOSC:
|
||||
if ch == '8' {
|
||||
if characterEquals(ch, '8') {
|
||||
ei.state = stateOSCWaitForParams
|
||||
ei.hyperlink = ""
|
||||
ei.hyperlink.Reset()
|
||||
return true, nil
|
||||
}
|
||||
|
||||
ei.state = stateOSCSkipUnknown
|
||||
return true, nil
|
||||
case stateOSCWaitForParams:
|
||||
if ch != ';' {
|
||||
if !characterEquals(ch, ';') {
|
||||
return true, errOSCParseError
|
||||
}
|
||||
|
||||
ei.state = stateOSCParams
|
||||
return true, nil
|
||||
case stateOSCParams:
|
||||
if ch == ';' {
|
||||
if characterEquals(ch, ';') {
|
||||
ei.state = stateOSCHyperlink
|
||||
}
|
||||
return true, nil
|
||||
case stateOSCHyperlink:
|
||||
switch ch {
|
||||
case 0x07:
|
||||
switch {
|
||||
case characterEquals(ch, 0x07):
|
||||
ei.state = stateNone
|
||||
case 0x1b:
|
||||
case characterEquals(ch, 0x1b):
|
||||
ei.state = stateOSCEndEscape
|
||||
default:
|
||||
ei.hyperlink += string(ch)
|
||||
ei.hyperlink.Write(ch)
|
||||
}
|
||||
return true, nil
|
||||
case stateOSCEndEscape:
|
||||
ei.state = stateNone
|
||||
return true, nil
|
||||
case stateOSCSkipUnknown:
|
||||
switch ch {
|
||||
case 0x07:
|
||||
switch {
|
||||
case characterEquals(ch, 0x07):
|
||||
ei.state = stateNone
|
||||
case 0x1b:
|
||||
case characterEquals(ch, 0x1b):
|
||||
ei.state = stateOSCEndEscape
|
||||
}
|
||||
return true, nil
|
||||
|
||||
75
vendor/github.com/jesseduffield/gocui/gui.go
generated
vendored
75
vendor/github.com/jesseduffield/gocui/gui.go
generated
vendored
@@ -8,13 +8,14 @@ import (
|
||||
"context"
|
||||
standardErrors "errors"
|
||||
"runtime"
|
||||
"slices"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/gdamore/tcell/v2"
|
||||
"github.com/go-errors/errors"
|
||||
"github.com/mattn/go-runewidth"
|
||||
"github.com/rivo/uniseg"
|
||||
)
|
||||
|
||||
// OutputMode represents an output mode, which determines how colors
|
||||
@@ -189,9 +190,9 @@ type Gui struct {
|
||||
|
||||
OnSearchEscape func() error
|
||||
// these keys must either be of type Key of rune
|
||||
SearchEscapeKey interface{}
|
||||
NextSearchMatchKey interface{}
|
||||
PrevSearchMatchKey interface{}
|
||||
SearchEscapeKey any
|
||||
NextSearchMatchKey any
|
||||
PrevSearchMatchKey any
|
||||
|
||||
ErrorHandler func(error) error
|
||||
|
||||
@@ -300,25 +301,16 @@ func (g *Gui) Size() (x, y int) {
|
||||
// SetRune writes a rune at the given point, relative to the top-left
|
||||
// corner of the terminal. It checks if the position is valid and applies
|
||||
// the given colors.
|
||||
// Should only be used if you know that the given rune is not part of a grapheme cluster.
|
||||
func (g *Gui) SetRune(x, y int, ch rune, fgColor, bgColor Attribute) error {
|
||||
if x < 0 || y < 0 || x >= g.maxX || y >= g.maxY {
|
||||
// swallowing error because it's not that big of a deal
|
||||
return nil
|
||||
}
|
||||
tcellSetCell(x, y, ch, fgColor, bgColor, g.outputMode)
|
||||
tcellSetCell(x, y, string(ch), fgColor, bgColor, g.outputMode)
|
||||
return nil
|
||||
}
|
||||
|
||||
// Rune returns the rune contained in the cell at the given position.
|
||||
// It checks if the position is valid.
|
||||
func (g *Gui) Rune(x, y int) (rune, error) {
|
||||
if x < 0 || y < 0 || x >= g.maxX || y >= g.maxY {
|
||||
return ' ', errors.New("invalid point")
|
||||
}
|
||||
c, _, _, _ := Screen.GetContent(x, y)
|
||||
return c, nil
|
||||
}
|
||||
|
||||
// SetView creates a new view with its top-left corner at (x0, y0)
|
||||
// and the bottom-right one at (x1, y1). If a view with the same name
|
||||
// already exists, its dimensions are updated; otherwise, the error
|
||||
@@ -554,7 +546,7 @@ func (g *Gui) CurrentView() *View {
|
||||
// It behaves differently on different platforms. Somewhere it doesn't register Alt key press,
|
||||
// on others it might report Ctrl as Alt. It's not consistent and therefore it's not recommended
|
||||
// to use with mouse keys.
|
||||
func (g *Gui) SetKeybinding(viewname string, key interface{}, mod Modifier, handler func(*Gui, *View) error) error {
|
||||
func (g *Gui) SetKeybinding(viewname string, key any, mod Modifier, handler func(*Gui, *View) error) error {
|
||||
var kb *keybinding
|
||||
|
||||
k, ch, err := getKey(key)
|
||||
@@ -572,7 +564,7 @@ func (g *Gui) SetKeybinding(viewname string, key interface{}, mod Modifier, hand
|
||||
}
|
||||
|
||||
// DeleteKeybinding deletes a keybinding.
|
||||
func (g *Gui) DeleteKeybinding(viewname string, key interface{}, mod Modifier) error {
|
||||
func (g *Gui) DeleteKeybinding(viewname string, key any, mod Modifier) error {
|
||||
k, ch, err := getKey(key)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -623,10 +615,8 @@ func (g *Gui) SetViewClickBinding(binding *ViewMouseBinding) error {
|
||||
|
||||
// BlackListKeybinding adds a keybinding to the blacklist
|
||||
func (g *Gui) BlacklistKeybinding(k Key) error {
|
||||
for _, j := range g.blacklist {
|
||||
if j == k {
|
||||
return ErrAlreadyBlacklisted
|
||||
}
|
||||
if slices.Contains(g.blacklist, k) {
|
||||
return ErrAlreadyBlacklisted
|
||||
}
|
||||
g.blacklist = append(g.blacklist, k)
|
||||
return nil
|
||||
@@ -653,7 +643,7 @@ func (g *Gui) SetOpenHyperlinkFunc(openHyperlinkFunc func(string, string) error)
|
||||
|
||||
// getKey takes an empty interface with a key and returns the corresponding
|
||||
// typed Key or rune.
|
||||
func getKey(key interface{}) (Key, rune, error) {
|
||||
func getKey(key any) (Key, rune, error) {
|
||||
switch t := key.(type) {
|
||||
case nil: // Ignore keybinding if `nil`
|
||||
return 0, 0, nil
|
||||
@@ -1103,7 +1093,7 @@ func (g *Gui) drawTitle(v *View, fgColor, bgColor Attribute) error {
|
||||
if err := g.SetRune(x, v.y0, ch, fgColor, bgColor); err != nil {
|
||||
return err
|
||||
}
|
||||
x += runewidth.RuneWidth(ch)
|
||||
x += uniseg.StringWidth(string(ch))
|
||||
}
|
||||
for i, ch := range str {
|
||||
if x < 0 {
|
||||
@@ -1128,7 +1118,7 @@ func (g *Gui) drawTitle(v *View, fgColor, bgColor Attribute) error {
|
||||
if err := g.SetRune(x, v.y0, ch, currentFgColor, currentBgColor); err != nil {
|
||||
return err
|
||||
}
|
||||
x += runewidth.RuneWidth(ch)
|
||||
x += uniseg.StringWidth(string(ch))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -1139,7 +1129,7 @@ func (g *Gui) drawSubtitle(v *View, fgColor, bgColor Attribute) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
start := v.x1 - 5 - runewidth.StringWidth(v.Subtitle)
|
||||
start := v.x1 - 5 - uniseg.StringWidth(v.Subtitle)
|
||||
if start < v.x0 {
|
||||
return nil
|
||||
}
|
||||
@@ -1151,7 +1141,7 @@ func (g *Gui) drawSubtitle(v *View, fgColor, bgColor Attribute) error {
|
||||
if err := g.SetRune(x, v.y0, ch, fgColor, bgColor); err != nil {
|
||||
return err
|
||||
}
|
||||
x += runewidth.RuneWidth(ch)
|
||||
x += uniseg.StringWidth(string(ch))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -1168,7 +1158,7 @@ func (g *Gui) drawListFooter(v *View, fgColor, bgColor Attribute) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
start := v.x1 - 1 - runewidth.StringWidth(message)
|
||||
start := v.x1 - 1 - uniseg.StringWidth(message)
|
||||
if start < v.x0 {
|
||||
return nil
|
||||
}
|
||||
@@ -1180,7 +1170,7 @@ func (g *Gui) drawListFooter(v *View, fgColor, bgColor Attribute) error {
|
||||
if err := g.SetRune(x, v.y1, ch, fgColor, bgColor); err != nil {
|
||||
return err
|
||||
}
|
||||
x += runewidth.RuneWidth(ch)
|
||||
x += uniseg.StringWidth(string(ch))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -1369,13 +1359,13 @@ func (g *Gui) onKey(ev *GocuiEvent) error {
|
||||
newCy = newY - v.oy
|
||||
}
|
||||
|
||||
lastCharForLine := len(v.lines[newY])
|
||||
for lastCharForLine > 0 && v.lines[newY][lastCharForLine-1].chr == 0 {
|
||||
lastCharForLine--
|
||||
visibleLineWidth := 0
|
||||
for _, c := range v.lines[newY] {
|
||||
visibleLineWidth += c.width
|
||||
}
|
||||
if lastCharForLine < newX {
|
||||
newX = lastCharForLine
|
||||
newCx = lastCharForLine - v.ox
|
||||
if visibleLineWidth < newX {
|
||||
newX = visibleLineWidth
|
||||
newCx = visibleLineWidth - v.ox
|
||||
}
|
||||
}
|
||||
if !IsMouseScrollKey(ev.Key) {
|
||||
@@ -1485,7 +1475,7 @@ func (g *Gui) execMouseKeybindings(view *View, ev *GocuiEvent, opts ViewMouseBin
|
||||
return false, nil
|
||||
}
|
||||
|
||||
func IsMouseKey(key interface{}) bool {
|
||||
func IsMouseKey(key any) bool {
|
||||
switch key {
|
||||
case
|
||||
MouseLeft,
|
||||
@@ -1502,7 +1492,7 @@ func IsMouseKey(key interface{}) bool {
|
||||
}
|
||||
}
|
||||
|
||||
func IsMouseScrollKey(key interface{}) bool {
|
||||
func IsMouseScrollKey(key any) bool {
|
||||
switch key {
|
||||
case
|
||||
MouseWheelUp,
|
||||
@@ -1640,12 +1630,7 @@ func (g *Gui) StartTicking(ctx context.Context) {
|
||||
|
||||
// isBlacklisted reports whether the key is blacklisted
|
||||
func (g *Gui) isBlacklisted(k Key) bool {
|
||||
for _, j := range g.blacklist {
|
||||
if j == k {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
return slices.Contains(g.blacklist, k)
|
||||
}
|
||||
|
||||
func (g *Gui) Suspend() error {
|
||||
@@ -1699,13 +1684,13 @@ func (g *Gui) Snapshot() string {
|
||||
|
||||
builder := &strings.Builder{}
|
||||
|
||||
for y := 0; y < height; y++ {
|
||||
for y := range height {
|
||||
for x := 0; x < width; x++ {
|
||||
char, _, _, charWidth := g.screen.GetContent(x, y)
|
||||
char, _, charWidth := g.screen.Get(x, y)
|
||||
if charWidth == 0 {
|
||||
continue
|
||||
}
|
||||
builder.WriteRune(char)
|
||||
builder.WriteString(char)
|
||||
if charWidth > 1 {
|
||||
x += charWidth - 1
|
||||
}
|
||||
|
||||
1
vendor/github.com/jesseduffield/gocui/gui_others.go
generated
vendored
1
vendor/github.com/jesseduffield/gocui/gui_others.go
generated
vendored
@@ -3,7 +3,6 @@
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build !windows
|
||||
// +build !windows
|
||||
|
||||
package gocui
|
||||
|
||||
|
||||
1
vendor/github.com/jesseduffield/gocui/gui_windows.go
generated
vendored
1
vendor/github.com/jesseduffield/gocui/gui_windows.go
generated
vendored
@@ -3,7 +3,6 @@
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build windows
|
||||
// +build windows
|
||||
|
||||
package gocui
|
||||
|
||||
|
||||
16
vendor/github.com/jesseduffield/gocui/keybinding.go
generated
vendored
16
vendor/github.com/jesseduffield/gocui/keybinding.go
generated
vendored
@@ -28,7 +28,7 @@ type keybinding struct {
|
||||
|
||||
// Parse takes the input string and extracts the keybinding.
|
||||
// Returns a Key / rune, a Modifier and an error.
|
||||
func Parse(input string) (interface{}, Modifier, error) {
|
||||
func Parse(input string) (any, Modifier, error) {
|
||||
if len(input) == 1 {
|
||||
_, r, err := getKey(rune(input[0]))
|
||||
if err != nil {
|
||||
@@ -40,8 +40,8 @@ func Parse(input string) (interface{}, Modifier, error) {
|
||||
var modifier Modifier
|
||||
cleaned := make([]string, 0)
|
||||
|
||||
tokens := strings.Split(input, "+")
|
||||
for _, t := range tokens {
|
||||
tokens := strings.SplitSeq(input, "+")
|
||||
for t := range tokens {
|
||||
normalized := strings.Title(strings.ToLower(t))
|
||||
if t == "Alt" {
|
||||
modifier = ModAlt
|
||||
@@ -59,8 +59,8 @@ func Parse(input string) (interface{}, Modifier, error) {
|
||||
}
|
||||
|
||||
// ParseAll takes an array of strings and returns a map of all keybindings.
|
||||
func ParseAll(input []string) (map[interface{}]Modifier, error) {
|
||||
ret := make(map[interface{}]Modifier)
|
||||
func ParseAll(input []string) (map[any]Modifier, error) {
|
||||
ret := make(map[any]Modifier)
|
||||
for _, i := range input {
|
||||
k, m, err := Parse(i)
|
||||
if err != nil {
|
||||
@@ -73,7 +73,7 @@ func ParseAll(input []string) (map[interface{}]Modifier, error) {
|
||||
|
||||
// MustParse takes the input string and returns a Key / rune and a Modifier.
|
||||
// It will panic if any error occured.
|
||||
func MustParse(input string) (interface{}, Modifier) {
|
||||
func MustParse(input string) (any, Modifier) {
|
||||
k, m, err := Parse(input)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
@@ -83,7 +83,7 @@ func MustParse(input string) (interface{}, Modifier) {
|
||||
|
||||
// MustParseAll takes an array of strings and returns a map of all keybindings.
|
||||
// It will panic if any error occured.
|
||||
func MustParseAll(input []string) map[interface{}]Modifier {
|
||||
func MustParseAll(input []string) map[any]Modifier {
|
||||
result, err := ParseAll(input)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
@@ -103,7 +103,7 @@ func newKeybinding(viewname string, key Key, ch rune, mod Modifier, handler func
|
||||
return kb
|
||||
}
|
||||
|
||||
func eventMatchesKey(ev *GocuiEvent, key interface{}) bool {
|
||||
func eventMatchesKey(ev *GocuiEvent, key any) bool {
|
||||
// assuming ModNone for now
|
||||
if ev.Mod != ModNone {
|
||||
return false
|
||||
|
||||
10
vendor/github.com/jesseduffield/gocui/loader.go
generated
vendored
10
vendor/github.com/jesseduffield/gocui/loader.go
generated
vendored
@@ -11,7 +11,7 @@ func (v *View) loaderLines() [][]cell {
|
||||
} else {
|
||||
duplicate[i] = make([]cell, len(v.lines[i])+2)
|
||||
copy(duplicate[i], v.lines[i])
|
||||
duplicate[i][len(duplicate[i])-2] = cell{chr: ' '}
|
||||
duplicate[i][len(duplicate[i])-2] = cell{chr: " "}
|
||||
duplicate[i][len(duplicate[i])-1] = Loader()
|
||||
}
|
||||
}
|
||||
@@ -21,13 +21,11 @@ func (v *View) loaderLines() [][]cell {
|
||||
|
||||
// Loader can show a loading animation
|
||||
func Loader() cell {
|
||||
characters := "|/-\\"
|
||||
frames := []string{"|", "/", "-", "\\"}
|
||||
now := time.Now()
|
||||
nanos := now.UnixNano()
|
||||
index := nanos / 50000000 % int64(len(characters))
|
||||
str := characters[index : index+1]
|
||||
chr := []rune(str)[0]
|
||||
index := nanos / 50000000 % int64(len(frames))
|
||||
return cell{
|
||||
chr: chr,
|
||||
chr: frames[index],
|
||||
}
|
||||
}
|
||||
|
||||
8
vendor/github.com/jesseduffield/gocui/tcell_driver.go
generated
vendored
8
vendor/github.com/jesseduffield/gocui/tcell_driver.go
generated
vendored
@@ -6,7 +6,6 @@ package gocui
|
||||
|
||||
import (
|
||||
"github.com/gdamore/tcell/v2"
|
||||
"github.com/mattn/go-runewidth"
|
||||
)
|
||||
|
||||
// We probably don't want this being a global variable for YOLO for now
|
||||
@@ -54,7 +53,6 @@ var runeReplacements = map[rune]string{
|
||||
|
||||
// tcellInit initializes tcell screen for use.
|
||||
func (g *Gui) tcellInit(runeReplacements map[rune]string) error {
|
||||
runewidth.DefaultCondition.EastAsianWidth = false
|
||||
tcell.SetEncodingFallback(tcell.EncodingFallbackASCII)
|
||||
|
||||
if s, e := tcell.NewScreen(); e != nil {
|
||||
@@ -97,10 +95,10 @@ func (g *Gui) tcellInitSimulation(width int, height int) error {
|
||||
}
|
||||
|
||||
// tcellSetCell sets the character cell at a given location to the given
|
||||
// content (rune) and attributes using provided OutputMode
|
||||
func tcellSetCell(x, y int, ch rune, fg, bg Attribute, outputMode OutputMode) {
|
||||
// content (grapheme cluster) and attributes using provided OutputMode
|
||||
func tcellSetCell(x, y int, ch string, fg, bg Attribute, outputMode OutputMode) {
|
||||
st := getTcellStyle(oldStyle{fg: fg, bg: bg, outputMode: outputMode})
|
||||
Screen.SetContent(x, y, ch, nil, st)
|
||||
Screen.Put(x, y, ch, st)
|
||||
}
|
||||
|
||||
// getTcellStyle creates tcell.Style from Attributes
|
||||
|
||||
416
vendor/github.com/jesseduffield/gocui/text_area.go
generated
vendored
416
vendor/github.com/jesseduffield/gocui/text_area.go
generated
vendored
@@ -2,9 +2,10 @@ package gocui
|
||||
|
||||
import (
|
||||
"regexp"
|
||||
"slices"
|
||||
"strings"
|
||||
|
||||
"github.com/mattn/go-runewidth"
|
||||
"github.com/rivo/uniseg"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -12,55 +13,114 @@ const (
|
||||
WORD_SEPARATORS = "*?_+-.[]~=/&;!#$%^(){}<>"
|
||||
)
|
||||
|
||||
type CursorMapping struct {
|
||||
Orig int
|
||||
Wrapped int
|
||||
type TextAreaCell struct {
|
||||
char string // string because it could be a multi-rune grapheme cluster
|
||||
width int
|
||||
x, y int // cell coordinates
|
||||
contentIndex int // byte index into the original content
|
||||
}
|
||||
|
||||
// returns the cursor x,y position after this cell
|
||||
func (c *TextAreaCell) nextCursorXY() (int, int) {
|
||||
if c.char == "\n" {
|
||||
return 0, c.y + 1
|
||||
}
|
||||
return c.x + c.width, c.y
|
||||
}
|
||||
|
||||
type TextArea struct {
|
||||
content []rune
|
||||
wrappedContent []rune
|
||||
cursorMapping []CursorMapping
|
||||
cursor int
|
||||
overwrite bool
|
||||
clipboard string
|
||||
AutoWrap bool
|
||||
AutoWrapWidth int
|
||||
content string
|
||||
cells []TextAreaCell
|
||||
cursor int // position in content, as an index into the byte array
|
||||
overwrite bool
|
||||
clipboard string
|
||||
AutoWrap bool
|
||||
AutoWrapWidth int
|
||||
}
|
||||
|
||||
func AutoWrapContent(content []rune, autoWrapWidth int) ([]rune, []CursorMapping) {
|
||||
estimatedNumberOfSoftLineBreaks := len(content) / autoWrapWidth
|
||||
cursorMapping := make([]CursorMapping, 0, estimatedNumberOfSoftLineBreaks)
|
||||
wrappedContent := make([]rune, 0, len(content)+estimatedNumberOfSoftLineBreaks)
|
||||
func stringToTextAreaCells(str string) []TextAreaCell {
|
||||
result := make([]TextAreaCell, 0, len(str))
|
||||
|
||||
contentIndex := 0
|
||||
state := -1
|
||||
for len(str) > 0 {
|
||||
var c string
|
||||
var w int
|
||||
c, str, w, state = uniseg.FirstGraphemeClusterInString(str, state)
|
||||
// only set char, width, and contentIndex; x and y will be set later
|
||||
result = append(result, TextAreaCell{char: c, width: w, contentIndex: contentIndex})
|
||||
contentIndex += len(c)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// Returns the indices in content where soft line breaks occur due to auto-wrapping to the given width.
|
||||
func AutoWrapContent(content string, autoWrapWidth int) []int {
|
||||
_, softLineBreakIndices := contentToCells(content, autoWrapWidth)
|
||||
return softLineBreakIndices
|
||||
}
|
||||
|
||||
func contentToCells(content string, autoWrapWidth int) ([]TextAreaCell, []int) {
|
||||
estimatedNumberOfSoftLineBreaks := 0
|
||||
if autoWrapWidth > 0 {
|
||||
estimatedNumberOfSoftLineBreaks = len(content) / autoWrapWidth
|
||||
}
|
||||
softLineBreakIndices := make([]int, 0, estimatedNumberOfSoftLineBreaks)
|
||||
result := make([]TextAreaCell, 0, len(content)+estimatedNumberOfSoftLineBreaks)
|
||||
startOfLine := 0
|
||||
currentLineWidth := 0
|
||||
indexOfLastWhitespace := -1
|
||||
var footNoteMatcher footNoteMatcher
|
||||
|
||||
for currentPos, r := range content {
|
||||
if r == '\n' {
|
||||
wrappedContent = append(wrappedContent, content[startOfLine:currentPos+1]...)
|
||||
cells := stringToTextAreaCells(content)
|
||||
y := 0
|
||||
|
||||
appendCellsSinceLineStart := func(to int) {
|
||||
x := 0
|
||||
for i := startOfLine; i < to; i++ {
|
||||
cells[i].x = x
|
||||
cells[i].y = y
|
||||
x += cells[i].width
|
||||
}
|
||||
|
||||
result = append(result, cells[startOfLine:to]...)
|
||||
}
|
||||
|
||||
for currentPos, c := range cells {
|
||||
if c.char == "\n" {
|
||||
appendCellsSinceLineStart(currentPos + 1)
|
||||
y++
|
||||
startOfLine = currentPos + 1
|
||||
indexOfLastWhitespace = -1
|
||||
currentLineWidth = 0
|
||||
footNoteMatcher.reset()
|
||||
} else {
|
||||
if r == ' ' && !footNoteMatcher.isFootNote() {
|
||||
currentLineWidth += c.width
|
||||
if c.char == " " && !footNoteMatcher.isFootNote() {
|
||||
indexOfLastWhitespace = currentPos + 1
|
||||
} else if currentPos-startOfLine >= autoWrapWidth && indexOfLastWhitespace >= 0 {
|
||||
} else if autoWrapWidth > 0 && currentLineWidth > autoWrapWidth && indexOfLastWhitespace >= 0 {
|
||||
wrapAt := indexOfLastWhitespace
|
||||
wrappedContent = append(wrappedContent, content[startOfLine:wrapAt]...)
|
||||
wrappedContent = append(wrappedContent, '\n')
|
||||
cursorMapping = append(cursorMapping, CursorMapping{wrapAt, len(wrappedContent)})
|
||||
appendCellsSinceLineStart(wrapAt)
|
||||
contentIndex := cells[wrapAt].contentIndex
|
||||
y++
|
||||
result = append(result, TextAreaCell{char: "\n", width: 1, contentIndex: contentIndex, x: 0, y: y})
|
||||
softLineBreakIndices = append(softLineBreakIndices, contentIndex)
|
||||
startOfLine = wrapAt
|
||||
indexOfLastWhitespace = -1
|
||||
currentLineWidth = 0
|
||||
for _, c1 := range cells[startOfLine : currentPos+1] {
|
||||
currentLineWidth += c1.width
|
||||
}
|
||||
footNoteMatcher.reset()
|
||||
}
|
||||
footNoteMatcher.addRune(r)
|
||||
|
||||
footNoteMatcher.addCharacter(c.char)
|
||||
}
|
||||
}
|
||||
|
||||
wrappedContent = append(wrappedContent, content[startOfLine:]...)
|
||||
appendCellsSinceLineStart(len(cells))
|
||||
|
||||
return wrappedContent, cursorMapping
|
||||
return result, softLineBreakIndices
|
||||
}
|
||||
|
||||
var footNoteRe = regexp.MustCompile(`^\[\d+\]:\s*$`)
|
||||
@@ -70,20 +130,20 @@ type footNoteMatcher struct {
|
||||
didFailToMatch bool
|
||||
}
|
||||
|
||||
func (self *footNoteMatcher) addRune(r rune) {
|
||||
func (self *footNoteMatcher) addCharacter(chr string) {
|
||||
if self.didFailToMatch {
|
||||
// don't bother tracking the rune if we know it can't possibly match any more
|
||||
return
|
||||
}
|
||||
|
||||
if self.lineStr.Len() == 0 && r != '[' {
|
||||
if self.lineStr.Len() == 0 && chr != "[" {
|
||||
// fail early if the first rune of a line isn't a '['; this is mainly to avoid a (possibly
|
||||
// expensive) regex match
|
||||
self.didFailToMatch = true
|
||||
return
|
||||
}
|
||||
|
||||
self.lineStr.WriteRune(r)
|
||||
self.lineStr.WriteString(chr)
|
||||
}
|
||||
|
||||
func (self *footNoteMatcher) isFootNote() bool {
|
||||
@@ -107,26 +167,29 @@ func (self *footNoteMatcher) reset() {
|
||||
self.didFailToMatch = false
|
||||
}
|
||||
|
||||
func (self *TextArea) autoWrapContent() {
|
||||
if self.AutoWrap {
|
||||
self.wrappedContent, self.cursorMapping = AutoWrapContent(self.content, self.AutoWrapWidth)
|
||||
} else {
|
||||
self.wrappedContent, self.cursorMapping = self.content, []CursorMapping{}
|
||||
func (self *TextArea) updateCells() {
|
||||
width := self.AutoWrapWidth
|
||||
if !self.AutoWrap {
|
||||
width = -1
|
||||
}
|
||||
|
||||
self.cells, _ = contentToCells(self.content, width)
|
||||
}
|
||||
|
||||
func (self *TextArea) TypeRune(r rune) {
|
||||
func (self *TextArea) typeCharacter(ch string) {
|
||||
widthToDelete := 0
|
||||
if self.overwrite && !self.atEnd() {
|
||||
self.content[self.cursor] = r
|
||||
} else {
|
||||
self.content = append(
|
||||
self.content[:self.cursor],
|
||||
append([]rune{r}, self.content[self.cursor:]...)...,
|
||||
)
|
||||
s, _, _, _ := uniseg.FirstGraphemeClusterInString(self.content[self.cursor:], -1)
|
||||
widthToDelete = len(s)
|
||||
}
|
||||
self.autoWrapContent()
|
||||
|
||||
self.cursor++
|
||||
self.content = self.content[:self.cursor] + ch + self.content[self.cursor+widthToDelete:]
|
||||
self.cursor += len(ch)
|
||||
}
|
||||
|
||||
func (self *TextArea) TypeCharacter(ch string) {
|
||||
self.typeCharacter(ch)
|
||||
self.updateCells()
|
||||
}
|
||||
|
||||
func (self *TextArea) BackSpaceChar() {
|
||||
@@ -134,9 +197,14 @@ func (self *TextArea) BackSpaceChar() {
|
||||
return
|
||||
}
|
||||
|
||||
self.content = append(self.content[:self.cursor-1], self.content[self.cursor:]...)
|
||||
self.autoWrapContent()
|
||||
self.cursor--
|
||||
cellCursor := self.contentCursorToCellCursor(self.cursor)
|
||||
widthToDelete := len(self.cells[cellCursor-1].char)
|
||||
|
||||
oldCursor := self.cursor
|
||||
self.cursor -= widthToDelete
|
||||
self.content = self.content[:self.cursor] + self.content[oldCursor:]
|
||||
|
||||
self.updateCells()
|
||||
}
|
||||
|
||||
func (self *TextArea) DeleteChar() {
|
||||
@@ -144,8 +212,10 @@ func (self *TextArea) DeleteChar() {
|
||||
return
|
||||
}
|
||||
|
||||
self.content = append(self.content[:self.cursor], self.content[self.cursor+1:]...)
|
||||
self.autoWrapContent()
|
||||
s, _, _, _ := uniseg.FirstGraphemeClusterInString(self.content[self.cursor:], -1)
|
||||
widthToDelete := len(s)
|
||||
self.content = self.content[:self.cursor] + self.content[self.cursor+widthToDelete:]
|
||||
self.updateCells()
|
||||
}
|
||||
|
||||
func (self *TextArea) MoveCursorLeft() {
|
||||
@@ -153,7 +223,8 @@ func (self *TextArea) MoveCursorLeft() {
|
||||
return
|
||||
}
|
||||
|
||||
self.cursor--
|
||||
cellCursor := self.contentCursorToCellCursor(self.cursor)
|
||||
self.cursor -= len(self.cells[cellCursor-1].char)
|
||||
}
|
||||
|
||||
func (self *TextArea) MoveCursorRight() {
|
||||
@@ -161,31 +232,38 @@ func (self *TextArea) MoveCursorRight() {
|
||||
return
|
||||
}
|
||||
|
||||
self.cursor++
|
||||
s, _, _, _ := uniseg.FirstGraphemeClusterInString(self.content[self.cursor:], -1)
|
||||
self.cursor += len(s)
|
||||
}
|
||||
|
||||
func (self *TextArea) MoveLeftWord() {
|
||||
func (self *TextArea) newCursorForMoveLeftWord() int {
|
||||
if self.cursor == 0 {
|
||||
return
|
||||
return 0
|
||||
}
|
||||
if self.atLineStart() {
|
||||
self.cursor--
|
||||
return
|
||||
return self.cursor - 1
|
||||
}
|
||||
|
||||
for !self.atLineStart() && strings.ContainsRune(WHITESPACES, self.content[self.cursor-1]) {
|
||||
self.cursor--
|
||||
cellCursor := self.contentCursorToCellCursor(self.cursor)
|
||||
for cellCursor > 0 && (self.isSoftLineBreak(cellCursor-1) || strings.Contains(WHITESPACES, self.cells[cellCursor-1].char)) {
|
||||
cellCursor--
|
||||
}
|
||||
separators := false
|
||||
for !self.atLineStart() && strings.ContainsRune(WORD_SEPARATORS, self.content[self.cursor-1]) {
|
||||
self.cursor--
|
||||
for cellCursor > 0 && strings.Contains(WORD_SEPARATORS, self.cells[cellCursor-1].char) {
|
||||
cellCursor--
|
||||
separators = true
|
||||
}
|
||||
if !separators {
|
||||
for !self.atLineStart() && !strings.ContainsRune(WHITESPACES+WORD_SEPARATORS, self.content[self.cursor-1]) {
|
||||
self.cursor--
|
||||
for cellCursor > 0 && self.cells[cellCursor-1].char != "\n" && !strings.Contains(WHITESPACES+WORD_SEPARATORS, self.cells[cellCursor-1].char) {
|
||||
cellCursor--
|
||||
}
|
||||
}
|
||||
|
||||
return self.cellCursorToContentCursor(cellCursor)
|
||||
}
|
||||
|
||||
func (self *TextArea) MoveLeftWord() {
|
||||
self.cursor = self.newCursorForMoveLeftWord()
|
||||
}
|
||||
|
||||
func (self *TextArea) MoveRightWord() {
|
||||
@@ -197,19 +275,22 @@ func (self *TextArea) MoveRightWord() {
|
||||
return
|
||||
}
|
||||
|
||||
for !self.atLineEnd() && strings.ContainsRune(WHITESPACES, self.content[self.cursor]) {
|
||||
self.cursor++
|
||||
cellCursor := self.contentCursorToCellCursor(self.cursor)
|
||||
for cellCursor < len(self.cells) && (self.isSoftLineBreak(cellCursor) || strings.Contains(WHITESPACES, self.cells[cellCursor].char)) {
|
||||
cellCursor++
|
||||
}
|
||||
separators := false
|
||||
for !self.atLineEnd() && strings.ContainsRune(WORD_SEPARATORS, self.content[self.cursor]) {
|
||||
self.cursor++
|
||||
for cellCursor < len(self.cells) && strings.Contains(WORD_SEPARATORS, self.cells[cellCursor].char) {
|
||||
cellCursor++
|
||||
separators = true
|
||||
}
|
||||
if !separators {
|
||||
for !self.atLineEnd() && !strings.ContainsRune(WHITESPACES+WORD_SEPARATORS, self.content[self.cursor]) {
|
||||
self.cursor++
|
||||
for cellCursor < len(self.cells) && self.cells[cellCursor].char != "\n" && !strings.Contains(WHITESPACES+WORD_SEPARATORS, self.cells[cellCursor].char) {
|
||||
cellCursor++
|
||||
}
|
||||
}
|
||||
|
||||
self.cursor = self.cellCursorToContentCursor(cellCursor)
|
||||
}
|
||||
|
||||
func (self *TextArea) MoveCursorUp() {
|
||||
@@ -223,11 +304,15 @@ func (self *TextArea) MoveCursorDown() {
|
||||
}
|
||||
|
||||
func (self *TextArea) GetContent() string {
|
||||
return string(self.wrappedContent)
|
||||
var b strings.Builder
|
||||
for _, c := range self.cells {
|
||||
b.WriteString(c.char)
|
||||
}
|
||||
return b.String()
|
||||
}
|
||||
|
||||
func (self *TextArea) GetUnwrappedContent() string {
|
||||
return string(self.content)
|
||||
return self.content
|
||||
}
|
||||
|
||||
func (self *TextArea) ToggleOverwrite() {
|
||||
@@ -246,9 +331,9 @@ func (self *TextArea) DeleteToStartOfLine() {
|
||||
return
|
||||
}
|
||||
|
||||
self.content = append(self.content[:self.cursor-1], self.content[self.cursor:]...)
|
||||
self.content = self.content[:self.cursor-1] + self.content[self.cursor:]
|
||||
self.cursor--
|
||||
self.autoWrapContent()
|
||||
self.updateCells()
|
||||
return
|
||||
}
|
||||
|
||||
@@ -263,9 +348,9 @@ func (self *TextArea) DeleteToStartOfLine() {
|
||||
// otherwise, you delete everything up to the start of the current line, without
|
||||
// deleting the newline character
|
||||
newlineIndex := self.closestNewlineOnLeft()
|
||||
self.clipboard = string(self.content[newlineIndex+1 : self.cursor])
|
||||
self.content = append(self.content[:newlineIndex+1], self.content[self.cursor:]...)
|
||||
self.autoWrapContent()
|
||||
self.clipboard = self.content[newlineIndex+1 : self.cursor]
|
||||
self.content = self.content[:newlineIndex+1] + self.content[self.cursor:]
|
||||
self.updateCells()
|
||||
self.cursor = newlineIndex + 1
|
||||
}
|
||||
|
||||
@@ -276,8 +361,8 @@ func (self *TextArea) DeleteToEndOfLine() {
|
||||
|
||||
// if we're at the end of the line, delete just the newline character
|
||||
if self.atLineEnd() {
|
||||
self.content = append(self.content[:self.cursor], self.content[self.cursor+1:]...)
|
||||
self.autoWrapContent()
|
||||
self.content = self.content[:self.cursor] + self.content[self.cursor+1:]
|
||||
self.updateCells()
|
||||
return
|
||||
}
|
||||
|
||||
@@ -290,9 +375,9 @@ func (self *TextArea) DeleteToEndOfLine() {
|
||||
}
|
||||
|
||||
lineEndIndex := self.closestNewlineOnRight()
|
||||
self.clipboard = string(self.content[self.cursor:lineEndIndex])
|
||||
self.content = append(self.content[:self.cursor], self.content[lineEndIndex:]...)
|
||||
self.autoWrapContent()
|
||||
self.clipboard = self.content[self.cursor:lineEndIndex]
|
||||
self.content = self.content[:self.cursor] + self.content[lineEndIndex:]
|
||||
self.updateCells()
|
||||
}
|
||||
|
||||
func (self *TextArea) GoToStartOfLine() {
|
||||
@@ -300,28 +385,30 @@ func (self *TextArea) GoToStartOfLine() {
|
||||
return
|
||||
}
|
||||
|
||||
// otherwise, you delete everything up to the start of the current line, without
|
||||
// deleting the newline character
|
||||
newlineIndex := self.closestNewlineOnLeft()
|
||||
self.cursor = newlineIndex + 1
|
||||
}
|
||||
|
||||
func (self *TextArea) closestNewlineOnLeft() int {
|
||||
wrappedCursor := self.origCursorToWrappedCursor(self.cursor)
|
||||
cellCursor := self.contentCursorToCellCursor(self.cursor)
|
||||
|
||||
newlineIndex := -1
|
||||
newlineCellIndex := -1
|
||||
|
||||
for i, r := range self.wrappedContent[0:wrappedCursor] {
|
||||
if r == '\n' {
|
||||
newlineIndex = i
|
||||
for i, c := range self.cells[0:cellCursor] {
|
||||
if c.char == "\n" {
|
||||
newlineCellIndex = i
|
||||
}
|
||||
}
|
||||
|
||||
unwrappedNewlineIndex := self.wrappedCursorToOrigCursor(newlineIndex)
|
||||
if unwrappedNewlineIndex >= 0 && self.content[unwrappedNewlineIndex] != '\n' {
|
||||
unwrappedNewlineIndex--
|
||||
if newlineCellIndex == -1 {
|
||||
return -1
|
||||
}
|
||||
return unwrappedNewlineIndex
|
||||
|
||||
newlineContentIndex := self.cells[newlineCellIndex].contentIndex
|
||||
if self.content[newlineContentIndex] != '\n' {
|
||||
newlineContentIndex--
|
||||
}
|
||||
return newlineContentIndex
|
||||
}
|
||||
|
||||
func (self *TextArea) GoToEndOfLine() {
|
||||
@@ -335,11 +422,11 @@ func (self *TextArea) GoToEndOfLine() {
|
||||
}
|
||||
|
||||
func (self *TextArea) closestNewlineOnRight() int {
|
||||
wrappedCursor := self.origCursorToWrappedCursor(self.cursor)
|
||||
cellCursor := self.contentCursorToCellCursor(self.cursor)
|
||||
|
||||
for i, r := range self.wrappedContent[wrappedCursor:] {
|
||||
if r == '\n' {
|
||||
return self.wrappedCursorToOrigCursor(wrappedCursor + i)
|
||||
for i, c := range self.cells[cellCursor:] {
|
||||
if c.char == "\n" {
|
||||
return self.cellCursorToContentCursor(cellCursor + i)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -361,10 +448,15 @@ func (self *TextArea) atLineStart() bool {
|
||||
(len(self.content) > self.cursor-1 && self.content[self.cursor-1] == '\n')
|
||||
}
|
||||
|
||||
func (self *TextArea) isSoftLineBreak(cellCursor int) bool {
|
||||
cell := self.cells[cellCursor]
|
||||
return cell.char == "\n" && self.content[cell.contentIndex] != '\n'
|
||||
}
|
||||
|
||||
func (self *TextArea) atSoftLineStart() bool {
|
||||
wrappedCursor := self.origCursorToWrappedCursor(self.cursor)
|
||||
return wrappedCursor == 0 ||
|
||||
(len(self.wrappedContent) > wrappedCursor-1 && self.wrappedContent[wrappedCursor-1] == '\n')
|
||||
cellCursor := self.contentCursorToCellCursor(self.cursor)
|
||||
return cellCursor == 0 ||
|
||||
(len(self.cells) > cellCursor-1 && self.cells[cellCursor-1].char == "\n")
|
||||
}
|
||||
|
||||
func (self *TextArea) atLineEnd() bool {
|
||||
@@ -373,91 +465,61 @@ func (self *TextArea) atLineEnd() bool {
|
||||
}
|
||||
|
||||
func (self *TextArea) atSoftLineEnd() bool {
|
||||
wrappedCursor := self.origCursorToWrappedCursor(self.cursor)
|
||||
return wrappedCursor == len(self.wrappedContent) ||
|
||||
(len(self.wrappedContent) > wrappedCursor+1 && self.wrappedContent[wrappedCursor+1] == '\n')
|
||||
cellCursor := self.contentCursorToCellCursor(self.cursor)
|
||||
return cellCursor == len(self.cells) ||
|
||||
(len(self.cells) > cellCursor+1 && self.cells[cellCursor+1].char == "\n")
|
||||
}
|
||||
|
||||
func (self *TextArea) BackSpaceWord() {
|
||||
if self.cursor == 0 {
|
||||
return
|
||||
}
|
||||
if self.atLineStart() {
|
||||
self.BackSpaceChar()
|
||||
newCursor := self.newCursorForMoveLeftWord()
|
||||
if newCursor == self.cursor {
|
||||
return
|
||||
}
|
||||
|
||||
right := self.cursor
|
||||
for !self.atLineStart() && strings.ContainsRune(WHITESPACES, self.content[self.cursor-1]) {
|
||||
self.cursor--
|
||||
clipboard := self.content[newCursor:self.cursor]
|
||||
if clipboard != "\n" {
|
||||
self.clipboard = clipboard
|
||||
}
|
||||
separators := false
|
||||
for !self.atLineStart() && strings.ContainsRune(WORD_SEPARATORS, self.content[self.cursor-1]) {
|
||||
self.cursor--
|
||||
separators = true
|
||||
}
|
||||
if !separators {
|
||||
for !self.atLineStart() && !strings.ContainsRune(WHITESPACES+WORD_SEPARATORS, self.content[self.cursor-1]) {
|
||||
self.cursor--
|
||||
}
|
||||
}
|
||||
|
||||
self.clipboard = string(self.content[self.cursor:right])
|
||||
self.content = append(self.content[:self.cursor], self.content[right:]...)
|
||||
self.autoWrapContent()
|
||||
self.content = self.content[:newCursor] + self.content[self.cursor:]
|
||||
self.cursor = newCursor
|
||||
self.updateCells()
|
||||
}
|
||||
|
||||
func (self *TextArea) Yank() {
|
||||
self.TypeString(self.clipboard)
|
||||
}
|
||||
|
||||
func origCursorToWrappedCursor(origCursor int, cursorMapping []CursorMapping) int {
|
||||
prevMapping := CursorMapping{0, 0}
|
||||
for _, mapping := range cursorMapping {
|
||||
if origCursor < mapping.Orig {
|
||||
break
|
||||
}
|
||||
prevMapping = mapping
|
||||
func (self *TextArea) contentCursorToCellCursor(origCursor int) int {
|
||||
idx, _ := slices.BinarySearchFunc(self.cells, origCursor, func(cell TextAreaCell, cursor int) int {
|
||||
return cell.contentIndex - cursor
|
||||
})
|
||||
for idx < len(self.cells)-1 && self.cells[idx+1].contentIndex == origCursor {
|
||||
idx++
|
||||
}
|
||||
return idx
|
||||
}
|
||||
|
||||
func (self *TextArea) cellCursorToContentCursor(cellCursor int) int {
|
||||
if cellCursor >= len(self.cells) {
|
||||
return len(self.content)
|
||||
}
|
||||
|
||||
return origCursor + prevMapping.Wrapped - prevMapping.Orig
|
||||
}
|
||||
|
||||
func (self *TextArea) origCursorToWrappedCursor(origCursor int) int {
|
||||
return origCursorToWrappedCursor(origCursor, self.cursorMapping)
|
||||
}
|
||||
|
||||
func wrappedCursorToOrigCursor(wrappedCursor int, cursorMapping []CursorMapping) int {
|
||||
prevMapping := CursorMapping{0, 0}
|
||||
for _, mapping := range cursorMapping {
|
||||
if wrappedCursor < mapping.Wrapped {
|
||||
break
|
||||
}
|
||||
prevMapping = mapping
|
||||
}
|
||||
|
||||
return wrappedCursor + prevMapping.Orig - prevMapping.Wrapped
|
||||
}
|
||||
|
||||
func (self *TextArea) wrappedCursorToOrigCursor(wrappedCursor int) int {
|
||||
return wrappedCursorToOrigCursor(wrappedCursor, self.cursorMapping)
|
||||
return self.cells[cellCursor].contentIndex
|
||||
}
|
||||
|
||||
func (self *TextArea) GetCursorXY() (int, int) {
|
||||
cursorX := 0
|
||||
cursorY := 0
|
||||
wrappedCursor := self.origCursorToWrappedCursor(self.cursor)
|
||||
for _, r := range self.wrappedContent[0:wrappedCursor] {
|
||||
if r == '\n' {
|
||||
cursorY++
|
||||
cursorX = 0
|
||||
} else {
|
||||
chWidth := runewidth.RuneWidth(r)
|
||||
cursorX += chWidth
|
||||
}
|
||||
if len(self.cells) == 0 {
|
||||
return 0, 0
|
||||
}
|
||||
|
||||
return cursorX, cursorY
|
||||
cellCursor := self.contentCursorToCellCursor(self.cursor)
|
||||
if cellCursor >= len(self.cells) {
|
||||
return self.cells[len(self.cells)-1].nextCursorXY()
|
||||
}
|
||||
if cellCursor > 0 && self.cells[cellCursor].char == "\n" {
|
||||
return self.cells[cellCursor-1].nextCursorXY()
|
||||
}
|
||||
cell := self.cells[cellCursor]
|
||||
return cell.x, cell.y
|
||||
}
|
||||
|
||||
// takes an x,y position and maps it to a 1D cursor position
|
||||
@@ -470,25 +532,24 @@ func (self *TextArea) SetCursor2D(x int, y int) {
|
||||
}
|
||||
|
||||
newCursor := 0
|
||||
for _, r := range self.wrappedContent {
|
||||
for _, c := range self.cells {
|
||||
if x <= 0 && y == 0 {
|
||||
self.cursor = self.wrappedCursorToOrigCursor(newCursor)
|
||||
if self.wrappedContent[newCursor] == '\n' {
|
||||
self.cursor = self.cellCursorToContentCursor(newCursor)
|
||||
if self.cells[newCursor].char == "\n" {
|
||||
self.moveLeftFromSoftLineBreak()
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
if r == '\n' {
|
||||
if c.char == "\n" {
|
||||
if y == 0 {
|
||||
self.cursor = self.wrappedCursorToOrigCursor(newCursor)
|
||||
self.cursor = self.cellCursorToContentCursor(newCursor)
|
||||
self.moveLeftFromSoftLineBreak()
|
||||
return
|
||||
}
|
||||
y--
|
||||
} else if y == 0 {
|
||||
chWidth := runewidth.RuneWidth(r)
|
||||
x -= chWidth
|
||||
x -= c.width
|
||||
}
|
||||
|
||||
newCursor++
|
||||
@@ -500,17 +561,22 @@ func (self *TextArea) SetCursor2D(x int, y int) {
|
||||
return
|
||||
}
|
||||
|
||||
self.cursor = self.wrappedCursorToOrigCursor(newCursor)
|
||||
self.cursor = self.cellCursorToContentCursor(newCursor)
|
||||
}
|
||||
|
||||
func (self *TextArea) Clear() {
|
||||
self.content = []rune{}
|
||||
self.wrappedContent = []rune{}
|
||||
self.content = ""
|
||||
self.cells = nil
|
||||
self.cursor = 0
|
||||
}
|
||||
|
||||
func (self *TextArea) TypeString(str string) {
|
||||
for _, r := range str {
|
||||
self.TypeRune(r)
|
||||
state := -1
|
||||
for str != "" {
|
||||
var chr string
|
||||
chr, str, _, state = uniseg.FirstGraphemeClusterInString(str, state)
|
||||
self.typeCharacter(chr)
|
||||
}
|
||||
|
||||
self.updateCells()
|
||||
}
|
||||
|
||||
255
vendor/github.com/jesseduffield/gocui/view.go
generated
vendored
255
vendor/github.com/jesseduffield/gocui/view.go
generated
vendored
@@ -5,7 +5,6 @@
|
||||
package gocui
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"strings"
|
||||
@@ -14,7 +13,7 @@ import (
|
||||
"unicode/utf8"
|
||||
|
||||
"github.com/gdamore/tcell/v2"
|
||||
"github.com/mattn/go-runewidth"
|
||||
"github.com/rivo/uniseg"
|
||||
)
|
||||
|
||||
// Constants for overlapping edges
|
||||
@@ -160,7 +159,7 @@ type View struct {
|
||||
|
||||
// If Mask is true, the View will display the mask instead of the real
|
||||
// content
|
||||
Mask rune
|
||||
Mask string
|
||||
|
||||
// Overlaps describes which edges are overlapping with another view's edges
|
||||
Overlaps byte
|
||||
@@ -397,20 +396,25 @@ type viewLine struct {
|
||||
}
|
||||
|
||||
type cell struct {
|
||||
chr rune
|
||||
chr string // a grapheme cluster
|
||||
width int // number of terminal cells occupied by chr (always 1 or 2)
|
||||
bgColor, fgColor Attribute
|
||||
hyperlink string
|
||||
}
|
||||
|
||||
type lineType []cell
|
||||
|
||||
func characterEquals(chr []byte, b byte) bool {
|
||||
return len(chr) == 1 && chr[0] == b
|
||||
}
|
||||
|
||||
// String returns a string from a given cell slice.
|
||||
func (l lineType) String() string {
|
||||
str := ""
|
||||
var str strings.Builder
|
||||
for _, c := range l {
|
||||
str += string(c.chr)
|
||||
str.WriteString(c.chr)
|
||||
}
|
||||
return str
|
||||
return str.String()
|
||||
}
|
||||
|
||||
// NewView returns a new View object.
|
||||
@@ -492,16 +496,16 @@ func (v *View) Name() string {
|
||||
return v.name
|
||||
}
|
||||
|
||||
// setRune sets a rune at the given point relative to the view. It applies the
|
||||
// specified colors, taking into account if the cell must be highlighted. Also,
|
||||
// it checks if the position is valid.
|
||||
func (v *View) setRune(x, y int, ch rune, fgColor, bgColor Attribute) {
|
||||
// setCharacter sets a character (grapheme cluster) at the given point relative to the view. It applies
|
||||
// the specified colors, taking into account if the cell must be highlighted. Also, it checks if the
|
||||
// position is valid.
|
||||
func (v *View) setCharacter(x, y int, ch string, fgColor, bgColor Attribute) {
|
||||
maxX, maxY := v.Size()
|
||||
if x < 0 || x >= maxX || y < 0 || y >= maxY {
|
||||
return
|
||||
}
|
||||
|
||||
if v.Mask != 0 {
|
||||
if v.Mask != "" {
|
||||
fgColor = v.FgColor
|
||||
bgColor = v.BgColor
|
||||
ch = v.Mask
|
||||
@@ -542,28 +546,14 @@ func (v *View) setRune(x, y int, ch rune, fgColor, bgColor Attribute) {
|
||||
fgColor |= AttrUnderline
|
||||
}
|
||||
|
||||
// Don't display NUL characters
|
||||
if ch == 0 {
|
||||
ch = ' '
|
||||
// Don't display empty characters
|
||||
if ch == "" {
|
||||
ch = " "
|
||||
}
|
||||
|
||||
tcellSetCell(v.x0+x+1, v.y0+y+1, ch, fgColor, bgColor, v.outMode)
|
||||
}
|
||||
|
||||
func min(a, b int) int {
|
||||
if a < b {
|
||||
return a
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
func max(a, b int) int {
|
||||
if a > b {
|
||||
return a
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
// SetCursor sets the cursor position of the view at the given point,
|
||||
// relative to the view. It is allowed to set the position to a point outside
|
||||
// the visible portion of the view, or even outside the content of the view.
|
||||
@@ -711,25 +701,26 @@ func (v *View) makeWriteable(x, y int) {
|
||||
}
|
||||
}
|
||||
|
||||
// writeCells copies []cell to specified location (x, y)
|
||||
// writeCells copies []cell to (v.wx, v.wy), and advances v.wx accordingly.
|
||||
// !!! caller MUST ensure that specified location (x, y) is writeable by calling makeWriteable
|
||||
func (v *View) writeCells(x, y int, cells []cell) {
|
||||
func (v *View) writeCells(cells []cell) {
|
||||
var newLen int
|
||||
// use maximum len available
|
||||
line := v.lines[y][:cap(v.lines[y])]
|
||||
maxCopy := len(line) - x
|
||||
line := v.lines[v.wy][:cap(v.lines[v.wy])]
|
||||
maxCopy := len(line) - v.wx
|
||||
if maxCopy < len(cells) {
|
||||
copy(line[x:], cells[:maxCopy])
|
||||
copy(line[v.wx:], cells[:maxCopy])
|
||||
line = append(line, cells[maxCopy:]...)
|
||||
newLen = len(line)
|
||||
} else { // maxCopy >= len(cells)
|
||||
copy(line[x:], cells)
|
||||
newLen = x + len(cells)
|
||||
if newLen < len(v.lines[y]) {
|
||||
newLen = len(v.lines[y])
|
||||
copy(line[v.wx:], cells)
|
||||
newLen = v.wx + len(cells)
|
||||
if newLen < len(v.lines[v.wy]) {
|
||||
newLen = len(v.lines[v.wy])
|
||||
}
|
||||
}
|
||||
v.lines[y] = line[:newLen]
|
||||
v.lines[v.wy] = line[:newLen]
|
||||
v.wx += len(cells)
|
||||
}
|
||||
|
||||
// Write appends a byte slice into the view's internal buffer. Because
|
||||
@@ -740,20 +731,12 @@ func (v *View) Write(p []byte) (n int, err error) {
|
||||
v.writeMutex.Lock()
|
||||
defer v.writeMutex.Unlock()
|
||||
|
||||
v.writeRunes(bytes.Runes(p))
|
||||
v.write(p)
|
||||
|
||||
return len(p), nil
|
||||
}
|
||||
|
||||
func (v *View) WriteRunes(p []rune) {
|
||||
v.writeMutex.Lock()
|
||||
defer v.writeMutex.Unlock()
|
||||
|
||||
v.writeRunes(p)
|
||||
}
|
||||
|
||||
// writeRunes copies slice of runes into internal lines buffer.
|
||||
func (v *View) writeRunes(p []rune) {
|
||||
func (v *View) write(p []byte) {
|
||||
v.tainted = true
|
||||
v.clearHover()
|
||||
|
||||
@@ -763,8 +746,9 @@ func (v *View) writeRunes(p []rune) {
|
||||
finishLine := func() {
|
||||
v.autoRenderHyperlinksInCurrentLine()
|
||||
if v.wx >= len(v.lines[v.wy]) {
|
||||
v.writeCells(v.wx, v.wy, []cell{{
|
||||
chr: 0,
|
||||
v.writeCells([]cell{{
|
||||
chr: "",
|
||||
width: 0,
|
||||
fgColor: 0,
|
||||
bgColor: 0,
|
||||
}})
|
||||
@@ -790,25 +774,29 @@ func (v *View) writeRunes(p []rune) {
|
||||
until--
|
||||
}
|
||||
|
||||
for _, r := range p[:until] {
|
||||
switch r {
|
||||
case '\n':
|
||||
state := -1
|
||||
var chr []byte
|
||||
var width int
|
||||
remaining := p[:until]
|
||||
|
||||
for len(remaining) > 0 {
|
||||
chr, remaining, width, state = uniseg.FirstGraphemeCluster(remaining, state)
|
||||
|
||||
switch {
|
||||
case characterEquals(chr, '\n'):
|
||||
finishLine()
|
||||
advanceToNextLine()
|
||||
case '\r':
|
||||
case characterEquals(chr, '\r'):
|
||||
finishLine()
|
||||
v.wx = 0
|
||||
default:
|
||||
truncateLine, cells := v.parseInput(r, v.wx, v.wy)
|
||||
truncateLine, cells := v.parseInput(chr, width, v.wx, v.wy)
|
||||
if cells == nil {
|
||||
continue
|
||||
}
|
||||
v.writeCells(v.wx, v.wy, cells)
|
||||
v.writeCells(cells)
|
||||
if truncateLine {
|
||||
length := v.wx + len(cells)
|
||||
v.lines[v.wy] = v.lines[v.wy][:length]
|
||||
} else {
|
||||
v.wx += len(cells)
|
||||
v.lines[v.wy] = v.lines[v.wy][:v.wx]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -825,20 +813,22 @@ func (v *View) writeRunes(p []rune) {
|
||||
// exported functions use the mutex. Non-exported functions are for internal use
|
||||
// and a calling function should use a mutex
|
||||
func (v *View) WriteString(s string) {
|
||||
v.WriteRunes([]rune(s))
|
||||
_, _ = v.Write([]byte(s))
|
||||
}
|
||||
|
||||
func (v *View) writeString(s string) {
|
||||
v.writeRunes([]rune(s))
|
||||
v.write([]byte(s))
|
||||
}
|
||||
|
||||
func findSubstring(line []cell, substringToFind []rune) int {
|
||||
for i := 0; i < len(line)-len(substringToFind); i++ {
|
||||
for j := 0; j < len(substringToFind); j++ {
|
||||
if line[i+j].chr != substringToFind[j] {
|
||||
var linkStartChars = []string{"h", "t", "t", "p", "s", ":", "/", "/"}
|
||||
|
||||
func findLinkStart(line []cell) int {
|
||||
for i := 0; i < len(line)-len(linkStartChars); i++ {
|
||||
for j := range linkStartChars {
|
||||
if line[i+j].chr != string(linkStartChars[j]) {
|
||||
break
|
||||
}
|
||||
if j == len(substringToFind)-1 {
|
||||
if j == len(linkStartChars)-1 {
|
||||
return i
|
||||
}
|
||||
}
|
||||
@@ -846,42 +836,43 @@ func findSubstring(line []cell, substringToFind []rune) int {
|
||||
return -1
|
||||
}
|
||||
|
||||
// We need a heuristic to find the end of a hyperlink. Searching for the
|
||||
// first character that is not a valid URI character is not quite good
|
||||
// enough, because in markdown it's common to have a hyperlink followed by a
|
||||
// ')', so we want to stop there. Hopefully URLs containing ')' are uncommon
|
||||
// enough that this is not a problem.
|
||||
var lineEndCharacters map[string]bool = map[string]bool{
|
||||
"": true,
|
||||
" ": true,
|
||||
"\n": true,
|
||||
">": true,
|
||||
"\"": true,
|
||||
")": true,
|
||||
}
|
||||
|
||||
func (v *View) autoRenderHyperlinksInCurrentLine() {
|
||||
if !v.AutoRenderHyperLinks {
|
||||
return
|
||||
}
|
||||
|
||||
// We need a heuristic to find the end of a hyperlink. Searching for the
|
||||
// first character that is not a valid URI character is not quite good
|
||||
// enough, because in markdown it's common to have a hyperlink followed by a
|
||||
// ')', so we want to stop there. Hopefully URLs containing ')' are uncommon
|
||||
// enough that this is not a problem.
|
||||
lineEndCharacters := map[rune]bool{
|
||||
'\000': true,
|
||||
' ': true,
|
||||
'\n': true,
|
||||
'>': true,
|
||||
'"': true,
|
||||
')': true,
|
||||
}
|
||||
line := v.lines[v.wy]
|
||||
start := 0
|
||||
for {
|
||||
linkStart := findSubstring(line[start:], []rune("https://"))
|
||||
linkStart := findLinkStart(line[start:])
|
||||
if linkStart == -1 {
|
||||
break
|
||||
}
|
||||
linkStart += start
|
||||
link := ""
|
||||
var link strings.Builder
|
||||
linkEnd := linkStart
|
||||
for ; linkEnd < len(line); linkEnd++ {
|
||||
if _, ok := lineEndCharacters[line[linkEnd].chr]; ok {
|
||||
break
|
||||
}
|
||||
link += string(line[linkEnd].chr)
|
||||
link.WriteString(string(line[linkEnd].chr))
|
||||
}
|
||||
for i := linkStart; i < linkEnd; i++ {
|
||||
v.lines[v.wy][i].hyperlink = link
|
||||
v.lines[v.wy][i].hyperlink = link.String()
|
||||
}
|
||||
start = linkEnd
|
||||
}
|
||||
@@ -890,17 +881,18 @@ func (v *View) autoRenderHyperlinksInCurrentLine() {
|
||||
// parseInput parses char by char the input written to the View. It returns nil
|
||||
// while processing ESC sequences. Otherwise, it returns a cell slice that
|
||||
// contains the processed data.
|
||||
func (v *View) parseInput(ch rune, x int, _ int) (bool, []cell) {
|
||||
func (v *View) parseInput(ch []byte, width int, x int, _ int) (bool, []cell) {
|
||||
cells := []cell{}
|
||||
truncateLine := false
|
||||
|
||||
isEscape, err := v.ei.parseOne(ch)
|
||||
if err != nil {
|
||||
for _, r := range v.ei.runes() {
|
||||
for _, chr := range v.ei.characters() {
|
||||
c := cell{
|
||||
fgColor: v.FgColor,
|
||||
bgColor: v.BgColor,
|
||||
chr: r,
|
||||
chr: chr,
|
||||
width: uniseg.StringWidth(chr),
|
||||
}
|
||||
cells = append(cells, c)
|
||||
}
|
||||
@@ -912,28 +904,31 @@ func (v *View) parseInput(ch rune, x int, _ int) (bool, []cell) {
|
||||
v.ei.instructionRead()
|
||||
cx := 0
|
||||
for _, cell := range v.lines[v.wy][0:v.wx] {
|
||||
cx += runewidth.RuneWidth(cell.chr)
|
||||
cx += cell.width
|
||||
}
|
||||
repeatCount = v.InnerWidth() - cx
|
||||
ch = ' '
|
||||
ch = []byte{' '}
|
||||
width = 1
|
||||
truncateLine = true
|
||||
} else if isEscape {
|
||||
// do not output anything
|
||||
return truncateLine, nil
|
||||
} else if ch == '\t' {
|
||||
} else if characterEquals(ch, '\t') {
|
||||
// fill tab-sized space
|
||||
tabWidth := v.TabWidth
|
||||
if tabWidth < 1 {
|
||||
tabWidth = 4
|
||||
}
|
||||
ch = ' '
|
||||
ch = []byte{' '}
|
||||
width = 1
|
||||
repeatCount = tabWidth - (x % tabWidth)
|
||||
}
|
||||
c := cell{
|
||||
fgColor: v.ei.curFgColor,
|
||||
bgColor: v.ei.curBgColor,
|
||||
hyperlink: v.ei.hyperlink,
|
||||
chr: ch,
|
||||
hyperlink: v.ei.hyperlink.String(),
|
||||
chr: string(ch),
|
||||
width: width,
|
||||
}
|
||||
for i := 0; i < repeatCount; i++ {
|
||||
cells = append(cells, c)
|
||||
@@ -961,8 +956,9 @@ func (v *View) Read(p []byte) (n int, err error) {
|
||||
}
|
||||
for v.ry < len(v.lines) {
|
||||
for v.rx < len(v.lines[v.ry]) {
|
||||
count := utf8.EncodeRune(buffer, v.lines[v.ry][v.rx].chr)
|
||||
copy(p[offset:], buffer[:count])
|
||||
s := v.lines[v.ry][v.rx].chr
|
||||
count := len(s)
|
||||
copy(p[offset:], s)
|
||||
v.rx++
|
||||
newOffset := offset + count
|
||||
if newOffset >= len(p) {
|
||||
@@ -1063,43 +1059,54 @@ func containsUpcaseChar(str string) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func stringToGraphemes(s string) []string {
|
||||
var graphemes []string
|
||||
state := -1
|
||||
for s != "" {
|
||||
var chr string
|
||||
chr, s, _, state = uniseg.FirstGraphemeClusterInString(s, state)
|
||||
graphemes = append(graphemes, chr)
|
||||
}
|
||||
return graphemes
|
||||
}
|
||||
|
||||
func (v *View) updateSearchPositions() {
|
||||
if v.searcher.searchString != "" {
|
||||
var normalizeRune func(r rune) rune
|
||||
var normalizeRune func(s string) string
|
||||
var normalizedSearchStr string
|
||||
// if we have any uppercase characters we'll do a case-sensitive search
|
||||
if containsUpcaseChar(v.searcher.searchString) {
|
||||
normalizeRune = func(r rune) rune { return r }
|
||||
normalizeRune = func(s string) string { return s }
|
||||
normalizedSearchStr = v.searcher.searchString
|
||||
} else {
|
||||
normalizeRune = unicode.ToLower
|
||||
normalizeRune = strings.ToLower
|
||||
normalizedSearchStr = strings.ToLower(v.searcher.searchString)
|
||||
}
|
||||
|
||||
searchStrGraphemes := stringToGraphemes(normalizedSearchStr)
|
||||
|
||||
v.searcher.searchPositions = []SearchPosition{}
|
||||
|
||||
searchPositionsForLine := func(line []cell, y int) []SearchPosition {
|
||||
var result []SearchPosition
|
||||
searchStringWidth := runewidth.StringWidth(v.searcher.searchString)
|
||||
searchStringWidth := uniseg.StringWidth(v.searcher.searchString)
|
||||
x := 0
|
||||
for startIdx, c := range line {
|
||||
for startIdx, cell := range line {
|
||||
found := true
|
||||
offset := 0
|
||||
for _, c := range normalizedSearchStr {
|
||||
if len(line)-1 < startIdx+offset {
|
||||
for i, c := range searchStrGraphemes {
|
||||
if len(line)-1 < startIdx+i {
|
||||
found = false
|
||||
break
|
||||
}
|
||||
if normalizeRune(line[startIdx+offset].chr) != c {
|
||||
if normalizeRune(line[startIdx+i].chr) != c {
|
||||
found = false
|
||||
break
|
||||
}
|
||||
offset += 1
|
||||
}
|
||||
if found {
|
||||
result = append(result, SearchPosition{XStart: x, XEnd: x + searchStringWidth, Y: y})
|
||||
}
|
||||
x += runewidth.RuneWidth(c.chr)
|
||||
x += cell.width
|
||||
}
|
||||
return result
|
||||
}
|
||||
@@ -1185,7 +1192,7 @@ func (v *View) draw() {
|
||||
start = len(v.viewLines) - 1
|
||||
}
|
||||
|
||||
emptyCell := cell{chr: ' ', fgColor: ColorDefault, bgColor: ColorDefault}
|
||||
emptyCell := cell{chr: " ", width: 1, fgColor: ColorDefault, bgColor: ColorDefault}
|
||||
var prevFgColor Attribute
|
||||
|
||||
for y, vline := range v.viewLines[start:] {
|
||||
@@ -1207,7 +1214,7 @@ func (v *View) draw() {
|
||||
|
||||
if x < 0 {
|
||||
if cellIdx < len(vline.line) {
|
||||
x += runewidth.RuneWidth(vline.line[cellIdx].chr)
|
||||
x += uniseg.StringWidth(vline.line[cellIdx].chr)
|
||||
cellIdx++
|
||||
continue
|
||||
} else {
|
||||
@@ -1241,11 +1248,9 @@ func (v *View) draw() {
|
||||
fgColor |= AttrUnderline
|
||||
}
|
||||
|
||||
v.setRune(x, y, c.chr, fgColor, bgColor)
|
||||
v.setCharacter(x, y, c.chr, fgColor, bgColor)
|
||||
|
||||
// Not sure why the previous code was here but it caused problems
|
||||
// when typing wide characters in an editor
|
||||
x += runewidth.RuneWidth(c.chr)
|
||||
x += c.width
|
||||
cellIdx++
|
||||
}
|
||||
}
|
||||
@@ -1345,9 +1350,9 @@ func (v *View) realPosition(vx, vy int) (x, y int, ok bool) {
|
||||
// clearRunes erases all the cells in the view.
|
||||
func (v *View) clearRunes() {
|
||||
maxX, maxY := v.InnerSize()
|
||||
for x := 0; x < maxX; x++ {
|
||||
for y := 0; y < maxY; y++ {
|
||||
tcellSetCell(v.x0+x+1, v.y0+y+1, ' ', v.FgColor, v.BgColor, v.outMode)
|
||||
for x := range maxX {
|
||||
for y := range maxY {
|
||||
tcellSetCell(v.x0+x+1, v.y0+y+1, " ", v.FgColor, v.BgColor, v.outMode)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1500,7 +1505,7 @@ func lineWrap(line []cell, columns int) [][]cell {
|
||||
lines := make([][]cell, 0, 1)
|
||||
for i := range line {
|
||||
currChr := line[i].chr
|
||||
rw := runewidth.RuneWidth(currChr)
|
||||
rw := uniseg.StringWidth(currChr)
|
||||
n += rw
|
||||
// if currChr == 'g' {
|
||||
// panic(n)
|
||||
@@ -1508,21 +1513,21 @@ func lineWrap(line []cell, columns int) [][]cell {
|
||||
if n > columns {
|
||||
// This code is convoluted but we've got comprehensive tests so feel free to do whatever you want
|
||||
// to the code to simplify it so long as our tests still pass.
|
||||
if currChr == ' ' {
|
||||
if currChr == " " {
|
||||
// if the line ends in a space, we'll omit it. This means there'll be no
|
||||
// way to distinguish between a clean break and a mid-word break, but
|
||||
// I think it's worth it.
|
||||
lines = append(lines, line[offset:i])
|
||||
offset = i + 1
|
||||
n = 0
|
||||
} else if currChr == '-' {
|
||||
} else if currChr == "-" {
|
||||
// if the last character is hyphen and the width of line is equal to the columns
|
||||
lines = append(lines, line[offset:i])
|
||||
offset = i
|
||||
n = rw
|
||||
} else if lastWhitespaceIndex != -1 {
|
||||
// if there is a space in the line and the line is not breaking at a space/hyphen
|
||||
if line[lastWhitespaceIndex].chr == '-' {
|
||||
if line[lastWhitespaceIndex].chr == "-" {
|
||||
// if break occurs at hyphen, we'll retain the hyphen
|
||||
lines = append(lines, line[offset:lastWhitespaceIndex+1])
|
||||
} else {
|
||||
@@ -1533,7 +1538,7 @@ func lineWrap(line []cell, columns int) [][]cell {
|
||||
offset = lastWhitespaceIndex + 1
|
||||
n = 0
|
||||
for _, c := range line[offset : i+1] {
|
||||
n += runewidth.RuneWidth(c.chr)
|
||||
n += c.width
|
||||
}
|
||||
} else {
|
||||
// in this case we're breaking mid-word
|
||||
@@ -1542,7 +1547,7 @@ func lineWrap(line []cell, columns int) [][]cell {
|
||||
n = rw
|
||||
}
|
||||
lastWhitespaceIndex = -1
|
||||
} else if line[i].chr == ' ' || line[i].chr == '-' {
|
||||
} else if line[i].chr == " " || line[i].chr == "-" {
|
||||
lastWhitespaceIndex = i
|
||||
}
|
||||
}
|
||||
@@ -1581,11 +1586,11 @@ func (v *View) GetClickedTabIndex(x int) int {
|
||||
return -1
|
||||
}
|
||||
for i, tab := range v.Tabs {
|
||||
charX += runewidth.StringWidth(tab)
|
||||
charX += uniseg.StringWidth(tab)
|
||||
if x <= charX {
|
||||
return i
|
||||
}
|
||||
charX += runewidth.StringWidth(" - ")
|
||||
charX += uniseg.StringWidth(" - ")
|
||||
if x <= charX {
|
||||
return -1
|
||||
}
|
||||
@@ -1848,7 +1853,7 @@ func containsColoredTextInLine(fgColorStr string, text string, line []cell) bool
|
||||
fgColor := tcell.GetColor(fgColorStr)
|
||||
|
||||
currentMatch := ""
|
||||
for i := 0; i < len(line); i++ {
|
||||
for i := range line {
|
||||
cell := line[i]
|
||||
|
||||
// stripping attributes by converting to and from hex
|
||||
|
||||
21
vendor/github.com/rivo/uniseg/LICENSE.txt
generated
vendored
Normal file
21
vendor/github.com/rivo/uniseg/LICENSE.txt
generated
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2019 Oliver Kuederle
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
137
vendor/github.com/rivo/uniseg/README.md
generated
vendored
Normal file
137
vendor/github.com/rivo/uniseg/README.md
generated
vendored
Normal file
@@ -0,0 +1,137 @@
|
||||
# Unicode Text Segmentation for Go
|
||||
|
||||
[](https://pkg.go.dev/github.com/rivo/uniseg)
|
||||
[](https://goreportcard.com/report/github.com/rivo/uniseg)
|
||||
|
||||
This Go package implements Unicode Text Segmentation according to [Unicode Standard Annex #29](https://unicode.org/reports/tr29/), Unicode Line Breaking according to [Unicode Standard Annex #14](https://unicode.org/reports/tr14/) (Unicode version 15.0.0), and monospace font string width calculation similar to [wcwidth](https://man7.org/linux/man-pages/man3/wcwidth.3.html).
|
||||
|
||||
## Background
|
||||
|
||||
### Grapheme Clusters
|
||||
|
||||
In Go, [strings are read-only slices of bytes](https://go.dev/blog/strings). They can be turned into Unicode code points using the `for` loop or by casting: `[]rune(str)`. However, multiple code points may be combined into one user-perceived character or what the Unicode specification calls "grapheme cluster". Here are some examples:
|
||||
|
||||
|String|Bytes (UTF-8)|Code points (runes)|Grapheme clusters|
|
||||
|-|-|-|-|
|
||||
|Käse|6 bytes: `4b 61 cc 88 73 65`|5 code points: `4b 61 308 73 65`|4 clusters: `[4b],[61 308],[73],[65]`|
|
||||
|🏳️🌈|14 bytes: `f0 9f 8f b3 ef b8 8f e2 80 8d f0 9f 8c 88`|4 code points: `1f3f3 fe0f 200d 1f308`|1 cluster: `[1f3f3 fe0f 200d 1f308]`|
|
||||
|🇩🇪|8 bytes: `f0 9f 87 a9 f0 9f 87 aa`|2 code points: `1f1e9 1f1ea`|1 cluster: `[1f1e9 1f1ea]`|
|
||||
|
||||
This package provides tools to iterate over these grapheme clusters. This may be used to determine the number of user-perceived characters, to split strings in their intended places, or to extract individual characters which form a unit.
|
||||
|
||||
### Word Boundaries
|
||||
|
||||
Word boundaries are used in a number of different contexts. The most familiar ones are selection (double-click mouse selection), cursor movement ("move to next word" control-arrow keys), and the dialog option "Whole Word Search" for search and replace. They are also used in database queries, to determine whether elements are within a certain number of words of one another. Searching may also use word boundaries in determining matching items. This package provides tools to determine word boundaries within strings.
|
||||
|
||||
### Sentence Boundaries
|
||||
|
||||
Sentence boundaries are often used for triple-click or some other method of selecting or iterating through blocks of text that are larger than single words. They are also used to determine whether words occur within the same sentence in database queries. This package provides tools to determine sentence boundaries within strings.
|
||||
|
||||
### Line Breaking
|
||||
|
||||
Line breaking, also known as word wrapping, is the process of breaking a section of text into lines such that it will fit in the available width of a page, window or other display area. This package provides tools to determine where a string may or may not be broken and where it must be broken (for example after newline characters).
|
||||
|
||||
### Monospace Width
|
||||
|
||||
Most terminals or text displays / text editors using a monospace font (for example source code editors) use a fixed width for each character. Some characters such as emojis or characters found in Asian and other languages may take up more than one character cell. This package provides tools to determine the number of cells a string will take up when displayed in a monospace font. See [here](https://pkg.go.dev/github.com/rivo/uniseg#hdr-Monospace_Width) for more information.
|
||||
|
||||
## Installation
|
||||
|
||||
```bash
|
||||
go get github.com/rivo/uniseg
|
||||
```
|
||||
|
||||
## Examples
|
||||
|
||||
### Counting Characters in a String
|
||||
|
||||
```go
|
||||
n := uniseg.GraphemeClusterCount("🇩🇪🏳️🌈")
|
||||
fmt.Println(n)
|
||||
// 2
|
||||
```
|
||||
|
||||
### Calculating the Monospace String Width
|
||||
|
||||
```go
|
||||
width := uniseg.StringWidth("🇩🇪🏳️🌈!")
|
||||
fmt.Println(width)
|
||||
// 5
|
||||
```
|
||||
|
||||
### Using the [`Graphemes`](https://pkg.go.dev/github.com/rivo/uniseg#Graphemes) Class
|
||||
|
||||
This is the most convenient method of iterating over grapheme clusters:
|
||||
|
||||
```go
|
||||
gr := uniseg.NewGraphemes("👍🏼!")
|
||||
for gr.Next() {
|
||||
fmt.Printf("%x ", gr.Runes())
|
||||
}
|
||||
// [1f44d 1f3fc] [21]
|
||||
```
|
||||
|
||||
### Using the [`Step`](https://pkg.go.dev/github.com/rivo/uniseg#Step) or [`StepString`](https://pkg.go.dev/github.com/rivo/uniseg#StepString) Function
|
||||
|
||||
This avoids allocating a new `Graphemes` object but it requires the handling of states and boundaries:
|
||||
|
||||
```go
|
||||
str := "🇩🇪🏳️🌈"
|
||||
state := -1
|
||||
var c string
|
||||
for len(str) > 0 {
|
||||
c, str, _, state = uniseg.StepString(str, state)
|
||||
fmt.Printf("%x ", []rune(c))
|
||||
}
|
||||
// [1f1e9 1f1ea] [1f3f3 fe0f 200d 1f308]
|
||||
```
|
||||
|
||||
### Advanced Examples
|
||||
|
||||
The [`Graphemes`](https://pkg.go.dev/github.com/rivo/uniseg#Graphemes) class offers the most convenient way to access all functionality of this package. But in some cases, it may be better to use the specialized functions directly. For example, if you're only interested in word segmentation, use [`FirstWord`](https://pkg.go.dev/github.com/rivo/uniseg#FirstWord) or [`FirstWordInString`](https://pkg.go.dev/github.com/rivo/uniseg#FirstWordInString):
|
||||
|
||||
```go
|
||||
str := "Hello, world!"
|
||||
state := -1
|
||||
var c string
|
||||
for len(str) > 0 {
|
||||
c, str, state = uniseg.FirstWordInString(str, state)
|
||||
fmt.Printf("(%s)\n", c)
|
||||
}
|
||||
// (Hello)
|
||||
// (,)
|
||||
// ( )
|
||||
// (world)
|
||||
// (!)
|
||||
```
|
||||
|
||||
Similarly, use
|
||||
|
||||
- [`FirstGraphemeCluster`](https://pkg.go.dev/github.com/rivo/uniseg#FirstGraphemeCluster) or [`FirstGraphemeClusterInString`](https://pkg.go.dev/github.com/rivo/uniseg#FirstGraphemeClusterInString) for grapheme cluster determination only,
|
||||
- [`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).
|
||||
|
||||
If you're only interested in the width of characters, use [`FirstGraphemeCluster`](https://pkg.go.dev/github.com/rivo/uniseg#FirstGraphemeCluster) or [`FirstGraphemeClusterInString`](https://pkg.go.dev/github.com/rivo/uniseg#FirstGraphemeClusterInString). It is much faster than using [`Step`](https://pkg.go.dev/github.com/rivo/uniseg#Step), [`StepString`](https://pkg.go.dev/github.com/rivo/uniseg#StepString), or the [`Graphemes`](https://pkg.go.dev/github.com/rivo/uniseg#Graphemes) class because it does not include the logic for word / sentence / line 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.
|
||||
|
||||
## Dependencies
|
||||
|
||||
This package does not depend on any packages outside the standard library.
|
||||
|
||||
## Sponsor this Project
|
||||
|
||||
[Become a Sponsor on GitHub](https://github.com/sponsors/rivo?metadata_source=uniseg_readme) to support this project!
|
||||
|
||||
## Your Feedback
|
||||
|
||||
Add your issue here on GitHub, preferably before submitting any PR's. Feel free to get in touch if you have any questions.
|
||||
108
vendor/github.com/rivo/uniseg/doc.go
generated
vendored
Normal file
108
vendor/github.com/rivo/uniseg/doc.go
generated
vendored
Normal file
@@ -0,0 +1,108 @@
|
||||
/*
|
||||
Package uniseg implements Unicode Text Segmentation, Unicode Line Breaking, and
|
||||
string width calculation for monospace fonts. Unicode Text Segmentation conforms
|
||||
to Unicode Standard Annex #29 (https://unicode.org/reports/tr29/) and Unicode
|
||||
Line Breaking conforms to Unicode Standard Annex #14
|
||||
(https://unicode.org/reports/tr14/).
|
||||
|
||||
In short, using this package, you can split a string into grapheme clusters
|
||||
(what people would usually refer to as a "character"), into words, and into
|
||||
sentences. Or, in its simplest case, this package allows you to count the number
|
||||
of characters in a string, especially when it contains complex characters such
|
||||
as emojis, combining characters, or characters from Asian, Arabic, Hebrew, or
|
||||
other languages. Additionally, you can use it to implement line breaking (or
|
||||
"word wrapping"), that is, to determine where text can be broken over to the
|
||||
next line when the width of the line is not big enough to fit the entire text.
|
||||
Finally, you can use it to calculate the display width of a string for monospace
|
||||
fonts.
|
||||
|
||||
# Getting Started
|
||||
|
||||
If you just want to count the number of characters in a string, you can use
|
||||
[GraphemeClusterCount]. If you want to determine the display width of a string,
|
||||
you can use [StringWidth]. If you want to iterate over a string, you can use
|
||||
[Step], [StepString], or the [Graphemes] class (more convenient but less
|
||||
performant). This will provide you with all information: grapheme clusters,
|
||||
word boundaries, sentence boundaries, line breaks, and monospace character
|
||||
widths. The specialized functions [FirstGraphemeCluster],
|
||||
[FirstGraphemeClusterInString], [FirstWord], [FirstWordInString],
|
||||
[FirstSentence], and [FirstSentenceInString] can be used if only one type of
|
||||
information is needed.
|
||||
|
||||
# Grapheme Clusters
|
||||
|
||||
Consider the rainbow flag emoji: 🏳️🌈. On most modern systems, it appears as one
|
||||
character. But its string representation actually has 14 bytes, so counting
|
||||
bytes (or using len("🏳️🌈")) will not work as expected. Counting runes won't,
|
||||
either: The flag has 4 Unicode code points, thus 4 runes. The stdlib function
|
||||
utf8.RuneCountInString("🏳️🌈") and len([]rune("🏳️🌈")) will both return 4.
|
||||
|
||||
The [GraphemeClusterCount] function will return 1 for the rainbow flag emoji.
|
||||
The Graphemes class and a variety of functions in this package will allow you to
|
||||
split strings into its grapheme clusters.
|
||||
|
||||
# Word Boundaries
|
||||
|
||||
Word boundaries are used in a number of different contexts. The most familiar
|
||||
ones are selection (double-click mouse selection), cursor movement ("move to
|
||||
next word" control-arrow keys), and the dialog option "Whole Word Search" for
|
||||
search and replace. This package provides methods for determining word
|
||||
boundaries.
|
||||
|
||||
# Sentence Boundaries
|
||||
|
||||
Sentence boundaries are often used for triple-click or some other method of
|
||||
selecting or iterating through blocks of text that are larger than single words.
|
||||
They are also used to determine whether words occur within the same sentence in
|
||||
database queries. This package provides methods for determining sentence
|
||||
boundaries.
|
||||
|
||||
# Line Breaking
|
||||
|
||||
Line breaking, also known as word wrapping, is the process of breaking a section
|
||||
of text into lines such that it will fit in the available width of a page,
|
||||
window or other display area. This package provides methods to determine the
|
||||
positions in a string where a line must be broken, may be broken, or must not be
|
||||
broken.
|
||||
|
||||
# Monospace Width
|
||||
|
||||
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 [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 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
|
||||
exceptions:
|
||||
|
||||
- Code points with grapheme cluster break properties Control, CR, LF, Extend,
|
||||
and ZWJ have a width of 0.
|
||||
- U+2E3A, Two-Em Dash, has a width of 3.
|
||||
- U+2E3B, Three-Em Dash, has a width of 4.
|
||||
- Characters with the East-Asian Width properties "Fullwidth" (F) and "Wide"
|
||||
(W) have a width of 2. (Properties "Ambiguous" (A) and "Neutral" (N) both
|
||||
have a width of 1.)
|
||||
- Code points with grapheme cluster break property Regional Indicator have a
|
||||
width of 2.
|
||||
- Code points with grapheme cluster break property Extended Pictographic have
|
||||
a width of 2, unless their Emoji Presentation flag is "No", in which case
|
||||
the width is 1.
|
||||
|
||||
For Hangul grapheme clusters composed of conjoining Jamo and for Regional
|
||||
Indicators (flags), all code points except the first one have a width of 0. For
|
||||
grapheme clusters starting with an Extended Pictographic, any additional code
|
||||
point will force a total width of 2, except if the Variation Selector-15
|
||||
(U+FE0E) is included, in which case the total width is always 1. Grapheme
|
||||
clusters ending with Variation Selector-16 (U+FE0F) have a width of 2.
|
||||
|
||||
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.
|
||||
|
||||
[wcswidth()]: https://man7.org/linux/man-pages/man3/wcswidth.3.html
|
||||
*/
|
||||
package uniseg
|
||||
2588
vendor/github.com/rivo/uniseg/eastasianwidth.go
generated
vendored
Normal file
2588
vendor/github.com/rivo/uniseg/eastasianwidth.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
295
vendor/github.com/rivo/uniseg/emojipresentation.go
generated
vendored
Normal file
295
vendor/github.com/rivo/uniseg/emojipresentation.go
generated
vendored
Normal file
@@ -0,0 +1,295 @@
|
||||
// Code generated via go generate from gen_properties.go. DO NOT EDIT.
|
||||
|
||||
package uniseg
|
||||
|
||||
// emojiPresentation are taken from
|
||||
//
|
||||
// and
|
||||
// https://unicode.org/Public/15.0.0/ucd/emoji/emoji-data.txt
|
||||
// ("Extended_Pictographic" only)
|
||||
// on September 5, 2023. See https://www.unicode.org/license.html for the Unicode
|
||||
// license agreement.
|
||||
var emojiPresentation = [][3]int{
|
||||
{0x231A, 0x231B, prEmojiPresentation}, // E0.6 [2] (⌚..⌛) watch..hourglass done
|
||||
{0x23E9, 0x23EC, prEmojiPresentation}, // E0.6 [4] (⏩..⏬) fast-forward button..fast down button
|
||||
{0x23F0, 0x23F0, prEmojiPresentation}, // E0.6 [1] (⏰) alarm clock
|
||||
{0x23F3, 0x23F3, prEmojiPresentation}, // E0.6 [1] (⏳) hourglass not done
|
||||
{0x25FD, 0x25FE, prEmojiPresentation}, // E0.6 [2] (◽..◾) white medium-small square..black medium-small square
|
||||
{0x2614, 0x2615, prEmojiPresentation}, // E0.6 [2] (☔..☕) umbrella with rain drops..hot beverage
|
||||
{0x2648, 0x2653, prEmojiPresentation}, // E0.6 [12] (♈..♓) Aries..Pisces
|
||||
{0x267F, 0x267F, prEmojiPresentation}, // E0.6 [1] (♿) wheelchair symbol
|
||||
{0x2693, 0x2693, prEmojiPresentation}, // E0.6 [1] (⚓) anchor
|
||||
{0x26A1, 0x26A1, prEmojiPresentation}, // E0.6 [1] (⚡) high voltage
|
||||
{0x26AA, 0x26AB, prEmojiPresentation}, // E0.6 [2] (⚪..⚫) white circle..black circle
|
||||
{0x26BD, 0x26BE, prEmojiPresentation}, // E0.6 [2] (⚽..⚾) soccer ball..baseball
|
||||
{0x26C4, 0x26C5, prEmojiPresentation}, // E0.6 [2] (⛄..⛅) snowman without snow..sun behind cloud
|
||||
{0x26CE, 0x26CE, prEmojiPresentation}, // E0.6 [1] (⛎) Ophiuchus
|
||||
{0x26D4, 0x26D4, prEmojiPresentation}, // E0.6 [1] (⛔) no entry
|
||||
{0x26EA, 0x26EA, prEmojiPresentation}, // E0.6 [1] (⛪) church
|
||||
{0x26F2, 0x26F3, prEmojiPresentation}, // E0.6 [2] (⛲..⛳) fountain..flag in hole
|
||||
{0x26F5, 0x26F5, prEmojiPresentation}, // E0.6 [1] (⛵) sailboat
|
||||
{0x26FA, 0x26FA, prEmojiPresentation}, // E0.6 [1] (⛺) tent
|
||||
{0x26FD, 0x26FD, prEmojiPresentation}, // E0.6 [1] (⛽) fuel pump
|
||||
{0x2705, 0x2705, prEmojiPresentation}, // E0.6 [1] (✅) check mark button
|
||||
{0x270A, 0x270B, prEmojiPresentation}, // E0.6 [2] (✊..✋) raised fist..raised hand
|
||||
{0x2728, 0x2728, prEmojiPresentation}, // E0.6 [1] (✨) sparkles
|
||||
{0x274C, 0x274C, prEmojiPresentation}, // E0.6 [1] (❌) cross mark
|
||||
{0x274E, 0x274E, prEmojiPresentation}, // E0.6 [1] (❎) cross mark button
|
||||
{0x2753, 0x2755, prEmojiPresentation}, // E0.6 [3] (❓..❕) red question mark..white exclamation mark
|
||||
{0x2757, 0x2757, prEmojiPresentation}, // E0.6 [1] (❗) red exclamation mark
|
||||
{0x2795, 0x2797, prEmojiPresentation}, // E0.6 [3] (➕..➗) plus..divide
|
||||
{0x27B0, 0x27B0, prEmojiPresentation}, // E0.6 [1] (➰) curly loop
|
||||
{0x27BF, 0x27BF, prEmojiPresentation}, // E1.0 [1] (➿) double curly loop
|
||||
{0x2B1B, 0x2B1C, prEmojiPresentation}, // E0.6 [2] (⬛..⬜) black large square..white large square
|
||||
{0x2B50, 0x2B50, prEmojiPresentation}, // E0.6 [1] (⭐) star
|
||||
{0x2B55, 0x2B55, prEmojiPresentation}, // E0.6 [1] (⭕) hollow red circle
|
||||
{0x1F004, 0x1F004, prEmojiPresentation}, // E0.6 [1] (🀄) mahjong red dragon
|
||||
{0x1F0CF, 0x1F0CF, prEmojiPresentation}, // E0.6 [1] (🃏) joker
|
||||
{0x1F18E, 0x1F18E, prEmojiPresentation}, // E0.6 [1] (🆎) AB button (blood type)
|
||||
{0x1F191, 0x1F19A, prEmojiPresentation}, // E0.6 [10] (🆑..🆚) CL button..VS button
|
||||
{0x1F1E6, 0x1F1FF, prEmojiPresentation}, // E0.0 [26] (🇦..🇿) regional indicator symbol letter a..regional indicator symbol letter z
|
||||
{0x1F201, 0x1F201, prEmojiPresentation}, // E0.6 [1] (🈁) Japanese “here” button
|
||||
{0x1F21A, 0x1F21A, prEmojiPresentation}, // E0.6 [1] (🈚) Japanese “free of charge” button
|
||||
{0x1F22F, 0x1F22F, prEmojiPresentation}, // E0.6 [1] (🈯) Japanese “reserved” button
|
||||
{0x1F232, 0x1F236, prEmojiPresentation}, // E0.6 [5] (🈲..🈶) Japanese “prohibited” button..Japanese “not free of charge” button
|
||||
{0x1F238, 0x1F23A, prEmojiPresentation}, // E0.6 [3] (🈸..🈺) Japanese “application” button..Japanese “open for business” button
|
||||
{0x1F250, 0x1F251, prEmojiPresentation}, // E0.6 [2] (🉐..🉑) Japanese “bargain” button..Japanese “acceptable” button
|
||||
{0x1F300, 0x1F30C, prEmojiPresentation}, // E0.6 [13] (🌀..🌌) cyclone..milky way
|
||||
{0x1F30D, 0x1F30E, prEmojiPresentation}, // E0.7 [2] (🌍..🌎) globe showing Europe-Africa..globe showing Americas
|
||||
{0x1F30F, 0x1F30F, prEmojiPresentation}, // E0.6 [1] (🌏) globe showing Asia-Australia
|
||||
{0x1F310, 0x1F310, prEmojiPresentation}, // E1.0 [1] (🌐) globe with meridians
|
||||
{0x1F311, 0x1F311, prEmojiPresentation}, // E0.6 [1] (🌑) new moon
|
||||
{0x1F312, 0x1F312, prEmojiPresentation}, // E1.0 [1] (🌒) waxing crescent moon
|
||||
{0x1F313, 0x1F315, prEmojiPresentation}, // E0.6 [3] (🌓..🌕) first quarter moon..full moon
|
||||
{0x1F316, 0x1F318, prEmojiPresentation}, // E1.0 [3] (🌖..🌘) waning gibbous moon..waning crescent moon
|
||||
{0x1F319, 0x1F319, prEmojiPresentation}, // E0.6 [1] (🌙) crescent moon
|
||||
{0x1F31A, 0x1F31A, prEmojiPresentation}, // E1.0 [1] (🌚) new moon face
|
||||
{0x1F31B, 0x1F31B, prEmojiPresentation}, // E0.6 [1] (🌛) first quarter moon face
|
||||
{0x1F31C, 0x1F31C, prEmojiPresentation}, // E0.7 [1] (🌜) last quarter moon face
|
||||
{0x1F31D, 0x1F31E, prEmojiPresentation}, // E1.0 [2] (🌝..🌞) full moon face..sun with face
|
||||
{0x1F31F, 0x1F320, prEmojiPresentation}, // E0.6 [2] (🌟..🌠) glowing star..shooting star
|
||||
{0x1F32D, 0x1F32F, prEmojiPresentation}, // E1.0 [3] (🌭..🌯) hot dog..burrito
|
||||
{0x1F330, 0x1F331, prEmojiPresentation}, // E0.6 [2] (🌰..🌱) chestnut..seedling
|
||||
{0x1F332, 0x1F333, prEmojiPresentation}, // E1.0 [2] (🌲..🌳) evergreen tree..deciduous tree
|
||||
{0x1F334, 0x1F335, prEmojiPresentation}, // E0.6 [2] (🌴..🌵) palm tree..cactus
|
||||
{0x1F337, 0x1F34A, prEmojiPresentation}, // E0.6 [20] (🌷..🍊) tulip..tangerine
|
||||
{0x1F34B, 0x1F34B, prEmojiPresentation}, // E1.0 [1] (🍋) lemon
|
||||
{0x1F34C, 0x1F34F, prEmojiPresentation}, // E0.6 [4] (🍌..🍏) banana..green apple
|
||||
{0x1F350, 0x1F350, prEmojiPresentation}, // E1.0 [1] (🍐) pear
|
||||
{0x1F351, 0x1F37B, prEmojiPresentation}, // E0.6 [43] (🍑..🍻) peach..clinking beer mugs
|
||||
{0x1F37C, 0x1F37C, prEmojiPresentation}, // E1.0 [1] (🍼) baby bottle
|
||||
{0x1F37E, 0x1F37F, prEmojiPresentation}, // E1.0 [2] (🍾..🍿) bottle with popping cork..popcorn
|
||||
{0x1F380, 0x1F393, prEmojiPresentation}, // E0.6 [20] (🎀..🎓) ribbon..graduation cap
|
||||
{0x1F3A0, 0x1F3C4, prEmojiPresentation}, // E0.6 [37] (🎠..🏄) carousel horse..person surfing
|
||||
{0x1F3C5, 0x1F3C5, prEmojiPresentation}, // E1.0 [1] (🏅) sports medal
|
||||
{0x1F3C6, 0x1F3C6, prEmojiPresentation}, // E0.6 [1] (🏆) trophy
|
||||
{0x1F3C7, 0x1F3C7, prEmojiPresentation}, // E1.0 [1] (🏇) horse racing
|
||||
{0x1F3C8, 0x1F3C8, prEmojiPresentation}, // E0.6 [1] (🏈) american football
|
||||
{0x1F3C9, 0x1F3C9, prEmojiPresentation}, // E1.0 [1] (🏉) rugby football
|
||||
{0x1F3CA, 0x1F3CA, prEmojiPresentation}, // E0.6 [1] (🏊) person swimming
|
||||
{0x1F3CF, 0x1F3D3, prEmojiPresentation}, // E1.0 [5] (🏏..🏓) cricket game..ping pong
|
||||
{0x1F3E0, 0x1F3E3, prEmojiPresentation}, // E0.6 [4] (🏠..🏣) house..Japanese post office
|
||||
{0x1F3E4, 0x1F3E4, prEmojiPresentation}, // E1.0 [1] (🏤) post office
|
||||
{0x1F3E5, 0x1F3F0, prEmojiPresentation}, // E0.6 [12] (🏥..🏰) hospital..castle
|
||||
{0x1F3F4, 0x1F3F4, prEmojiPresentation}, // E1.0 [1] (🏴) black flag
|
||||
{0x1F3F8, 0x1F407, prEmojiPresentation}, // E1.0 [16] (🏸..🐇) badminton..rabbit
|
||||
{0x1F408, 0x1F408, prEmojiPresentation}, // E0.7 [1] (🐈) cat
|
||||
{0x1F409, 0x1F40B, prEmojiPresentation}, // E1.0 [3] (🐉..🐋) dragon..whale
|
||||
{0x1F40C, 0x1F40E, prEmojiPresentation}, // E0.6 [3] (🐌..🐎) snail..horse
|
||||
{0x1F40F, 0x1F410, prEmojiPresentation}, // E1.0 [2] (🐏..🐐) ram..goat
|
||||
{0x1F411, 0x1F412, prEmojiPresentation}, // E0.6 [2] (🐑..🐒) ewe..monkey
|
||||
{0x1F413, 0x1F413, prEmojiPresentation}, // E1.0 [1] (🐓) rooster
|
||||
{0x1F414, 0x1F414, prEmojiPresentation}, // E0.6 [1] (🐔) chicken
|
||||
{0x1F415, 0x1F415, prEmojiPresentation}, // E0.7 [1] (🐕) dog
|
||||
{0x1F416, 0x1F416, prEmojiPresentation}, // E1.0 [1] (🐖) pig
|
||||
{0x1F417, 0x1F429, prEmojiPresentation}, // E0.6 [19] (🐗..🐩) boar..poodle
|
||||
{0x1F42A, 0x1F42A, prEmojiPresentation}, // E1.0 [1] (🐪) camel
|
||||
{0x1F42B, 0x1F43E, prEmojiPresentation}, // E0.6 [20] (🐫..🐾) two-hump camel..paw prints
|
||||
{0x1F440, 0x1F440, prEmojiPresentation}, // E0.6 [1] (👀) eyes
|
||||
{0x1F442, 0x1F464, prEmojiPresentation}, // E0.6 [35] (👂..👤) ear..bust in silhouette
|
||||
{0x1F465, 0x1F465, prEmojiPresentation}, // E1.0 [1] (👥) busts in silhouette
|
||||
{0x1F466, 0x1F46B, prEmojiPresentation}, // E0.6 [6] (👦..👫) boy..woman and man holding hands
|
||||
{0x1F46C, 0x1F46D, prEmojiPresentation}, // E1.0 [2] (👬..👭) men holding hands..women holding hands
|
||||
{0x1F46E, 0x1F4AC, prEmojiPresentation}, // E0.6 [63] (👮..💬) police officer..speech balloon
|
||||
{0x1F4AD, 0x1F4AD, prEmojiPresentation}, // E1.0 [1] (💭) thought balloon
|
||||
{0x1F4AE, 0x1F4B5, prEmojiPresentation}, // E0.6 [8] (💮..💵) white flower..dollar banknote
|
||||
{0x1F4B6, 0x1F4B7, prEmojiPresentation}, // E1.0 [2] (💶..💷) euro banknote..pound banknote
|
||||
{0x1F4B8, 0x1F4EB, prEmojiPresentation}, // E0.6 [52] (💸..📫) money with wings..closed mailbox with raised flag
|
||||
{0x1F4EC, 0x1F4ED, prEmojiPresentation}, // E0.7 [2] (📬..📭) open mailbox with raised flag..open mailbox with lowered flag
|
||||
{0x1F4EE, 0x1F4EE, prEmojiPresentation}, // E0.6 [1] (📮) postbox
|
||||
{0x1F4EF, 0x1F4EF, prEmojiPresentation}, // E1.0 [1] (📯) postal horn
|
||||
{0x1F4F0, 0x1F4F4, prEmojiPresentation}, // E0.6 [5] (📰..📴) newspaper..mobile phone off
|
||||
{0x1F4F5, 0x1F4F5, prEmojiPresentation}, // E1.0 [1] (📵) no mobile phones
|
||||
{0x1F4F6, 0x1F4F7, prEmojiPresentation}, // E0.6 [2] (📶..📷) antenna bars..camera
|
||||
{0x1F4F8, 0x1F4F8, prEmojiPresentation}, // E1.0 [1] (📸) camera with flash
|
||||
{0x1F4F9, 0x1F4FC, prEmojiPresentation}, // E0.6 [4] (📹..📼) video camera..videocassette
|
||||
{0x1F4FF, 0x1F502, prEmojiPresentation}, // E1.0 [4] (📿..🔂) prayer beads..repeat single button
|
||||
{0x1F503, 0x1F503, prEmojiPresentation}, // E0.6 [1] (🔃) clockwise vertical arrows
|
||||
{0x1F504, 0x1F507, prEmojiPresentation}, // E1.0 [4] (🔄..🔇) counterclockwise arrows button..muted speaker
|
||||
{0x1F508, 0x1F508, prEmojiPresentation}, // E0.7 [1] (🔈) speaker low volume
|
||||
{0x1F509, 0x1F509, prEmojiPresentation}, // E1.0 [1] (🔉) speaker medium volume
|
||||
{0x1F50A, 0x1F514, prEmojiPresentation}, // E0.6 [11] (🔊..🔔) speaker high volume..bell
|
||||
{0x1F515, 0x1F515, prEmojiPresentation}, // E1.0 [1] (🔕) bell with slash
|
||||
{0x1F516, 0x1F52B, prEmojiPresentation}, // E0.6 [22] (🔖..🔫) bookmark..water pistol
|
||||
{0x1F52C, 0x1F52D, prEmojiPresentation}, // E1.0 [2] (🔬..🔭) microscope..telescope
|
||||
{0x1F52E, 0x1F53D, prEmojiPresentation}, // E0.6 [16] (🔮..🔽) crystal ball..downwards button
|
||||
{0x1F54B, 0x1F54E, prEmojiPresentation}, // E1.0 [4] (🕋..🕎) kaaba..menorah
|
||||
{0x1F550, 0x1F55B, prEmojiPresentation}, // E0.6 [12] (🕐..🕛) one o’clock..twelve o’clock
|
||||
{0x1F55C, 0x1F567, prEmojiPresentation}, // E0.7 [12] (🕜..🕧) one-thirty..twelve-thirty
|
||||
{0x1F57A, 0x1F57A, prEmojiPresentation}, // E3.0 [1] (🕺) man dancing
|
||||
{0x1F595, 0x1F596, prEmojiPresentation}, // E1.0 [2] (🖕..🖖) middle finger..vulcan salute
|
||||
{0x1F5A4, 0x1F5A4, prEmojiPresentation}, // E3.0 [1] (🖤) black heart
|
||||
{0x1F5FB, 0x1F5FF, prEmojiPresentation}, // E0.6 [5] (🗻..🗿) mount fuji..moai
|
||||
{0x1F600, 0x1F600, prEmojiPresentation}, // E1.0 [1] (😀) grinning face
|
||||
{0x1F601, 0x1F606, prEmojiPresentation}, // E0.6 [6] (😁..😆) beaming face with smiling eyes..grinning squinting face
|
||||
{0x1F607, 0x1F608, prEmojiPresentation}, // E1.0 [2] (😇..😈) smiling face with halo..smiling face with horns
|
||||
{0x1F609, 0x1F60D, prEmojiPresentation}, // E0.6 [5] (😉..😍) winking face..smiling face with heart-eyes
|
||||
{0x1F60E, 0x1F60E, prEmojiPresentation}, // E1.0 [1] (😎) smiling face with sunglasses
|
||||
{0x1F60F, 0x1F60F, prEmojiPresentation}, // E0.6 [1] (😏) smirking face
|
||||
{0x1F610, 0x1F610, prEmojiPresentation}, // E0.7 [1] (😐) neutral face
|
||||
{0x1F611, 0x1F611, prEmojiPresentation}, // E1.0 [1] (😑) expressionless face
|
||||
{0x1F612, 0x1F614, prEmojiPresentation}, // E0.6 [3] (😒..😔) unamused face..pensive face
|
||||
{0x1F615, 0x1F615, prEmojiPresentation}, // E1.0 [1] (😕) confused face
|
||||
{0x1F616, 0x1F616, prEmojiPresentation}, // E0.6 [1] (😖) confounded face
|
||||
{0x1F617, 0x1F617, prEmojiPresentation}, // E1.0 [1] (😗) kissing face
|
||||
{0x1F618, 0x1F618, prEmojiPresentation}, // E0.6 [1] (😘) face blowing a kiss
|
||||
{0x1F619, 0x1F619, prEmojiPresentation}, // E1.0 [1] (😙) kissing face with smiling eyes
|
||||
{0x1F61A, 0x1F61A, prEmojiPresentation}, // E0.6 [1] (😚) kissing face with closed eyes
|
||||
{0x1F61B, 0x1F61B, prEmojiPresentation}, // E1.0 [1] (😛) face with tongue
|
||||
{0x1F61C, 0x1F61E, prEmojiPresentation}, // E0.6 [3] (😜..😞) winking face with tongue..disappointed face
|
||||
{0x1F61F, 0x1F61F, prEmojiPresentation}, // E1.0 [1] (😟) worried face
|
||||
{0x1F620, 0x1F625, prEmojiPresentation}, // E0.6 [6] (😠..😥) angry face..sad but relieved face
|
||||
{0x1F626, 0x1F627, prEmojiPresentation}, // E1.0 [2] (😦..😧) frowning face with open mouth..anguished face
|
||||
{0x1F628, 0x1F62B, prEmojiPresentation}, // E0.6 [4] (😨..😫) fearful face..tired face
|
||||
{0x1F62C, 0x1F62C, prEmojiPresentation}, // E1.0 [1] (😬) grimacing face
|
||||
{0x1F62D, 0x1F62D, prEmojiPresentation}, // E0.6 [1] (😭) loudly crying face
|
||||
{0x1F62E, 0x1F62F, prEmojiPresentation}, // E1.0 [2] (😮..😯) face with open mouth..hushed face
|
||||
{0x1F630, 0x1F633, prEmojiPresentation}, // E0.6 [4] (😰..😳) anxious face with sweat..flushed face
|
||||
{0x1F634, 0x1F634, prEmojiPresentation}, // E1.0 [1] (😴) sleeping face
|
||||
{0x1F635, 0x1F635, prEmojiPresentation}, // E0.6 [1] (😵) face with crossed-out eyes
|
||||
{0x1F636, 0x1F636, prEmojiPresentation}, // E1.0 [1] (😶) face without mouth
|
||||
{0x1F637, 0x1F640, prEmojiPresentation}, // E0.6 [10] (😷..🙀) face with medical mask..weary cat
|
||||
{0x1F641, 0x1F644, prEmojiPresentation}, // E1.0 [4] (🙁..🙄) slightly frowning face..face with rolling eyes
|
||||
{0x1F645, 0x1F64F, prEmojiPresentation}, // E0.6 [11] (🙅..🙏) person gesturing NO..folded hands
|
||||
{0x1F680, 0x1F680, prEmojiPresentation}, // E0.6 [1] (🚀) rocket
|
||||
{0x1F681, 0x1F682, prEmojiPresentation}, // E1.0 [2] (🚁..🚂) helicopter..locomotive
|
||||
{0x1F683, 0x1F685, prEmojiPresentation}, // E0.6 [3] (🚃..🚅) railway car..bullet train
|
||||
{0x1F686, 0x1F686, prEmojiPresentation}, // E1.0 [1] (🚆) train
|
||||
{0x1F687, 0x1F687, prEmojiPresentation}, // E0.6 [1] (🚇) metro
|
||||
{0x1F688, 0x1F688, prEmojiPresentation}, // E1.0 [1] (🚈) light rail
|
||||
{0x1F689, 0x1F689, prEmojiPresentation}, // E0.6 [1] (🚉) station
|
||||
{0x1F68A, 0x1F68B, prEmojiPresentation}, // E1.0 [2] (🚊..🚋) tram..tram car
|
||||
{0x1F68C, 0x1F68C, prEmojiPresentation}, // E0.6 [1] (🚌) bus
|
||||
{0x1F68D, 0x1F68D, prEmojiPresentation}, // E0.7 [1] (🚍) oncoming bus
|
||||
{0x1F68E, 0x1F68E, prEmojiPresentation}, // E1.0 [1] (🚎) trolleybus
|
||||
{0x1F68F, 0x1F68F, prEmojiPresentation}, // E0.6 [1] (🚏) bus stop
|
||||
{0x1F690, 0x1F690, prEmojiPresentation}, // E1.0 [1] (🚐) minibus
|
||||
{0x1F691, 0x1F693, prEmojiPresentation}, // E0.6 [3] (🚑..🚓) ambulance..police car
|
||||
{0x1F694, 0x1F694, prEmojiPresentation}, // E0.7 [1] (🚔) oncoming police car
|
||||
{0x1F695, 0x1F695, prEmojiPresentation}, // E0.6 [1] (🚕) taxi
|
||||
{0x1F696, 0x1F696, prEmojiPresentation}, // E1.0 [1] (🚖) oncoming taxi
|
||||
{0x1F697, 0x1F697, prEmojiPresentation}, // E0.6 [1] (🚗) automobile
|
||||
{0x1F698, 0x1F698, prEmojiPresentation}, // E0.7 [1] (🚘) oncoming automobile
|
||||
{0x1F699, 0x1F69A, prEmojiPresentation}, // E0.6 [2] (🚙..🚚) sport utility vehicle..delivery truck
|
||||
{0x1F69B, 0x1F6A1, prEmojiPresentation}, // E1.0 [7] (🚛..🚡) articulated lorry..aerial tramway
|
||||
{0x1F6A2, 0x1F6A2, prEmojiPresentation}, // E0.6 [1] (🚢) ship
|
||||
{0x1F6A3, 0x1F6A3, prEmojiPresentation}, // E1.0 [1] (🚣) person rowing boat
|
||||
{0x1F6A4, 0x1F6A5, prEmojiPresentation}, // E0.6 [2] (🚤..🚥) speedboat..horizontal traffic light
|
||||
{0x1F6A6, 0x1F6A6, prEmojiPresentation}, // E1.0 [1] (🚦) vertical traffic light
|
||||
{0x1F6A7, 0x1F6AD, prEmojiPresentation}, // E0.6 [7] (🚧..🚭) construction..no smoking
|
||||
{0x1F6AE, 0x1F6B1, prEmojiPresentation}, // E1.0 [4] (🚮..🚱) litter in bin sign..non-potable water
|
||||
{0x1F6B2, 0x1F6B2, prEmojiPresentation}, // E0.6 [1] (🚲) bicycle
|
||||
{0x1F6B3, 0x1F6B5, prEmojiPresentation}, // E1.0 [3] (🚳..🚵) no bicycles..person mountain biking
|
||||
{0x1F6B6, 0x1F6B6, prEmojiPresentation}, // E0.6 [1] (🚶) person walking
|
||||
{0x1F6B7, 0x1F6B8, prEmojiPresentation}, // E1.0 [2] (🚷..🚸) no pedestrians..children crossing
|
||||
{0x1F6B9, 0x1F6BE, prEmojiPresentation}, // E0.6 [6] (🚹..🚾) men’s room..water closet
|
||||
{0x1F6BF, 0x1F6BF, prEmojiPresentation}, // E1.0 [1] (🚿) shower
|
||||
{0x1F6C0, 0x1F6C0, prEmojiPresentation}, // E0.6 [1] (🛀) person taking bath
|
||||
{0x1F6C1, 0x1F6C5, prEmojiPresentation}, // E1.0 [5] (🛁..🛅) bathtub..left luggage
|
||||
{0x1F6CC, 0x1F6CC, prEmojiPresentation}, // E1.0 [1] (🛌) person in bed
|
||||
{0x1F6D0, 0x1F6D0, prEmojiPresentation}, // E1.0 [1] (🛐) place of worship
|
||||
{0x1F6D1, 0x1F6D2, prEmojiPresentation}, // E3.0 [2] (🛑..🛒) stop sign..shopping cart
|
||||
{0x1F6D5, 0x1F6D5, prEmojiPresentation}, // E12.0 [1] (🛕) hindu temple
|
||||
{0x1F6D6, 0x1F6D7, prEmojiPresentation}, // E13.0 [2] (🛖..🛗) hut..elevator
|
||||
{0x1F6DC, 0x1F6DC, prEmojiPresentation}, // E15.0 [1] (🛜) wireless
|
||||
{0x1F6DD, 0x1F6DF, prEmojiPresentation}, // E14.0 [3] (🛝..🛟) playground slide..ring buoy
|
||||
{0x1F6EB, 0x1F6EC, prEmojiPresentation}, // E1.0 [2] (🛫..🛬) airplane departure..airplane arrival
|
||||
{0x1F6F4, 0x1F6F6, prEmojiPresentation}, // E3.0 [3] (🛴..🛶) kick scooter..canoe
|
||||
{0x1F6F7, 0x1F6F8, prEmojiPresentation}, // E5.0 [2] (🛷..🛸) sled..flying saucer
|
||||
{0x1F6F9, 0x1F6F9, prEmojiPresentation}, // E11.0 [1] (🛹) skateboard
|
||||
{0x1F6FA, 0x1F6FA, prEmojiPresentation}, // E12.0 [1] (🛺) auto rickshaw
|
||||
{0x1F6FB, 0x1F6FC, prEmojiPresentation}, // E13.0 [2] (🛻..🛼) pickup truck..roller skate
|
||||
{0x1F7E0, 0x1F7EB, prEmojiPresentation}, // E12.0 [12] (🟠..🟫) orange circle..brown square
|
||||
{0x1F7F0, 0x1F7F0, prEmojiPresentation}, // E14.0 [1] (🟰) heavy equals sign
|
||||
{0x1F90C, 0x1F90C, prEmojiPresentation}, // E13.0 [1] (🤌) pinched fingers
|
||||
{0x1F90D, 0x1F90F, prEmojiPresentation}, // E12.0 [3] (🤍..🤏) white heart..pinching hand
|
||||
{0x1F910, 0x1F918, prEmojiPresentation}, // E1.0 [9] (🤐..🤘) zipper-mouth face..sign of the horns
|
||||
{0x1F919, 0x1F91E, prEmojiPresentation}, // E3.0 [6] (🤙..🤞) call me hand..crossed fingers
|
||||
{0x1F91F, 0x1F91F, prEmojiPresentation}, // E5.0 [1] (🤟) love-you gesture
|
||||
{0x1F920, 0x1F927, prEmojiPresentation}, // E3.0 [8] (🤠..🤧) cowboy hat face..sneezing face
|
||||
{0x1F928, 0x1F92F, prEmojiPresentation}, // E5.0 [8] (🤨..🤯) face with raised eyebrow..exploding head
|
||||
{0x1F930, 0x1F930, prEmojiPresentation}, // E3.0 [1] (🤰) pregnant woman
|
||||
{0x1F931, 0x1F932, prEmojiPresentation}, // E5.0 [2] (🤱..🤲) breast-feeding..palms up together
|
||||
{0x1F933, 0x1F93A, prEmojiPresentation}, // E3.0 [8] (🤳..🤺) selfie..person fencing
|
||||
{0x1F93C, 0x1F93E, prEmojiPresentation}, // E3.0 [3] (🤼..🤾) people wrestling..person playing handball
|
||||
{0x1F93F, 0x1F93F, prEmojiPresentation}, // E12.0 [1] (🤿) diving mask
|
||||
{0x1F940, 0x1F945, prEmojiPresentation}, // E3.0 [6] (🥀..🥅) wilted flower..goal net
|
||||
{0x1F947, 0x1F94B, prEmojiPresentation}, // E3.0 [5] (🥇..🥋) 1st place medal..martial arts uniform
|
||||
{0x1F94C, 0x1F94C, prEmojiPresentation}, // E5.0 [1] (🥌) curling stone
|
||||
{0x1F94D, 0x1F94F, prEmojiPresentation}, // E11.0 [3] (🥍..🥏) lacrosse..flying disc
|
||||
{0x1F950, 0x1F95E, prEmojiPresentation}, // E3.0 [15] (🥐..🥞) croissant..pancakes
|
||||
{0x1F95F, 0x1F96B, prEmojiPresentation}, // E5.0 [13] (🥟..🥫) dumpling..canned food
|
||||
{0x1F96C, 0x1F970, prEmojiPresentation}, // E11.0 [5] (🥬..🥰) leafy green..smiling face with hearts
|
||||
{0x1F971, 0x1F971, prEmojiPresentation}, // E12.0 [1] (🥱) yawning face
|
||||
{0x1F972, 0x1F972, prEmojiPresentation}, // E13.0 [1] (🥲) smiling face with tear
|
||||
{0x1F973, 0x1F976, prEmojiPresentation}, // E11.0 [4] (🥳..🥶) partying face..cold face
|
||||
{0x1F977, 0x1F978, prEmojiPresentation}, // E13.0 [2] (🥷..🥸) ninja..disguised face
|
||||
{0x1F979, 0x1F979, prEmojiPresentation}, // E14.0 [1] (🥹) face holding back tears
|
||||
{0x1F97A, 0x1F97A, prEmojiPresentation}, // E11.0 [1] (🥺) pleading face
|
||||
{0x1F97B, 0x1F97B, prEmojiPresentation}, // E12.0 [1] (🥻) sari
|
||||
{0x1F97C, 0x1F97F, prEmojiPresentation}, // E11.0 [4] (🥼..🥿) lab coat..flat shoe
|
||||
{0x1F980, 0x1F984, prEmojiPresentation}, // E1.0 [5] (🦀..🦄) crab..unicorn
|
||||
{0x1F985, 0x1F991, prEmojiPresentation}, // E3.0 [13] (🦅..🦑) eagle..squid
|
||||
{0x1F992, 0x1F997, prEmojiPresentation}, // E5.0 [6] (🦒..🦗) giraffe..cricket
|
||||
{0x1F998, 0x1F9A2, prEmojiPresentation}, // E11.0 [11] (🦘..🦢) kangaroo..swan
|
||||
{0x1F9A3, 0x1F9A4, prEmojiPresentation}, // E13.0 [2] (🦣..🦤) mammoth..dodo
|
||||
{0x1F9A5, 0x1F9AA, prEmojiPresentation}, // E12.0 [6] (🦥..🦪) sloth..oyster
|
||||
{0x1F9AB, 0x1F9AD, prEmojiPresentation}, // E13.0 [3] (🦫..🦭) beaver..seal
|
||||
{0x1F9AE, 0x1F9AF, prEmojiPresentation}, // E12.0 [2] (🦮..🦯) guide dog..white cane
|
||||
{0x1F9B0, 0x1F9B9, prEmojiPresentation}, // E11.0 [10] (🦰..🦹) red hair..supervillain
|
||||
{0x1F9BA, 0x1F9BF, prEmojiPresentation}, // E12.0 [6] (🦺..🦿) safety vest..mechanical leg
|
||||
{0x1F9C0, 0x1F9C0, prEmojiPresentation}, // E1.0 [1] (🧀) cheese wedge
|
||||
{0x1F9C1, 0x1F9C2, prEmojiPresentation}, // E11.0 [2] (🧁..🧂) cupcake..salt
|
||||
{0x1F9C3, 0x1F9CA, prEmojiPresentation}, // E12.0 [8] (🧃..🧊) beverage box..ice
|
||||
{0x1F9CB, 0x1F9CB, prEmojiPresentation}, // E13.0 [1] (🧋) bubble tea
|
||||
{0x1F9CC, 0x1F9CC, prEmojiPresentation}, // E14.0 [1] (🧌) troll
|
||||
{0x1F9CD, 0x1F9CF, prEmojiPresentation}, // E12.0 [3] (🧍..🧏) person standing..deaf person
|
||||
{0x1F9D0, 0x1F9E6, prEmojiPresentation}, // E5.0 [23] (🧐..🧦) face with monocle..socks
|
||||
{0x1F9E7, 0x1F9FF, prEmojiPresentation}, // E11.0 [25] (🧧..🧿) red envelope..nazar amulet
|
||||
{0x1FA70, 0x1FA73, prEmojiPresentation}, // E12.0 [4] (🩰..🩳) ballet shoes..shorts
|
||||
{0x1FA74, 0x1FA74, prEmojiPresentation}, // E13.0 [1] (🩴) thong sandal
|
||||
{0x1FA75, 0x1FA77, prEmojiPresentation}, // E15.0 [3] (🩵..🩷) light blue heart..pink heart
|
||||
{0x1FA78, 0x1FA7A, prEmojiPresentation}, // E12.0 [3] (🩸..🩺) drop of blood..stethoscope
|
||||
{0x1FA7B, 0x1FA7C, prEmojiPresentation}, // E14.0 [2] (🩻..🩼) x-ray..crutch
|
||||
{0x1FA80, 0x1FA82, prEmojiPresentation}, // E12.0 [3] (🪀..🪂) yo-yo..parachute
|
||||
{0x1FA83, 0x1FA86, prEmojiPresentation}, // E13.0 [4] (🪃..🪆) boomerang..nesting dolls
|
||||
{0x1FA87, 0x1FA88, prEmojiPresentation}, // E15.0 [2] (🪇..🪈) maracas..flute
|
||||
{0x1FA90, 0x1FA95, prEmojiPresentation}, // E12.0 [6] (🪐..🪕) ringed planet..banjo
|
||||
{0x1FA96, 0x1FAA8, prEmojiPresentation}, // E13.0 [19] (🪖..🪨) military helmet..rock
|
||||
{0x1FAA9, 0x1FAAC, prEmojiPresentation}, // E14.0 [4] (🪩..🪬) mirror ball..hamsa
|
||||
{0x1FAAD, 0x1FAAF, prEmojiPresentation}, // E15.0 [3] (🪭..🪯) folding hand fan..khanda
|
||||
{0x1FAB0, 0x1FAB6, prEmojiPresentation}, // E13.0 [7] (🪰..🪶) fly..feather
|
||||
{0x1FAB7, 0x1FABA, prEmojiPresentation}, // E14.0 [4] (🪷..🪺) lotus..nest with eggs
|
||||
{0x1FABB, 0x1FABD, prEmojiPresentation}, // E15.0 [3] (🪻..🪽) hyacinth..wing
|
||||
{0x1FABF, 0x1FABF, prEmojiPresentation}, // E15.0 [1] (🪿) goose
|
||||
{0x1FAC0, 0x1FAC2, prEmojiPresentation}, // E13.0 [3] (🫀..🫂) anatomical heart..people hugging
|
||||
{0x1FAC3, 0x1FAC5, prEmojiPresentation}, // E14.0 [3] (🫃..🫅) pregnant man..person with crown
|
||||
{0x1FACE, 0x1FACF, prEmojiPresentation}, // E15.0 [2] (🫎..🫏) moose..donkey
|
||||
{0x1FAD0, 0x1FAD6, prEmojiPresentation}, // E13.0 [7] (🫐..🫖) blueberries..teapot
|
||||
{0x1FAD7, 0x1FAD9, prEmojiPresentation}, // E14.0 [3] (🫗..🫙) pouring liquid..jar
|
||||
{0x1FADA, 0x1FADB, prEmojiPresentation}, // E15.0 [2] (🫚..🫛) ginger root..pea pod
|
||||
{0x1FAE0, 0x1FAE7, prEmojiPresentation}, // E14.0 [8] (🫠..🫧) melting face..bubbles
|
||||
{0x1FAE8, 0x1FAE8, prEmojiPresentation}, // E15.0 [1] (🫨) shaking face
|
||||
{0x1FAF0, 0x1FAF6, prEmojiPresentation}, // E14.0 [7] (🫰..🫶) hand with index finger and thumb crossed..heart hands
|
||||
{0x1FAF7, 0x1FAF8, prEmojiPresentation}, // E15.0 [2] (🫷..🫸) leftwards pushing hand..rightwards pushing hand
|
||||
}
|
||||
215
vendor/github.com/rivo/uniseg/gen_breaktest.go
generated
vendored
Normal file
215
vendor/github.com/rivo/uniseg/gen_breaktest.go
generated
vendored
Normal file
@@ -0,0 +1,215 @@
|
||||
//go:build generate
|
||||
|
||||
// This program generates a Go containing a slice of test cases based on the
|
||||
// Unicode Character Database auxiliary data files. The command line arguments
|
||||
// are as follows:
|
||||
//
|
||||
// 1. The name of the Unicode data file (just the filename, without extension).
|
||||
// 2. The name of the locally generated Go file.
|
||||
// 3. The name of the slice containing the test cases.
|
||||
// 4. The name of the generator, for logging purposes.
|
||||
//
|
||||
//go:generate go run gen_breaktest.go GraphemeBreakTest graphemebreak_test.go graphemeBreakTestCases graphemes
|
||||
//go:generate go run gen_breaktest.go WordBreakTest wordbreak_test.go wordBreakTestCases words
|
||||
//go:generate go run gen_breaktest.go SentenceBreakTest sentencebreak_test.go sentenceBreakTestCases sentences
|
||||
//go:generate go run gen_breaktest.go LineBreakTest linebreak_test.go lineBreakTestCases lines
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"go/format"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
"time"
|
||||
)
|
||||
|
||||
// We want to test against a specific version rather than the latest. When the
|
||||
// package is upgraded to a new version, change these to generate new tests.
|
||||
const (
|
||||
testCaseURL = `https://www.unicode.org/Public/15.0.0/ucd/auxiliary/%s.txt`
|
||||
)
|
||||
|
||||
func main() {
|
||||
if len(os.Args) < 5 {
|
||||
fmt.Println("Not enough arguments, see code for details")
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
log.SetPrefix("gen_breaktest (" + os.Args[4] + "): ")
|
||||
log.SetFlags(0)
|
||||
|
||||
// Read text of testcases and parse into Go source code.
|
||||
src, err := parse(fmt.Sprintf(testCaseURL, os.Args[1]))
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
// Format the Go code.
|
||||
formatted, err := format.Source(src)
|
||||
if err != nil {
|
||||
log.Fatalln("gofmt:", err)
|
||||
}
|
||||
|
||||
// Write it out.
|
||||
log.Print("Writing to ", os.Args[2])
|
||||
if err := ioutil.WriteFile(os.Args[2], formatted, 0644); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
// parse reads a break text file, either from a local file or from a URL. It
|
||||
// parses the file data into Go source code representing the test cases.
|
||||
func parse(url string) ([]byte, error) {
|
||||
log.Printf("Parsing %s", url)
|
||||
res, err := http.Get(url)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
body := res.Body
|
||||
defer body.Close()
|
||||
|
||||
buf := new(bytes.Buffer)
|
||||
buf.Grow(120 << 10)
|
||||
buf.WriteString(`// Code generated via go generate from gen_breaktest.go. DO NOT EDIT.
|
||||
|
||||
package uniseg
|
||||
|
||||
// ` + os.Args[3] + ` are Grapheme testcases taken from
|
||||
// ` + url + `
|
||||
// on ` + time.Now().Format("January 2, 2006") + `. See
|
||||
// https://www.unicode.org/license.html for the Unicode license agreement.
|
||||
var ` + os.Args[3] + ` = []testCase {
|
||||
`)
|
||||
|
||||
sc := bufio.NewScanner(body)
|
||||
num := 1
|
||||
var line []byte
|
||||
original := make([]byte, 0, 64)
|
||||
expected := make([]byte, 0, 64)
|
||||
for sc.Scan() {
|
||||
num++
|
||||
line = sc.Bytes()
|
||||
if len(line) == 0 || line[0] == '#' {
|
||||
continue
|
||||
}
|
||||
var comment []byte
|
||||
if i := bytes.IndexByte(line, '#'); i >= 0 {
|
||||
comment = bytes.TrimSpace(line[i+1:])
|
||||
line = bytes.TrimSpace(line[:i])
|
||||
}
|
||||
original, expected, err := parseRuneSequence(line, original[:0], expected[:0])
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf(`line %d: %v: %q`, num, err, line)
|
||||
}
|
||||
fmt.Fprintf(buf, "\t{original: \"%s\", expected: %s}, // %s\n", original, expected, comment)
|
||||
}
|
||||
if err := sc.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Check for final "# EOF", useful check if we're streaming via HTTP
|
||||
if !bytes.Equal(line, []byte("# EOF")) {
|
||||
return nil, fmt.Errorf(`line %d: exected "# EOF" as final line, got %q`, num, line)
|
||||
}
|
||||
buf.WriteString("}\n")
|
||||
return buf.Bytes(), nil
|
||||
}
|
||||
|
||||
// Used by parseRuneSequence to match input via bytes.HasPrefix.
|
||||
var (
|
||||
prefixBreak = []byte("÷ ")
|
||||
prefixDontBreak = []byte("× ")
|
||||
breakOk = []byte("÷")
|
||||
breakNo = []byte("×")
|
||||
)
|
||||
|
||||
// parseRuneSequence parses a rune + breaking opportunity sequence from b
|
||||
// and appends the Go code for testcase.original to orig
|
||||
// and appends the Go code for testcase.expected to exp.
|
||||
// It retuns the new orig and exp slices.
|
||||
//
|
||||
// E.g. for the input b="÷ 0020 × 0308 ÷ 1F1E6 ÷"
|
||||
// it will append
|
||||
//
|
||||
// "\u0020\u0308\U0001F1E6"
|
||||
//
|
||||
// and "[][]rune{{0x0020,0x0308},{0x1F1E6},}"
|
||||
// to orig and exp respectively.
|
||||
//
|
||||
// The formatting of exp is expected to be cleaned up by gofmt or format.Source.
|
||||
// Note we explicitly require the sequence to start with ÷ and we implicitly
|
||||
// require it to end with ÷.
|
||||
func parseRuneSequence(b, orig, exp []byte) ([]byte, []byte, error) {
|
||||
// Check for and remove first ÷ or ×.
|
||||
if !bytes.HasPrefix(b, prefixBreak) && !bytes.HasPrefix(b, prefixDontBreak) {
|
||||
return nil, nil, errors.New("expected ÷ or × as first character")
|
||||
}
|
||||
if bytes.HasPrefix(b, prefixBreak) {
|
||||
b = b[len(prefixBreak):]
|
||||
} else {
|
||||
b = b[len(prefixDontBreak):]
|
||||
}
|
||||
|
||||
boundary := true
|
||||
exp = append(exp, "[][]rune{"...)
|
||||
for len(b) > 0 {
|
||||
if boundary {
|
||||
exp = append(exp, '{')
|
||||
}
|
||||
exp = append(exp, "0x"...)
|
||||
// Find end of hex digits.
|
||||
var i int
|
||||
for i = 0; i < len(b) && b[i] != ' '; i++ {
|
||||
if d := b[i]; ('0' <= d || d <= '9') ||
|
||||
('A' <= d || d <= 'F') ||
|
||||
('a' <= d || d <= 'f') {
|
||||
continue
|
||||
}
|
||||
return nil, nil, errors.New("bad hex digit")
|
||||
}
|
||||
switch i {
|
||||
case 4:
|
||||
orig = append(orig, "\\u"...)
|
||||
case 5:
|
||||
orig = append(orig, "\\U000"...)
|
||||
default:
|
||||
return nil, nil, errors.New("unsupport code point hex length")
|
||||
}
|
||||
orig = append(orig, b[:i]...)
|
||||
exp = append(exp, b[:i]...)
|
||||
b = b[i:]
|
||||
|
||||
// Check for space between hex and ÷ or ×.
|
||||
if len(b) < 1 || b[0] != ' ' {
|
||||
return nil, nil, errors.New("bad input")
|
||||
}
|
||||
b = b[1:]
|
||||
|
||||
// Check for next boundary.
|
||||
switch {
|
||||
case bytes.HasPrefix(b, breakOk):
|
||||
boundary = true
|
||||
b = b[len(breakOk):]
|
||||
case bytes.HasPrefix(b, breakNo):
|
||||
boundary = false
|
||||
b = b[len(breakNo):]
|
||||
default:
|
||||
return nil, nil, errors.New("missing ÷ or ×")
|
||||
}
|
||||
if boundary {
|
||||
exp = append(exp, '}')
|
||||
}
|
||||
exp = append(exp, ',')
|
||||
if len(b) > 0 && b[0] == ' ' {
|
||||
b = b[1:]
|
||||
}
|
||||
}
|
||||
exp = append(exp, '}')
|
||||
return orig, exp, nil
|
||||
}
|
||||
261
vendor/github.com/rivo/uniseg/gen_properties.go
generated
vendored
Normal file
261
vendor/github.com/rivo/uniseg/gen_properties.go
generated
vendored
Normal file
@@ -0,0 +1,261 @@
|
||||
//go:build generate
|
||||
|
||||
// This program generates a property file in Go file from Unicode Character
|
||||
// Database auxiliary data files. The command line arguments are as follows:
|
||||
//
|
||||
// 1. The name of the Unicode data file (just the filename, without extension).
|
||||
// Can be "-" (to skip) if the emoji flag is included.
|
||||
// 2. The name of the locally generated Go file.
|
||||
// 3. The name of the slice mapping code points to properties.
|
||||
// 4. The name of the generator, for logging purposes.
|
||||
// 5. (Optional) Flags, comma-separated. The following flags are available:
|
||||
// - "emojis=<property>": include the specified emoji properties (e.g.
|
||||
// "Extended_Pictographic").
|
||||
// - "gencat": include general category properties.
|
||||
//
|
||||
//go:generate go run gen_properties.go auxiliary/GraphemeBreakProperty graphemeproperties.go graphemeCodePoints graphemes emojis=Extended_Pictographic
|
||||
//go:generate go run gen_properties.go auxiliary/WordBreakProperty wordproperties.go workBreakCodePoints words emojis=Extended_Pictographic
|
||||
//go:generate go run gen_properties.go auxiliary/SentenceBreakProperty sentenceproperties.go sentenceBreakCodePoints sentences
|
||||
//go:generate go run gen_properties.go LineBreak lineproperties.go lineBreakCodePoints lines gencat
|
||||
//go:generate go run gen_properties.go EastAsianWidth eastasianwidth.go eastAsianWidth eastasianwidth
|
||||
//go:generate go run gen_properties.go - emojipresentation.go emojiPresentation emojipresentation emojis=Emoji_Presentation
|
||||
package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"go/format"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
"regexp"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
// We want to test against a specific version rather than the latest. When the
|
||||
// package is upgraded to a new version, change these to generate new tests.
|
||||
const (
|
||||
propertyURL = `https://www.unicode.org/Public/15.0.0/ucd/%s.txt`
|
||||
emojiURL = `https://unicode.org/Public/15.0.0/ucd/emoji/emoji-data.txt`
|
||||
)
|
||||
|
||||
// The regular expression for a line containing a code point range property.
|
||||
var propertyPattern = regexp.MustCompile(`^([0-9A-F]{4,6})(\.\.([0-9A-F]{4,6}))?\s*;\s*([A-Za-z0-9_]+)\s*#\s(.+)$`)
|
||||
|
||||
func main() {
|
||||
if len(os.Args) < 5 {
|
||||
fmt.Println("Not enough arguments, see code for details")
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
log.SetPrefix("gen_properties (" + os.Args[4] + "): ")
|
||||
log.SetFlags(0)
|
||||
|
||||
// Parse flags.
|
||||
flags := make(map[string]string)
|
||||
if len(os.Args) >= 6 {
|
||||
for _, flag := range strings.Split(os.Args[5], ",") {
|
||||
flagFields := strings.Split(flag, "=")
|
||||
if len(flagFields) == 1 {
|
||||
flags[flagFields[0]] = "yes"
|
||||
} else {
|
||||
flags[flagFields[0]] = flagFields[1]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Parse the text file and generate Go source code from it.
|
||||
_, includeGeneralCategory := flags["gencat"]
|
||||
var mainURL string
|
||||
if os.Args[1] != "-" {
|
||||
mainURL = fmt.Sprintf(propertyURL, os.Args[1])
|
||||
}
|
||||
src, err := parse(mainURL, flags["emojis"], includeGeneralCategory)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
// Format the Go code.
|
||||
formatted, err := format.Source([]byte(src))
|
||||
if err != nil {
|
||||
log.Fatal("gofmt:", err)
|
||||
}
|
||||
|
||||
// Save it to the (local) target file.
|
||||
log.Print("Writing to ", os.Args[2])
|
||||
if err := ioutil.WriteFile(os.Args[2], formatted, 0644); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
// parse parses the Unicode Properties text files located at the given URLs and
|
||||
// returns their equivalent Go source code to be used in the uniseg package. If
|
||||
// "emojiProperty" is not an empty string, emoji code points for that emoji
|
||||
// property (e.g. "Extended_Pictographic") will be included. In those cases, you
|
||||
// may pass an empty "propertyURL" to skip parsing the main properties file. If
|
||||
// "includeGeneralCategory" is true, the Unicode General Category property will
|
||||
// be extracted from the comments and included in the output.
|
||||
func parse(propertyURL, emojiProperty string, includeGeneralCategory bool) (string, error) {
|
||||
if propertyURL == "" && emojiProperty == "" {
|
||||
return "", errors.New("no properties to parse")
|
||||
}
|
||||
|
||||
// Temporary buffer to hold properties.
|
||||
var properties [][4]string
|
||||
|
||||
// Open the first URL.
|
||||
if propertyURL != "" {
|
||||
log.Printf("Parsing %s", propertyURL)
|
||||
res, err := http.Get(propertyURL)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
in1 := res.Body
|
||||
defer in1.Close()
|
||||
|
||||
// Parse it.
|
||||
scanner := bufio.NewScanner(in1)
|
||||
num := 0
|
||||
for scanner.Scan() {
|
||||
num++
|
||||
line := strings.TrimSpace(scanner.Text())
|
||||
|
||||
// Skip comments and empty lines.
|
||||
if strings.HasPrefix(line, "#") || line == "" {
|
||||
continue
|
||||
}
|
||||
|
||||
// Everything else must be a code point range, a property and a comment.
|
||||
from, to, property, comment, err := parseProperty(line)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("%s line %d: %v", os.Args[4], num, err)
|
||||
}
|
||||
properties = append(properties, [4]string{from, to, property, comment})
|
||||
}
|
||||
if err := scanner.Err(); err != nil {
|
||||
return "", err
|
||||
}
|
||||
}
|
||||
|
||||
// Open the second URL.
|
||||
if emojiProperty != "" {
|
||||
log.Printf("Parsing %s", emojiURL)
|
||||
res, err := http.Get(emojiURL)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
in2 := res.Body
|
||||
defer in2.Close()
|
||||
|
||||
// Parse it.
|
||||
scanner := bufio.NewScanner(in2)
|
||||
num := 0
|
||||
for scanner.Scan() {
|
||||
num++
|
||||
line := scanner.Text()
|
||||
|
||||
// Skip comments, empty lines, and everything not containing
|
||||
// "Extended_Pictographic".
|
||||
if strings.HasPrefix(line, "#") || line == "" || !strings.Contains(line, emojiProperty) {
|
||||
continue
|
||||
}
|
||||
|
||||
// Everything else must be a code point range, a property and a comment.
|
||||
from, to, property, comment, err := parseProperty(line)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("emojis line %d: %v", num, err)
|
||||
}
|
||||
properties = append(properties, [4]string{from, to, property, comment})
|
||||
}
|
||||
if err := scanner.Err(); err != nil {
|
||||
return "", err
|
||||
}
|
||||
}
|
||||
|
||||
// Avoid overflow during binary search.
|
||||
if len(properties) >= 1<<31 {
|
||||
return "", errors.New("too many properties")
|
||||
}
|
||||
|
||||
// Sort properties.
|
||||
sort.Slice(properties, func(i, j int) bool {
|
||||
left, _ := strconv.ParseUint(properties[i][0], 16, 64)
|
||||
right, _ := strconv.ParseUint(properties[j][0], 16, 64)
|
||||
return left < right
|
||||
})
|
||||
|
||||
// Header.
|
||||
var (
|
||||
buf bytes.Buffer
|
||||
emojiComment string
|
||||
)
|
||||
columns := 3
|
||||
if includeGeneralCategory {
|
||||
columns = 4
|
||||
}
|
||||
if emojiURL != "" {
|
||||
emojiComment = `
|
||||
// and
|
||||
// ` + emojiURL + `
|
||||
// ("Extended_Pictographic" only)`
|
||||
}
|
||||
buf.WriteString(`// Code generated via go generate from gen_properties.go. DO NOT EDIT.
|
||||
|
||||
package uniseg
|
||||
|
||||
// ` + os.Args[3] + ` are taken from
|
||||
// ` + propertyURL + emojiComment + `
|
||||
// on ` + time.Now().Format("January 2, 2006") + `. See https://www.unicode.org/license.html for the Unicode
|
||||
// license agreement.
|
||||
var ` + os.Args[3] + ` = [][` + strconv.Itoa(columns) + `]int{
|
||||
`)
|
||||
|
||||
// Properties.
|
||||
for _, prop := range properties {
|
||||
if includeGeneralCategory {
|
||||
generalCategory := "gc" + prop[3][:2]
|
||||
if generalCategory == "gcL&" {
|
||||
generalCategory = "gcLC"
|
||||
}
|
||||
prop[3] = prop[3][3:]
|
||||
fmt.Fprintf(&buf, "{0x%s,0x%s,%s,%s}, // %s\n", prop[0], prop[1], translateProperty("pr", prop[2]), generalCategory, prop[3])
|
||||
} else {
|
||||
fmt.Fprintf(&buf, "{0x%s,0x%s,%s}, // %s\n", prop[0], prop[1], translateProperty("pr", prop[2]), prop[3])
|
||||
}
|
||||
}
|
||||
|
||||
// Tail.
|
||||
buf.WriteString("}")
|
||||
|
||||
return buf.String(), nil
|
||||
}
|
||||
|
||||
// parseProperty parses a line of the Unicode properties text file containing a
|
||||
// property for a code point range and returns it along with its comment.
|
||||
func parseProperty(line string) (from, to, property, comment string, err error) {
|
||||
fields := propertyPattern.FindStringSubmatch(line)
|
||||
if fields == nil {
|
||||
err = errors.New("no property found")
|
||||
return
|
||||
}
|
||||
from = fields[1]
|
||||
to = fields[3]
|
||||
if to == "" {
|
||||
to = from
|
||||
}
|
||||
property = fields[4]
|
||||
comment = fields[5]
|
||||
return
|
||||
}
|
||||
|
||||
// translateProperty translates a property name as used in the Unicode data file
|
||||
// to a variable used in the Go code.
|
||||
func translateProperty(prefix, property string) string {
|
||||
return prefix + strings.ReplaceAll(property, "_", "")
|
||||
}
|
||||
331
vendor/github.com/rivo/uniseg/grapheme.go
generated
vendored
Normal file
331
vendor/github.com/rivo/uniseg/grapheme.go
generated
vendored
Normal file
@@ -0,0 +1,331 @@
|
||||
package uniseg
|
||||
|
||||
import "unicode/utf8"
|
||||
|
||||
// Graphemes implements an iterator over Unicode grapheme clusters, or
|
||||
// user-perceived characters. While iterating, it also provides information
|
||||
// about word boundaries, sentence boundaries, line breaks, and monospace
|
||||
// character widths.
|
||||
//
|
||||
// After constructing the class via [NewGraphemes] for a given string "str",
|
||||
// [Graphemes.Next] is called for every grapheme cluster in a loop until it
|
||||
// returns false. Inside the loop, information about the grapheme cluster as
|
||||
// well as boundary information and character width is available via the various
|
||||
// methods (see examples below).
|
||||
//
|
||||
// This class basically wraps the [StepString] parser and provides a convenient
|
||||
// interface to it. If you are only interested in some parts of this package's
|
||||
// functionality, using the specialized functions starting with "First" is
|
||||
// almost always faster.
|
||||
type Graphemes struct {
|
||||
// The original string.
|
||||
original string
|
||||
|
||||
// The remaining string to be parsed.
|
||||
remaining string
|
||||
|
||||
// The current grapheme cluster.
|
||||
cluster string
|
||||
|
||||
// The byte offset of the current grapheme cluster relative to the original
|
||||
// string.
|
||||
offset int
|
||||
|
||||
// The current boundary information of the [Step] parser.
|
||||
boundaries int
|
||||
|
||||
// The current state of the [Step] parser.
|
||||
state int
|
||||
}
|
||||
|
||||
// NewGraphemes returns a new grapheme cluster iterator.
|
||||
func NewGraphemes(str string) *Graphemes {
|
||||
return &Graphemes{
|
||||
original: str,
|
||||
remaining: str,
|
||||
state: -1,
|
||||
}
|
||||
}
|
||||
|
||||
// Next advances the iterator by one grapheme cluster and returns false if no
|
||||
// clusters are left. This function must be called before the first cluster is
|
||||
// accessed.
|
||||
func (g *Graphemes) Next() bool {
|
||||
if len(g.remaining) == 0 {
|
||||
// We're already past the end.
|
||||
g.state = -2
|
||||
g.cluster = ""
|
||||
return false
|
||||
}
|
||||
g.offset += len(g.cluster)
|
||||
g.cluster, g.remaining, g.boundaries, g.state = StepString(g.remaining, g.state)
|
||||
return true
|
||||
}
|
||||
|
||||
// Runes returns a slice of runes (code points) which corresponds to the current
|
||||
// grapheme cluster. If the iterator is already past the end or [Graphemes.Next]
|
||||
// has not yet been called, nil is returned.
|
||||
func (g *Graphemes) Runes() []rune {
|
||||
if g.state < 0 {
|
||||
return nil
|
||||
}
|
||||
return []rune(g.cluster)
|
||||
}
|
||||
|
||||
// Str returns a substring of the original string which corresponds to the
|
||||
// current grapheme cluster. If the iterator is already past the end or
|
||||
// [Graphemes.Next] has not yet been called, an empty string is returned.
|
||||
func (g *Graphemes) Str() string {
|
||||
return g.cluster
|
||||
}
|
||||
|
||||
// Bytes returns a byte slice which corresponds to the current grapheme cluster.
|
||||
// If the iterator is already past the end or [Graphemes.Next] has not yet been
|
||||
// called, nil is returned.
|
||||
func (g *Graphemes) Bytes() []byte {
|
||||
if g.state < 0 {
|
||||
return nil
|
||||
}
|
||||
return []byte(g.cluster)
|
||||
}
|
||||
|
||||
// Positions returns the interval of the current grapheme cluster as byte
|
||||
// positions into the original string. The first returned value "from" indexes
|
||||
// the first byte and the second returned value "to" indexes the first byte that
|
||||
// is not included anymore, i.e. str[from:to] is the current grapheme cluster of
|
||||
// the original string "str". If [Graphemes.Next] has not yet been called, both
|
||||
// values are 0. If the iterator is already past the end, both values are 1.
|
||||
func (g *Graphemes) Positions() (int, int) {
|
||||
if g.state == -1 {
|
||||
return 0, 0
|
||||
} else if g.state == -2 {
|
||||
return 1, 1
|
||||
}
|
||||
return g.offset, g.offset + len(g.cluster)
|
||||
}
|
||||
|
||||
// IsWordBoundary returns true if a word ends after the current grapheme
|
||||
// cluster.
|
||||
func (g *Graphemes) IsWordBoundary() bool {
|
||||
if g.state < 0 {
|
||||
return true
|
||||
}
|
||||
return g.boundaries&MaskWord != 0
|
||||
}
|
||||
|
||||
// IsSentenceBoundary returns true if a sentence ends after the current
|
||||
// grapheme cluster.
|
||||
func (g *Graphemes) IsSentenceBoundary() bool {
|
||||
if g.state < 0 {
|
||||
return true
|
||||
}
|
||||
return g.boundaries&MaskSentence != 0
|
||||
}
|
||||
|
||||
// LineBreak returns whether the line can be broken after the current grapheme
|
||||
// cluster. A value of [LineDontBreak] means the line may not be broken, a value
|
||||
// of [LineMustBreak] means the line must be broken, and a value of
|
||||
// [LineCanBreak] means the line may or may not be broken.
|
||||
func (g *Graphemes) LineBreak() int {
|
||||
if g.state == -1 {
|
||||
return LineDontBreak
|
||||
}
|
||||
if g.state == -2 {
|
||||
return LineMustBreak
|
||||
}
|
||||
return g.boundaries & MaskLine
|
||||
}
|
||||
|
||||
// Width returns the monospace width of the current grapheme cluster.
|
||||
func (g *Graphemes) Width() int {
|
||||
if g.state < 0 {
|
||||
return 0
|
||||
}
|
||||
return g.boundaries >> ShiftWidth
|
||||
}
|
||||
|
||||
// Reset puts the iterator into its initial state such that the next call to
|
||||
// [Graphemes.Next] sets it to the first grapheme cluster again.
|
||||
func (g *Graphemes) Reset() {
|
||||
g.state = -1
|
||||
g.offset = 0
|
||||
g.cluster = ""
|
||||
g.remaining = g.original
|
||||
}
|
||||
|
||||
// GraphemeClusterCount returns the number of user-perceived characters
|
||||
// (grapheme clusters) for the given string.
|
||||
func GraphemeClusterCount(s string) (n int) {
|
||||
state := -1
|
||||
for len(s) > 0 {
|
||||
_, s, _, state = FirstGraphemeClusterInString(s, state)
|
||||
n++
|
||||
}
|
||||
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
|
||||
|
||||
// FirstGraphemeCluster returns the first grapheme cluster found in the given
|
||||
// byte slice according to the rules of [Unicode Standard Annex #29, Grapheme
|
||||
// Cluster Boundaries]. This function can be called continuously to extract all
|
||||
// grapheme clusters from a byte slice, as illustrated in the example below.
|
||||
//
|
||||
// If you don't know the current state, for example when calling the function
|
||||
// for the first time, you must pass -1. For consecutive calls, pass the state
|
||||
// and rest slice returned by the previous call.
|
||||
//
|
||||
// The "rest" slice is the sub-slice of the original byte slice "b" starting
|
||||
// after the last byte of the identified grapheme cluster. If the length of the
|
||||
// "rest" slice is 0, the entire byte slice "b" has been processed. The
|
||||
// "cluster" byte slice is the sub-slice of the input slice containing the
|
||||
// identified grapheme cluster.
|
||||
//
|
||||
// The returned width is the width of the grapheme cluster for most monospace
|
||||
// fonts where a value of 1 represents one character cell.
|
||||
//
|
||||
// Given an empty byte slice "b", the function returns nil values.
|
||||
//
|
||||
// While slightly less convenient than using the Graphemes class, this function
|
||||
// has much better performance and makes no allocations. It lends itself well to
|
||||
// large byte slices.
|
||||
//
|
||||
// [Unicode Standard Annex #29, Grapheme Cluster Boundaries]: http://unicode.org/reports/tr29/#Grapheme_Cluster_Boundaries
|
||||
func FirstGraphemeCluster(b []byte, state int) (cluster, rest []byte, width, newState int) {
|
||||
// An empty byte slice returns nothing.
|
||||
if len(b) == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
// Extract the first rune.
|
||||
r, length := utf8.DecodeRune(b)
|
||||
if len(b) <= length { // If we're already past the end, there is nothing else to parse.
|
||||
var prop int
|
||||
if state < 0 {
|
||||
prop = propertyGraphemes(r)
|
||||
} else {
|
||||
prop = state >> shiftGraphemePropState
|
||||
}
|
||||
return b, nil, runeWidth(r, prop), grAny | (prop << shiftGraphemePropState)
|
||||
}
|
||||
|
||||
// If we don't know the state, determine it now.
|
||||
var firstProp int
|
||||
if state < 0 {
|
||||
state, firstProp, _ = transitionGraphemeState(state, r)
|
||||
} else {
|
||||
firstProp = state >> shiftGraphemePropState
|
||||
}
|
||||
width += runeWidth(r, firstProp)
|
||||
|
||||
// Transition until we find a boundary.
|
||||
for {
|
||||
var (
|
||||
prop int
|
||||
boundary bool
|
||||
)
|
||||
|
||||
r, l := utf8.DecodeRune(b[length:])
|
||||
state, prop, boundary = transitionGraphemeState(state&maskGraphemeState, r)
|
||||
|
||||
if boundary {
|
||||
return b[:length], b[length:], width, state | (prop << shiftGraphemePropState)
|
||||
}
|
||||
|
||||
if firstProp == prExtendedPictographic {
|
||||
if r == vs15 {
|
||||
width = 1
|
||||
} else if r == vs16 {
|
||||
width = 2
|
||||
}
|
||||
} else if firstProp != prRegionalIndicator && firstProp != prL {
|
||||
width += runeWidth(r, prop)
|
||||
}
|
||||
|
||||
length += l
|
||||
if len(b) <= length {
|
||||
return b, nil, width, grAny | (prop << shiftGraphemePropState)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// FirstGraphemeClusterInString is like [FirstGraphemeCluster] but its input and
|
||||
// outputs are strings.
|
||||
func FirstGraphemeClusterInString(str string, state int) (cluster, rest string, width, newState int) {
|
||||
// An empty string returns nothing.
|
||||
if len(str) == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
// Extract the first rune.
|
||||
r, length := utf8.DecodeRuneInString(str)
|
||||
if len(str) <= length { // If we're already past the end, there is nothing else to parse.
|
||||
var prop int
|
||||
if state < 0 {
|
||||
prop = propertyGraphemes(r)
|
||||
} else {
|
||||
prop = state >> shiftGraphemePropState
|
||||
}
|
||||
return str, "", runeWidth(r, prop), grAny | (prop << shiftGraphemePropState)
|
||||
}
|
||||
|
||||
// If we don't know the state, determine it now.
|
||||
var firstProp int
|
||||
if state < 0 {
|
||||
state, firstProp, _ = transitionGraphemeState(state, r)
|
||||
} else {
|
||||
firstProp = state >> shiftGraphemePropState
|
||||
}
|
||||
width += runeWidth(r, firstProp)
|
||||
|
||||
// Transition until we find a boundary.
|
||||
for {
|
||||
var (
|
||||
prop int
|
||||
boundary bool
|
||||
)
|
||||
|
||||
r, l := utf8.DecodeRuneInString(str[length:])
|
||||
state, prop, boundary = transitionGraphemeState(state&maskGraphemeState, r)
|
||||
|
||||
if boundary {
|
||||
return str[:length], str[length:], width, state | (prop << shiftGraphemePropState)
|
||||
}
|
||||
|
||||
if firstProp == prExtendedPictographic {
|
||||
if r == vs15 {
|
||||
width = 1
|
||||
} else if r == vs16 {
|
||||
width = 2
|
||||
}
|
||||
} else if firstProp != prRegionalIndicator && firstProp != prL {
|
||||
width += runeWidth(r, prop)
|
||||
}
|
||||
|
||||
length += l
|
||||
if len(str) <= length {
|
||||
return str, "", width, grAny | (prop << shiftGraphemePropState)
|
||||
}
|
||||
}
|
||||
}
|
||||
1915
vendor/github.com/rivo/uniseg/graphemeproperties.go
generated
vendored
Normal file
1915
vendor/github.com/rivo/uniseg/graphemeproperties.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
176
vendor/github.com/rivo/uniseg/graphemerules.go
generated
vendored
Normal file
176
vendor/github.com/rivo/uniseg/graphemerules.go
generated
vendored
Normal file
@@ -0,0 +1,176 @@
|
||||
package uniseg
|
||||
|
||||
// The states of the grapheme cluster parser.
|
||||
const (
|
||||
grAny = iota
|
||||
grCR
|
||||
grControlLF
|
||||
grL
|
||||
grLVV
|
||||
grLVTT
|
||||
grPrepend
|
||||
grExtendedPictographic
|
||||
grExtendedPictographicZWJ
|
||||
grRIOdd
|
||||
grRIEven
|
||||
)
|
||||
|
||||
// The grapheme cluster parser's breaking instructions.
|
||||
const (
|
||||
grNoBoundary = iota
|
||||
grBoundary
|
||||
)
|
||||
|
||||
// grTransitions implements the grapheme cluster parser's state transitions.
|
||||
// Maps state and property to a new state, a breaking instruction, and rule
|
||||
// number. The breaking instruction always refers to the boundary between the
|
||||
// last and next code point. Returns negative values if no transition is found.
|
||||
//
|
||||
// This function is used as follows:
|
||||
//
|
||||
// 1. Find specific state + specific property. Stop if found.
|
||||
// 2. Find specific state + any property.
|
||||
// 3. Find any state + specific property.
|
||||
// 4. If only (2) or (3) (but not both) was found, stop.
|
||||
// 5. If both (2) and (3) were found, use state from (3) and breaking instruction
|
||||
// from the transition with the lower rule number, prefer (3) if rule numbers
|
||||
// are equal. Stop.
|
||||
// 6. Assume grAny and grBoundary.
|
||||
//
|
||||
// Unicode version 15.0.0.
|
||||
func grTransitions(state, prop int) (newState int, newProp int, boundary int) {
|
||||
// It turns out that using a big switch statement is much faster than using
|
||||
// a map.
|
||||
|
||||
switch uint64(state) | uint64(prop)<<32 {
|
||||
// GB5
|
||||
case grAny | prCR<<32:
|
||||
return grCR, grBoundary, 50
|
||||
case grAny | prLF<<32:
|
||||
return grControlLF, grBoundary, 50
|
||||
case grAny | prControl<<32:
|
||||
return grControlLF, grBoundary, 50
|
||||
|
||||
// GB4
|
||||
case grCR | prAny<<32:
|
||||
return grAny, grBoundary, 40
|
||||
case grControlLF | prAny<<32:
|
||||
return grAny, grBoundary, 40
|
||||
|
||||
// GB3
|
||||
case grCR | prLF<<32:
|
||||
return grControlLF, grNoBoundary, 30
|
||||
|
||||
// GB6
|
||||
case grAny | prL<<32:
|
||||
return grL, grBoundary, 9990
|
||||
case grL | prL<<32:
|
||||
return grL, grNoBoundary, 60
|
||||
case grL | prV<<32:
|
||||
return grLVV, grNoBoundary, 60
|
||||
case grL | prLV<<32:
|
||||
return grLVV, grNoBoundary, 60
|
||||
case grL | prLVT<<32:
|
||||
return grLVTT, grNoBoundary, 60
|
||||
|
||||
// GB7
|
||||
case grAny | prLV<<32:
|
||||
return grLVV, grBoundary, 9990
|
||||
case grAny | prV<<32:
|
||||
return grLVV, grBoundary, 9990
|
||||
case grLVV | prV<<32:
|
||||
return grLVV, grNoBoundary, 70
|
||||
case grLVV | prT<<32:
|
||||
return grLVTT, grNoBoundary, 70
|
||||
|
||||
// GB8
|
||||
case grAny | prLVT<<32:
|
||||
return grLVTT, grBoundary, 9990
|
||||
case grAny | prT<<32:
|
||||
return grLVTT, grBoundary, 9990
|
||||
case grLVTT | prT<<32:
|
||||
return grLVTT, grNoBoundary, 80
|
||||
|
||||
// GB9
|
||||
case grAny | prExtend<<32:
|
||||
return grAny, grNoBoundary, 90
|
||||
case grAny | prZWJ<<32:
|
||||
return grAny, grNoBoundary, 90
|
||||
|
||||
// GB9a
|
||||
case grAny | prSpacingMark<<32:
|
||||
return grAny, grNoBoundary, 91
|
||||
|
||||
// GB9b
|
||||
case grAny | prPrepend<<32:
|
||||
return grPrepend, grBoundary, 9990
|
||||
case grPrepend | prAny<<32:
|
||||
return grAny, grNoBoundary, 92
|
||||
|
||||
// GB11
|
||||
case grAny | prExtendedPictographic<<32:
|
||||
return grExtendedPictographic, grBoundary, 9990
|
||||
case grExtendedPictographic | prExtend<<32:
|
||||
return grExtendedPictographic, grNoBoundary, 110
|
||||
case grExtendedPictographic | prZWJ<<32:
|
||||
return grExtendedPictographicZWJ, grNoBoundary, 110
|
||||
case grExtendedPictographicZWJ | prExtendedPictographic<<32:
|
||||
return grExtendedPictographic, grNoBoundary, 110
|
||||
|
||||
// GB12 / GB13
|
||||
case grAny | prRegionalIndicator<<32:
|
||||
return grRIOdd, grBoundary, 9990
|
||||
case grRIOdd | prRegionalIndicator<<32:
|
||||
return grRIEven, grNoBoundary, 120
|
||||
case grRIEven | prRegionalIndicator<<32:
|
||||
return grRIOdd, grBoundary, 120
|
||||
default:
|
||||
return -1, -1, -1
|
||||
}
|
||||
}
|
||||
|
||||
// transitionGraphemeState determines the new state of the grapheme cluster
|
||||
// parser given the current state and the next code point. It also returns the
|
||||
// code point's grapheme property (the value mapped by the [graphemeCodePoints]
|
||||
// table) and whether a cluster boundary was detected.
|
||||
func transitionGraphemeState(state int, r rune) (newState, prop int, boundary bool) {
|
||||
// Determine the property of the next character.
|
||||
prop = propertyGraphemes(r)
|
||||
|
||||
// Find the applicable transition.
|
||||
nextState, nextProp, _ := grTransitions(state, prop)
|
||||
if nextState >= 0 {
|
||||
// We have a specific transition. We'll use it.
|
||||
return nextState, prop, nextProp == grBoundary
|
||||
}
|
||||
|
||||
// No specific transition found. Try the less specific ones.
|
||||
anyPropState, anyPropProp, anyPropRule := grTransitions(state, prAny)
|
||||
anyStateState, anyStateProp, anyStateRule := grTransitions(grAny, prop)
|
||||
if anyPropState >= 0 && anyStateState >= 0 {
|
||||
// Both apply. We'll use a mix (see comments for grTransitions).
|
||||
newState = anyStateState
|
||||
boundary = anyStateProp == grBoundary
|
||||
if anyPropRule < anyStateRule {
|
||||
boundary = anyPropProp == grBoundary
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
if anyPropState >= 0 {
|
||||
// We only have a specific state.
|
||||
return anyPropState, prop, anyPropProp == grBoundary
|
||||
// This branch will probably never be reached because okAnyState will
|
||||
// always be true given the current transition map. But we keep it here
|
||||
// for future modifications to the transition map where this may not be
|
||||
// true anymore.
|
||||
}
|
||||
|
||||
if anyStateState >= 0 {
|
||||
// We only have a specific property.
|
||||
return anyStateState, prop, anyStateProp == grBoundary
|
||||
}
|
||||
|
||||
// No known transition. GB999: Any ÷ Any.
|
||||
return grAny, prop, true
|
||||
}
|
||||
134
vendor/github.com/rivo/uniseg/line.go
generated
vendored
Normal file
134
vendor/github.com/rivo/uniseg/line.go
generated
vendored
Normal file
@@ -0,0 +1,134 @@
|
||||
package uniseg
|
||||
|
||||
import "unicode/utf8"
|
||||
|
||||
// FirstLineSegment returns the prefix of the given byte slice after which a
|
||||
// decision to break the string over to the next line can or must be made,
|
||||
// according to the rules of [Unicode Standard Annex #14]. This is used to
|
||||
// implement line breaking.
|
||||
//
|
||||
// Line breaking, also known as word wrapping, is the process of breaking a
|
||||
// section of text into lines such that it will fit in the available width of a
|
||||
// page, window or other display area.
|
||||
//
|
||||
// The returned "segment" may not be broken into smaller parts, unless no other
|
||||
// breaking opportunities present themselves, in which case you may break by
|
||||
// grapheme clusters (using the [FirstGraphemeCluster] function to determine the
|
||||
// grapheme clusters).
|
||||
//
|
||||
// The "mustBreak" flag indicates whether you MUST break the line after the
|
||||
// given segment (true), for example after newline characters, or you MAY break
|
||||
// the line after the given segment (false).
|
||||
//
|
||||
// This function can be called continuously to extract all non-breaking sub-sets
|
||||
// from a byte slice, as illustrated in the example below.
|
||||
//
|
||||
// If you don't know the current state, for example when calling the function
|
||||
// for the first time, you must pass -1. For consecutive calls, pass the state
|
||||
// and rest slice returned by the previous call.
|
||||
//
|
||||
// The "rest" slice is the sub-slice of the original byte slice "b" starting
|
||||
// after the last byte of the identified line segment. If the length of the
|
||||
// "rest" slice is 0, the entire byte slice "b" has been processed. The
|
||||
// "segment" byte slice is the sub-slice of the input slice containing the
|
||||
// identified line segment.
|
||||
//
|
||||
// Given an empty byte slice "b", the function returns nil values.
|
||||
//
|
||||
// Note that in accordance with [UAX #14 LB3], the final segment will end with
|
||||
// "mustBreak" set to true. You can choose to ignore this by checking if the
|
||||
// length of the "rest" slice is 0 and calling [HasTrailingLineBreak] or
|
||||
// [HasTrailingLineBreakInString] on the last rune.
|
||||
//
|
||||
// Note also that this algorithm may break within grapheme clusters. This is
|
||||
// addressed in Section 8.2 Example 6 of UAX #14. To avoid this, you can use
|
||||
// the [Step] function instead.
|
||||
//
|
||||
// [Unicode Standard Annex #14]: https://www.unicode.org/reports/tr14/
|
||||
// [UAX #14 LB3]: https://www.unicode.org/reports/tr14/#Algorithm
|
||||
func FirstLineSegment(b []byte, state int) (segment, rest []byte, mustBreak bool, newState int) {
|
||||
// An empty byte slice returns nothing.
|
||||
if len(b) == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
// Extract the first rune.
|
||||
r, length := utf8.DecodeRune(b)
|
||||
if len(b) <= length { // If we're already past the end, there is nothing else to parse.
|
||||
return b, nil, true, lbAny // LB3.
|
||||
}
|
||||
|
||||
// If we don't know the state, determine it now.
|
||||
if state < 0 {
|
||||
state, _ = transitionLineBreakState(state, r, b[length:], "")
|
||||
}
|
||||
|
||||
// Transition until we find a boundary.
|
||||
var boundary int
|
||||
for {
|
||||
r, l := utf8.DecodeRune(b[length:])
|
||||
state, boundary = transitionLineBreakState(state, r, b[length+l:], "")
|
||||
|
||||
if boundary != LineDontBreak {
|
||||
return b[:length], b[length:], boundary == LineMustBreak, state
|
||||
}
|
||||
|
||||
length += l
|
||||
if len(b) <= length {
|
||||
return b, nil, true, lbAny // LB3
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// FirstLineSegmentInString is like [FirstLineSegment] but its input and outputs
|
||||
// are strings.
|
||||
func FirstLineSegmentInString(str string, state int) (segment, rest string, mustBreak bool, newState int) {
|
||||
// An empty byte slice returns nothing.
|
||||
if len(str) == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
// Extract the first rune.
|
||||
r, length := utf8.DecodeRuneInString(str)
|
||||
if len(str) <= length { // If we're already past the end, there is nothing else to parse.
|
||||
return str, "", true, lbAny // LB3.
|
||||
}
|
||||
|
||||
// If we don't know the state, determine it now.
|
||||
if state < 0 {
|
||||
state, _ = transitionLineBreakState(state, r, nil, str[length:])
|
||||
}
|
||||
|
||||
// Transition until we find a boundary.
|
||||
var boundary int
|
||||
for {
|
||||
r, l := utf8.DecodeRuneInString(str[length:])
|
||||
state, boundary = transitionLineBreakState(state, r, nil, str[length+l:])
|
||||
|
||||
if boundary != LineDontBreak {
|
||||
return str[:length], str[length:], boundary == LineMustBreak, state
|
||||
}
|
||||
|
||||
length += l
|
||||
if len(str) <= length {
|
||||
return str, "", true, lbAny // LB3.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// HasTrailingLineBreak returns true if the last rune in the given byte slice is
|
||||
// one of the hard line break code points defined in LB4 and LB5 of [UAX #14].
|
||||
//
|
||||
// [UAX #14]: https://www.unicode.org/reports/tr14/#Algorithm
|
||||
func HasTrailingLineBreak(b []byte) bool {
|
||||
r, _ := utf8.DecodeLastRune(b)
|
||||
property, _ := propertyLineBreak(r)
|
||||
return property == prBK || property == prCR || property == prLF || property == prNL
|
||||
}
|
||||
|
||||
// HasTrailingLineBreakInString is like [HasTrailingLineBreak] but for a string.
|
||||
func HasTrailingLineBreakInString(str string) bool {
|
||||
r, _ := utf8.DecodeLastRuneInString(str)
|
||||
property, _ := propertyLineBreak(r)
|
||||
return property == prBK || property == prCR || property == prLF || property == prNL
|
||||
}
|
||||
3554
vendor/github.com/rivo/uniseg/lineproperties.go
generated
vendored
Normal file
3554
vendor/github.com/rivo/uniseg/lineproperties.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
626
vendor/github.com/rivo/uniseg/linerules.go
generated
vendored
Normal file
626
vendor/github.com/rivo/uniseg/linerules.go
generated
vendored
Normal file
@@ -0,0 +1,626 @@
|
||||
package uniseg
|
||||
|
||||
import "unicode/utf8"
|
||||
|
||||
// The states of the line break parser.
|
||||
const (
|
||||
lbAny = iota
|
||||
lbBK
|
||||
lbCR
|
||||
lbLF
|
||||
lbNL
|
||||
lbSP
|
||||
lbZW
|
||||
lbWJ
|
||||
lbGL
|
||||
lbBA
|
||||
lbHY
|
||||
lbCL
|
||||
lbCP
|
||||
lbEX
|
||||
lbIS
|
||||
lbSY
|
||||
lbOP
|
||||
lbQU
|
||||
lbQUSP
|
||||
lbNS
|
||||
lbCLCPSP
|
||||
lbB2
|
||||
lbB2SP
|
||||
lbCB
|
||||
lbBB
|
||||
lbLB21a
|
||||
lbHL
|
||||
lbAL
|
||||
lbNU
|
||||
lbPR
|
||||
lbEB
|
||||
lbIDEM
|
||||
lbNUNU
|
||||
lbNUSY
|
||||
lbNUIS
|
||||
lbNUCL
|
||||
lbNUCP
|
||||
lbPO
|
||||
lbJL
|
||||
lbJV
|
||||
lbJT
|
||||
lbH2
|
||||
lbH3
|
||||
lbOddRI
|
||||
lbEvenRI
|
||||
lbExtPicCn
|
||||
lbZWJBit = 64
|
||||
lbCPeaFWHBit = 128
|
||||
)
|
||||
|
||||
// These constants define whether a given text may be broken into the next line.
|
||||
// If the break is optional (LineCanBreak), you may choose to break or not based
|
||||
// on your own criteria, for example, if the text has reached the available
|
||||
// width.
|
||||
const (
|
||||
LineDontBreak = iota // You may not break the line here.
|
||||
LineCanBreak // You may or may not break the line here.
|
||||
LineMustBreak // You must break the line here.
|
||||
)
|
||||
|
||||
// lbTransitions implements the line break parser's state transitions. It's
|
||||
// anologous to [grTransitions], see comments there for details.
|
||||
//
|
||||
// Unicode version 15.0.0.
|
||||
func lbTransitions(state, prop int) (newState, lineBreak, rule int) {
|
||||
switch uint64(state) | uint64(prop)<<32 {
|
||||
// LB4.
|
||||
case lbBK | prAny<<32:
|
||||
return lbAny, LineMustBreak, 40
|
||||
|
||||
// LB5.
|
||||
case lbCR | prLF<<32:
|
||||
return lbLF, LineDontBreak, 50
|
||||
case lbCR | prAny<<32:
|
||||
return lbAny, LineMustBreak, 50
|
||||
case lbLF | prAny<<32:
|
||||
return lbAny, LineMustBreak, 50
|
||||
case lbNL | prAny<<32:
|
||||
return lbAny, LineMustBreak, 50
|
||||
|
||||
// LB6.
|
||||
case lbAny | prBK<<32:
|
||||
return lbBK, LineDontBreak, 60
|
||||
case lbAny | prCR<<32:
|
||||
return lbCR, LineDontBreak, 60
|
||||
case lbAny | prLF<<32:
|
||||
return lbLF, LineDontBreak, 60
|
||||
case lbAny | prNL<<32:
|
||||
return lbNL, LineDontBreak, 60
|
||||
|
||||
// LB7.
|
||||
case lbAny | prSP<<32:
|
||||
return lbSP, LineDontBreak, 70
|
||||
case lbAny | prZW<<32:
|
||||
return lbZW, LineDontBreak, 70
|
||||
|
||||
// LB8.
|
||||
case lbZW | prSP<<32:
|
||||
return lbZW, LineDontBreak, 70
|
||||
case lbZW | prAny<<32:
|
||||
return lbAny, LineCanBreak, 80
|
||||
|
||||
// LB11.
|
||||
case lbAny | prWJ<<32:
|
||||
return lbWJ, LineDontBreak, 110
|
||||
case lbWJ | prAny<<32:
|
||||
return lbAny, LineDontBreak, 110
|
||||
|
||||
// LB12.
|
||||
case lbAny | prGL<<32:
|
||||
return lbGL, LineCanBreak, 310
|
||||
case lbGL | prAny<<32:
|
||||
return lbAny, LineDontBreak, 120
|
||||
|
||||
// LB13 (simple transitions).
|
||||
case lbAny | prCL<<32:
|
||||
return lbCL, LineCanBreak, 310
|
||||
case lbAny | prCP<<32:
|
||||
return lbCP, LineCanBreak, 310
|
||||
case lbAny | prEX<<32:
|
||||
return lbEX, LineDontBreak, 130
|
||||
case lbAny | prIS<<32:
|
||||
return lbIS, LineCanBreak, 310
|
||||
case lbAny | prSY<<32:
|
||||
return lbSY, LineCanBreak, 310
|
||||
|
||||
// LB14.
|
||||
case lbAny | prOP<<32:
|
||||
return lbOP, LineCanBreak, 310
|
||||
case lbOP | prSP<<32:
|
||||
return lbOP, LineDontBreak, 70
|
||||
case lbOP | prAny<<32:
|
||||
return lbAny, LineDontBreak, 140
|
||||
|
||||
// LB15.
|
||||
case lbQU | prSP<<32:
|
||||
return lbQUSP, LineDontBreak, 70
|
||||
case lbQU | prOP<<32:
|
||||
return lbOP, LineDontBreak, 150
|
||||
case lbQUSP | prOP<<32:
|
||||
return lbOP, LineDontBreak, 150
|
||||
|
||||
// LB16.
|
||||
case lbCL | prSP<<32:
|
||||
return lbCLCPSP, LineDontBreak, 70
|
||||
case lbNUCL | prSP<<32:
|
||||
return lbCLCPSP, LineDontBreak, 70
|
||||
case lbCP | prSP<<32:
|
||||
return lbCLCPSP, LineDontBreak, 70
|
||||
case lbNUCP | prSP<<32:
|
||||
return lbCLCPSP, LineDontBreak, 70
|
||||
case lbCL | prNS<<32:
|
||||
return lbNS, LineDontBreak, 160
|
||||
case lbNUCL | prNS<<32:
|
||||
return lbNS, LineDontBreak, 160
|
||||
case lbCP | prNS<<32:
|
||||
return lbNS, LineDontBreak, 160
|
||||
case lbNUCP | prNS<<32:
|
||||
return lbNS, LineDontBreak, 160
|
||||
case lbCLCPSP | prNS<<32:
|
||||
return lbNS, LineDontBreak, 160
|
||||
|
||||
// LB17.
|
||||
case lbAny | prB2<<32:
|
||||
return lbB2, LineCanBreak, 310
|
||||
case lbB2 | prSP<<32:
|
||||
return lbB2SP, LineDontBreak, 70
|
||||
case lbB2 | prB2<<32:
|
||||
return lbB2, LineDontBreak, 170
|
||||
case lbB2SP | prB2<<32:
|
||||
return lbB2, LineDontBreak, 170
|
||||
|
||||
// LB18.
|
||||
case lbSP | prAny<<32:
|
||||
return lbAny, LineCanBreak, 180
|
||||
case lbQUSP | prAny<<32:
|
||||
return lbAny, LineCanBreak, 180
|
||||
case lbCLCPSP | prAny<<32:
|
||||
return lbAny, LineCanBreak, 180
|
||||
case lbB2SP | prAny<<32:
|
||||
return lbAny, LineCanBreak, 180
|
||||
|
||||
// LB19.
|
||||
case lbAny | prQU<<32:
|
||||
return lbQU, LineDontBreak, 190
|
||||
case lbQU | prAny<<32:
|
||||
return lbAny, LineDontBreak, 190
|
||||
|
||||
// LB20.
|
||||
case lbAny | prCB<<32:
|
||||
return lbCB, LineCanBreak, 200
|
||||
case lbCB | prAny<<32:
|
||||
return lbAny, LineCanBreak, 200
|
||||
|
||||
// LB21.
|
||||
case lbAny | prBA<<32:
|
||||
return lbBA, LineDontBreak, 210
|
||||
case lbAny | prHY<<32:
|
||||
return lbHY, LineDontBreak, 210
|
||||
case lbAny | prNS<<32:
|
||||
return lbNS, LineDontBreak, 210
|
||||
case lbAny | prBB<<32:
|
||||
return lbBB, LineCanBreak, 310
|
||||
case lbBB | prAny<<32:
|
||||
return lbAny, LineDontBreak, 210
|
||||
|
||||
// LB21a.
|
||||
case lbAny | prHL<<32:
|
||||
return lbHL, LineCanBreak, 310
|
||||
case lbHL | prHY<<32:
|
||||
return lbLB21a, LineDontBreak, 210
|
||||
case lbHL | prBA<<32:
|
||||
return lbLB21a, LineDontBreak, 210
|
||||
case lbLB21a | prAny<<32:
|
||||
return lbAny, LineDontBreak, 211
|
||||
|
||||
// LB21b.
|
||||
case lbSY | prHL<<32:
|
||||
return lbHL, LineDontBreak, 212
|
||||
case lbNUSY | prHL<<32:
|
||||
return lbHL, LineDontBreak, 212
|
||||
|
||||
// LB22.
|
||||
case lbAny | prIN<<32:
|
||||
return lbAny, LineDontBreak, 220
|
||||
|
||||
// LB23.
|
||||
case lbAny | prAL<<32:
|
||||
return lbAL, LineCanBreak, 310
|
||||
case lbAny | prNU<<32:
|
||||
return lbNU, LineCanBreak, 310
|
||||
case lbAL | prNU<<32:
|
||||
return lbNU, LineDontBreak, 230
|
||||
case lbHL | prNU<<32:
|
||||
return lbNU, LineDontBreak, 230
|
||||
case lbNU | prAL<<32:
|
||||
return lbAL, LineDontBreak, 230
|
||||
case lbNU | prHL<<32:
|
||||
return lbHL, LineDontBreak, 230
|
||||
case lbNUNU | prAL<<32:
|
||||
return lbAL, LineDontBreak, 230
|
||||
case lbNUNU | prHL<<32:
|
||||
return lbHL, LineDontBreak, 230
|
||||
|
||||
// LB23a.
|
||||
case lbAny | prPR<<32:
|
||||
return lbPR, LineCanBreak, 310
|
||||
case lbAny | prID<<32:
|
||||
return lbIDEM, LineCanBreak, 310
|
||||
case lbAny | prEB<<32:
|
||||
return lbEB, LineCanBreak, 310
|
||||
case lbAny | prEM<<32:
|
||||
return lbIDEM, LineCanBreak, 310
|
||||
case lbPR | prID<<32:
|
||||
return lbIDEM, LineDontBreak, 231
|
||||
case lbPR | prEB<<32:
|
||||
return lbEB, LineDontBreak, 231
|
||||
case lbPR | prEM<<32:
|
||||
return lbIDEM, LineDontBreak, 231
|
||||
case lbIDEM | prPO<<32:
|
||||
return lbPO, LineDontBreak, 231
|
||||
case lbEB | prPO<<32:
|
||||
return lbPO, LineDontBreak, 231
|
||||
|
||||
// LB24.
|
||||
case lbAny | prPO<<32:
|
||||
return lbPO, LineCanBreak, 310
|
||||
case lbPR | prAL<<32:
|
||||
return lbAL, LineDontBreak, 240
|
||||
case lbPR | prHL<<32:
|
||||
return lbHL, LineDontBreak, 240
|
||||
case lbPO | prAL<<32:
|
||||
return lbAL, LineDontBreak, 240
|
||||
case lbPO | prHL<<32:
|
||||
return lbHL, LineDontBreak, 240
|
||||
case lbAL | prPR<<32:
|
||||
return lbPR, LineDontBreak, 240
|
||||
case lbAL | prPO<<32:
|
||||
return lbPO, LineDontBreak, 240
|
||||
case lbHL | prPR<<32:
|
||||
return lbPR, LineDontBreak, 240
|
||||
case lbHL | prPO<<32:
|
||||
return lbPO, LineDontBreak, 240
|
||||
|
||||
// LB25 (simple transitions).
|
||||
case lbPR | prNU<<32:
|
||||
return lbNU, LineDontBreak, 250
|
||||
case lbPO | prNU<<32:
|
||||
return lbNU, LineDontBreak, 250
|
||||
case lbOP | prNU<<32:
|
||||
return lbNU, LineDontBreak, 250
|
||||
case lbHY | prNU<<32:
|
||||
return lbNU, LineDontBreak, 250
|
||||
case lbNU | prNU<<32:
|
||||
return lbNUNU, LineDontBreak, 250
|
||||
case lbNU | prSY<<32:
|
||||
return lbNUSY, LineDontBreak, 250
|
||||
case lbNU | prIS<<32:
|
||||
return lbNUIS, LineDontBreak, 250
|
||||
case lbNUNU | prNU<<32:
|
||||
return lbNUNU, LineDontBreak, 250
|
||||
case lbNUNU | prSY<<32:
|
||||
return lbNUSY, LineDontBreak, 250
|
||||
case lbNUNU | prIS<<32:
|
||||
return lbNUIS, LineDontBreak, 250
|
||||
case lbNUSY | prNU<<32:
|
||||
return lbNUNU, LineDontBreak, 250
|
||||
case lbNUSY | prSY<<32:
|
||||
return lbNUSY, LineDontBreak, 250
|
||||
case lbNUSY | prIS<<32:
|
||||
return lbNUIS, LineDontBreak, 250
|
||||
case lbNUIS | prNU<<32:
|
||||
return lbNUNU, LineDontBreak, 250
|
||||
case lbNUIS | prSY<<32:
|
||||
return lbNUSY, LineDontBreak, 250
|
||||
case lbNUIS | prIS<<32:
|
||||
return lbNUIS, LineDontBreak, 250
|
||||
case lbNU | prCL<<32:
|
||||
return lbNUCL, LineDontBreak, 250
|
||||
case lbNU | prCP<<32:
|
||||
return lbNUCP, LineDontBreak, 250
|
||||
case lbNUNU | prCL<<32:
|
||||
return lbNUCL, LineDontBreak, 250
|
||||
case lbNUNU | prCP<<32:
|
||||
return lbNUCP, LineDontBreak, 250
|
||||
case lbNUSY | prCL<<32:
|
||||
return lbNUCL, LineDontBreak, 250
|
||||
case lbNUSY | prCP<<32:
|
||||
return lbNUCP, LineDontBreak, 250
|
||||
case lbNUIS | prCL<<32:
|
||||
return lbNUCL, LineDontBreak, 250
|
||||
case lbNUIS | prCP<<32:
|
||||
return lbNUCP, LineDontBreak, 250
|
||||
case lbNU | prPO<<32:
|
||||
return lbPO, LineDontBreak, 250
|
||||
case lbNUNU | prPO<<32:
|
||||
return lbPO, LineDontBreak, 250
|
||||
case lbNUSY | prPO<<32:
|
||||
return lbPO, LineDontBreak, 250
|
||||
case lbNUIS | prPO<<32:
|
||||
return lbPO, LineDontBreak, 250
|
||||
case lbNUCL | prPO<<32:
|
||||
return lbPO, LineDontBreak, 250
|
||||
case lbNUCP | prPO<<32:
|
||||
return lbPO, LineDontBreak, 250
|
||||
case lbNU | prPR<<32:
|
||||
return lbPR, LineDontBreak, 250
|
||||
case lbNUNU | prPR<<32:
|
||||
return lbPR, LineDontBreak, 250
|
||||
case lbNUSY | prPR<<32:
|
||||
return lbPR, LineDontBreak, 250
|
||||
case lbNUIS | prPR<<32:
|
||||
return lbPR, LineDontBreak, 250
|
||||
case lbNUCL | prPR<<32:
|
||||
return lbPR, LineDontBreak, 250
|
||||
case lbNUCP | prPR<<32:
|
||||
return lbPR, LineDontBreak, 250
|
||||
|
||||
// LB26.
|
||||
case lbAny | prJL<<32:
|
||||
return lbJL, LineCanBreak, 310
|
||||
case lbAny | prJV<<32:
|
||||
return lbJV, LineCanBreak, 310
|
||||
case lbAny | prJT<<32:
|
||||
return lbJT, LineCanBreak, 310
|
||||
case lbAny | prH2<<32:
|
||||
return lbH2, LineCanBreak, 310
|
||||
case lbAny | prH3<<32:
|
||||
return lbH3, LineCanBreak, 310
|
||||
case lbJL | prJL<<32:
|
||||
return lbJL, LineDontBreak, 260
|
||||
case lbJL | prJV<<32:
|
||||
return lbJV, LineDontBreak, 260
|
||||
case lbJL | prH2<<32:
|
||||
return lbH2, LineDontBreak, 260
|
||||
case lbJL | prH3<<32:
|
||||
return lbH3, LineDontBreak, 260
|
||||
case lbJV | prJV<<32:
|
||||
return lbJV, LineDontBreak, 260
|
||||
case lbJV | prJT<<32:
|
||||
return lbJT, LineDontBreak, 260
|
||||
case lbH2 | prJV<<32:
|
||||
return lbJV, LineDontBreak, 260
|
||||
case lbH2 | prJT<<32:
|
||||
return lbJT, LineDontBreak, 260
|
||||
case lbJT | prJT<<32:
|
||||
return lbJT, LineDontBreak, 260
|
||||
case lbH3 | prJT<<32:
|
||||
return lbJT, LineDontBreak, 260
|
||||
|
||||
// LB27.
|
||||
case lbJL | prPO<<32:
|
||||
return lbPO, LineDontBreak, 270
|
||||
case lbJV | prPO<<32:
|
||||
return lbPO, LineDontBreak, 270
|
||||
case lbJT | prPO<<32:
|
||||
return lbPO, LineDontBreak, 270
|
||||
case lbH2 | prPO<<32:
|
||||
return lbPO, LineDontBreak, 270
|
||||
case lbH3 | prPO<<32:
|
||||
return lbPO, LineDontBreak, 270
|
||||
case lbPR | prJL<<32:
|
||||
return lbJL, LineDontBreak, 270
|
||||
case lbPR | prJV<<32:
|
||||
return lbJV, LineDontBreak, 270
|
||||
case lbPR | prJT<<32:
|
||||
return lbJT, LineDontBreak, 270
|
||||
case lbPR | prH2<<32:
|
||||
return lbH2, LineDontBreak, 270
|
||||
case lbPR | prH3<<32:
|
||||
return lbH3, LineDontBreak, 270
|
||||
|
||||
// LB28.
|
||||
case lbAL | prAL<<32:
|
||||
return lbAL, LineDontBreak, 280
|
||||
case lbAL | prHL<<32:
|
||||
return lbHL, LineDontBreak, 280
|
||||
case lbHL | prAL<<32:
|
||||
return lbAL, LineDontBreak, 280
|
||||
case lbHL | prHL<<32:
|
||||
return lbHL, LineDontBreak, 280
|
||||
|
||||
// LB29.
|
||||
case lbIS | prAL<<32:
|
||||
return lbAL, LineDontBreak, 290
|
||||
case lbIS | prHL<<32:
|
||||
return lbHL, LineDontBreak, 290
|
||||
case lbNUIS | prAL<<32:
|
||||
return lbAL, LineDontBreak, 290
|
||||
case lbNUIS | prHL<<32:
|
||||
return lbHL, LineDontBreak, 290
|
||||
|
||||
default:
|
||||
return -1, -1, -1
|
||||
}
|
||||
}
|
||||
|
||||
// transitionLineBreakState determines the new state of the line break parser
|
||||
// given the current state and the next code point. It also returns the type of
|
||||
// line break: LineDontBreak, LineCanBreak, or LineMustBreak. If more than one
|
||||
// code point is needed to determine the new state, the byte slice or the string
|
||||
// starting after rune "r" can be used (whichever is not nil or empty) for
|
||||
// further lookups.
|
||||
func transitionLineBreakState(state int, r rune, b []byte, str string) (newState int, lineBreak int) {
|
||||
// Determine the property of the next character.
|
||||
nextProperty, generalCategory := propertyLineBreak(r)
|
||||
|
||||
// Prepare.
|
||||
var forceNoBreak, isCPeaFWH bool
|
||||
if state >= 0 && state&lbCPeaFWHBit != 0 {
|
||||
isCPeaFWH = true // LB30: CP but ea is not F, W, or H.
|
||||
state = state &^ lbCPeaFWHBit
|
||||
}
|
||||
if state >= 0 && state&lbZWJBit != 0 {
|
||||
state = state &^ lbZWJBit // Extract zero-width joiner bit.
|
||||
forceNoBreak = true // LB8a.
|
||||
}
|
||||
|
||||
defer func() {
|
||||
// Transition into LB30.
|
||||
if newState == lbCP || newState == lbNUCP {
|
||||
ea := propertyEastAsianWidth(r)
|
||||
if ea != prF && ea != prW && ea != prH {
|
||||
newState |= lbCPeaFWHBit
|
||||
}
|
||||
}
|
||||
|
||||
// Override break.
|
||||
if forceNoBreak {
|
||||
lineBreak = LineDontBreak
|
||||
}
|
||||
}()
|
||||
|
||||
// LB1.
|
||||
if nextProperty == prAI || nextProperty == prSG || nextProperty == prXX {
|
||||
nextProperty = prAL
|
||||
} else if nextProperty == prSA {
|
||||
if generalCategory == gcMn || generalCategory == gcMc {
|
||||
nextProperty = prCM
|
||||
} else {
|
||||
nextProperty = prAL
|
||||
}
|
||||
} else if nextProperty == prCJ {
|
||||
nextProperty = prNS
|
||||
}
|
||||
|
||||
// Combining marks.
|
||||
if nextProperty == prZWJ || nextProperty == prCM {
|
||||
var bit int
|
||||
if nextProperty == prZWJ {
|
||||
bit = lbZWJBit
|
||||
}
|
||||
mustBreakState := state < 0 || state == lbBK || state == lbCR || state == lbLF || state == lbNL
|
||||
if !mustBreakState && state != lbSP && state != lbZW && state != lbQUSP && state != lbCLCPSP && state != lbB2SP {
|
||||
// LB9.
|
||||
return state | bit, LineDontBreak
|
||||
} else {
|
||||
// LB10.
|
||||
if mustBreakState {
|
||||
return lbAL | bit, LineMustBreak
|
||||
}
|
||||
return lbAL | bit, LineCanBreak
|
||||
}
|
||||
}
|
||||
|
||||
// Find the applicable transition in the table.
|
||||
var rule int
|
||||
newState, lineBreak, rule = lbTransitions(state, nextProperty)
|
||||
if newState < 0 {
|
||||
// No specific transition found. Try the less specific ones.
|
||||
anyPropProp, anyPropLineBreak, anyPropRule := lbTransitions(state, prAny)
|
||||
anyStateProp, anyStateLineBreak, anyStateRule := lbTransitions(lbAny, nextProperty)
|
||||
if anyPropProp >= 0 && anyStateProp >= 0 {
|
||||
// Both apply. We'll use a mix (see comments for grTransitions).
|
||||
newState, lineBreak, rule = anyStateProp, anyStateLineBreak, anyStateRule
|
||||
if anyPropRule < anyStateRule {
|
||||
lineBreak, rule = anyPropLineBreak, anyPropRule
|
||||
}
|
||||
} else if anyPropProp >= 0 {
|
||||
// We only have a specific state.
|
||||
newState, lineBreak, rule = anyPropProp, anyPropLineBreak, anyPropRule
|
||||
// This branch will probably never be reached because okAnyState will
|
||||
// always be true given the current transition map. But we keep it here
|
||||
// for future modifications to the transition map where this may not be
|
||||
// true anymore.
|
||||
} else if anyStateProp >= 0 {
|
||||
// We only have a specific property.
|
||||
newState, lineBreak, rule = anyStateProp, anyStateLineBreak, anyStateRule
|
||||
} else {
|
||||
// No known transition. LB31: ALL ÷ ALL.
|
||||
newState, lineBreak, rule = lbAny, LineCanBreak, 310
|
||||
}
|
||||
}
|
||||
|
||||
// LB12a.
|
||||
if rule > 121 &&
|
||||
nextProperty == prGL &&
|
||||
(state != lbSP && state != lbBA && state != lbHY && state != lbLB21a && state != lbQUSP && state != lbCLCPSP && state != lbB2SP) {
|
||||
return lbGL, LineDontBreak
|
||||
}
|
||||
|
||||
// LB13.
|
||||
if rule > 130 && state != lbNU && state != lbNUNU {
|
||||
switch nextProperty {
|
||||
case prCL:
|
||||
return lbCL, LineDontBreak
|
||||
case prCP:
|
||||
return lbCP, LineDontBreak
|
||||
case prIS:
|
||||
return lbIS, LineDontBreak
|
||||
case prSY:
|
||||
return lbSY, LineDontBreak
|
||||
}
|
||||
}
|
||||
|
||||
// LB25 (look ahead).
|
||||
if rule > 250 &&
|
||||
(state == lbPR || state == lbPO) &&
|
||||
nextProperty == prOP || nextProperty == prHY {
|
||||
var r rune
|
||||
if b != nil { // Byte slice version.
|
||||
r, _ = utf8.DecodeRune(b)
|
||||
} else { // String version.
|
||||
r, _ = utf8.DecodeRuneInString(str)
|
||||
}
|
||||
if r != utf8.RuneError {
|
||||
pr, _ := propertyLineBreak(r)
|
||||
if pr == prNU {
|
||||
return lbNU, LineDontBreak
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// LB30 (part one).
|
||||
if rule > 300 {
|
||||
if (state == lbAL || state == lbHL || state == lbNU || state == lbNUNU) && nextProperty == prOP {
|
||||
ea := propertyEastAsianWidth(r)
|
||||
if ea != prF && ea != prW && ea != prH {
|
||||
return lbOP, LineDontBreak
|
||||
}
|
||||
} else if isCPeaFWH {
|
||||
switch nextProperty {
|
||||
case prAL:
|
||||
return lbAL, LineDontBreak
|
||||
case prHL:
|
||||
return lbHL, LineDontBreak
|
||||
case prNU:
|
||||
return lbNU, LineDontBreak
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// LB30a.
|
||||
if newState == lbAny && nextProperty == prRI {
|
||||
if state != lbOddRI && state != lbEvenRI { // Includes state == -1.
|
||||
// Transition into the first RI.
|
||||
return lbOddRI, lineBreak
|
||||
}
|
||||
if state == lbOddRI {
|
||||
// Don't break pairs of Regional Indicators.
|
||||
return lbEvenRI, LineDontBreak
|
||||
}
|
||||
return lbOddRI, lineBreak
|
||||
}
|
||||
|
||||
// LB30b.
|
||||
if rule > 302 {
|
||||
if nextProperty == prEM {
|
||||
if state == lbEB || state == lbExtPicCn {
|
||||
return prAny, LineDontBreak
|
||||
}
|
||||
}
|
||||
graphemeProperty := propertyGraphemes(r)
|
||||
if graphemeProperty == prExtendedPictographic && generalCategory == gcCn {
|
||||
return lbExtPicCn, LineCanBreak
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
208
vendor/github.com/rivo/uniseg/properties.go
generated
vendored
Normal file
208
vendor/github.com/rivo/uniseg/properties.go
generated
vendored
Normal file
@@ -0,0 +1,208 @@
|
||||
package uniseg
|
||||
|
||||
// The Unicode properties as used in the various parsers. Only the ones needed
|
||||
// in the context of this package are included.
|
||||
const (
|
||||
prXX = 0 // Same as prAny.
|
||||
prAny = iota // prAny must be 0.
|
||||
prPrepend // Grapheme properties must come first, to reduce the number of bits stored in the state vector.
|
||||
prCR
|
||||
prLF
|
||||
prControl
|
||||
prExtend
|
||||
prRegionalIndicator
|
||||
prSpacingMark
|
||||
prL
|
||||
prV
|
||||
prT
|
||||
prLV
|
||||
prLVT
|
||||
prZWJ
|
||||
prExtendedPictographic
|
||||
prNewline
|
||||
prWSegSpace
|
||||
prDoubleQuote
|
||||
prSingleQuote
|
||||
prMidNumLet
|
||||
prNumeric
|
||||
prMidLetter
|
||||
prMidNum
|
||||
prExtendNumLet
|
||||
prALetter
|
||||
prFormat
|
||||
prHebrewLetter
|
||||
prKatakana
|
||||
prSp
|
||||
prSTerm
|
||||
prClose
|
||||
prSContinue
|
||||
prATerm
|
||||
prUpper
|
||||
prLower
|
||||
prSep
|
||||
prOLetter
|
||||
prCM
|
||||
prBA
|
||||
prBK
|
||||
prSP
|
||||
prEX
|
||||
prQU
|
||||
prAL
|
||||
prPR
|
||||
prPO
|
||||
prOP
|
||||
prCP
|
||||
prIS
|
||||
prHY
|
||||
prSY
|
||||
prNU
|
||||
prCL
|
||||
prNL
|
||||
prGL
|
||||
prAI
|
||||
prBB
|
||||
prHL
|
||||
prSA
|
||||
prJL
|
||||
prJV
|
||||
prJT
|
||||
prNS
|
||||
prZW
|
||||
prB2
|
||||
prIN
|
||||
prWJ
|
||||
prID
|
||||
prEB
|
||||
prCJ
|
||||
prH2
|
||||
prH3
|
||||
prSG
|
||||
prCB
|
||||
prRI
|
||||
prEM
|
||||
prN
|
||||
prNa
|
||||
prA
|
||||
prW
|
||||
prH
|
||||
prF
|
||||
prEmojiPresentation
|
||||
)
|
||||
|
||||
// Unicode General Categories. Only the ones needed in the context of this
|
||||
// package are included.
|
||||
const (
|
||||
gcNone = iota // gcNone must be 0.
|
||||
gcCc
|
||||
gcZs
|
||||
gcPo
|
||||
gcSc
|
||||
gcPs
|
||||
gcPe
|
||||
gcSm
|
||||
gcPd
|
||||
gcNd
|
||||
gcLu
|
||||
gcSk
|
||||
gcPc
|
||||
gcLl
|
||||
gcSo
|
||||
gcLo
|
||||
gcPi
|
||||
gcCf
|
||||
gcNo
|
||||
gcPf
|
||||
gcLC
|
||||
gcLm
|
||||
gcMn
|
||||
gcMe
|
||||
gcMc
|
||||
gcNl
|
||||
gcZl
|
||||
gcZp
|
||||
gcCn
|
||||
gcCs
|
||||
gcCo
|
||||
)
|
||||
|
||||
// Special code points.
|
||||
const (
|
||||
vs15 = 0xfe0e // Variation Selector-15 (text presentation)
|
||||
vs16 = 0xfe0f // Variation Selector-16 (emoji presentation)
|
||||
)
|
||||
|
||||
// propertySearch performs a binary search on a property slice and returns the
|
||||
// entry whose range (start = first array element, end = second array element)
|
||||
// includes r, or an array of 0's if no such entry was found.
|
||||
func propertySearch[E interface{ [3]int | [4]int }](dictionary []E, r rune) (result E) {
|
||||
// Run a binary search.
|
||||
from := 0
|
||||
to := len(dictionary)
|
||||
for to > from {
|
||||
middle := (from + to) / 2
|
||||
cpRange := dictionary[middle]
|
||||
if int(r) < cpRange[0] {
|
||||
to = middle
|
||||
continue
|
||||
}
|
||||
if int(r) > cpRange[1] {
|
||||
from = middle + 1
|
||||
continue
|
||||
}
|
||||
return cpRange
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// property returns the Unicode property value (see constants above) of the
|
||||
// given code point.
|
||||
func property(dictionary [][3]int, r rune) int {
|
||||
return propertySearch(dictionary, r)[2]
|
||||
}
|
||||
|
||||
// propertyLineBreak returns the Unicode property value and General Category
|
||||
// (see constants above) of the given code point, as listed in the line break
|
||||
// code points table, while fast tracking ASCII digits and letters.
|
||||
func propertyLineBreak(r rune) (property, generalCategory int) {
|
||||
if r >= 'a' && r <= 'z' {
|
||||
return prAL, gcLl
|
||||
}
|
||||
if r >= 'A' && r <= 'Z' {
|
||||
return prAL, gcLu
|
||||
}
|
||||
if r >= '0' && r <= '9' {
|
||||
return prNU, gcNd
|
||||
}
|
||||
entry := propertySearch(lineBreakCodePoints, r)
|
||||
return entry[2], entry[3]
|
||||
}
|
||||
|
||||
// propertyGraphemes returns the Unicode grapheme cluster property value of the
|
||||
// given code point while fast tracking ASCII characters.
|
||||
func propertyGraphemes(r rune) int {
|
||||
if r >= 0x20 && r <= 0x7e {
|
||||
return prAny
|
||||
}
|
||||
if r == 0x0a {
|
||||
return prLF
|
||||
}
|
||||
if r == 0x0d {
|
||||
return prCR
|
||||
}
|
||||
if r >= 0 && r <= 0x1f || r == 0x7f {
|
||||
return prControl
|
||||
}
|
||||
return property(graphemeCodePoints, r)
|
||||
}
|
||||
|
||||
// propertyEastAsianWidth returns the Unicode East Asian Width property value of
|
||||
// the given code point while fast tracking ASCII characters.
|
||||
func propertyEastAsianWidth(r rune) int {
|
||||
if r >= 0x20 && r <= 0x7e {
|
||||
return prNa
|
||||
}
|
||||
if r >= 0 && r <= 0x1f || r == 0x7f {
|
||||
return prN
|
||||
}
|
||||
return property(eastAsianWidth, r)
|
||||
}
|
||||
90
vendor/github.com/rivo/uniseg/sentence.go
generated
vendored
Normal file
90
vendor/github.com/rivo/uniseg/sentence.go
generated
vendored
Normal file
@@ -0,0 +1,90 @@
|
||||
package uniseg
|
||||
|
||||
import "unicode/utf8"
|
||||
|
||||
// FirstSentence returns the first sentence found in the given byte slice
|
||||
// according to the rules of [Unicode Standard Annex #29, Sentence Boundaries].
|
||||
// This function can be called continuously to extract all sentences from a byte
|
||||
// slice, as illustrated in the example below.
|
||||
//
|
||||
// If you don't know the current state, for example when calling the function
|
||||
// for the first time, you must pass -1. For consecutive calls, pass the state
|
||||
// and rest slice returned by the previous call.
|
||||
//
|
||||
// The "rest" slice is the sub-slice of the original byte slice "b" starting
|
||||
// after the last byte of the identified sentence. If the length of the "rest"
|
||||
// slice is 0, the entire byte slice "b" has been processed. The "sentence" byte
|
||||
// slice is the sub-slice of the input slice containing the identified sentence.
|
||||
//
|
||||
// Given an empty byte slice "b", the function returns nil values.
|
||||
//
|
||||
// [Unicode Standard Annex #29, Sentence Boundaries]: http://unicode.org/reports/tr29/#Sentence_Boundaries
|
||||
func FirstSentence(b []byte, state int) (sentence, rest []byte, newState int) {
|
||||
// An empty byte slice returns nothing.
|
||||
if len(b) == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
// Extract the first rune.
|
||||
r, length := utf8.DecodeRune(b)
|
||||
if len(b) <= length { // If we're already past the end, there is nothing else to parse.
|
||||
return b, nil, sbAny
|
||||
}
|
||||
|
||||
// If we don't know the state, determine it now.
|
||||
if state < 0 {
|
||||
state, _ = transitionSentenceBreakState(state, r, b[length:], "")
|
||||
}
|
||||
|
||||
// Transition until we find a boundary.
|
||||
var boundary bool
|
||||
for {
|
||||
r, l := utf8.DecodeRune(b[length:])
|
||||
state, boundary = transitionSentenceBreakState(state, r, b[length+l:], "")
|
||||
|
||||
if boundary {
|
||||
return b[:length], b[length:], state
|
||||
}
|
||||
|
||||
length += l
|
||||
if len(b) <= length {
|
||||
return b, nil, sbAny
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// FirstSentenceInString is like [FirstSentence] but its input and outputs are
|
||||
// strings.
|
||||
func FirstSentenceInString(str string, state int) (sentence, rest string, newState int) {
|
||||
// An empty byte slice returns nothing.
|
||||
if len(str) == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
// Extract the first rune.
|
||||
r, length := utf8.DecodeRuneInString(str)
|
||||
if len(str) <= length { // If we're already past the end, there is nothing else to parse.
|
||||
return str, "", sbAny
|
||||
}
|
||||
|
||||
// If we don't know the state, determine it now.
|
||||
if state < 0 {
|
||||
state, _ = transitionSentenceBreakState(state, r, nil, str[length:])
|
||||
}
|
||||
|
||||
// Transition until we find a boundary.
|
||||
var boundary bool
|
||||
for {
|
||||
r, l := utf8.DecodeRuneInString(str[length:])
|
||||
state, boundary = transitionSentenceBreakState(state, r, nil, str[length+l:])
|
||||
|
||||
if boundary {
|
||||
return str[:length], str[length:], state
|
||||
}
|
||||
|
||||
length += l
|
||||
if len(str) <= length {
|
||||
return str, "", sbAny
|
||||
}
|
||||
}
|
||||
}
|
||||
2845
vendor/github.com/rivo/uniseg/sentenceproperties.go
generated
vendored
Normal file
2845
vendor/github.com/rivo/uniseg/sentenceproperties.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
276
vendor/github.com/rivo/uniseg/sentencerules.go
generated
vendored
Normal file
276
vendor/github.com/rivo/uniseg/sentencerules.go
generated
vendored
Normal file
@@ -0,0 +1,276 @@
|
||||
package uniseg
|
||||
|
||||
import "unicode/utf8"
|
||||
|
||||
// The states of the sentence break parser.
|
||||
const (
|
||||
sbAny = iota
|
||||
sbCR
|
||||
sbParaSep
|
||||
sbATerm
|
||||
sbUpper
|
||||
sbLower
|
||||
sbSB7
|
||||
sbSB8Close
|
||||
sbSB8Sp
|
||||
sbSTerm
|
||||
sbSB8aClose
|
||||
sbSB8aSp
|
||||
)
|
||||
|
||||
// sbTransitions implements the sentence break parser's state transitions. It's
|
||||
// anologous to [grTransitions], see comments there for details.
|
||||
//
|
||||
// Unicode version 15.0.0.
|
||||
func sbTransitions(state, prop int) (newState int, sentenceBreak bool, rule int) {
|
||||
switch uint64(state) | uint64(prop)<<32 {
|
||||
// SB3.
|
||||
case sbAny | prCR<<32:
|
||||
return sbCR, false, 9990
|
||||
case sbCR | prLF<<32:
|
||||
return sbParaSep, false, 30
|
||||
|
||||
// SB4.
|
||||
case sbAny | prSep<<32:
|
||||
return sbParaSep, false, 9990
|
||||
case sbAny | prLF<<32:
|
||||
return sbParaSep, false, 9990
|
||||
case sbParaSep | prAny<<32:
|
||||
return sbAny, true, 40
|
||||
case sbCR | prAny<<32:
|
||||
return sbAny, true, 40
|
||||
|
||||
// SB6.
|
||||
case sbAny | prATerm<<32:
|
||||
return sbATerm, false, 9990
|
||||
case sbATerm | prNumeric<<32:
|
||||
return sbAny, false, 60
|
||||
case sbSB7 | prNumeric<<32:
|
||||
return sbAny, false, 60 // Because ATerm also appears in SB7.
|
||||
|
||||
// SB7.
|
||||
case sbAny | prUpper<<32:
|
||||
return sbUpper, false, 9990
|
||||
case sbAny | prLower<<32:
|
||||
return sbLower, false, 9990
|
||||
case sbUpper | prATerm<<32:
|
||||
return sbSB7, false, 70
|
||||
case sbLower | prATerm<<32:
|
||||
return sbSB7, false, 70
|
||||
case sbSB7 | prUpper<<32:
|
||||
return sbUpper, false, 70
|
||||
|
||||
// SB8a.
|
||||
case sbAny | prSTerm<<32:
|
||||
return sbSTerm, false, 9990
|
||||
case sbATerm | prSContinue<<32:
|
||||
return sbAny, false, 81
|
||||
case sbATerm | prATerm<<32:
|
||||
return sbATerm, false, 81
|
||||
case sbATerm | prSTerm<<32:
|
||||
return sbSTerm, false, 81
|
||||
case sbSB7 | prSContinue<<32:
|
||||
return sbAny, false, 81
|
||||
case sbSB7 | prATerm<<32:
|
||||
return sbATerm, false, 81
|
||||
case sbSB7 | prSTerm<<32:
|
||||
return sbSTerm, false, 81
|
||||
case sbSB8Close | prSContinue<<32:
|
||||
return sbAny, false, 81
|
||||
case sbSB8Close | prATerm<<32:
|
||||
return sbATerm, false, 81
|
||||
case sbSB8Close | prSTerm<<32:
|
||||
return sbSTerm, false, 81
|
||||
case sbSB8Sp | prSContinue<<32:
|
||||
return sbAny, false, 81
|
||||
case sbSB8Sp | prATerm<<32:
|
||||
return sbATerm, false, 81
|
||||
case sbSB8Sp | prSTerm<<32:
|
||||
return sbSTerm, false, 81
|
||||
case sbSTerm | prSContinue<<32:
|
||||
return sbAny, false, 81
|
||||
case sbSTerm | prATerm<<32:
|
||||
return sbATerm, false, 81
|
||||
case sbSTerm | prSTerm<<32:
|
||||
return sbSTerm, false, 81
|
||||
case sbSB8aClose | prSContinue<<32:
|
||||
return sbAny, false, 81
|
||||
case sbSB8aClose | prATerm<<32:
|
||||
return sbATerm, false, 81
|
||||
case sbSB8aClose | prSTerm<<32:
|
||||
return sbSTerm, false, 81
|
||||
case sbSB8aSp | prSContinue<<32:
|
||||
return sbAny, false, 81
|
||||
case sbSB8aSp | prATerm<<32:
|
||||
return sbATerm, false, 81
|
||||
case sbSB8aSp | prSTerm<<32:
|
||||
return sbSTerm, false, 81
|
||||
|
||||
// SB9.
|
||||
case sbATerm | prClose<<32:
|
||||
return sbSB8Close, false, 90
|
||||
case sbSB7 | prClose<<32:
|
||||
return sbSB8Close, false, 90
|
||||
case sbSB8Close | prClose<<32:
|
||||
return sbSB8Close, false, 90
|
||||
case sbATerm | prSp<<32:
|
||||
return sbSB8Sp, false, 90
|
||||
case sbSB7 | prSp<<32:
|
||||
return sbSB8Sp, false, 90
|
||||
case sbSB8Close | prSp<<32:
|
||||
return sbSB8Sp, false, 90
|
||||
case sbSTerm | prClose<<32:
|
||||
return sbSB8aClose, false, 90
|
||||
case sbSB8aClose | prClose<<32:
|
||||
return sbSB8aClose, false, 90
|
||||
case sbSTerm | prSp<<32:
|
||||
return sbSB8aSp, false, 90
|
||||
case sbSB8aClose | prSp<<32:
|
||||
return sbSB8aSp, false, 90
|
||||
case sbATerm | prSep<<32:
|
||||
return sbParaSep, false, 90
|
||||
case sbATerm | prCR<<32:
|
||||
return sbParaSep, false, 90
|
||||
case sbATerm | prLF<<32:
|
||||
return sbParaSep, false, 90
|
||||
case sbSB7 | prSep<<32:
|
||||
return sbParaSep, false, 90
|
||||
case sbSB7 | prCR<<32:
|
||||
return sbParaSep, false, 90
|
||||
case sbSB7 | prLF<<32:
|
||||
return sbParaSep, false, 90
|
||||
case sbSB8Close | prSep<<32:
|
||||
return sbParaSep, false, 90
|
||||
case sbSB8Close | prCR<<32:
|
||||
return sbParaSep, false, 90
|
||||
case sbSB8Close | prLF<<32:
|
||||
return sbParaSep, false, 90
|
||||
case sbSTerm | prSep<<32:
|
||||
return sbParaSep, false, 90
|
||||
case sbSTerm | prCR<<32:
|
||||
return sbParaSep, false, 90
|
||||
case sbSTerm | prLF<<32:
|
||||
return sbParaSep, false, 90
|
||||
case sbSB8aClose | prSep<<32:
|
||||
return sbParaSep, false, 90
|
||||
case sbSB8aClose | prCR<<32:
|
||||
return sbParaSep, false, 90
|
||||
case sbSB8aClose | prLF<<32:
|
||||
return sbParaSep, false, 90
|
||||
|
||||
// SB10.
|
||||
case sbSB8Sp | prSp<<32:
|
||||
return sbSB8Sp, false, 100
|
||||
case sbSB8aSp | prSp<<32:
|
||||
return sbSB8aSp, false, 100
|
||||
case sbSB8Sp | prSep<<32:
|
||||
return sbParaSep, false, 100
|
||||
case sbSB8Sp | prCR<<32:
|
||||
return sbParaSep, false, 100
|
||||
case sbSB8Sp | prLF<<32:
|
||||
return sbParaSep, false, 100
|
||||
|
||||
// SB11.
|
||||
case sbATerm | prAny<<32:
|
||||
return sbAny, true, 110
|
||||
case sbSB7 | prAny<<32:
|
||||
return sbAny, true, 110
|
||||
case sbSB8Close | prAny<<32:
|
||||
return sbAny, true, 110
|
||||
case sbSB8Sp | prAny<<32:
|
||||
return sbAny, true, 110
|
||||
case sbSTerm | prAny<<32:
|
||||
return sbAny, true, 110
|
||||
case sbSB8aClose | prAny<<32:
|
||||
return sbAny, true, 110
|
||||
case sbSB8aSp | prAny<<32:
|
||||
return sbAny, true, 110
|
||||
// We'll always break after ParaSep due to SB4.
|
||||
|
||||
default:
|
||||
return -1, false, -1
|
||||
}
|
||||
}
|
||||
|
||||
// transitionSentenceBreakState determines the new state of the sentence break
|
||||
// parser given the current state and the next code point. It also returns
|
||||
// whether a sentence boundary was detected. If more than one code point is
|
||||
// needed to determine the new state, the byte slice or the string starting
|
||||
// after rune "r" can be used (whichever is not nil or empty) for further
|
||||
// lookups.
|
||||
func transitionSentenceBreakState(state int, r rune, b []byte, str string) (newState int, sentenceBreak bool) {
|
||||
// Determine the property of the next character.
|
||||
nextProperty := property(sentenceBreakCodePoints, r)
|
||||
|
||||
// SB5 (Replacing Ignore Rules).
|
||||
if nextProperty == prExtend || nextProperty == prFormat {
|
||||
if state == sbParaSep || state == sbCR {
|
||||
return sbAny, true // Make sure we don't apply SB5 to SB3 or SB4.
|
||||
}
|
||||
if state < 0 {
|
||||
return sbAny, true // SB1.
|
||||
}
|
||||
return state, false
|
||||
}
|
||||
|
||||
// Find the applicable transition in the table.
|
||||
var rule int
|
||||
newState, sentenceBreak, rule = sbTransitions(state, nextProperty)
|
||||
if newState < 0 {
|
||||
// No specific transition found. Try the less specific ones.
|
||||
anyPropState, anyPropProp, anyPropRule := sbTransitions(state, prAny)
|
||||
anyStateState, anyStateProp, anyStateRule := sbTransitions(sbAny, nextProperty)
|
||||
if anyPropState >= 0 && anyStateState >= 0 {
|
||||
// Both apply. We'll use a mix (see comments for grTransitions).
|
||||
newState, sentenceBreak, rule = anyStateState, anyStateProp, anyStateRule
|
||||
if anyPropRule < anyStateRule {
|
||||
sentenceBreak, rule = anyPropProp, anyPropRule
|
||||
}
|
||||
} else if anyPropState >= 0 {
|
||||
// We only have a specific state.
|
||||
newState, sentenceBreak, rule = anyPropState, anyPropProp, anyPropRule
|
||||
// This branch will probably never be reached because okAnyState will
|
||||
// always be true given the current transition map. But we keep it here
|
||||
// for future modifications to the transition map where this may not be
|
||||
// true anymore.
|
||||
} else if anyStateState >= 0 {
|
||||
// We only have a specific property.
|
||||
newState, sentenceBreak, rule = anyStateState, anyStateProp, anyStateRule
|
||||
} else {
|
||||
// No known transition. SB999: Any × Any.
|
||||
newState, sentenceBreak, rule = sbAny, false, 9990
|
||||
}
|
||||
}
|
||||
|
||||
// SB8.
|
||||
if rule > 80 && (state == sbATerm || state == sbSB8Close || state == sbSB8Sp || state == sbSB7) {
|
||||
// Check the right side of the rule.
|
||||
var length int
|
||||
for nextProperty != prOLetter &&
|
||||
nextProperty != prUpper &&
|
||||
nextProperty != prLower &&
|
||||
nextProperty != prSep &&
|
||||
nextProperty != prCR &&
|
||||
nextProperty != prLF &&
|
||||
nextProperty != prATerm &&
|
||||
nextProperty != prSTerm {
|
||||
// Move on to the next rune.
|
||||
if b != nil { // Byte slice version.
|
||||
r, length = utf8.DecodeRune(b)
|
||||
b = b[length:]
|
||||
} else { // String version.
|
||||
r, length = utf8.DecodeRuneInString(str)
|
||||
str = str[length:]
|
||||
}
|
||||
if r == utf8.RuneError {
|
||||
break
|
||||
}
|
||||
nextProperty = property(sentenceBreakCodePoints, r)
|
||||
}
|
||||
if nextProperty == prLower {
|
||||
return sbLower, false
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
242
vendor/github.com/rivo/uniseg/step.go
generated
vendored
Normal file
242
vendor/github.com/rivo/uniseg/step.go
generated
vendored
Normal file
@@ -0,0 +1,242 @@
|
||||
package uniseg
|
||||
|
||||
import "unicode/utf8"
|
||||
|
||||
// The bit masks used to extract boundary information returned by [Step].
|
||||
const (
|
||||
MaskLine = 3
|
||||
MaskWord = 4
|
||||
MaskSentence = 8
|
||||
)
|
||||
|
||||
// The number of bits to shift the boundary information returned by [Step] to
|
||||
// obtain the monospace width of the grapheme cluster.
|
||||
const ShiftWidth = 4
|
||||
|
||||
// The bit positions by which boundary flags are shifted by the [Step] function.
|
||||
// These must correspond to the Mask constants.
|
||||
const (
|
||||
shiftWord = 2
|
||||
shiftSentence = 3
|
||||
// shiftwWidth is ShiftWidth above. No mask as these are always the remaining bits.
|
||||
)
|
||||
|
||||
// The bit positions by which states are shifted by the [Step] function. These
|
||||
// values must ensure state values defined for each of the boundary algorithms
|
||||
// don't overlap (and that they all still fit in a single int). These must
|
||||
// correspond to the Mask constants.
|
||||
const (
|
||||
shiftWordState = 4
|
||||
shiftSentenceState = 9
|
||||
shiftLineState = 13
|
||||
shiftPropState = 21 // No mask as these are always the remaining bits.
|
||||
)
|
||||
|
||||
// The bit mask used to extract the state returned by the [Step] function, after
|
||||
// shifting. These values must correspond to the shift constants.
|
||||
const (
|
||||
maskGraphemeState = 0xf
|
||||
maskWordState = 0x1f
|
||||
maskSentenceState = 0xf
|
||||
maskLineState = 0xff
|
||||
)
|
||||
|
||||
// Step returns the first grapheme cluster (user-perceived character) found in
|
||||
// the given byte slice. It also returns information about the boundary between
|
||||
// that grapheme cluster and the one following it as well as the monospace width
|
||||
// of the grapheme cluster. There are three types of boundary information: word
|
||||
// boundaries, sentence boundaries, and line breaks. This function is therefore
|
||||
// a combination of [FirstGraphemeCluster], [FirstWord], [FirstSentence], and
|
||||
// [FirstLineSegment].
|
||||
//
|
||||
// The "boundaries" return value can be evaluated as follows:
|
||||
//
|
||||
// - boundaries&MaskWord != 0: The boundary is a word boundary.
|
||||
// - boundaries&MaskWord == 0: The boundary is not a word boundary.
|
||||
// - boundaries&MaskSentence != 0: The boundary is a sentence boundary.
|
||||
// - boundaries&MaskSentence == 0: The boundary is not a sentence boundary.
|
||||
// - boundaries&MaskLine == LineDontBreak: You must not break the line at the
|
||||
// boundary.
|
||||
// - boundaries&MaskLine == LineMustBreak: You must break the line at the
|
||||
// boundary.
|
||||
// - boundaries&MaskLine == LineCanBreak: You may or may not break the line at
|
||||
// the boundary.
|
||||
// - boundaries >> ShiftWidth: The width of the grapheme cluster for most
|
||||
// monospace fonts where a value of 1 represents one character cell.
|
||||
//
|
||||
// This function can be called continuously to extract all grapheme clusters
|
||||
// from a byte slice, as illustrated in the examples below.
|
||||
//
|
||||
// If you don't know which state to pass, for example when calling the function
|
||||
// for the first time, you must pass -1. For consecutive calls, pass the state
|
||||
// and rest slice returned by the previous call.
|
||||
//
|
||||
// The "rest" slice is the sub-slice of the original byte slice "b" starting
|
||||
// after the last byte of the identified grapheme cluster. If the length of the
|
||||
// "rest" slice is 0, the entire byte slice "b" has been processed. The
|
||||
// "cluster" byte slice is the sub-slice of the input slice containing the
|
||||
// first identified grapheme cluster.
|
||||
//
|
||||
// Given an empty byte slice "b", the function returns nil values.
|
||||
//
|
||||
// While slightly less convenient than using the Graphemes class, this function
|
||||
// has much better performance and makes no allocations. It lends itself well to
|
||||
// large byte slices.
|
||||
//
|
||||
// Note that in accordance with [UAX #14 LB3], the final segment will end with
|
||||
// a mandatory line break (boundaries&MaskLine == LineMustBreak). You can choose
|
||||
// to ignore this by checking if the length of the "rest" slice is 0 and calling
|
||||
// [HasTrailingLineBreak] or [HasTrailingLineBreakInString] on the last rune.
|
||||
//
|
||||
// [UAX #14 LB3]: https://www.unicode.org/reports/tr14/#Algorithm
|
||||
func Step(b []byte, state int) (cluster, rest []byte, boundaries int, newState int) {
|
||||
// An empty byte slice returns nothing.
|
||||
if len(b) == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
// Extract the first rune.
|
||||
r, length := utf8.DecodeRune(b)
|
||||
if len(b) <= length { // If we're already past the end, there is nothing else to parse.
|
||||
var prop int
|
||||
if state < 0 {
|
||||
prop = propertyGraphemes(r)
|
||||
} else {
|
||||
prop = state >> shiftPropState
|
||||
}
|
||||
return b, nil, LineMustBreak | (1 << shiftWord) | (1 << shiftSentence) | (runeWidth(r, prop) << ShiftWidth), grAny | (wbAny << shiftWordState) | (sbAny << shiftSentenceState) | (lbAny << shiftLineState) | (prop << shiftPropState)
|
||||
}
|
||||
|
||||
// If we don't know the state, determine it now.
|
||||
var graphemeState, wordState, sentenceState, lineState, firstProp int
|
||||
remainder := b[length:]
|
||||
if state < 0 {
|
||||
graphemeState, firstProp, _ = transitionGraphemeState(state, r)
|
||||
wordState, _ = transitionWordBreakState(state, r, remainder, "")
|
||||
sentenceState, _ = transitionSentenceBreakState(state, r, remainder, "")
|
||||
lineState, _ = transitionLineBreakState(state, r, remainder, "")
|
||||
} else {
|
||||
graphemeState = state & maskGraphemeState
|
||||
wordState = (state >> shiftWordState) & maskWordState
|
||||
sentenceState = (state >> shiftSentenceState) & maskSentenceState
|
||||
lineState = (state >> shiftLineState) & maskLineState
|
||||
firstProp = state >> shiftPropState
|
||||
}
|
||||
|
||||
// Transition until we find a grapheme cluster boundary.
|
||||
width := runeWidth(r, firstProp)
|
||||
for {
|
||||
var (
|
||||
graphemeBoundary, wordBoundary, sentenceBoundary bool
|
||||
lineBreak, prop int
|
||||
)
|
||||
|
||||
r, l := utf8.DecodeRune(remainder)
|
||||
remainder = b[length+l:]
|
||||
|
||||
graphemeState, prop, graphemeBoundary = transitionGraphemeState(graphemeState, r)
|
||||
wordState, wordBoundary = transitionWordBreakState(wordState, r, remainder, "")
|
||||
sentenceState, sentenceBoundary = transitionSentenceBreakState(sentenceState, r, remainder, "")
|
||||
lineState, lineBreak = transitionLineBreakState(lineState, r, remainder, "")
|
||||
|
||||
if graphemeBoundary {
|
||||
boundary := lineBreak | (width << ShiftWidth)
|
||||
if wordBoundary {
|
||||
boundary |= 1 << shiftWord
|
||||
}
|
||||
if sentenceBoundary {
|
||||
boundary |= 1 << shiftSentence
|
||||
}
|
||||
return b[:length], b[length:], boundary, graphemeState | (wordState << shiftWordState) | (sentenceState << shiftSentenceState) | (lineState << shiftLineState) | (prop << shiftPropState)
|
||||
}
|
||||
|
||||
if firstProp == prExtendedPictographic {
|
||||
if r == vs15 {
|
||||
width = 1
|
||||
} else if r == vs16 {
|
||||
width = 2
|
||||
}
|
||||
} else if firstProp != prRegionalIndicator && firstProp != prL {
|
||||
width += runeWidth(r, prop)
|
||||
}
|
||||
|
||||
length += l
|
||||
if len(b) <= length {
|
||||
return b, nil, LineMustBreak | (1 << shiftWord) | (1 << shiftSentence) | (width << ShiftWidth), grAny | (wbAny << shiftWordState) | (sbAny << shiftSentenceState) | (lbAny << shiftLineState) | (prop << shiftPropState)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// StepString is like [Step] but its input and outputs are strings.
|
||||
func StepString(str string, state int) (cluster, rest string, boundaries int, newState int) {
|
||||
// An empty byte slice returns nothing.
|
||||
if len(str) == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
// Extract the first rune.
|
||||
r, length := utf8.DecodeRuneInString(str)
|
||||
if len(str) <= length { // If we're already past the end, there is nothing else to parse.
|
||||
prop := propertyGraphemes(r)
|
||||
return str, "", LineMustBreak | (1 << shiftWord) | (1 << shiftSentence) | (runeWidth(r, prop) << ShiftWidth), grAny | (wbAny << shiftWordState) | (sbAny << shiftSentenceState) | (lbAny << shiftLineState)
|
||||
}
|
||||
|
||||
// If we don't know the state, determine it now.
|
||||
var graphemeState, wordState, sentenceState, lineState, firstProp int
|
||||
remainder := str[length:]
|
||||
if state < 0 {
|
||||
graphemeState, firstProp, _ = transitionGraphemeState(state, r)
|
||||
wordState, _ = transitionWordBreakState(state, r, nil, remainder)
|
||||
sentenceState, _ = transitionSentenceBreakState(state, r, nil, remainder)
|
||||
lineState, _ = transitionLineBreakState(state, r, nil, remainder)
|
||||
} else {
|
||||
graphemeState = state & maskGraphemeState
|
||||
wordState = (state >> shiftWordState) & maskWordState
|
||||
sentenceState = (state >> shiftSentenceState) & maskSentenceState
|
||||
lineState = (state >> shiftLineState) & maskLineState
|
||||
firstProp = state >> shiftPropState
|
||||
}
|
||||
|
||||
// Transition until we find a grapheme cluster boundary.
|
||||
width := runeWidth(r, firstProp)
|
||||
for {
|
||||
var (
|
||||
graphemeBoundary, wordBoundary, sentenceBoundary bool
|
||||
lineBreak, prop int
|
||||
)
|
||||
|
||||
r, l := utf8.DecodeRuneInString(remainder)
|
||||
remainder = str[length+l:]
|
||||
|
||||
graphemeState, prop, graphemeBoundary = transitionGraphemeState(graphemeState, r)
|
||||
wordState, wordBoundary = transitionWordBreakState(wordState, r, nil, remainder)
|
||||
sentenceState, sentenceBoundary = transitionSentenceBreakState(sentenceState, r, nil, remainder)
|
||||
lineState, lineBreak = transitionLineBreakState(lineState, r, nil, remainder)
|
||||
|
||||
if graphemeBoundary {
|
||||
boundary := lineBreak | (width << ShiftWidth)
|
||||
if wordBoundary {
|
||||
boundary |= 1 << shiftWord
|
||||
}
|
||||
if sentenceBoundary {
|
||||
boundary |= 1 << shiftSentence
|
||||
}
|
||||
return str[:length], str[length:], boundary, graphemeState | (wordState << shiftWordState) | (sentenceState << shiftSentenceState) | (lineState << shiftLineState) | (prop << shiftPropState)
|
||||
}
|
||||
|
||||
if firstProp == prExtendedPictographic {
|
||||
if r == vs15 {
|
||||
width = 1
|
||||
} else if r == vs16 {
|
||||
width = 2
|
||||
}
|
||||
} else if firstProp != prRegionalIndicator && firstProp != prL {
|
||||
width += runeWidth(r, prop)
|
||||
}
|
||||
|
||||
length += l
|
||||
if len(str) <= length {
|
||||
return str, "", LineMustBreak | (1 << shiftWord) | (1 << shiftSentence) | (width << ShiftWidth), grAny | (wbAny << shiftWordState) | (sbAny << shiftSentenceState) | (lbAny << shiftLineState) | (prop << shiftPropState)
|
||||
}
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user