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 }