diff options
| -rw-r--r-- | commands/msg/forward.go | 104 | ||||
| -rw-r--r-- | commands/msg/reply.go | 96 | 
2 files changed, 130 insertions, 70 deletions
| diff --git a/commands/msg/forward.go b/commands/msg/forward.go new file mode 100644 index 0000000..d7ecf66 --- /dev/null +++ b/commands/msg/forward.go @@ -0,0 +1,104 @@ +package msg + +import ( +	"bufio" +	"errors" +	"fmt" +	"git.sr.ht/~sircmpwn/aerc/widgets" +	"github.com/emersion/go-message" +	"github.com/emersion/go-message/mail" +	"io" +) + +type forward struct{} + +func init() { +	register(forward{}) +} + +func (_ forward) Aliases() []string { +	return []string{"forward"} +} + +func (_ forward) Complete(aerc *widgets.Aerc, args []string) []string { +	return nil +} + +func (_ forward) Execute(aerc *widgets.Aerc, args []string) error { +	if len(args) != 1 { +		return errors.New("Usage: forward") +	} + +	widget := aerc.SelectedTab().(widgets.ProvidesMessage) +	acct := widget.SelectedAccount() +	if acct == nil { +		return errors.New("No account selected") +	} +	store := widget.Store() +	if store == nil { +		return errors.New("Cannot perform action. Messages still loading") +	} +	msg, err := widget.SelectedMessage() +	if err != nil { +		return err +	} +	acct.Logger().Println("Forwarding email " + msg.Envelope.MessageId) + +	subject := "Fwd: " + msg.Envelope.Subject +	defaults := map[string]string{ +		"Subject": subject, +	} +	composer := widgets.NewComposer(aerc.Config(), acct.AccountConfig(), +		acct.Worker(), defaults) + +	addTab := func() { +		tab := aerc.NewTab(composer, subject) +		composer.OnHeaderChange("Subject", func(subject string) { +			if subject == "" { +				tab.Name = "New email" +			} else { +				tab.Name = subject +			} +			tab.Content.Invalidate() +		}) +	} + +	// TODO: something more intelligent than fetching the 1st part +	// TODO: add attachments! +	store.FetchBodyPart(msg.Uid, []int{1}, func(reader io.Reader) { +		header := message.Header{} +		header.SetText( +			"Content-Transfer-Encoding", msg.BodyStructure.Encoding) +		header.SetContentType( +			msg.BodyStructure.MIMEType, msg.BodyStructure.Params) +		header.SetText("Content-Description", msg.BodyStructure.Description) +		entity, err := message.New(header, reader) +		if err != nil { +			// TODO: Do something with the error +			addTab() +			return +		} +		mreader := mail.NewReader(entity) +		part, err := mreader.NextPart() +		if err != nil { +			// TODO: Do something with the error +			addTab() +			return +		} + +		pipeout, pipein := io.Pipe() +		scanner := bufio.NewScanner(part.Body) +		go composer.SetContents(pipeout) +		// TODO: Let user customize the date format used here +		io.WriteString(pipein, fmt.Sprintf("Forwarded message from %s on %s:\n\n", +			msg.Envelope.From[0].Name, +			msg.Envelope.Date.Format("Mon Jan 2, 2006 at 3:04 PM"))) +		for scanner.Scan() { +			io.WriteString(pipein, fmt.Sprintf("%s\n", scanner.Text())) +		} +		pipein.Close() +		pipeout.Close() +		addTab() +	}) +	return nil +} diff --git a/commands/msg/reply.go b/commands/msg/reply.go index 029cb42..bab16e1 100644 --- a/commands/msg/reply.go +++ b/commands/msg/reply.go @@ -24,7 +24,7 @@ func init() {  }  func (_ reply) Aliases() []string { -	return []string{"reply", "forward"} +	return []string{"reply"}  }  func (_ reply) Complete(aerc *widgets.Aerc, args []string) []string { @@ -103,14 +103,10 @@ func (_ reply) Execute(aerc *widgets.Aerc, args []string) error {  	}  	var subject string -	if args[0] == "forward" { -		subject = "Fwd: " + msg.Envelope.Subject +	if !strings.HasPrefix(msg.Envelope.Subject, "Re: ") { +		subject = "Re: " + msg.Envelope.Subject  	} else { -		if !strings.HasPrefix(msg.Envelope.Subject, "Re: ") { -			subject = "Re: " + msg.Envelope.Subject -		} else { -			subject = msg.Envelope.Subject -		} +		subject = msg.Envelope.Subject  	}  	defaults := map[string]string{ @@ -139,16 +135,25 @@ func (_ reply) Execute(aerc *widgets.Aerc, args []string) error {  		})  	} -	if args[0] == "forward" { -		// TODO: something more intelligent than fetching the 1st part -		// TODO: add attachments! -		store.FetchBodyPart(msg.Uid, []int{1}, func(reader io.Reader) { +	if quote { +		var ( +			path []int +			part *models.BodyStructure +		) +		if len(msg.BodyStructure.Parts) != 0 { +			part, path = findPlaintext(msg.BodyStructure, path) +		} +		if part == nil { +			part = msg.BodyStructure +			path = []int{1} +		} + +		store.FetchBodyPart(msg.Uid, path, func(reader io.Reader) {  			header := message.Header{}  			header.SetText( -				"Content-Transfer-Encoding", msg.BodyStructure.Encoding) -			header.SetContentType( -				msg.BodyStructure.MIMEType, msg.BodyStructure.Params) -			header.SetText("Content-Description", msg.BodyStructure.Description) +				"Content-Transfer-Encoding", part.Encoding) +			header.SetContentType(part.MIMEType, part.Params) +			header.SetText("Content-Description", part.Description)  			entity, err := message.New(header, reader)  			if err != nil {  				// TODO: Do something with the error @@ -167,67 +172,18 @@ func (_ reply) Execute(aerc *widgets.Aerc, args []string) error {  			scanner := bufio.NewScanner(part.Body)  			go composer.SetContents(pipeout)  			// TODO: Let user customize the date format used here -			io.WriteString(pipein, fmt.Sprintf("Forwarded message from %s on %s:\n\n", -				msg.Envelope.From[0].Name, -				msg.Envelope.Date.Format("Mon Jan 2, 2006 at 3:04 PM"))) +			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].Name))  			for scanner.Scan() { -				io.WriteString(pipein, fmt.Sprintf("%s\n", scanner.Text())) +				io.WriteString(pipein, fmt.Sprintf("> %s\n", scanner.Text()))  			}  			pipein.Close()  			pipeout.Close()  			addTab()  		})  	} else { -		if quote { -			var ( -				path []int -				part *models.BodyStructure -			) -			if len(msg.BodyStructure.Parts) != 0 { -				part, path = findPlaintext(msg.BodyStructure, path) -			} -			if part == nil { -				part = msg.BodyStructure -				path = []int{1} -			} - -			store.FetchBodyPart(msg.Uid, path, func(reader io.Reader) { -				header := message.Header{} -				header.SetText( -					"Content-Transfer-Encoding", part.Encoding) -				header.SetContentType(part.MIMEType, part.Params) -				header.SetText("Content-Description", part.Description) -				entity, err := message.New(header, reader) -				if err != nil { -					// TODO: Do something with the error -					addTab() -					return -				} -				mreader := mail.NewReader(entity) -				part, err := mreader.NextPart() -				if err != nil { -					// TODO: Do something with the error -					addTab() -					return -				} - -				pipeout, pipein := io.Pipe() -				scanner := bufio.NewScanner(part.Body) -				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].Name)) -				for scanner.Scan() { -					io.WriteString(pipein, fmt.Sprintf("> %s\n", scanner.Text())) -				} -				pipein.Close() -				pipeout.Close() -				addTab() -			}) -		} else { -			addTab() -		} +		addTab()  	}  	return nil | 
