From fbcc49d1ddeceb03f71d61691188d4960da61632 Mon Sep 17 00:00:00 2001 From: Tony Narlock Date: Sun, 13 Mar 2022 18:08:15 -0500 Subject: [PATCH 01/12] feat: Allow passing sleep_before / sleep_after to commands For those trying to get the timing of commands just right. --- tmuxp/workspacebuilder.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/tmuxp/workspacebuilder.py b/tmuxp/workspacebuilder.py index 3bb8f499702..4f085b1e15a 100644 --- a/tmuxp/workspacebuilder.py +++ b/tmuxp/workspacebuilder.py @@ -5,6 +5,7 @@ """ import logging +import time from libtmux.exc import TmuxSessionExists from libtmux.pane import Pane @@ -363,11 +364,21 @@ def get_pane_shell(): suppress = True enter = pconf.get("enter", True) + sleep_before = pconf.get("sleep_before", None) + sleep_after = pconf.get("sleep_after", None) for cmd in pconf["shell_command"]: enter = cmd.get("enter", enter) + sleep_before = cmd.get("sleep_before", sleep_before) + sleep_after = cmd.get("sleep_after", sleep_after) + + if sleep_before is not None: + time.sleep(sleep_before) p.send_keys(cmd["cmd"], suppress_history=suppress, enter=enter) + if sleep_after is not None: + time.sleep(sleep_after) + if "focus" in pconf and pconf["focus"]: w.select_pane(p["pane_id"]) From bd0c85fc087556d72a0b57ad0e668929063e4fcd Mon Sep 17 00:00:00 2001 From: Tony Narlock Date: Sat, 12 Mar 2022 16:46:25 -0600 Subject: [PATCH 02/12] test(workspacebuilder): sleep_before and sleep_after --- tests/test_workspacebuilder.py | 106 +++++++++++++++++++++++++++++++++ 1 file changed, 106 insertions(+) diff --git a/tests/test_workspacebuilder.py b/tests/test_workspacebuilder.py index 158f9f68751..933de7017c1 100644 --- a/tests/test_workspacebuilder.py +++ b/tests/test_workspacebuilder.py @@ -1021,3 +1021,109 @@ def test_load_workspace_enter( assert output in captured_pane else: assert output not in captured_pane + + +@pytest.mark.parametrize( + "yaml,sleep,output", + [ + [ + textwrap.dedent( + """ +session_name: Should not execute +windows: +- panes: + - shell_command: + - cmd: echo "___$((1 + 5))___" + sleep_before: 2 + - cmd: echo "___$((1 + 3))___" + sleep_before: 1 + """ + ), + 1.5, + "___4___", + ], + [ + textwrap.dedent( + """ +session_name: Should not execute +windows: +- panes: + - shell_command: + - cmd: echo "___$((1 + 5))___" + sleep_before: 2 + - cmd: echo "___$((1 + 3))___" + sleep_before: 1 + """ + ), + 3, + "___4___", + ], + [ + textwrap.dedent( + """ +session_name: Should not execute +windows: +- panes: + - shell_command: + - cmd: echo "___$((1 + 3))___" + sleep_before: 2 + """ + ), + 2, + "___4___", + ], + [ + textwrap.dedent( + """ +session_name: Should not execute +windows: +- panes: + - shell_command: + - cmd: echo "___$((1 + 3))___" + sleep_before: 2 + """ + ), + 2, + "___4___", + ], + ], + ids=[ + "command_level_sleep_3_shortform", + "command_level_pane_sleep_3_longform", + "pane_sleep_2_shortform", + "pane_sleep_2_longform", + ], +) +def test_load_workspace_sleep( + tmp_path: pathlib.Path, + server: libtmux.Server, + monkeypatch: pytest.MonkeyPatch, + yaml, + sleep: int, + output, +): + yaml_config = tmp_path / "simple.yaml" + yaml_config.write_text( + yaml, + encoding="utf-8", + ) + sconfig = kaptan.Kaptan(handler="yaml") + sconfig = sconfig.import_config(str(yaml_config)).get() + sconfig = config.expand(sconfig) + sconfig = config.trickle(sconfig) + builder = WorkspaceBuilder(sconf=sconfig, server=server) + builder.build() + + t = time.process_time() + + time.sleep(1) + session = builder.session + pane = session.attached_pane + + while (time.process_time() - t) * 1000 < sleep: + captured_pane = "\n".join(pane.capture_pane()) + + assert output not in captured_pane + time.sleep(0.1) + captured_pane = "\n".join(pane.capture_pane()) + assert output in captured_pane From 18f8bc465475af9f5c126c31e921308f2e68fbc1 Mon Sep 17 00:00:00 2001 From: Tony Narlock Date: Sun, 13 Mar 2022 18:27:43 -0500 Subject: [PATCH 03/12] docs(examples): Add pausing examples --- examples/sleep-pane-level.json | 27 +++++++++++++++++++++++++++ examples/sleep-pane-level.yaml | 13 +++++++++++++ examples/sleep.json | 28 ++++++++++++++++++++++++++++ examples/sleep.yaml | 16 ++++++++++++++++ 4 files changed, 84 insertions(+) create mode 100644 examples/sleep-pane-level.json create mode 100644 examples/sleep-pane-level.yaml create mode 100644 examples/sleep.json create mode 100644 examples/sleep.yaml diff --git a/examples/sleep-pane-level.json b/examples/sleep-pane-level.json new file mode 100644 index 00000000000..92daeeab77c --- /dev/null +++ b/examples/sleep-pane-level.json @@ -0,0 +1,27 @@ +{ + "session_name": "Pause / skip command execution (pane-level)", + "windows": [ + { + "panes": [ + { + "sleep_before": 2, + "shell_command": [ + "echo \"___$((11 + 1))___\"", + { + "cmd": "echo \"___$((1 + 3))___\"" + }, + { + "cmd": "echo \"___$((1 + 3))___\"" + }, + { + "cmd": "echo \"Stuff rendering here!\"" + }, + { + "cmd": "echo \"2 seconds later\"" + } + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/examples/sleep-pane-level.yaml b/examples/sleep-pane-level.yaml new file mode 100644 index 00000000000..eb64e0fd7ee --- /dev/null +++ b/examples/sleep-pane-level.yaml @@ -0,0 +1,13 @@ +session_name: Pause / skip command execution (pane-level) +windows: +- panes: + - + # Wait 2 seconds before sending all commands in this pane + sleep_before: 2 + shell_command: + - echo "___$((11 + 1))___" + - cmd: echo "___$((1 + 3))___" + - cmd: echo "___$((1 + 3))___" + - cmd: echo "Stuff rendering here!" + - cmd: echo "2 seconds later" + diff --git a/examples/sleep.json b/examples/sleep.json new file mode 100644 index 00000000000..2136cab086f --- /dev/null +++ b/examples/sleep.json @@ -0,0 +1,28 @@ +{ + "session_name": "Pause / skip command execution (command-level)", + "windows": [ + { + "panes": [ + { + "shell_command": [ + "echo \"___$((11 + 1))___\"", + { + "cmd": "echo \"___$((1 + 3))___\"", + "sleep_before": 2 + }, + { + "cmd": "echo \"___$((1 + 3))___\"" + }, + { + "cmd": "echo \"Stuff rendering here!\"", + "sleep_after": 2 + }, + { + "cmd": "echo \"2 seconds later\"" + } + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/examples/sleep.yaml b/examples/sleep.yaml new file mode 100644 index 00000000000..ae90586b7ae --- /dev/null +++ b/examples/sleep.yaml @@ -0,0 +1,16 @@ +session_name: Pause / skip command execution (command-level) +windows: +- panes: + - shell_command: + # Executes immediately + - echo "___$((11 + 1))___" + # Delays before sending 2 seconds + - cmd: echo "___$((1 + 3))___" + sleep_before: 2 + # Executes immediately + - cmd: echo "___$((1 + 3))___" + # Pauses 2 seconds after + - cmd: echo "Stuff rendering here!" + sleep_after: 2 + # Executes after earlier commands (after 2 sec) + - cmd: echo "2 seconds later" From 87dec20ffb2fc5d512946062ae8b7baa061185de Mon Sep 17 00:00:00 2001 From: Tony Narlock Date: Sun, 13 Mar 2022 18:27:56 -0500 Subject: [PATCH 04/12] docs(examples): Add examples to page --- docs/examples.md | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/docs/examples.md b/docs/examples.md index 70c8ba3c4a4..268190b018f 100644 --- a/docs/examples.md +++ b/docs/examples.md @@ -375,6 +375,50 @@ Omit sending {kbd}`enter` to key commands. Equivalent to ```` +## Pausing commands + +```{versionadded} 1.10.0b4 +`sleep_before` and `sleep_after` options added. Pane and command-level support. +``` + +Omit sending {kbd}`enter` to key commands. Equivalent to having +a [`time.sleep`](time.sleep) before and after [`send_keys`](libtmux.Pane.send_keys). + +````{tab} YAML + +```{literalinclude} ../examples/sleep.yaml +:language: yaml + +``` + +```` + +````{tab} JSON + +```{literalinclude} ../examples/sleep.json +:language: json + +``` + +```` + +````{tab} YAML (pane-level) + +```{literalinclude} ../examples/sleep-pane-level.yaml +:language: yaml + +``` + +```` + +````{tab} JSON (pane-level) + +```{literalinclude} ../examples/sleep-pane-level.json +:language: json + +``` + +```` ## Window Index From 06a85102758e17254581d18d65fb4cd07295d405 Mon Sep 17 00:00:00 2001 From: Tony Narlock Date: Sun, 13 Mar 2022 18:28:06 -0500 Subject: [PATCH 05/12] docs(CHANGES): Update for pausing --- CHANGES | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/CHANGES b/CHANGES index 03d66a7bd20..be470b649de 100644 --- a/CHANGES +++ b/CHANGES @@ -22,6 +22,27 @@ enter: false ``` +- #750: Pause execution via `sleep_before: [int]` and `sleep_after: [int]` + + ```yaml + session_name: Pause / skip command execution (command-level) + windows: + - panes: + - shell_command: + # Executes immediately + - echo "___$((11 + 1))___" + # Delays before sending 2 seconds + - cmd: echo "___$((1 + 3))___" + sleep_before: 2 + # Executes immediately + - cmd: echo "___$((1 + 3))___" + # Pauses 2 seconds after + - cmd: echo "Stuff rendering here!" + sleep_after: 2 + # Executes after earlier commands (after 2 sec) + - cmd: echo "2 seconds later" + ``` + - #701: `tmuxp freeze` now accepts `--quiet` and `--yes` along with the `--config-format` and filename (`--save-to`). This means you can do it all in one command: From f63cf6dae91099cc20585611ce20a8b4e312ce13 Mon Sep 17 00:00:00 2001 From: Tony Narlock Date: Sun, 13 Mar 2022 18:28:56 -0500 Subject: [PATCH 06/12] docs: Fix typo in skip command execution --- docs/examples.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/examples.md b/docs/examples.md index 268190b018f..f1714689091 100644 --- a/docs/examples.md +++ b/docs/examples.md @@ -332,6 +332,8 @@ This will add the `shell_command` to the bash history in the pane. ```{versionadded} 1.10.0b1 `enter: false` option. Pane-level support. +``` + ```{versionadded} 1.10.0b3 Support command-level skipping. ``` From e04360854bceffc0c2daf6b53c10157663ee63c8 Mon Sep 17 00:00:00 2001 From: Tony Narlock Date: Sun, 13 Mar 2022 18:30:24 -0500 Subject: [PATCH 07/12] docs(examples): Synchronize titles --- examples/skip-send-pane-level.json | 4 ++-- examples/skip-send-pane-level.yaml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/skip-send-pane-level.json b/examples/skip-send-pane-level.json index 43a88fa2999..2fa8a2535ce 100644 --- a/examples/skip-send-pane-level.json +++ b/examples/skip-send-pane-level.json @@ -1,5 +1,5 @@ { - "session_name": "Skip all pane commands", + "session_name": "Skip command execution (pane-level)", "windows": [ { "panes": [ @@ -17,4 +17,4 @@ ] } ] -} \ No newline at end of file +} diff --git a/examples/skip-send-pane-level.yaml b/examples/skip-send-pane-level.yaml index cbc9d77ebbf..03628f76918 100644 --- a/examples/skip-send-pane-level.yaml +++ b/examples/skip-send-pane-level.yaml @@ -1,4 +1,4 @@ -session_name: Skip all pane commands +session_name: Skip command execution (pane-level) windows: - panes: - shell_command: echo "___$((1 + 3))___" From f59c57aff3e4c444c16a191d423be62ca066d326 Mon Sep 17 00:00:00 2001 From: Tony Narlock Date: Sun, 13 Mar 2022 19:08:47 -0500 Subject: [PATCH 08/12] tests(sleep): Test shell_command_before --- tests/test_workspacebuilder.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/tests/test_workspacebuilder.py b/tests/test_workspacebuilder.py index 933de7017c1..c22998d80e9 100644 --- a/tests/test_workspacebuilder.py +++ b/tests/test_workspacebuilder.py @@ -1081,6 +1081,21 @@ def test_load_workspace_enter( - shell_command: - cmd: echo "___$((1 + 3))___" sleep_before: 2 + """ + ), + 2, + "___4___", + ], + [ + textwrap.dedent( + """ +session_name: Should not execute +shell_command_before: + - cmd: echo "sleeping before" + sleep_before: 2 +windows: +- panes: + - echo "___$((1 + 3))___" """ ), 2, @@ -1092,6 +1107,7 @@ def test_load_workspace_enter( "command_level_pane_sleep_3_longform", "pane_sleep_2_shortform", "pane_sleep_2_longform", + "shell_before_before_command_level", ], ) def test_load_workspace_sleep( From 05918f8deeb7e17c7bf1d1537b4f9f9aaca487aa Mon Sep 17 00:00:00 2001 From: Tony Narlock Date: Sun, 13 Mar 2022 19:11:49 -0500 Subject: [PATCH 09/12] tests(sleep): 3 reruns --- tests/test_workspacebuilder.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/test_workspacebuilder.py b/tests/test_workspacebuilder.py index c22998d80e9..fdcf63c3e9f 100644 --- a/tests/test_workspacebuilder.py +++ b/tests/test_workspacebuilder.py @@ -1110,6 +1110,7 @@ def test_load_workspace_enter( "shell_before_before_command_level", ], ) +@pytest.mark.flaky(reruns=3) def test_load_workspace_sleep( tmp_path: pathlib.Path, server: libtmux.Server, From 98717d736ca0548100065ea933e9e3b2cfc7b949 Mon Sep 17 00:00:00 2001 From: Tony Narlock Date: Sun, 13 Mar 2022 19:15:54 -0500 Subject: [PATCH 10/12] docs(sleep): Add virtualenv example --- examples/sleep-virtualenv.yaml | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 examples/sleep-virtualenv.yaml diff --git a/examples/sleep-virtualenv.yaml b/examples/sleep-virtualenv.yaml new file mode 100644 index 00000000000..5370fa34c70 --- /dev/null +++ b/examples/sleep-virtualenv.yaml @@ -0,0 +1,11 @@ +session_name: virtualenv +shell_command_before: +# - cmd: source $(poetry env info --path)/bin/activate +# - cmd: source `pipenv --venv`/bin/activate +- cmd: source .venv/bin/activate + sleep_before: 1 + sleep_after: 1 +windows: +- panes: + - shell_command: + - ./manage.py runserver From e841edbc657e9f5958098a9698b89f622239824e Mon Sep 17 00:00:00 2001 From: Tony Narlock Date: Sun, 13 Mar 2022 19:25:27 -0500 Subject: [PATCH 11/12] docs(example): Add virtualenv + sleep example --- docs/examples.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/docs/examples.md b/docs/examples.md index f1714689091..23b72d15189 100644 --- a/docs/examples.md +++ b/docs/examples.md @@ -386,6 +386,16 @@ Omit sending {kbd}`enter` to key commands. Equivalent to Omit sending {kbd}`enter` to key commands. Equivalent to having a [`time.sleep`](time.sleep) before and after [`send_keys`](libtmux.Pane.send_keys). +This is especially useful for expensive commands where the terminal needs some breathing room (virtualenv, poetry, pipenv, sourcing a configuration, launching a tui app, etc). + +````{tab} Virtualenv + +```{literalinclude} ../examples/sleep-virtualenv.yaml +:language: yaml + +``` +```` + ````{tab} YAML ```{literalinclude} ../examples/sleep.yaml From 89bfa9ea11d77dd23603d34aeec160354d728e46 Mon Sep 17 00:00:00 2001 From: Tony Narlock Date: Sun, 13 Mar 2022 19:33:24 -0500 Subject: [PATCH 12/12] docs(sleep): Add note about it being blocking --- docs/examples.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/examples.md b/docs/examples.md index 23b72d15189..e84376744fb 100644 --- a/docs/examples.md +++ b/docs/examples.md @@ -383,6 +383,10 @@ Omit sending {kbd}`enter` to key commands. Equivalent to `sleep_before` and `sleep_after` options added. Pane and command-level support. ``` +```{warning} +This will delay loading as it runs synchronously for each pane. In future version asynchronous support, (i.e. [`asyncio`](asyncio)) will speed up this up. +``` + Omit sending {kbd}`enter` to key commands. Equivalent to having a [`time.sleep`](time.sleep) before and after [`send_keys`](libtmux.Pane.send_keys).