diff options
author | Nojus Gudinavičius <nojus.gudinavicius@gmail.com> | 2023-10-22 19:54:48 +0300 |
---|---|---|
committer | Robin Jarry <robin@jarry.cc> | 2023-10-24 22:55:40 +0200 |
commit | 4ceafd0b7b71bd934a0f15c1139ed74d0a518b70 (patch) | |
tree | 69a90cf7bff1b6b6c2db9f45ace3a66e0d8916ef | |
parent | cbc43e891a8e7ada2c95bd4a2a161facb5156516 (diff) | |
download | aerc-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.go | 22 | ||||
-rw-r--r-- | config/binds.conf | 1 | ||||
-rw-r--r-- | doc/aerc.1.scd | 3 | ||||
-rw-r--r-- | lib/ui/ui.go | 33 | ||||
-rw-r--r-- | main.go | 5 |
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() } @@ -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 { |