github.com/oam-dev/kubevela@v1.9.11/references/cli/top/view/yaml_view.go (about) 1 /* 2 Copyright 2022 The KubeVela Authors. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package view 18 19 import ( 20 "context" 21 "fmt" 22 "regexp" 23 "strings" 24 25 "github.com/gdamore/tcell/v2" 26 "github.com/rivo/tview" 27 28 "github.com/oam-dev/kubevela/references/cli/top/component" 29 "github.com/oam-dev/kubevela/references/cli/top/model" 30 ) 31 32 // YamlView is the resource yaml view, this view display info of yaml text of the resource 33 type YamlView struct { 34 *tview.TextView 35 app *App 36 actions model.KeyActions 37 ctx context.Context 38 } 39 40 var ( 41 keyValRX = regexp.MustCompile(`\A(\s*)([\w|\-|\.|\/|\s]+):\s(.+)\z`) 42 keyRX = regexp.MustCompile(`\A(\s*)([\w|\-|\.|\/|\s]+):\s*\z`) 43 yamlViewInstance = new(YamlView) 44 ) 45 46 const ( 47 yamlFullFmt = "%s[key::b]%s[colon::-]: [val::]%s" 48 yamlKeyFmt = "%s[key::b]%s[colon::-]:" 49 yamlValueFmt = "[val::]%s" 50 ) 51 52 // NewYamlView return a new yaml view 53 func NewYamlView(ctx context.Context, app *App) model.View { 54 yamlViewInstance.ctx = ctx 55 if yamlViewInstance.TextView == nil { 56 yamlViewInstance.TextView = tview.NewTextView() 57 yamlViewInstance.actions = make(model.KeyActions) 58 yamlViewInstance.app = app 59 } 60 return yamlViewInstance 61 } 62 63 // Init the yaml view 64 func (v *YamlView) Init() { 65 title := fmt.Sprintf("[ %s ]", v.Name()) 66 v.SetDynamicColors(true) 67 v.SetRegions(true) 68 v.SetBorder(true) 69 v.SetBorderAttributes(tcell.AttrItalic) 70 v.SetTitle(title).SetTitleColor(v.app.config.Theme.Table.Title.Color()) 71 v.bindKeys() 72 v.SetInputCapture(v.keyboard) 73 } 74 75 // Start the yaml view 76 func (v *YamlView) Start() { 77 v.Clear() 78 gvr, ok := v.ctx.Value(&model.CtxKeyGVR).(*model.GVR) 79 if ok { 80 obj, err := model.GetResourceObject(v.app.client, gvr) 81 if err != nil { 82 v.SetText(fmt.Sprintf("can't load the Yaml text of the resource!, because %s", err)) 83 return 84 } 85 yaml, err := model.ToYaml(obj) 86 if err != nil { 87 v.SetText(fmt.Sprintf("can't load the Yaml text of the resource!, because %s", err)) 88 return 89 } 90 yaml = v.HighlightText(yaml) 91 v.SetText(yaml) 92 } else { 93 v.SetText("can't load the Yaml text of the resource!") 94 } 95 } 96 97 // Stop the yaml view 98 func (v *YamlView) Stop() { 99 v.Clear() 100 } 101 102 // Name return the name of yaml view 103 func (v *YamlView) Name() string { 104 return "Yaml" 105 } 106 107 // Hint return the menu hints of yaml view 108 func (v *YamlView) Hint() []model.MenuHint { 109 return v.actions.Hint() 110 } 111 112 // HighlightText highlight the key, colon, value text of the yaml text 113 func (v *YamlView) HighlightText(yaml string) string { 114 lines := strings.Split(tview.Escape(yaml), "\n") 115 116 fullFmt := strings.Replace(yamlFullFmt, "[key", "["+v.app.config.Theme.Yaml.Key.String(), 1) 117 fullFmt = strings.Replace(fullFmt, "[colon", "["+v.app.config.Theme.Yaml.Colon.String(), 1) 118 fullFmt = strings.Replace(fullFmt, "[val", "["+v.app.config.Theme.Yaml.Value.String(), 1) 119 120 keyFmt := strings.Replace(yamlKeyFmt, "[key", "["+v.app.config.Theme.Yaml.Key.String(), 1) 121 keyFmt = strings.Replace(keyFmt, "[colon", "["+v.app.config.Theme.Yaml.Colon.String(), 1) 122 123 valFmt := strings.Replace(yamlValueFmt, "[val", "["+v.app.config.Theme.Yaml.Value.String(), 1) 124 125 buff := make([]string, 0, len(lines)) 126 for _, l := range lines { 127 res := keyValRX.FindStringSubmatch(l) 128 if len(res) == 4 { 129 buff = append(buff, fmt.Sprintf(fullFmt, res[1], res[2], res[3])) 130 continue 131 } 132 res = keyRX.FindStringSubmatch(l) 133 if len(res) == 3 { 134 buff = append(buff, fmt.Sprintf(keyFmt, res[1], res[2])) 135 continue 136 } 137 138 buff = append(buff, fmt.Sprintf(valFmt, l)) 139 } 140 141 return strings.Join(buff, "\n") 142 } 143 144 func (v *YamlView) keyboard(event *tcell.EventKey) *tcell.EventKey { 145 key := event.Key() 146 if key == tcell.KeyUp || key == tcell.KeyDown { 147 return event 148 } 149 if a, ok := v.actions[component.StandardizeKey(event)]; ok { 150 return a.Action(event) 151 } 152 return event 153 } 154 155 func (v *YamlView) bindKeys() { 156 v.actions.Delete([]tcell.Key{tcell.KeyEnter}) 157 v.actions.Add(model.KeyActions{ 158 component.KeyQ: model.KeyAction{Description: "Back", Action: v.app.Back, Visible: true, Shared: true}, 159 component.KeyHelp: model.KeyAction{Description: "Help", Action: v.app.helpView, Visible: true, Shared: true}, 160 }) 161 }