Add bell and command option to notify_on_cmd_finish
Instead of sending a desktop notification, it can be set to ring the terminal bell or run a user-specified command.
This commit is contained in:
parent
04506975e5
commit
a0d5f7a07b
6 changed files with 69 additions and 10 deletions
|
|
@ -1210,6 +1210,7 @@ class Screen:
|
|||
def current_pointer_shape(self) -> str: ...
|
||||
def change_pointer_shape(self, op: str, name: str) -> None: ...
|
||||
|
||||
def bell(self) -> None: ...
|
||||
|
||||
def set_tab_bar_render_data(
|
||||
os_window_id: int, screen: Screen, left: int, top: int, right: int, bottom: int
|
||||
|
|
|
|||
|
|
@ -3168,11 +3168,35 @@
|
|||
:code:`always`
|
||||
Always send a notification, regardless of window state.
|
||||
|
||||
Furthermore, you can set the minimum duration for what is considered a
|
||||
Furthermore, you can set two optional arguments:
|
||||
|
||||
1. The minimum duration for what is considered a
|
||||
long running command. The default is 5 seconds. Specify a second argument
|
||||
to set the duration. For example: :code:`invisible 15`.
|
||||
Do not set the value too small, otherwise a command that launches a new OS Window
|
||||
and exits will spam a notification.
|
||||
|
||||
2. The action to perform. The default is :code:`notify`. The possible values are:
|
||||
|
||||
:code:`notify`
|
||||
Send a desktop notification.
|
||||
|
||||
:code:`bell`
|
||||
Ring the terminal bell.
|
||||
|
||||
:code:`command`
|
||||
Run a custom command. All subsequent arguments are the cmdline to run.
|
||||
|
||||
Some more examples::
|
||||
|
||||
# Send a notification when a command takes more than 5 seconds in an unfocused window
|
||||
notify_on_cmd_finish unfocused
|
||||
# Send a notification when a command takes more than 10 seconds in a invisible window
|
||||
notify_on_cmd_finish invisible 10.0
|
||||
# Ring a bell when a command takes more than 10 seconds in a invisible window
|
||||
notify_on_cmd_finish invisible 10.0 bell
|
||||
# Run 'notify-send' when a command takes more than 10 seconds in a invisible window
|
||||
notify_on_cmd_finish invisible 10.0 command notify-send command finished
|
||||
'''
|
||||
)
|
||||
|
||||
|
|
|
|||
7
kitty/options/types.py
generated
7
kitty/options/types.py
generated
|
|
@ -8,7 +8,10 @@
|
|||
from kitty.fast_data_types import Color, SingleKey
|
||||
import kitty.fast_data_types
|
||||
import kitty.fonts
|
||||
from kitty.options.utils import AliasMap, KeyDefinition, KeyMap, MouseMap, MouseMapping, SequenceMap, TabBarMarginHeight
|
||||
from kitty.options.utils import (
|
||||
AliasMap, KeyDefinition, KeyMap, MouseMap, MouseMapping, NotifyOnCmdFinish, SequenceMap,
|
||||
TabBarMarginHeight
|
||||
)
|
||||
import kitty.options.utils
|
||||
from kitty.types import FloatEdges
|
||||
import kitty.types
|
||||
|
|
@ -546,7 +549,7 @@ class Options:
|
|||
mark3_background: Color = Color(242, 116, 188)
|
||||
mark3_foreground: Color = Color(0, 0, 0)
|
||||
mouse_hide_wait: float = 0.0 if is_macos else 3.0
|
||||
notify_on_cmd_finish: typing.Tuple[str, float] = ('never', 5.0)
|
||||
notify_on_cmd_finish: NotifyOnCmdFinish = NotifyOnCmdFinish(when='never', duration=5.0, action='notify', cmdline=[])
|
||||
open_url_with: typing.List[str] = ['default']
|
||||
paste_actions: typing.FrozenSet[str] = frozenset({'confirm', 'quote-urls-at-prompt'})
|
||||
placement_strategy: choices_for_placement_strategy = 'center'
|
||||
|
|
|
|||
|
|
@ -702,14 +702,32 @@ def active_tab_title_template(x: str) -> Optional[str]:
|
|||
return None if x == 'none' else x
|
||||
|
||||
|
||||
def notify_on_cmd_finish(x: str) -> Tuple[str, float]:
|
||||
class NotifyOnCmdFinish(NamedTuple):
|
||||
when: str
|
||||
duration: float
|
||||
action: str
|
||||
cmdline: List[str]
|
||||
|
||||
def notify_on_cmd_finish(x: str) -> NotifyOnCmdFinish:
|
||||
parts = x.split()
|
||||
if parts[0] not in ('never', 'unfocused', 'invisible', 'always'):
|
||||
raise ValueError(f'Unknown notify_on_cmd_finish value: {x}')
|
||||
raise ValueError(f'Unknown notify_on_cmd_finish value: {parts[0]}')
|
||||
when = parts[0]
|
||||
duration = 5.0
|
||||
if len(parts) > 1:
|
||||
duration = float(parts[1])
|
||||
return parts[0], duration
|
||||
action = 'notify'
|
||||
cmdline = []
|
||||
if len(parts) > 2:
|
||||
if parts[2] not in ('notify', 'bell', 'command'):
|
||||
raise ValueError(f'Unknown notify_on_cmd_finish action: {parts[2]}')
|
||||
action = parts[2]
|
||||
if action == 'command':
|
||||
if len(parts) > 3:
|
||||
cmdline = parts[3:]
|
||||
else:
|
||||
raise ValueError('notify_on_cmd_finish `command` action needs a command line')
|
||||
return NotifyOnCmdFinish(when, duration, action, cmdline)
|
||||
|
||||
|
||||
def config_or_absolute_path(x: str, env: Optional[Dict[str, str]] = None) -> Optional[str]:
|
||||
|
|
|
|||
|
|
@ -4519,6 +4519,7 @@ line_edge_colors(Screen *self, PyObject *a UNUSED) {
|
|||
}
|
||||
|
||||
WRAP0(update_only_line_graphics_data)
|
||||
WRAP0(bell)
|
||||
|
||||
|
||||
#define MND(name, args) {#name, (PyCFunction)name, args, #name},
|
||||
|
|
@ -4609,6 +4610,7 @@ static PyMethodDef methods[] = {
|
|||
MND(marked_cells, METH_NOARGS)
|
||||
MND(scroll_to_next_mark, METH_VARARGS)
|
||||
MND(update_only_line_graphics_data, METH_NOARGS)
|
||||
MND(bell, METH_NOARGS)
|
||||
{"select_graphic_rendition", (PyCFunction)_select_graphic_rendition, METH_VARARGS, ""},
|
||||
|
||||
{NULL} /* Sentinel */
|
||||
|
|
|
|||
|
|
@ -1339,15 +1339,26 @@ def cmd_output_marking(self, is_start: int) -> None:
|
|||
self.call_watchers(self.watchers.on_cmd_startstop, {"is_start": False, "time": end_time})
|
||||
|
||||
opts = get_options()
|
||||
mode, duration = opts.notify_on_cmd_finish
|
||||
when, duration, action, cmdline = opts.notify_on_cmd_finish
|
||||
|
||||
if last_cmd_output_duration >= duration and mode != 'never':
|
||||
if last_cmd_output_duration >= duration and when != 'never':
|
||||
cmd = NotificationCommand()
|
||||
cmd.title = 'kitty'
|
||||
cmd.body = 'Command finished in a background window.\nClick to focus.'
|
||||
cmd.actions = 'focus'
|
||||
cmd.only_when = OnlyWhen(mode)
|
||||
notify_with_command(cmd, self.id)
|
||||
cmd.only_when = OnlyWhen(when)
|
||||
if action == 'notify':
|
||||
notify_with_command(cmd, self.id)
|
||||
elif action == 'bell':
|
||||
def bell(title: str, body: str, identifier: str) -> None:
|
||||
self.screen.bell()
|
||||
notify_with_command(cmd, self.id, notify_implementation=bell)
|
||||
elif action == 'command':
|
||||
def run_command(title: str, body: str, identifier: str) -> None:
|
||||
open_cmd(cmdline)
|
||||
notify_with_command(cmd, self.id, notify_implementation=run_command)
|
||||
else:
|
||||
raise ValueError(f'Unknown action in option `notify_on_cmd_finish`: {action}')
|
||||
# }}}
|
||||
|
||||
# mouse actions {{{
|
||||
|
|
|
|||
Loading…
Reference in a new issue