From 4ceafd0b7b71bd934a0f15c1139ed74d0a518b70 Mon Sep 17 00:00:00 2001 From: Nojus Gudinavičius Date: Sun, 22 Oct 2023 19:54:48 +0300 Subject: commands: add :suspend MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add :suspend to suspend the aerc process, returning to shell. Include documentation and default Ctrl-z keybinding for it. Changelog-added: New `:suspend` command bound to `` by default. Signed-off-by: Nojus Gudinavičius Signed-off-by: Robin Jarry --- commands/suspend.go | 22 ++++++++++++++++++++++ config/binds.conf | 1 + doc/aerc.1.scd | 3 +++ lib/ui/ui.go | 33 +++++++++++++++++++++++++++++++++ main.go | 5 +++++ 5 files changed, 64 insertions(+) create mode 100644 commands/suspend.go diff --git a/commands/suspend.go b/commands/suspend.go new file mode 100644 index 00000000..80d59028 --- /dev/null +++ b/commands/suspend.go @@ -0,0 +1,22 @@ +package commands + +import "git.sr.ht/~rjarry/aerc/lib/ui" + +type Suspend struct{} + +func init() { + register(Suspend{}) +} + +func (Suspend) Aliases() []string { + return []string{"suspend"} +} + +func (Suspend) Complete(args []string) []string { + return nil +} + +func (Suspend) Execute(args []string) error { + ui.QueueSuspend() + return nil +} diff --git a/config/binds.conf b/config/binds.conf index 1b0c42c2..c0e28af9 100644 --- a/config/binds.conf +++ b/config/binds.conf @@ -9,6 +9,7 @@ ? = :help keys = :prompt 'Quit?' quit = :prompt 'Quit?' quit + = :suspend [messages] q = :prompt 'Quit?' quit diff --git a/doc/aerc.1.scd b/doc/aerc.1.scd index a48735d7..8443302c 100644 --- a/doc/aerc.1.scd +++ b/doc/aerc.1.scd @@ -167,6 +167,9 @@ These commands work in any context. *:choose* *-o* __ __ __ [*-o* __ __ __]... Prompts the user to choose from various options. +*:suspend* + Suspends the aerc process. Some ongoing connections may be terminated. + *:quit* [*-f*]++ *:exit* [*-f*] Exits aerc. If a task is being performed that should not be interrupted diff --git a/lib/ui/ui.go b/lib/ui/ui.go index d2506b48..6a28eb9c 100644 --- a/lib/ui/ui.go +++ b/lib/ui/ui.go @@ -1,7 +1,10 @@ package ui import ( + "os" + "os/signal" "sync/atomic" + "syscall" "github.com/gdamore/tcell/v2" ) @@ -38,6 +41,8 @@ var state struct { screen tcell.Screen popover *Popover dirty uint32 // == 1 if render has been queued in Redraw channel + // == 1 if suspend is pending + suspending uint32 } func Initialize(content DrawableInteractive) error { @@ -79,6 +84,34 @@ func Exit() { close(Quit) } +var SuspendQueue = make(chan bool, 1) + +func QueueSuspend() { + if atomic.SwapUint32(&state.suspending, 1) != 1 { + SuspendQueue <- true + } +} + +func Suspend() error { + var err error + if atomic.SwapUint32(&state.suspending, 0) != 0 { + err = state.screen.Suspend() + if err == nil { + sigcont := make(chan os.Signal, 1) + signal.Notify(sigcont, syscall.SIGCONT) + err = syscall.Kill(0, syscall.SIGTSTP) + if err == nil { + <-sigcont + } + signal.Reset(syscall.SIGCONT) + err = state.screen.Resume() + state.content.Draw(state.ctx) + state.screen.Show() + } + } + return err +} + func Close() { state.screen.Fini() } diff --git a/main.go b/main.go index fe3a2e7b..d63c9eef 100644 --- a/main.go +++ b/main.go @@ -307,6 +307,11 @@ loop: callback() case <-ui.Redraw: ui.Render() + case <-ui.SuspendQueue: + err = ui.Suspend() + if err != nil { + app.PushError(fmt.Sprintf("suspend: %s", err)) + } case <-ui.Quit: err = app.CloseBackends() if err != nil { -- cgit v1.2.3-54-g00ecf