From 1e83e6657d52c1a7746a6b9425861de1cf83ff28 Mon Sep 17 00:00:00 2001 From: Carlos Alexandro Becker Date: Fri, 9 Jan 2026 08:44:29 -0300 Subject: [PATCH] feat: paste as file (#1800) Signed-off-by: Carlos Alexandro Becker --- internal/ui/model/ui.go | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/internal/ui/model/ui.go b/internal/ui/model/ui.go index e3ea96b2f35eff10874bdc6b92dae410622ff4cf..98685e0a2128e938d1439e2ab78b2a84398cab6d 100644 --- a/internal/ui/model/ui.go +++ b/internal/ui/model/ui.go @@ -9,7 +9,9 @@ import ( "net/http" "os" "path/filepath" + "regexp" "slices" + "strconv" "strings" "charm.land/bubbles/v2/help" @@ -1917,6 +1919,25 @@ func (m *UI) handlePasteMsg(msg tea.PasteMsg) tea.Cmd { return nil } + // If pasted text has more than 2 newlines, treat it as a file attachment. + if strings.Count(msg.Content, "\n") > 2 { + return func() tea.Msg { + content := []byte(msg.Content) + if int64(len(content)) > maxAttachmentSize { + return uiutil.ReportWarn("Paste is too big (>5mb)") + } + name := fmt.Sprintf("paste_%d.txt", m.pasteIdx()) + mimeBufferSize := min(512, len(content)) + mimeType := http.DetectContentType(content[:mimeBufferSize]) + return message.Attachment{ + FileName: name, + FilePath: name, + MimeType: mimeType, + Content: content, + } + } + } + var cmd tea.Cmd path := strings.ReplaceAll(msg.Content, "\\ ", " ") // Try to get an image. @@ -1966,6 +1987,23 @@ func (m *UI) handlePasteMsg(msg tea.PasteMsg) tea.Cmd { } } +var pasteRE = regexp.MustCompile(`paste_(\d+).txt`) + +func (m *UI) pasteIdx() int { + result := 0 + for _, at := range m.attachments.List() { + found := pasteRE.FindStringSubmatch(at.FileName) + if len(found) == 0 { + continue + } + idx, err := strconv.Atoi(found[1]) + if err == nil { + result = max(result, idx) + } + } + return result + 1 +} + // renderLogo renders the Crush logo with the given styles and dimensions. func renderLogo(t *styles.Styles, compact bool, width int) string { return logo.Render(version.Version, compact, logo.Opts{