github.com/lmorg/murex@v0.0.0-20240217211045-e081c89cd4ef/shell/preview.go (about)

     1  package shell
     2  
     3  import (
     4  	"fmt"
     5  	"strings"
     6  
     7  	"github.com/lmorg/murex/utils/readline"
     8  )
     9  
    10  const binaryFile = "file contains binary data"
    11  
    12  func errBinaryFile(b byte) error {
    13  	return fmt.Errorf("%s: %d", binaryFile, b)
    14  }
    15  
    16  func previewParse(p []byte, size *readline.PreviewSizeT) ([]string, int, error) {
    17  	var (
    18  		lines []string
    19  		line  []byte
    20  		b     byte
    21  		i     = len(p)
    22  		last  byte
    23  	)
    24  
    25  	for j := 0; j <= i; j++ {
    26  		if j < i {
    27  			b = p[j]
    28  		} else {
    29  			b = ' '
    30  		}
    31  
    32  		if b == 8 {
    33  			// handle backspace gracefully
    34  			if len(line) > 0 {
    35  				line = line[:len(line)-1]
    36  			}
    37  			continue
    38  		}
    39  
    40  		if b < ' ' && b != '\t' && b != '\r' && b != '\n' {
    41  			return nil, 0, errBinaryFile(p[j])
    42  		}
    43  
    44  		switch b {
    45  		case '\r':
    46  			last = b
    47  			continue
    48  		case '\n':
    49  			if (len(line) == 0 && len(lines) > 0 && len(lines[len(lines)-1]) == size.Width) ||
    50  				last == '\r' {
    51  				last = b
    52  				continue
    53  			}
    54  			lines = append(lines, string(line))
    55  			line = []byte{}
    56  		case '\t':
    57  			line = append(line, ' ', ' ', ' ', ' ')
    58  		default:
    59  			line = append(line, b)
    60  		}
    61  
    62  		if len(line) >= size.Width {
    63  			lines = append(lines, string(line))
    64  			line = []byte{}
    65  		}
    66  		last = b
    67  	}
    68  
    69  	if len(line) > 0 {
    70  		lines = append(lines, string(line))
    71  	}
    72  
    73  	return lines, 0, nil
    74  }
    75  
    76  func previewPos(lines []string, item string) int {
    77  	for i := range lines {
    78  		switch {
    79  		case strings.HasPrefix(item, "--"):
    80  			switch {
    81  			case strings.Contains(lines[i], ", "+item):
    82  				// comma separated
    83  				return i
    84  			case strings.Contains(lines[i], "  "+item):
    85  				// whitespace separated
    86  				return i
    87  			default:
    88  				continue
    89  			}
    90  		default:
    91  			if strings.Contains(lines[i], "  "+item) {
    92  				return i
    93  			}
    94  		}
    95  	}
    96  
    97  	return 0
    98  }