8000 Implements `if` conditions for pane and window by soraxas · Pull Request #942 · tmux-python/tmuxp · GitHub
[go: up one dir, main page]

Skip to content

Implements if conditions for pane and window #942

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 10 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
support shell expression and python statements
Signed-off-by: Tin Lai <tin@tinyiu.com>
  • Loading branch information
soraxas committed Jul 22, 2024
commit e95fda969d2bcd4f5d789cb28e9aaf2c5315bdbc
17 changes: 9 additions & 8 deletions examples/if-conditions.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,25 +5,26 @@ environment:
windows:
# the following would not shows up as it evaluates to false
- window_name: window 1 ${ha} $Foo
if:
shell: ${Foo}
if: ${Foo}
panes:
- shell_command:
- echo "this shouldn't shows up"
- echo neither should this $Foo
- window_name: window 2
panes:
# should not shows up
# should not shows up; using shell expression
- if:
python: 1+1==3
shell: '[ 5 -lt 4 ]'
shell_command:
- echo the above is a false statement
# no if conditions
- shell_command:
- echo no condition
# python conditions
- if:
python: import os; os.path.isdir('${PWD}')
shell_command:
- echo "checking for PWD (${PWD}) is a directory in python"
- python -m http.server
# display by default, but can be disabled by running `show_htop=false tmuxp load .....`
- if: ${show_htop}
shell_command:
- echo the above is a true statement (by default), but can be disabled on-demand
- echo "the above is a true statement (by default), but can be disabled on-demand"
- htop
30 changes: 18 additions & 12 deletions src/tmuxp/workspace/loader.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import logging
import os
import pathlib
import subprocess
import typing as t

logger = logging.getLogger(__name__)
Expand All @@ -16,9 +17,10 @@ def optional_windows_and_pane(
The function evaluates the 'if' condition specified in `workspace_dict` to determine inclusion:
- If 'if' key is not present, it defaults to True.
- If 'if' is a string or boolean, it's treated as a shell variable.
- 'if' can be a dictionary containing 'shell' or 'python' keys with valid expressions.
- 'shell' expressions are expanded and checked against true values ('y', 'yes', '1', 'on', 'true', 't').
- 'python' expressions are evaluated using `eval()`
- 'if' can be a dictionary containing 'shell', 'shell_var' or 'python' keys with valid expressions.
- 'shell_var' expressions are expanded and checked against true values ('y', 'yes', '1', 'on', 'true', 't').
- 'shell' expressions are evaluated using subprocess
- 'python' expressions are evaluated using `exec()`

Parameters
----------
Expand All @@ -35,18 +37,22 @@ def optional_windows_and_pane(
if_cond = workspace_dict["if"]
if isinstance(if_cond, (str, bool)):
# treat this as shell variable
if_cond = {"shell": if_cond}
if not isinstance(if_cond, dict) or not ("shell" in if_cond or "python" in if_cond):
if_cond = {"shell_var": if_cond}
if not isinstance(if_cond, dict) or not any(predicate in if_cond for predicate in ("python", "shell", "shell_var")):
raise ValueError(f"if conditions does not contains valid expression: {if_cond}")
if "shell_var" in if_cond:
if expandshell(str(if_cond["shell_var"])).lower() not in ("y", "yes", "1", "on", "true", "t"):
return False
if "shell" in if_cond:
if isinstance(if_cond["shell"], str):
if expandshell(if_cond["shell"]).lower() not in ("y", "yes", "1", "on", "true", "t"):
return False
elif isinstance(if_cond["shell"], bool):
if not if_cond["shell"]:
return False
if subprocess.run(if_cond["shell"], shell=True).returncode != 0:
return False
if "python" in if_cond:
if if_cond["python"] and not eval(if_cond["python"]): # dangerous
# assign the result of the last statement from the python snippet
py_statements = if_cond["python"].split(";")
py_statements[-1] = f"ret={py_statements[-1]}"
locals = {}
exec(";".join(py_statements), {}, locals)
if not locals['ret']:
return False
return True

Expand Down
0