github.com/daidehu6831/wails/v2@v2.2.0/pkg/menu/keys/parser.go (about)

     1  package keys
     2  
     3  import (
     4  	"fmt"
     5  	"strconv"
     6  	"strings"
     7  
     8  	"github.com/leaanthony/slicer"
     9  )
    10  
    11  var namedKeys = slicer.String([]string{"backspace", "tab", "return", "enter", "escape", "left", "right", "up", "down", "space", "delete", "home", "end", "page up", "page down", "f1", "f2", "f3", "f4", "f5", "f6", "f7", "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15", "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23", "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31", "f32", "f33", "f34", "f35", "numlock"})
    12  
    13  func parseKey(key string) (string, bool) {
    14  
    15  	// Lowercase!
    16  	key = strings.ToLower(key)
    17  
    18  	// Check special case
    19  	if key == "plus" {
    20  		return "+", true
    21  	}
    22  
    23  	// Handle named keys
    24  	if namedKeys.Contains(key) {
    25  		return key, true
    26  	}
    27  
    28  	// Check we only have a single character
    29  	if len(key) != 1 {
    30  		return "", false
    31  	}
    32  
    33  	runeKey := rune(key[0])
    34  
    35  	// This may be too inclusive
    36  	if strconv.IsPrint(runeKey) {
    37  		return key, true
    38  	}
    39  
    40  	return "", false
    41  
    42  }
    43  
    44  func Parse(shortcut string) (*Accelerator, error) {
    45  
    46  	var result Accelerator
    47  
    48  	// Split the shortcut by +
    49  	components := strings.Split(shortcut, "+")
    50  
    51  	// If we only have one it should be a key
    52  	// We require components
    53  	if len(components) == 0 {
    54  		return nil, fmt.Errorf("no components given to validateComponents")
    55  	}
    56  
    57  	// Keep track of modifiers we have processed
    58  	var modifiersProcessed slicer.StringSlicer
    59  
    60  	// Check components
    61  	for index, component := range components {
    62  
    63  		// If last component
    64  		if index == len(components)-1 {
    65  			processedkey, validKey := parseKey(component)
    66  			if !validKey {
    67  				return nil, fmt.Errorf("'%s' is not a valid key", component)
    68  			}
    69  			result.Key = processedkey
    70  			continue
    71  		}
    72  
    73  		// Not last component - needs to be modifier
    74  		lowercaseComponent := strings.ToLower(component)
    75  		thisModifier, valid := modifierMap[lowercaseComponent]
    76  		if !valid {
    77  			return nil, fmt.Errorf("'%s' is not a valid modifier", component)
    78  		}
    79  		// Needs to be unique
    80  		if modifiersProcessed.Contains(lowercaseComponent) {
    81  			return nil, fmt.Errorf("Modifier '%s' is defined twice for shortcut: %s", component, shortcut)
    82  		}
    83  
    84  		// Save this data
    85  		result.Modifiers = append(result.Modifiers, thisModifier)
    86  		modifiersProcessed.Add(lowercaseComponent)
    87  	}
    88  
    89  	return &result, nil
    90  }