aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNojus Gudinavičius <nojus.gudinavicius@gmail.com>2023-10-22 19:54:48 +0300
committerRobin Jarry <robin@jarry.cc>2023-10-24 22:55:40 +0200
commit4ceafd0b7b71bd934a0f15c1139ed74d0a518b70 (patch)
tree69a90cf7bff1b6b6c2db9f45ace3a66e0d8916ef
parentcbc43e891a8e7ada2c95bd4a2a161facb5156516 (diff)
downloadaerc-4ceafd0b7b71bd934a0f15c1139ed74d0a518b70.tar.gz
aerc-4ceafd0b7b71bd934a0f15c1139ed74d0a518b70.zip
commands: add :suspend
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 `<C-z>` by default. Signed-off-by: Nojus Gudinavičius <nojus.gudinavicius@gmail.com> Signed-off-by: Robin Jarry <robin@jarry.cc>
-rw-r--r--commands/suspend.go22
-rw-r--r--config/binds.conf1
-rw-r--r--doc/aerc.1.scd3
-rw-r--r--lib/ui/ui.go33
-rw-r--r--main.go5
5 files changed, 64 insertions, 0 deletions
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<Enter>
<C-c> = :prompt 'Quit?' quit<Enter>
<C-q> = :prompt 'Quit?' quit<Enter>
+<C-z> = :suspend<Enter>
[messages]
q = :prompt 'Quit?' quit<Enter>
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* _<key>_ _<text>_ _<command>_ [*-o* _<key>_ _<text>_ _<command>_]...
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 {