paste.go

  1package fsext
  2
  3import (
  4	"runtime"
  5	"strings"
  6)
  7
  8func PasteStringToPaths(s string) []string {
  9	switch runtime.GOOS {
 10	case "windows":
 11		return windowsPasteStringToPaths(s)
 12	default:
 13		return unixPasteStringToPaths(s)
 14	}
 15}
 16
 17func windowsPasteStringToPaths(s string) []string {
 18	if strings.TrimSpace(s) == "" {
 19		return nil
 20	}
 21
 22	var (
 23		paths    []string
 24		current  strings.Builder
 25		inQuotes = false
 26	)
 27	for i := range len(s) {
 28		ch := s[i]
 29
 30		switch {
 31		case ch == '"':
 32			if inQuotes {
 33				// End of quoted section
 34				if current.Len() > 0 {
 35					paths = append(paths, current.String())
 36					current.Reset()
 37				}
 38				inQuotes = false
 39			} else {
 40				// Start of quoted section
 41				inQuotes = true
 42			}
 43		case inQuotes:
 44			current.WriteByte(ch)
 45		}
 46		// Skip characters outside quotes and spaces between quoted sections
 47	}
 48
 49	// Add any remaining content if quotes were properly closed
 50	if current.Len() > 0 && !inQuotes {
 51		paths = append(paths, current.String())
 52	}
 53
 54	// If quotes were not closed, return empty (malformed input)
 55	if inQuotes {
 56		return nil
 57	}
 58
 59	return paths
 60}
 61
 62func unixPasteStringToPaths(s string) []string {
 63	if strings.TrimSpace(s) == "" {
 64		return nil
 65	}
 66
 67	var (
 68		paths   []string
 69		current strings.Builder
 70		escaped = false
 71	)
 72	for i := range len(s) {
 73		ch := s[i]
 74
 75		switch {
 76		case escaped:
 77			// After a backslash, add the character as-is (including space)
 78			current.WriteByte(ch)
 79			escaped = false
 80		case ch == '\\':
 81			// Check if this backslash is at the end of the string
 82			if i == len(s)-1 {
 83				// Trailing backslash, treat as literal
 84				current.WriteByte(ch)
 85			} else {
 86				// Start of escape sequence
 87				escaped = true
 88			}
 89		case ch == ' ':
 90			// Space separates paths (unless escaped)
 91			if current.Len() > 0 {
 92				paths = append(paths, current.String())
 93				current.Reset()
 94			}
 95		default:
 96			current.WriteByte(ch)
 97		}
 98	}
 99
100	// Handle trailing backslash if present
101	if escaped {
102		current.WriteByte('\\')
103	}
104
105	// Add the last path if any
106	if current.Len() > 0 {
107		paths = append(paths, current.String())
108	}
109
110	return paths
111}