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  }