parent
e4eaf4d047
commit
83b5feeb37
2
Makefile
2
Makefile
|
|
@ -5,7 +5,7 @@ PACKAGE := github.com/derailed/$(NAME)
|
|||
GIT_REV ?= $(shell git rev-parse --short HEAD)
|
||||
SOURCE_DATE_EPOCH ?= $(shell date +%s)
|
||||
DATE ?= $(shell date -u -d @${SOURCE_DATE_EPOCH} +"%Y-%m-%dT%H:%M:%SZ")
|
||||
VERSION ?= v0.25.0
|
||||
VERSION ?= v0.25.1
|
||||
IMG_NAME := derailed/k9s
|
||||
IMAGE := ${IMG_NAME}:${VERSION}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,28 @@
|
|||
<img src="https://raw.githubusercontent.com/derailed/k9s/master/assets/k9s_small.png" align="right" width="200" height="auto"/>
|
||||
|
||||
# Release v0.25.1
|
||||
|
||||
## Notes
|
||||
|
||||
Thank you to all that contributed with flushing out issues and enhancements for K9s! I'll try to mark some of these issues as fixed. But if you don't mind grab the latest rev and see if we're happier with some of the fixes! If you've filed an issue please help me verify and close. Your support, kindness and awesome suggestions to make K9s better are as ever very much noted and appreciated!
|
||||
|
||||
If you feel K9s is helping your Kubernetes journey, please consider joining our [sponsorship program](https://github.com/sponsors/derailed) and/or make some noise on social! [@kitesurfer](https://twitter.com/kitesurfer)
|
||||
|
||||
On Slack? Please join us [K9slackers](https://join.slack.com/t/k9sers/shared_invite/enQtOTA5MDEyNzI5MTU0LWQ1ZGI3MzliYzZhZWEyNzYxYzA3NjE0YTk1YmFmNzViZjIyNzhkZGI0MmJjYzhlNjdlMGJhYzE2ZGU1NjkyNTM)
|
||||
|
||||
## Maintenance Release!
|
||||
|
||||
Looks like we've broken a few little thingies...
|
||||
May need a few rapid fires to regain some sanity so please bare with us and thank you for your reports!!
|
||||
|
||||
---
|
||||
|
||||
## Resolved Issues
|
||||
|
||||
* [Issue #1308](https://github.com/derailed/k9s/issues/1308) Command auto-complete suggestions disappear after screen refresh interval #1308
|
||||
* [Issue #1307](https://github.com/derailed/k9s/issues/1307) Displayed Cluster name is always read from current-contex
|
||||
* [Issue #1296](https://github.com/derailed/k9s/issues/1244) Scoobie doo was not a cow - NOTE: Switch to dialog to keep live context!
|
||||
|
||||
---
|
||||
|
||||
<img src="https://raw.githubusercontent.com/derailed/k9s/master/assets/imhotep_logo.png" width="32" height="auto"/> © 2020 Imhotep Software LLC. All materials licensed under [Apache v2.0](http://www.apache.org/licenses/LICENSE-2.0)
|
||||
15
go.mod
15
go.mod
|
|
@ -2,12 +2,6 @@ module github.com/derailed/k9s
|
|||
|
||||
go 1.17
|
||||
|
||||
replace (
|
||||
github.com/docker/distribution => github.com/docker/distribution v0.0.0-20191216044856-a8371794149d
|
||||
github.com/docker/docker => github.com/moby/moby v17.12.0-ce-rc1.0.20200618181300-9dc6525e6118+incompatible
|
||||
github.com/gdamore/tcell/v2 => github.com/derailed/tcell/v2 v2.3.1-rc.2
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/adrg/xdg v0.3.4
|
||||
github.com/atotto/clipboard v0.1.4
|
||||
|
|
@ -15,10 +9,10 @@ require (
|
|||
github.com/cenkalti/backoff/v4 v4.1.1
|
||||
github.com/derailed/popeye v0.9.7
|
||||
github.com/derailed/tview v0.6.3
|
||||
github.com/fatih/color v1.12.0
|
||||
github.com/fatih/color v1.13.0
|
||||
github.com/fsnotify/fsnotify v1.5.1
|
||||
github.com/fvbommel/sortorder v1.0.2
|
||||
github.com/gdamore/tcell/v2 v2.3.1
|
||||
github.com/gdamore/tcell/v2 v2.4.0
|
||||
github.com/ghodss/yaml v1.0.0
|
||||
github.com/kylelemons/godebug v1.1.0 // indirect
|
||||
github.com/mattn/go-runewidth v0.0.13
|
||||
|
|
@ -113,8 +107,8 @@ require (
|
|||
github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de // indirect
|
||||
github.com/lucasb-eyer/go-colorful v1.2.0 // indirect
|
||||
github.com/mailru/easyjson v0.7.6 // indirect
|
||||
github.com/mattn/go-colorable v0.1.8 // indirect
|
||||
github.com/mattn/go-isatty v0.0.12 // indirect
|
||||
github.com/mattn/go-colorable v0.1.9 // indirect
|
||||
github.com/mattn/go-isatty v0.0.14 // indirect
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 // indirect
|
||||
github.com/mitchellh/copystructure v1.1.1 // indirect
|
||||
github.com/mitchellh/go-wordwrap v1.0.0 // indirect
|
||||
|
|
@ -168,6 +162,7 @@ require (
|
|||
k8s.io/component-base v0.22.0 // indirect
|
||||
k8s.io/kube-openapi v0.0.0-20210421082810-95288971da7e // indirect
|
||||
k8s.io/utils v0.0.0-20210707171843-4b05e18ac7d9 // indirect
|
||||
rsc.io/letsencrypt v0.0.3 // indirect
|
||||
sigs.k8s.io/kustomize/api v0.8.11 // indirect
|
||||
sigs.k8s.io/kustomize/kyaml v0.11.0 // indirect
|
||||
sigs.k8s.io/structured-merge-diff/v4 v4.1.2 // indirect
|
||||
|
|
|
|||
26
go.sum
26
go.sum
|
|
@ -214,8 +214,6 @@ github.com/denisenkom/go-mssqldb v0.0.0-20191001013358-cfbb681360f0/go.mod h1:xb
|
|||
github.com/denverdino/aliyungo v0.0.0-20190125010748-a747050bb1ba/go.mod h1:dV8lFg6daOBZbT6/BDGIz6Y3WFGn8juu6G+CQ6LHtl0=
|
||||
github.com/derailed/popeye v0.9.7 h1:EnOl8rwvAlN4KJo62+V7J713ZAWFQmKCrTBBBBBkbmQ=
|
||||
github.com/derailed/popeye v0.9.7/go.mod h1:Ih3wTG7wBOuxdqz5tlCuCFq/vyB+Te/IpqY5HwgUTEA=
|
||||
github.com/derailed/tcell/v2 v2.3.1-rc.2 h1:9TmZB/IwL3MA1Jf4pC4rfMaPTcVYIN62IwE7X7A9emU=
|
||||
github.com/derailed/tcell/v2 v2.3.1-rc.2/go.mod h1:wegJ+SscH+jPjEQIAV/dI/grLTRm5R4IE2M479NDSL0=
|
||||
github.com/derailed/tview v0.6.3 h1:4GFzcmuVjHYHKlLEpU8lSiUBVfHeYQEC0z5tlBLp4CI=
|
||||
github.com/derailed/tview v0.6.3/go.mod h1:j2GwRsCb3NZe7lRjKIeplvZLkg8duyNWG6I4y+bZwEE=
|
||||
github.com/dgrijalva/jwt-go v0.0.0-20170104182250-a601269ab70c/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
|
||||
|
|
@ -224,8 +222,11 @@ github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8
|
|||
github.com/dnaeon/go-vcr v1.0.1/go.mod h1:aBB1+wY4s93YsC3HHjMBMrwTj2R9FHDzUr9KyGc8n1E=
|
||||
github.com/docker/cli v20.10.5+incompatible h1:bjflayQbWg+xOkF2WPEAOi4Y7zWhR7ptoPhV/VqLVDE=
|
||||
github.com/docker/cli v20.10.5+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
|
||||
github.com/docker/distribution v0.0.0-20191216044856-a8371794149d h1:jC8tT/S0OGx2cswpeUTn4gOIea8P08lD3VFQT0cOZ50=
|
||||
github.com/docker/distribution v0.0.0-20191216044856-a8371794149d/go.mod h1:0+TTO4EOBfRPhZXAeF1Vu+W3hHZ8eLp8PgKVZlcvtFY=
|
||||
github.com/docker/distribution v2.7.1+incompatible h1:a5mlkVzth6W5A4fOsS3D2EO5BUmsJpcB+cRlLU7cSug=
|
||||
github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
|
||||
github.com/docker/docker v17.12.0-ce-rc1.0.20200618181300-9dc6525e6118+incompatible h1:iWPIG7pWIsCwT6ZtHnTUpoVMnete7O/pzd9HFE3+tn8=
|
||||
github.com/docker/docker v17.12.0-ce-rc1.0.20200618181300-9dc6525e6118+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
||||
github.com/docker/docker-credential-helpers v0.6.3 h1:zI2p9+1NQYdnG6sMU26EX4aVGlqbInSQxQXLvzJ4RPQ=
|
||||
github.com/docker/docker-credential-helpers v0.6.3/go.mod h1:WRaJzqw3CTB9bk10avuGsjVBZsD05qeibJ1/TYlvc0Y=
|
||||
github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ=
|
||||
|
|
@ -265,8 +266,8 @@ github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d/go.mod h1:ZZM
|
|||
github.com/fatih/camelcase v1.0.0 h1:hxNvNX/xYBp0ovncs8WyWZrOrpBNub/JfaMvbURyft8=
|
||||
github.com/fatih/camelcase v1.0.0/go.mod h1:yN2Sb0lFhZJUdVvtELVWefmrXpuZESvPmqwoZc+/fpc=
|
||||
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
|
||||
github.com/fatih/color v1.12.0 h1:mRhaKNwANqRgUBGKmnI5ZxEk7QXmjQeCcuYFMX2bfcc=
|
||||
github.com/fatih/color v1.12.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM=
|
||||
github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w=
|
||||
github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk=
|
||||
github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
|
||||
github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k=
|
||||
github.com/form3tech-oss/jwt-go v3.2.3+incompatible h1:7ZaBxOI7TMoYBfyA3cQHErNNyAWIKUMIwqxEtgHOs5c=
|
||||
|
|
@ -284,6 +285,9 @@ github.com/garyburd/redigo v0.0.0-20150301180006-535138d7bcd7 h1:LofdAjjjqCSXMwL
|
|||
github.com/garyburd/redigo v0.0.0-20150301180006-535138d7bcd7/go.mod h1:NR3MbYisc3/PwhQ00EMzDiPmrwpPxAn5GI05/YaO1SY=
|
||||
github.com/gdamore/encoding v1.0.0 h1:+7OoQ1Bc6eTm5niUzBa0Ctsh6JbMW6Ra+YNuAtDBdko=
|
||||
github.com/gdamore/encoding v1.0.0/go.mod h1:alR0ol34c49FCSBLjhosxzcPHQbf2trDkoo5dl+VrEg=
|
||||
github.com/gdamore/tcell/v2 v2.2.1/go.mod h1:cTTuF84Dlj/RqmaCIV5p4w8uG1zWdk0SF6oBpwHp4fU=
|
||||
github.com/gdamore/tcell/v2 v2.4.0 h1:W6dxJEmaxYvhICFoTY3WrLLEXsQ11SaFnKGVEXW57KM=
|
||||
github.com/gdamore/tcell/v2 v2.4.0/go.mod h1:cTTuF84Dlj/RqmaCIV5p4w8uG1zWdk0SF6oBpwHp4fU=
|
||||
github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk=
|
||||
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||
github.com/globalsign/mgo v0.0.0-20180905125535-1ca0a4f7cbcb/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q=
|
||||
|
|
@ -595,12 +599,13 @@ github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJ
|
|||
github.com/markbates/pkger v0.17.1/go.mod h1:0JoVlrol20BSywW79rN3kdFFsE5xYM+rSCQDXbLhiuI=
|
||||
github.com/marstr/guid v1.1.0/go.mod h1:74gB1z2wpxxInTG6yaqA7KrtM0NZ+RbrcqDvYHefzho=
|
||||
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
|
||||
github.com/mattn/go-colorable v0.1.8 h1:c1ghPdyEDarC70ftn0y+A/Ee++9zz8ljHG1b13eJ0s8=
|
||||
github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
|
||||
github.com/mattn/go-colorable v0.1.9 h1:sqDoxXbdeALODt0DAeJCVp38ps9ZogZEAXjus69YV3U=
|
||||
github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
|
||||
github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
|
||||
github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
|
||||
github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY=
|
||||
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
|
||||
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-oci8 v0.0.7/go.mod h1:wjDx6Xm9q7dFtHJvIlrI99JytznLw5wQ4R+9mNXJwGI=
|
||||
github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
|
||||
github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
|
||||
|
|
@ -635,8 +640,6 @@ github.com/mitchellh/osext v0.0.0-20151018003038-5e2d6d41470f/go.mod h1:OkQIRizQ
|
|||
github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
|
||||
github.com/mitchellh/reflectwalk v1.0.1 h1:FVzMWA5RllMAKIdUSC8mdWo3XtwoecrH79BY70sEEpE=
|
||||
github.com/mitchellh/reflectwalk v1.0.1/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
|
||||
github.com/moby/moby v17.12.0-ce-rc1.0.20200618181300-9dc6525e6118+incompatible h1:NT0cwArZg/wGdvY8pzej4tPr+9WGmDdkF8Suj+mkz2g=
|
||||
github.com/moby/moby v17.12.0-ce-rc1.0.20200618181300-9dc6525e6118+incompatible/go.mod h1:fDXVQ6+S340veQPv35CzDahGBmHsiclFwfEygB/TWMc=
|
||||
github.com/moby/spdystream v0.2.0 h1:cjW1zVyyoiM0T7b6UoySUFqzXMoqRckQtXwGPiBhOM8=
|
||||
github.com/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c=
|
||||
github.com/moby/term v0.0.0-20201216013528-df9cb8a40635/go.mod h1:FBS0z0QWA44HXygs7VXDUOGoN/1TV3RuWkLO04am3wc=
|
||||
|
|
@ -788,7 +791,6 @@ github.com/rogpeppe/go-internal v1.4.0/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTE
|
|||
github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ=
|
||||
github.com/rs/xid v1.3.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
|
||||
github.com/rs/zerolog v1.18.0/go.mod h1:9nvC1axdVrAHcu/s9taAVfBuIdTZLVQmKQyvrUjF5+I=
|
||||
github.com/rs/zerolog v1.22.0/go.mod h1:ZPhntP/xmq1nnND05hhpAh2QMhSsA4UN3MGZ6O2J3hM=
|
||||
github.com/rs/zerolog v1.25.0 h1:Rj7XygbUHKUlDPcVdoLyR91fJBsduXj5fRxyqIQj/II=
|
||||
github.com/rs/zerolog v1.25.0/go.mod h1:7KHcEGe0QZPOm2IE4Kpb5rTh6n1h2hIgS5OOnu1rUaI=
|
||||
github.com/rubenv/sql-migrate v0.0.0-20200616145509-8d140a17f351 h1:HXr/qUllAWv9riaI4zh2eXWKmCSDqVS/XH1MRHLKRwk=
|
||||
|
|
@ -1468,6 +1470,8 @@ k8s.io/utils v0.0.0-20201110183641-67b214c5f920/go.mod h1:jPW/WVKK9YHAvNhRxK0md/
|
|||
k8s.io/utils v0.0.0-20210707171843-4b05e18ac7d9 h1:imL9YgXQ9p7xmPzHFm/vVd/cF78jad+n4wK1ABwYtMM=
|
||||
k8s.io/utils v0.0.0-20210707171843-4b05e18ac7d9/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
|
||||
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
|
||||
rsc.io/letsencrypt v0.0.3 h1:H7xDfhkaFFSYEJlKeq38RwX2jYcnTeHuDQyT+mMNMwM=
|
||||
rsc.io/letsencrypt v0.0.3/go.mod h1:buyQKZ6IXrRnB7TdkHP0RyEybLx18HHyOSoTyoOLqNY=
|
||||
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
|
||||
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
|
||||
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.15/go.mod h1:LEScyzhFmoF5pso/YSeBstl57mOzx9xlU9n85RGrDQg=
|
||||
|
|
|
|||
|
|
@ -87,11 +87,7 @@ func (c *Config) reset() {
|
|||
|
||||
// SwitchContext changes the kubeconfig context to a new cluster.
|
||||
func (c *Config) SwitchContext(name string) error {
|
||||
cfg, err := c.rawConfig()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if cfg.CurrentContext == name {
|
||||
if n, err := c.CurrentContextName(); err == nil && n == name {
|
||||
return nil
|
||||
}
|
||||
context, err := c.GetContext(name)
|
||||
|
|
@ -196,9 +192,12 @@ func (c *Config) CurrentClusterName() (string, error) {
|
|||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
current := cfg.CurrentContext
|
||||
context, err := c.CurrentContextName()
|
||||
if err != nil {
|
||||
context = cfg.CurrentContext
|
||||
}
|
||||
|
||||
if ctx, ok := cfg.Contexts[current]; ok {
|
||||
if ctx, ok := cfg.Contexts[context]; ok {
|
||||
return ctx.Cluster, nil
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ import (
|
|||
const (
|
||||
maxBuff = 10
|
||||
|
||||
keyEntryDelay = 200 * time.Millisecond
|
||||
keyEntryDelay = 100 * time.Millisecond
|
||||
|
||||
// CommandBuffer represents a command buffer.
|
||||
CommandBuffer BufferKind = 1 << iota
|
||||
|
|
@ -24,10 +24,10 @@ type (
|
|||
// BuffWatcher represents a command buffer listener.
|
||||
BuffWatcher interface {
|
||||
// BufferCompleted indicates input was accepted.
|
||||
BufferCompleted(s string)
|
||||
BufferCompleted(text, suggestion string)
|
||||
|
||||
// BufferChanged indicates the buffer was changed.
|
||||
BufferChanged(s string)
|
||||
BufferChanged(text, suggestion string)
|
||||
|
||||
// BufferActive indicates the buff activity changed.
|
||||
BufferActive(state bool, kind BufferKind)
|
||||
|
|
@ -36,13 +36,14 @@ type (
|
|||
|
||||
// CmdBuff represents user command input.
|
||||
type CmdBuff struct {
|
||||
buff []rune
|
||||
listeners []BuffWatcher
|
||||
hotKey rune
|
||||
kind BufferKind
|
||||
active bool
|
||||
cancel context.CancelFunc
|
||||
mx sync.RWMutex
|
||||
buff []rune
|
||||
suggestion string
|
||||
listeners []BuffWatcher
|
||||
hotKey rune
|
||||
kind BufferKind
|
||||
active bool
|
||||
cancel context.CancelFunc
|
||||
mx sync.RWMutex
|
||||
}
|
||||
|
||||
// NewCmdBuff returns a new command buffer.
|
||||
|
|
@ -76,9 +77,14 @@ func (c *CmdBuff) GetText() string {
|
|||
return string(c.buff)
|
||||
}
|
||||
|
||||
// GetSuggestion returns the current suggestion.
|
||||
func (c *CmdBuff) GetSuggestion() string {
|
||||
return c.suggestion
|
||||
}
|
||||
|
||||
// SetText initializes the buffer with a command.
|
||||
func (c *CmdBuff) SetText(cmd string) {
|
||||
c.buff = []rune(cmd)
|
||||
func (c *CmdBuff) SetText(text, suggestion string) {
|
||||
c.buff, c.suggestion = []rune(text), suggestion
|
||||
c.fireBufferCompleted()
|
||||
}
|
||||
|
||||
|
|
@ -186,14 +192,14 @@ func (c *CmdBuff) RemoveListener(l BuffWatcher) {
|
|||
func (c *CmdBuff) fireBufferCompleted() {
|
||||
text := c.GetText()
|
||||
for _, l := range c.listeners {
|
||||
l.BufferCompleted(text)
|
||||
l.BufferCompleted(text, c.suggestion)
|
||||
}
|
||||
}
|
||||
|
||||
func (c *CmdBuff) fireBufferChanged() {
|
||||
text := c.GetText()
|
||||
for _, l := range c.listeners {
|
||||
l.BufferChanged(text)
|
||||
l.BufferChanged(text, c.suggestion)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -8,17 +8,17 @@ import (
|
|||
)
|
||||
|
||||
type testListener struct {
|
||||
text string
|
||||
act int
|
||||
inact int
|
||||
text, suggestion string
|
||||
act int
|
||||
inact int
|
||||
}
|
||||
|
||||
func (l *testListener) BufferChanged(s string) {
|
||||
l.text = s
|
||||
func (l *testListener) BufferChanged(t, s string) {
|
||||
l.text, l.suggestion = t, s
|
||||
}
|
||||
|
||||
func (l *testListener) BufferCompleted(s string) {
|
||||
l.text = s
|
||||
func (l *testListener) BufferCompleted(t, s string) {
|
||||
l.text, l.suggestion = t, s
|
||||
}
|
||||
|
||||
func (l *testListener) BufferActive(s bool, _ model.BufferKind) {
|
||||
|
|
|
|||
|
|
@ -122,15 +122,19 @@ func (f *FishBuff) Delete() {
|
|||
|
||||
func (f *FishBuff) fireSuggestionChanged(ss []string) {
|
||||
f.suggestions, f.suggestionIndex = ss, 0
|
||||
|
||||
var suggest string
|
||||
if len(ss) == 0 {
|
||||
f.suggestionIndex = -1
|
||||
return
|
||||
} else {
|
||||
suggest = ss[f.suggestionIndex]
|
||||
}
|
||||
f.SetText(f.GetText(), suggest)
|
||||
|
||||
text, sug := f.GetText(), ss[f.suggestionIndex]
|
||||
for _, l := range f.listeners {
|
||||
if listener, ok := l.(SuggestionListener); ok {
|
||||
listener.SuggestionChanged(text, sug)
|
||||
}
|
||||
}
|
||||
// BOZO!!
|
||||
//for _, l := range f.listeners {
|
||||
// if listener, ok := l.(SuggestionListener); ok {
|
||||
// listener.SuggestionChanged(text, sug)
|
||||
// }
|
||||
//}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ func TestFishDelete(t *testing.T) {
|
|||
f.SetActive(true)
|
||||
|
||||
assert.Equal(t, 2, m.changeCount)
|
||||
assert.Equal(t, 2, m.suggCount)
|
||||
assert.Equal(t, 1, m.suggCount)
|
||||
assert.True(t, m.active)
|
||||
assert.Equal(t, "blee", m.suggestion)
|
||||
|
||||
|
|
@ -75,12 +75,15 @@ type mockSuggestionListener struct {
|
|||
active bool
|
||||
}
|
||||
|
||||
func (m *mockSuggestionListener) BufferChanged(s string) {
|
||||
func (m *mockSuggestionListener) BufferChanged(_, _ string) {
|
||||
m.changeCount++
|
||||
}
|
||||
|
||||
func (m *mockSuggestionListener) BufferCompleted(s string) {
|
||||
m.text = s
|
||||
func (m *mockSuggestionListener) BufferCompleted(text, suggest string) {
|
||||
if m.suggestion != suggest {
|
||||
m.suggCount++
|
||||
}
|
||||
m.text, m.suggestion = text, suggest
|
||||
}
|
||||
|
||||
func (m *mockSuggestionListener) BufferActive(state bool, kind model.BufferKind) {
|
||||
|
|
|
|||
|
|
@ -93,10 +93,10 @@ func (a *App) SetRunning(f bool) {
|
|||
}
|
||||
|
||||
// BufferCompleted indicates input was accepted.
|
||||
func (a *App) BufferCompleted(s string) {}
|
||||
func (a *App) BufferCompleted(_, _ string) {}
|
||||
|
||||
// BufferChanged indicates the buffer was changed.
|
||||
func (a *App) BufferChanged(s string) {}
|
||||
func (a *App) BufferChanged(_, _ string) {}
|
||||
|
||||
// BufferActive indicates the buff activity changed.
|
||||
func (a *App) BufferActive(state bool, kind model.BufferKind) {
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ import (
|
|||
func TestAppGetCmd(t *testing.T) {
|
||||
a := ui.NewApp(config.NewConfig(nil), "")
|
||||
a.Init()
|
||||
a.CmdBuff().SetText("blee")
|
||||
a.CmdBuff().SetText("blee", "")
|
||||
|
||||
assert.Equal(t, "blee", a.GetCmd())
|
||||
}
|
||||
|
|
@ -19,7 +19,7 @@ func TestAppGetCmd(t *testing.T) {
|
|||
func TestAppInCmdMode(t *testing.T) {
|
||||
a := ui.NewApp(config.NewConfig(nil), "")
|
||||
a.Init()
|
||||
a.CmdBuff().SetText("blee")
|
||||
a.CmdBuff().SetText("blee", "")
|
||||
assert.False(t, a.InCmdMode())
|
||||
|
||||
a.CmdBuff().SetActive(false)
|
||||
|
|
@ -29,7 +29,7 @@ func TestAppInCmdMode(t *testing.T) {
|
|||
func TestAppResetCmd(t *testing.T) {
|
||||
a := ui.NewApp(config.NewConfig(nil), "")
|
||||
a.Init()
|
||||
a.CmdBuff().SetText("blee")
|
||||
a.CmdBuff().SetText("blee", "")
|
||||
|
||||
a.ResetCmd()
|
||||
|
||||
|
|
@ -43,7 +43,7 @@ func TestAppHasCmd(t *testing.T) {
|
|||
a.ActivateCmd(true)
|
||||
assert.False(t, a.HasCmd())
|
||||
|
||||
a.CmdBuff().SetText("blee")
|
||||
a.CmdBuff().SetText("blee", "")
|
||||
assert.True(t, a.InCmdMode())
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,59 @@
|
|||
package dialog
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/derailed/k9s/internal/config"
|
||||
"github.com/derailed/k9s/internal/ui"
|
||||
"github.com/derailed/tview"
|
||||
"github.com/gdamore/tcell/v2"
|
||||
)
|
||||
|
||||
// ShowConfirm pops a confirmation dialog.
|
||||
func ShowError(styles config.Dialog, pages *ui.Pages, msg string) {
|
||||
f := tview.NewForm()
|
||||
f.SetItemPadding(0)
|
||||
f.SetButtonsAlign(tview.AlignCenter).
|
||||
SetButtonBackgroundColor(styles.ButtonBgColor.Color()).
|
||||
SetButtonTextColor(styles.ButtonFgColor.Color()).
|
||||
SetLabelColor(styles.LabelFgColor.Color()).
|
||||
SetFieldTextColor(tcell.ColorIndianRed)
|
||||
f.AddButton("Dismiss", func() {
|
||||
dismissError(pages)
|
||||
})
|
||||
if b := f.GetButton(0); b != nil {
|
||||
b.SetBackgroundColorActivated(styles.ButtonFocusBgColor.Color())
|
||||
b.SetLabelColorActivated(styles.ButtonFocusFgColor.Color())
|
||||
}
|
||||
f.SetFocus(0)
|
||||
modal := tview.NewModalForm("<error>", f)
|
||||
modal.SetText(cowTalk(f, msg))
|
||||
modal.SetTextColor(tcell.ColorOrangeRed)
|
||||
modal.SetDoneFunc(func(int, string) {
|
||||
dismissError(pages)
|
||||
})
|
||||
pages.AddPage(confirmKey, modal, false, false)
|
||||
pages.ShowPage(confirmKey)
|
||||
}
|
||||
|
||||
func dismissError(pages *ui.Pages) {
|
||||
pages.RemovePage(confirmKey)
|
||||
}
|
||||
|
||||
func cowTalk(f *tview.Form, says string) string {
|
||||
msg := fmt.Sprintf("< Ruroh? %s >", says)
|
||||
buff := make([]string, 0, len(cow)+3)
|
||||
buff = append(buff, msg)
|
||||
buff = append(buff, cow...)
|
||||
|
||||
return strings.Join(buff, "\n")
|
||||
}
|
||||
|
||||
var cow = []string{
|
||||
`\ ^__^ `,
|
||||
` \ (oo)\_______ `,
|
||||
` (__)\ )\/\`,
|
||||
` ||----w | `,
|
||||
` || || `,
|
||||
}
|
||||
|
|
@ -37,11 +37,14 @@ type Suggester interface {
|
|||
// PromptModel represents a prompt buffer.
|
||||
type PromptModel interface {
|
||||
// SetText sets the model text.
|
||||
SetText(string)
|
||||
SetText(txt, sug string)
|
||||
|
||||
// GetText returns the current text.
|
||||
GetText() string
|
||||
|
||||
// GetSuggestion returns the current suggestion.
|
||||
GetSuggestion() string
|
||||
|
||||
// ClearText clears out model text.
|
||||
ClearText(fire bool)
|
||||
|
||||
|
|
@ -141,7 +144,7 @@ func (p *Prompt) keyboard(evt *tcell.EventKey) *tcell.EventKey {
|
|||
p.model.ClearText(true)
|
||||
p.model.SetActive(false)
|
||||
case tcell.KeyEnter, tcell.KeyCtrlE:
|
||||
p.model.SetText(p.model.GetText())
|
||||
p.model.SetText(p.model.GetText(), "")
|
||||
p.model.SetActive(false)
|
||||
case tcell.KeyCtrlW, tcell.KeyCtrlU:
|
||||
p.model.ClearText(true)
|
||||
|
|
@ -155,7 +158,7 @@ func (p *Prompt) keyboard(evt *tcell.EventKey) *tcell.EventKey {
|
|||
}
|
||||
case tcell.KeyTab, tcell.KeyRight, tcell.KeyCtrlF:
|
||||
if s, ok := m.CurrentSuggestion(); ok {
|
||||
p.model.SetText(p.model.GetText() + s)
|
||||
p.model.SetText(p.model.GetText()+s, "")
|
||||
m.ClearSuggestions()
|
||||
}
|
||||
}
|
||||
|
|
@ -180,20 +183,13 @@ func (p *Prompt) InCmdMode() bool {
|
|||
|
||||
func (p *Prompt) activate() {
|
||||
p.SetCursorIndex(len(p.model.GetText()))
|
||||
p.write(p.model.GetText(), "")
|
||||
p.write(p.model.GetText(), p.model.GetSuggestion())
|
||||
p.model.Notify(false)
|
||||
}
|
||||
|
||||
func (p *Prompt) update(s string) {
|
||||
f := func() {
|
||||
p.Clear()
|
||||
p.write(s, "")
|
||||
}
|
||||
if p.app == nil {
|
||||
f()
|
||||
return
|
||||
}
|
||||
p.app.QueueUpdate(f)
|
||||
func (p *Prompt) update(text, suggestion string) {
|
||||
p.Clear()
|
||||
p.write(text, suggestion)
|
||||
}
|
||||
|
||||
func (p *Prompt) suggest(text, suggestion string) {
|
||||
|
|
@ -214,19 +210,18 @@ func (p *Prompt) write(text, suggest string) {
|
|||
// Event Listener protocol...
|
||||
|
||||
// BufferCompleted indicates input was accepted.
|
||||
func (p *Prompt) BufferCompleted(s string) {
|
||||
p.update(s)
|
||||
func (p *Prompt) BufferCompleted(text, suggestion string) {
|
||||
p.update(text, suggestion)
|
||||
}
|
||||
|
||||
// BufferChanged indicates the buffer was changed.
|
||||
func (p *Prompt) BufferChanged(s string) {
|
||||
p.update(s)
|
||||
func (p *Prompt) BufferChanged(text, suggestion string) {
|
||||
p.update(text, suggestion)
|
||||
}
|
||||
|
||||
// SuggestionChanged notifies the suggestion changed.
|
||||
func (p *Prompt) SuggestionChanged(text, sugg string) {
|
||||
p.Clear()
|
||||
p.write(text, sugg)
|
||||
func (p *Prompt) SuggestionChanged(text, suggestion string) {
|
||||
p.suggest(text, suggestion)
|
||||
}
|
||||
|
||||
// BufferActive indicates the buff activity changed.
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ func TestCmdUpdate(t *testing.T) {
|
|||
v.SetModel(model)
|
||||
|
||||
model.AddListener(v)
|
||||
model.SetText("blee")
|
||||
model.SetText("blee", "")
|
||||
model.Add('!')
|
||||
|
||||
assert.Equal(t, "\x00> [::b]blee!\n", v.GetText(false))
|
||||
|
|
|
|||
|
|
@ -59,10 +59,10 @@ type buffL struct {
|
|||
changed int
|
||||
}
|
||||
|
||||
func (b *buffL) BufferChanged(s string) {
|
||||
func (b *buffL) BufferChanged(_, _ string) {
|
||||
b.changed++
|
||||
}
|
||||
func (b *buffL) BufferCompleted(s string) {}
|
||||
func (b *buffL) BufferCompleted(_, _ string) {}
|
||||
|
||||
func (b *buffL) BufferActive(state bool, kind model.BufferKind) {
|
||||
b.active++
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ import (
|
|||
"github.com/derailed/k9s/internal/config"
|
||||
"github.com/derailed/k9s/internal/model"
|
||||
"github.com/derailed/k9s/internal/ui"
|
||||
"github.com/derailed/k9s/internal/ui/dialog"
|
||||
"github.com/derailed/k9s/internal/watch"
|
||||
"github.com/derailed/tview"
|
||||
"github.com/gdamore/tcell/v2"
|
||||
|
|
@ -567,10 +568,8 @@ func (a *App) gotoCmd(evt *tcell.EventKey) *tcell.EventKey {
|
|||
return evt
|
||||
}
|
||||
|
||||
func (a *App) meowCmd(msg string) {
|
||||
if err := a.inject(NewCow(a, msg)); err != nil {
|
||||
a.Flash().Err(err)
|
||||
}
|
||||
func (a *App) cowCmd(msg string) {
|
||||
dialog.ShowError(a.Styles.Dialog(), a.Content.Pages, msg)
|
||||
}
|
||||
|
||||
func (a *App) dirCmd(path string) error {
|
||||
|
|
@ -633,20 +632,14 @@ func (a *App) gotoResource(cmd, path string, clearStack bool) {
|
|||
return
|
||||
}
|
||||
|
||||
c := NewCow(a, err.Error())
|
||||
_ = c.Init(context.Background())
|
||||
if clearStack {
|
||||
a.Content.Stack.Clear()
|
||||
}
|
||||
a.Content.Push(c)
|
||||
dialog.ShowError(a.Styles.Dialog(), a.Content.Pages, err.Error())
|
||||
}
|
||||
|
||||
func (a *App) inject(c model.Component) error {
|
||||
ctx := context.WithValue(context.Background(), internal.KeyApp, a)
|
||||
if err := c.Init(ctx); err != nil {
|
||||
log.Error().Err(err).Msgf("component init failed for %q %v", c.Name(), err)
|
||||
c = NewCow(a, err.Error())
|
||||
_ = c.Init(ctx)
|
||||
dialog.ShowError(a.Styles.Dialog(), a.Content.Pages, err.Error())
|
||||
}
|
||||
a.Content.Push(c)
|
||||
|
||||
|
|
|
|||
|
|
@ -156,12 +156,12 @@ func (b *Browser) Stop() {
|
|||
}
|
||||
|
||||
// BufferChanged indicates the buffer was changed.
|
||||
func (b *Browser) BufferChanged(s string) {}
|
||||
func (b *Browser) BufferChanged(_, _ string) {}
|
||||
|
||||
// BufferCompleted indicates input was accepted.
|
||||
func (b *Browser) BufferCompleted(s string) {
|
||||
if ui.IsLabelSelector(s) {
|
||||
b.GetModel().SetLabelFilter(ui.TrimLabelSelector(s))
|
||||
func (b *Browser) BufferCompleted(text, _ string) {
|
||||
if ui.IsLabelSelector(text) {
|
||||
b.GetModel().SetLabelFilter(ui.TrimLabelSelector(text))
|
||||
} else {
|
||||
b.GetModel().SetLabelFilter("")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -176,8 +176,8 @@ func isContextCmd(c string) bool {
|
|||
func (c *Command) specialCmd(cmd, path string) bool {
|
||||
cmds := strings.Split(cmd, " ")
|
||||
switch cmds[0] {
|
||||
case "meow":
|
||||
c.app.meowCmd(path)
|
||||
case "cow":
|
||||
c.app.cowCmd(path)
|
||||
return true
|
||||
case "q", "Q", "quit":
|
||||
c.app.BailOut()
|
||||
|
|
|
|||
|
|
@ -107,11 +107,11 @@ func (d *Details) TextFiltered(lines []string, matches fuzzy.Matches) {
|
|||
}
|
||||
|
||||
// BufferChanged indicates the buffer was changed.
|
||||
func (d *Details) BufferChanged(s string) {}
|
||||
func (d *Details) BufferChanged(_, _ string) {}
|
||||
|
||||
// BufferCompleted indicates input was accepted.
|
||||
func (d *Details) BufferCompleted(s string) {
|
||||
d.model.Filter(s)
|
||||
func (d *Details) BufferCompleted(text, _ string) {
|
||||
d.model.Filter(text)
|
||||
d.updateTitle()
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -119,11 +119,11 @@ func (v *LiveView) ResourceChanged(lines []string, matches fuzzy.Matches) {
|
|||
}
|
||||
|
||||
// BufferChanged indicates the buffer was changed.
|
||||
func (v *LiveView) BufferChanged(s string) {}
|
||||
func (v *LiveView) BufferChanged(_, _ string) {}
|
||||
|
||||
// BufferCompleted indicates input was accepted.
|
||||
func (v *LiveView) BufferCompleted(s string) {
|
||||
v.model.Filter(s)
|
||||
func (v *LiveView) BufferCompleted(text, _ string) {
|
||||
v.model.Filter(text)
|
||||
}
|
||||
|
||||
// BufferActive indicates the buff activity changed.
|
||||
|
|
|
|||
|
|
@ -161,13 +161,13 @@ func (l *Log) LogChanged(lines [][]byte) {
|
|||
}
|
||||
|
||||
// BufferCompleted indicates input was accepted.
|
||||
func (l *Log) BufferCompleted(s string) {
|
||||
l.model.Filter(s)
|
||||
func (l *Log) BufferCompleted(text, _ string) {
|
||||
l.model.Filter(text)
|
||||
l.updateTitle()
|
||||
}
|
||||
|
||||
// BufferChanged indicates the buffer was changed.
|
||||
func (l *Log) BufferChanged(string) {}
|
||||
func (l *Log) BufferChanged(_, _ string) {}
|
||||
|
||||
// BufferActive indicates the buff activity changed.
|
||||
func (l *Log) BufferActive(state bool, k model.BufferKind) {
|
||||
|
|
|
|||
|
|
@ -56,10 +56,10 @@ func (l *Logger) Init(_ context.Context) error {
|
|||
}
|
||||
|
||||
// BufferChanged indicates the buffer was changed.
|
||||
func (l *Logger) BufferChanged(s string) {}
|
||||
func (l *Logger) BufferChanged(_, _ string) {}
|
||||
|
||||
// BufferCompleted indicates input was accepted.
|
||||
func (l *Logger) BufferCompleted(s string) {}
|
||||
func (l *Logger) BufferCompleted(_, _ string) {}
|
||||
|
||||
// BufferActive indicates the buff activity changed.
|
||||
func (l *Logger) BufferActive(state bool, k model.BufferKind) {
|
||||
|
|
|
|||
|
|
@ -322,10 +322,10 @@ func (s *Sanitizer) SetEnvFn(EnvFunc) {}
|
|||
func (s *Sanitizer) Refresh() {}
|
||||
|
||||
// BufferChanged indicates the buffer was changed.
|
||||
func (s *Sanitizer) BufferChanged(q string) {}
|
||||
func (s *Sanitizer) BufferChanged(_, _ string) {}
|
||||
|
||||
// BufferCompleted indicates input was accepted.
|
||||
func (s *Sanitizer) BufferCompleted(q string) {
|
||||
func (s *Sanitizer) BufferCompleted(_, _ string) {
|
||||
s.update(s.filter(s.model.Peek()))
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -151,14 +151,14 @@ func (t *Table) SetEnterFn(f EnterFunc) {
|
|||
func (t *Table) SetExtraActionsFn(BoostActionsFunc) {}
|
||||
|
||||
// BufferCompleted indicates input was accepted.
|
||||
func (t *Table) BufferCompleted(s string) {
|
||||
func (t *Table) BufferCompleted(text, _ string) {
|
||||
t.app.QueueUpdateDraw(func() {
|
||||
t.Filter(s)
|
||||
t.Filter(text)
|
||||
})
|
||||
}
|
||||
|
||||
// BufferChanged indicates the buffer was changed.
|
||||
func (t *Table) BufferChanged(s string) {}
|
||||
func (t *Table) BufferChanged(_, _ string) {}
|
||||
|
||||
// BufferActive indicates the buff activity changed.
|
||||
func (t *Table) BufferActive(state bool, k model.BufferKind) {
|
||||
|
|
|
|||
|
|
@ -67,7 +67,7 @@ func TestTableViewFilter(t *testing.T) {
|
|||
v.SetModel(&mockTableModel{})
|
||||
v.Refresh()
|
||||
v.CmdBuff().SetActive(true)
|
||||
v.CmdBuff().SetText("blee")
|
||||
v.CmdBuff().SetText("blee", "")
|
||||
|
||||
assert.Equal(t, 3, v.GetRowCount())
|
||||
}
|
||||
|
|
|
|||
|
|
@ -558,12 +558,12 @@ func (x *Xray) SetEnvFn(EnvFunc) {}
|
|||
func (x *Xray) Refresh() {}
|
||||
|
||||
// BufferCompleted indicates the buffer was changed.
|
||||
func (x *Xray) BufferCompleted(s string) {
|
||||
func (x *Xray) BufferCompleted(_, _ string) {
|
||||
x.update(x.filter(x.model.Peek()))
|
||||
}
|
||||
|
||||
// BufferChanged indicates the buffer was changed.
|
||||
func (x *Xray) BufferChanged(s string) {}
|
||||
func (x *Xray) BufferChanged(_, _ string) {}
|
||||
|
||||
// BufferActive indicates the buff activity changed.
|
||||
func (x *Xray) BufferActive(state bool, k model.BufferKind) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue