@@ -9,7 +9,9 @@ import (
11 "path/filepath"
11 "path/filepath"
15 "charm.land/bubbles/v2/help"
17 "charm.land/bubbles/v2/help"
@@ -1917,6 +1919,25 @@ func (m *UI) handlePasteMsg(msg tea.PasteMsg) tea.Cmd {
1917 return nil
1919 return nil
1922+ // If pasted text has more than 2 newlines, treat it as a file attachment.
1923+ if strings.Count(msg.Content, "\n") > 2 {
1924+ return func() tea.Msg {
1925+ content := []byte(msg.Content)
1926+ if int64(len(content)) > maxAttachmentSize {
1927+ return uiutil.ReportWarn("Paste is too big (>5mb)")
1929+ name := fmt.Sprintf("paste_%d.txt", m.pasteIdx())
1930+ mimeBufferSize := min(512, len(content))
1931+ mimeType := http.DetectContentType(content[:mimeBufferSize])
1932+ return message.Attachment{
1935+ MimeType: mimeType,
1920 var cmd tea.Cmd
1941 var cmd tea.Cmd
1921 path := strings.ReplaceAll(msg.Content, "\\ ", " ")
1942 path := strings.ReplaceAll(msg.Content, "\\ ", " ")
1922 // Try to get an image.
1943 // Try to get an image.
@@ -1966,6 +1987,23 @@ func (m *UI) handlePasteMsg(msg tea.PasteMsg) tea.Cmd {
1990+var pasteRE = regexp.MustCompile(`paste_(\d+).txt`)
1992+func (m *UI) pasteIdx() int {
1994+ for _, at := range m.attachments.List() {
1995+ found := pasteRE.FindStringSubmatch(at.FileName)
1996+ if len(found) == 0 {
1999+ idx, err := strconv.Atoi(found[1])
2001+ result = max(result, idx)
1969// renderLogo renders the Crush logo with the given styles and dimensions.
2007// renderLogo renders the Crush logo with the given styles and dimensions.
1970func renderLogo(t *styles.Styles, compact bool, width int) string {
2008func renderLogo(t *styles.Styles, compact bool, width int) string {
1971 return logo.Render(version.Version, compact, logo.Opts{
2009 return logo.Render(version.Version, compact, logo.Opts{