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  }