Repository: derailed/k9s
File: internal/view/browser.go (Go)

Code before:
	if err := pluginActions(b, b.Actions()); err != nil {
		log.Warn().Msgf("Plugins load failed: %s", err)
		b.app.Logo().Warn("Plugins load failed!")
	}
	if err := hotKeyActions(b, b.Actions()); err != nil {
		log.Warn().Msgf("Hotkeys load failed: %s", err)
		b.app.Logo().Warn("HotKeys load failed!")
	}
	b.app.Menu().HydrateMenu(b.Hints())
}

func (b *Browser) namespaceActions(aa *ui.KeyActions) {
	if !b.meta.Namespaced || b.GetTable().Path != "" {
		return
	}
	aa.Add(ui.KeyN, ui.NewKeyAction("Copy Namespace", b.cpNsCmd, false))

	b.namespaces = make(map[int]string, data.MaxFavoritesNS)
	aa.Add(ui.Key0, ui.NewKeyAction(client.NamespaceAll, b.switchNamespaceCmd, true))
	b.namespaces[0] = client.NamespaceAll
	index := 1
	for _, ns := range b.app.Config.FavNamespaces() {
		if ns == client.NamespaceAll {
			continue
		}
		numKey := ui.Key0 + tcell.Key(index)
		// no assumption is made about the length of FavNamespaces
		if numKey > ui.Key9 {
			break
		}
		aa.Add(numKey, ui.NewKeyAction(ns, b.switchNamespaceCmd, true))
		b.namespaces[index] = ns
		index++
	}
}

func (b *Browser) simpleDelete(selections []string, msg string) {
	dialog.ShowConfirm(b.app.Styles.Dialog(), b.app.Content.Pages, "Confirm Delete", msg, func() {
		b.ShowDeleted()
		if len(selections) > 1 {
			b.app.Flash().Infof("Delete %d marked %s", len(selections), b.GVR().R())
		} else {
			b.app.Flash().Infof("Delete resource %s %s", b.GVR(), selections[0])
		}
		for _, sel := range selections {
			nuker, ok := b.accessor.(dao.Nuker)
			if !ok {
				b.app.Flash().Errf("Invalid nuker %T", b.accessor)
				continue
			}
			if err := nuker.Delete(context.Background(), sel, nil, dao.DefaultGrace); err != nil {

Review comment (suggestion):
I think all we need here is to make sure the key is within the index range. 

```go
		if k, ok := ui.NumKeys[index]; ok {
			aa.Add(k, ui.NewKeyAction(ns, b.switchNamespaceCmd, true))
			b.namespaces[index] = ns
			index++
		} else {
			log.Warn().Msgf("No more keys available for namespace %s: %d of %d]. Skipping...", ns, index, data.MaxFavoritesNS)
		}
```

Code after:
	if err := pluginActions(b, b.Actions()); err != nil {
		log.Warn().Msgf("Plugins load failed: %s", err)
		b.app.Logo().Warn("Plugins load failed!")
	}
	if err := hotKeyActions(b, b.Actions()); err != nil {
		log.Warn().Msgf("Hotkeys load failed: %s", err)
		b.app.Logo().Warn("HotKeys load failed!")
	}
	b.app.Menu().HydrateMenu(b.Hints())
}

func (b *Browser) namespaceActions(aa *ui.KeyActions) {
	if !b.meta.Namespaced || b.GetTable().Path != "" {
		return
	}
	aa.Add(ui.KeyN, ui.NewKeyAction("Copy Namespace", b.cpNsCmd, false))

	b.namespaces = make(map[int]string, data.MaxFavoritesNS)
	aa.Add(ui.Key0, ui.NewKeyAction(client.NamespaceAll, b.switchNamespaceCmd, true))
	b.namespaces[0] = client.NamespaceAll
	index := 1
	favNamespaces := b.app.Config.FavNamespaces()
	for _, ns := range favNamespaces {
		if ns == client.NamespaceAll {
			continue
		}
		if numKey, ok := ui.NumKeys[index]; ok {
			aa.Add(numKey, ui.NewKeyAction(ns, b.switchNamespaceCmd, true))
			b.namespaces[index] = ns
			index++
		} else {
			log.Warn().Msgf("No number key available for favorite namespace %s (%d of %d). Skipping...", ns, index, len(favNamespaces))
			break
		}
	}
}

func (b *Browser) simpleDelete(selections []string, msg string) {
	dialog.ShowConfirm(b.app.Styles.Dialog(), b.app.Content.Pages, "Confirm Delete", msg, func() {
		b.ShowDeleted()
		if len(selections) > 1 {
			b.app.Flash().Infof("Delete %d marked %s", len(selections), b.GVR().R())
		} else {
			b.app.Flash().Infof("Delete resource %s %s", b.GVR(), selections[0])
		}
		for _, sel := range selections {
			nuker, ok := b.accessor.(dao.Nuker)
			if !ok {
				b.app.Flash().Errf("Invalid nuker %T", b.accessor)
				continue
			}