From 887ff6550d64aa0243192c922c977f41ce549e42 Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Sun, 26 May 2019 11:58:14 -0400 Subject: [PATCH] Implement :edit in compose screen --- Makefile | 8 ++++- commands/compose/edit.go | 21 +++++++++++ config/binds.conf | 1 + widgets/compose.go | 78 ++++++++++++++++++++++++++-------------- 4 files changed, 80 insertions(+), 28 deletions(-) create mode 100644 commands/compose/edit.go diff --git a/Makefile b/Makefile index 09ee192..0fb0217 100644 --- a/Makefile +++ b/Makefile @@ -8,11 +8,17 @@ GOFLAGS?= GOSRC := \ $(wildcard *.go) \ $(wildcard commands/*.go) \ - $(wildcard config/*.go) \ + $(wildcard commands/account/*.go) \ + $(wildcard commands/compose/*.go) \ + $(wildcard commands/msgview/*.go) \ + $(wildcard config/terminal/*.go) \ $(wildcard lib/*.go) \ + $(wildcard lib/ui/*.go) \ $(wildcard ui/*.go) \ $(wildcard widgets/*.go) \ $(wildcard worker/*.go) \ + $(wildcard worker/imap/*.go) \ + $(wildcard worker/types/*.go) \ go.mod go.sum aerc: $(GOSRC) diff --git a/commands/compose/edit.go b/commands/compose/edit.go new file mode 100644 index 0000000..18ba481 --- /dev/null +++ b/commands/compose/edit.go @@ -0,0 +1,21 @@ +package compose + +import ( + "errors" + + "git.sr.ht/~sircmpwn/aerc/widgets" +) + +func init() { + register("edit", CommandEdit) +} + +func CommandEdit(aerc *widgets.Aerc, args []string) error { + if len(args) != 1 { + return errors.New("Usage: edit") + } + composer, _ := aerc.SelectedTab().(*widgets.Composer) + composer.ShowTerminal() + composer.FocusTerminal() + return nil +} diff --git a/config/binds.conf b/config/binds.conf index 0c8c492..6a3ff23 100644 --- a/config/binds.conf +++ b/config/binds.conf @@ -72,6 +72,7 @@ $ex = # Keybindings used when reviewing a message to be sent y = :send n = :abort +q = :abort e = :edit a = :attach diff --git a/widgets/compose.go b/widgets/compose.go index 9de7f97..7daaf7b 100644 --- a/widgets/compose.go +++ b/widgets/compose.go @@ -27,7 +27,8 @@ type Composer struct { to *headerEditor } - config *config.AccountConfig + acct *config.AccountConfig + config *config.AercConfig defaults map[string]string editor *Terminal @@ -75,34 +76,22 @@ func NewComposer(conf *config.AercConfig, return nil } - editorName := conf.Compose.Editor - if editorName == "" { - editorName = os.Getenv("EDITOR") - } - if editorName == "" { - editorName = "vi" - } - editor := exec.Command(editorName, email.Name()) - term, _ := NewTerminal(editor) - grid.AddChild(headers).At(0, 0) - grid.AddChild(term).At(1, 0) c := &Composer{ - config: acct, - editor: term, + acct: acct, + config: conf, email: email, grid: grid, worker: worker, // You have to backtab to get to "From", since you usually don't edit it focused: 1, - focusable: []ui.DrawableInteractive{from, to, subject, term}, + focusable: []ui.DrawableInteractive{from, to, subject}, } c.headers.to = to c.headers.from = from c.headers.subject = subject - - term.OnClose = c.termClosed + c.ShowTerminal() return c } @@ -136,6 +125,9 @@ func (c *Composer) SetContents(reader io.Reader) *Composer { } func (c *Composer) FocusTerminal() *Composer { + if c.editor == nil { + return c + } c.focusable[c.focused].Focus(false) c.focused = 3 c.focusable[c.focused].Focus(true) @@ -194,7 +186,7 @@ func (c *Composer) Focus(focus bool) { } func (c *Composer) Config() *config.AccountConfig { - return c.config + return c.acct } func (c *Composer) Worker() *types.Worker { @@ -288,11 +280,36 @@ func (c *Composer) WriteMessage(header *mail.Header, writer io.Writer) error { } func (c *Composer) termClosed(err error) { - // TODO: do we care about that error (note: yes, we do) c.grid.RemoveChild(c.editor) - c.grid.AddChild(newReviewMessage(c)).At(1, 0) + c.review = newReviewMessage(c, err) + c.grid.AddChild(c.review).At(1, 0) c.editor.Destroy() c.editor = nil + c.focusable = c.focusable[:len(c.focusable)-1] + if c.focused >= len(c.focusable) { + c.focused = len(c.focusable) - 1 + } +} + +func (c *Composer) ShowTerminal() { + if c.editor != nil { + return + } + if c.review != nil { + c.grid.RemoveChild(c.review) + } + editorName := c.config.Compose.Editor + if editorName == "" { + editorName = os.Getenv("EDITOR") + } + if editorName == "" { + editorName = "vi" + } + editor := exec.Command(editorName, c.email.Name()) + c.editor, _ = NewTerminal(editor) // TODO: handle error + c.editor.OnClose = c.termClosed + c.grid.AddChild(c.editor).At(1, 0) + c.focusable = append(c.focusable, c.editor) } func (c *Composer) PrevField() { @@ -359,7 +376,7 @@ type reviewMessage struct { grid *ui.Grid } -func newReviewMessage(composer *Composer) *reviewMessage { +func newReviewMessage(composer *Composer, err error) *reviewMessage { grid := ui.NewGrid().Rows([]ui.GridSpec{ {ui.SIZE_EXACT, 2}, {ui.SIZE_EXACT, 1}, @@ -367,12 +384,19 @@ func newReviewMessage(composer *Composer) *reviewMessage { }).Columns([]ui.GridSpec{ {ui.SIZE_WEIGHT, 1}, }) - grid.AddChild(ui.NewText( - "Send this email? [y]es/[n]o/[e]dit/[a]ttach file")).At(0, 0) - grid.AddChild(ui.NewText("Attachments:"). - Reverse(true)).At(1, 0) - // TODO: Attachments - grid.AddChild(ui.NewText("(none)")).At(2, 0) + if err != nil { + grid.AddChild(ui.NewText(err.Error()). + Color(tcell.ColorRed, tcell.ColorDefault)) + grid.AddChild(ui.NewText("Press [q] to close this tab.")).At(1, 0) + } else { + // TODO: source this from actual keybindings? + grid.AddChild(ui.NewText( + "Send this email? [y]es/[n]o/[e]dit")).At(0, 0) + grid.AddChild(ui.NewText("Attachments:"). + Reverse(true)).At(1, 0) + // TODO: Attachments + grid.AddChild(ui.NewText("(none)")).At(2, 0) + } return &reviewMessage{ composer: composer,