about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorDrew DeVault <sir@cmpwn.com>2019-05-16 12:39:22 -0400
committerDrew DeVault <sir@cmpwn.com>2019-05-16 12:39:22 -0400
commit8be59cae6c133f38fa534df2dc9f79e6c7a810fb (patch)
tree5cda762c19856a2b2ebb65b12468b84c3fede483
parent475b697bdfd7a5821282174f14f8d904e47aff4d (diff)
downloadaerc-8be59cae6c133f38fa534df2dc9f79e6c7a810fb.tar.gz
Implement :reply -q and :reply -a
-rw-r--r--commands/account/reply.go80
-rw-r--r--go.mod1
-rw-r--r--go.sum2
-rw-r--r--widgets/compose.go9
4 files changed, 73 insertions, 19 deletions
diff --git a/commands/account/reply.go b/commands/account/reply.go
index d0d65a5..803c616 100644
--- a/commands/account/reply.go
+++ b/commands/account/reply.go
@@ -1,10 +1,13 @@
 package account
 
 import (
+	"bufio"
 	"errors"
 	"fmt"
+	"io"
 	"strings"
 
+	"git.sr.ht/~sircmpwn/getopt"
 	"github.com/emersion/go-imap"
 
 	"git.sr.ht/~sircmpwn/aerc2/widgets"
@@ -15,12 +18,28 @@ func init() {
 }
 
 func Reply(aerc *widgets.Aerc, args []string) error {
-	if len(args) != 1 {
+	opts, optind, err := getopt.Getopts(args[1:], "aq")
+	if err != nil {
+		return err
+	}
+	if optind != len(args) - 1 {
 		return errors.New("Usage: reply [-aq]")
 	}
-	// TODO: Reply all (w/ getopt)
+	var (
+		quote    bool
+		replyAll bool
+	)
+	for _, opt := range opts {
+		switch opt.Option {
+		case 'a':
+			replyAll = true
+		case 'q':
+			quote = true
+		}
+	}
 
 	acct := aerc.SelectedAccount()
+	store := acct.Messages().Store()
 	msg := acct.Messages().Selected()
 	acct.Logger().Println("Replying to email " + msg.Envelope.MessageId)
 
@@ -43,14 +62,15 @@ func Reply(aerc *widgets.Aerc, args []string) error {
 				addr.MailboxName, addr.HostName))
 		}
 	}
-	// TODO: Only if reply all
-	for _, addr := range msg.Envelope.Cc {
-		if addr.PersonalName != "" {
-			cc = append(cc, fmt.Sprintf("%s <%s@%s>",
-				addr.PersonalName, addr.MailboxName, addr.HostName))
-		} else {
-			cc = append(cc, fmt.Sprintf("<%s@%s>",
-				addr.MailboxName, addr.HostName))
+	if replyAll {
+		for _, addr := range msg.Envelope.Cc {
+			if addr.PersonalName != "" {
+				cc = append(cc, fmt.Sprintf("%s <%s@%s>",
+					addr.PersonalName, addr.MailboxName, addr.HostName))
+			} else {
+				cc = append(cc, fmt.Sprintf("<%s@%s>",
+					addr.MailboxName, addr.HostName))
+			}
 		}
 	}
 
@@ -66,16 +86,38 @@ func Reply(aerc *widgets.Aerc, args []string) error {
 		}).
 		FocusTerminal()
 
-	tab := aerc.NewTab(composer, subject)
+	addTab := func() {
+		tab := aerc.NewTab(composer, subject)
+		composer.OnSubjectChange(func(subject string) {
+			if subject == "" {
+				tab.Name = "New email"
+			} else {
+				tab.Name = subject
+			}
+			tab.Content.Invalidate()
+		})
+	}
 
-	composer.OnSubjectChange(func(subject string) {
-		if subject == "" {
-			tab.Name = "New email"
-		} else {
-			tab.Name = subject
-		}
-		tab.Content.Invalidate()
-	})
+	if quote {
+		// TODO: something more intelligent than fetching the 0th part
+		store.FetchBodyPart(msg.Uid, 0, func(reader io.Reader) {
+			pipeout, pipein := io.Pipe()
+			scanner := bufio.NewScanner(reader)
+			go composer.SetContents(pipeout)
+			// TODO: Let user customize the date format used here
+			io.WriteString(pipein, fmt.Sprintf("On %s %s wrote:\n",
+				msg.Envelope.Date.Format("Mon Jan 2, 2006 at 3:04 PM"),
+				msg.Envelope.From[0].PersonalName))
+			for scanner.Scan() {
+				io.WriteString(pipein, fmt.Sprintf("> %s\n",scanner.Text()))
+			}
+			pipein.Close()
+			pipeout.Close()
+			addTab()
+		})
+	} else {
+		addTab()
+	}
 
 	return nil
 }
diff --git a/go.mod b/go.mod
index f81ae62..68f355c 100644
--- a/go.mod
+++ b/go.mod
@@ -1,6 +1,7 @@
 module git.sr.ht/~sircmpwn/aerc2
 
 require (
+	git.sr.ht/~sircmpwn/getopt v0.0.0-20190214165041-9a4f886f9fc7
 	git.sr.ht/~sircmpwn/go-libvterm v0.0.0-20190421201021-3184f6f13687
 	git.sr.ht/~sircmpwn/pty v0.0.0-20190330154901-3a43678975a9
 	github.com/danwakefield/fnmatch v0.0.0-20160403171240-cbb64ac3d964
diff --git a/go.sum b/go.sum
index 8f497fe..48a1ca5 100644
--- a/go.sum
+++ b/go.sum
@@ -1,3 +1,5 @@
+git.sr.ht/~sircmpwn/getopt v0.0.0-20190214165041-9a4f886f9fc7 h1:xTFH5S/3ltiRvAtETLLDFWm5nVIouT5GeCPHm8UaVEU=
+git.sr.ht/~sircmpwn/getopt v0.0.0-20190214165041-9a4f886f9fc7/go.mod h1:wMEGFFFNuPos7vHmWXfszqImLppbc0wEhh6JBfJIUgw=
 git.sr.ht/~sircmpwn/go-libvterm v0.0.0-20190421201021-3184f6f13687 h1:hs5EqBs82PIYXaGC14RJJpDK6jnEjM0rSdy646TFlT0=
 git.sr.ht/~sircmpwn/go-libvterm v0.0.0-20190421201021-3184f6f13687/go.mod h1:cp37LbiS1y4CrTOmKSF87ZMLwawWUF612RYKTi8vbDc=
 git.sr.ht/~sircmpwn/pty v0.0.0-20190330154901-3a43678975a9 h1:WWPN5lf6KzXp3xWRrPQZ4MLR3yrFEI4Ysz7HSQ1G/yo=
diff --git a/widgets/compose.go b/widgets/compose.go
index 02a9d0c..14dfaaa 100644
--- a/widgets/compose.go
+++ b/widgets/compose.go
@@ -124,6 +124,15 @@ func (c *Composer) Defaults(defaults map[string]string) *Composer {
 	return c
 }
 
+// Note: this does not reload the editor. You must call this before the first
+// Draw() call.
+func (c *Composer) SetContents(reader io.Reader) *Composer {
+	c.email.Seek(0, os.SEEK_SET)
+	io.Copy(c.email, reader)
+	c.email.Seek(0, os.SEEK_SET)
+	return c
+}
+
 func (c *Composer) FocusTerminal() *Composer {
 	c.focusable[c.focused].Focus(false)
 	c.focused = 3