github.com/lmorg/murex@v0.0.0-20240217211045-e081c89cd4ef/utils/readline/tokenise.go (about) 1 package readline 2 3 import "strings" 4 5 func tokeniseLine(line []rune, linePos int) ([]string, int, int) { 6 if len(line) == 0 { 7 return nil, 0, 0 8 } 9 10 var adjust int 11 if linePos >= len(line) { 12 adjust = linePos - len(line) - 1 13 linePos = len(line) - 1 14 } 15 16 var index, pos int 17 var punc bool 18 19 split := make([]string, 1) 20 21 for i, r := range line { 22 switch { 23 case (r >= 33 && 47 >= r) || 24 (r >= 58 && 64 >= r) || 25 (r >= 91 && 94 >= r) || 26 r == 96 || 27 (r >= 123 && 126 >= r): 28 29 if i > 0 && line[i-1] != r { 30 split = append(split, "") 31 } 32 split[len(split)-1] += string(r) 33 punc = true 34 35 case r == ' ' || r == '\t': 36 split[len(split)-1] += string(r) 37 punc = true 38 39 default: 40 if punc { 41 split = append(split, "") 42 } 43 split[len(split)-1] += string(r) 44 punc = false 45 } 46 47 if i == linePos { 48 index = len(split) - 1 49 pos = len(split[index]) - 1 50 } 51 } 52 53 return split, index, pos - adjust 54 } 55 56 func tokeniseSplitSpaces(line []rune, linePos int) ([]string, int, int) { 57 if len(line) == 0 { 58 return nil, 0, 0 59 } 60 61 var index, pos int 62 split := make([]string, 1) 63 64 for i, r := range line { 65 switch { 66 case r == ' ' || r == '\t': 67 split[len(split)-1] += string(r) 68 69 default: 70 if i > 0 && (line[i-1] == ' ' || line[i-1] == '\t') { 71 split = append(split, "") 72 } 73 split[len(split)-1] += string(r) 74 } 75 76 if i == linePos { 77 index = len(split) - 1 78 pos = len(split[index]) - 1 79 } 80 } 81 82 return split, index, pos 83 } 84 85 func tokeniseBrackets(line []rune, linePos int) ([]string, int, int) { 86 var ( 87 open, close rune 88 split []string 89 count int 90 pos = make(map[int]int) 91 match int 92 single, double bool 93 ) 94 95 switch line[linePos] { 96 case '(', ')': 97 open = '(' 98 close = ')' 99 100 case '{', '[': 101 open = line[linePos] 102 close = line[linePos] + 2 103 104 case '}', ']': 105 open = line[linePos] - 2 106 close = line[linePos] 107 108 default: 109 return nil, 0, 0 110 } 111 112 for i := range line { 113 switch line[i] { 114 case '\'': 115 if !single { 116 double = !double 117 } 118 119 case '"': 120 if !double { 121 single = !single 122 } 123 124 case open: 125 if !single && !double { 126 count++ 127 pos[count] = i 128 if i == linePos { 129 match = count 130 split = []string{string(line[:i-1])} 131 } 132 133 } else if i == linePos { 134 return nil, 0, 0 135 } 136 137 case close: 138 if !single && !double { 139 if match == count { 140 split = append(split, string(line[pos[count]:i])) 141 return split, 1, 0 142 } 143 if i == linePos { 144 split = []string{ 145 string(line[:pos[count]-1]), 146 string(line[pos[count]:i]), 147 } 148 return split, 1, len(split[1]) 149 } 150 count-- 151 152 } else if i == linePos { 153 return nil, 0, 0 154 } 155 } 156 } 157 158 return nil, 0, 0 159 } 160 161 func rTrimWhiteSpace(oldString string) (newString string) { 162 return strings.TrimRight(oldString, " ") 163 // TODO: support tab chars 164 /* 165 newString = oldString 166 for len(oldString) > 0 { 167 if newString[len(newString)-1] == ' ' || newString[len(newString)-1] == '\t' { 168 newString = newString[:len(newString)-1] 169 } else { 170 break 171 } 172 } 173 return*/ 174 }