diff --git a/internal/app/app.go b/internal/app/app.go index 3a1834a..a726181 100644 --- a/internal/app/app.go +++ b/internal/app/app.go @@ -102,6 +102,9 @@ func (a *App) quit() { func (a *App) onInputCapture(event *tcell.EventKey) *tcell.EventKey { switch { + case keybind.Matches(event, a.cfg.Keybinds.Suspend.Keybind): + a.suspend() + return nil case keybind.Matches(event, a.cfg.Keybinds.Quit.Keybind): a.quit() return nil diff --git a/internal/app/suspend_default.go b/internal/app/suspend_default.go new file mode 100644 index 0000000..c020fba --- /dev/null +++ b/internal/app/suspend_default.go @@ -0,0 +1,5 @@ +//go:build !unix + +package app + +func (a *App) suspend() {} diff --git a/internal/app/suspend_unix.go b/internal/app/suspend_unix.go new file mode 100644 index 0000000..baff2d6 --- /dev/null +++ b/internal/app/suspend_unix.go @@ -0,0 +1,20 @@ +//go:build unix + +package app + +import ( + "os" + "os/signal" + "syscall" +) + +func (a *App) suspend() { + a.inner.Suspend(func() { + c := make(chan os.Signal, 1) + signal.Notify(c, syscall.SIGCONT) + defer signal.Stop(c) + + _ = syscall.Kill(0, syscall.SIGTSTP) + <-c + }) +} diff --git a/internal/config/config.toml b/internal/config/config.toml index 9433729..befded5 100644 --- a/internal/config/config.toml +++ b/internal/config/config.toml @@ -87,10 +87,11 @@ focus_previous = "ctrl+h" focus_next = "ctrl+l" # Hide/show the guilds tree. toggle_guilds_tree = "ctrl+b" -quit = "ctrl+c" # Log out and remove the authentication token from keyring. # Requires re-login upon restart. logout = "ctrl+d" +suspend = "ctrl+z" +quit = "ctrl+c" [keybinds.picker] toggle = "ctrl+k" @@ -152,6 +153,7 @@ send = "enter" cancel = "esc" # Complete usernames when mentioning tab_complete = "tab" +undo = "ctrl+u" open_editor = "ctrl+e" open_file_picker = "ctrl+\\" diff --git a/internal/config/keybinds.go b/internal/config/keybinds.go index 44711c4..4c39f5d 100644 --- a/internal/config/keybinds.go +++ b/internal/config/keybinds.go @@ -96,6 +96,7 @@ type MessageInputKeybinds struct { Send Keybind `toml:"send"` Cancel Keybind `toml:"cancel"` TabComplete Keybind `toml:"tab_complete"` + Undo Keybind `toml:"undo"` OpenEditor Keybind `toml:"open_editor"` OpenFilePicker Keybind `toml:"open_file_picker"` @@ -109,6 +110,7 @@ type Keybinds struct { ToggleGuildsTree Keybind `toml:"toggle_guilds_tree"` ToggleChannelsPicker Keybind `toml:"toggle_channels_picker"` ToggleHelp Keybind `toml:"toggle_help"` + Suspend Keybind `toml:"suspend"` FocusGuildsTree Keybind `toml:"focus_guilds_tree"` FocusMessagesList Keybind `toml:"focus_messages_list"` @@ -132,6 +134,7 @@ func defaultKeybinds() Keybinds { ToggleGuildsTree: newKeybind("ctrl+b", "toggle guilds"), ToggleChannelsPicker: newKeybind("ctrl+k", "channels picker"), ToggleHelp: newKeybind("ctrl+.", "help"), + Suspend: newKeybind("ctrl+z", "suspend"), FocusGuildsTree: newKeybind("ctrl+g", "guilds"), FocusMessagesList: newKeybind("ctrl+t", "messages"), @@ -198,6 +201,7 @@ func defaultKeybinds() Keybinds { Send: newKeybind("enter", "send"), Cancel: newKeybind("esc", "cancel"), TabComplete: newKeybind("tab", "complete"), + Undo: newKeybind("ctrl+u", "undo"), OpenEditor: newKeybind("ctrl+e", "editor"), OpenFilePicker: newKeybind("ctrl+\\", "attach"), }, diff --git a/internal/ui/chat/message_input.go b/internal/ui/chat/message_input.go index 16e03b0..02f62b7 100644 --- a/internal/ui/chat/message_input.go +++ b/internal/ui/chat/message_input.go @@ -126,6 +126,8 @@ func (mi *messageInput) onInputCapture(event *tcell.EventKey) *tcell.EventKey { case keybind.Matches(event, mi.cfg.Keybinds.MessageInput.TabComplete.Keybind): go mi.chatView.app.QueueUpdateDraw(func() { mi.tabComplete() }) return nil + case keybind.Matches(event, mi.cfg.Keybinds.MessageInput.Undo.Keybind): + return tcell.NewEventKey(tcell.KeyCtrlZ, "", tcell.ModNone) default: if mi.cfg.TypingIndicator.Send && mi.typingTimer == nil { mi.typingTimer = time.AfterFunc(typingDuration, func() { @@ -717,7 +719,7 @@ func (mi *messageInput) FullHelp() [][]keybind.Keybind { } return [][]keybind.Keybind{ - {cfg.Send.Keybind, cfg.Cancel.Keybind, cfg.TabComplete.Keybind}, + {cfg.Send.Keybind, cfg.Cancel.Keybind, cfg.TabComplete.Keybind, cfg.Undo.Keybind}, openEditor, } }