|
8 | 8 | logger = logging.getLogger(__name__)
|
9 | 9 |
|
10 | 10 |
|
| 11 | +def optional_windows_and_pane( |
| 12 | + workspace_dict: t.Dict[str, t.Any], |
| 13 | +) -> bool: |
| 14 | + """Determine if a window or pane should be included based on `if` conditions. |
| 15 | +
|
| 16 | + The function evaluates the 'if' condition specified in `workspace_dict` to determine inclusion: |
| 17 | + - If 'if' key is not present, it defaults to True. |
| 18 | + - If 'if' is a string or boolean, it's treated as a shell variable. |
| 19 | + - 'if' can be a dictionary containing 'shell' or 'python' keys with valid expressions. |
| 20 | + - 'shell' expressions are expanded and checked against true values ('y', 'yes', '1', 'on', 'true', 't'). |
| 21 | + - 'python' expressions are evaluated using `eval()` |
| 22 | +
|
| 23 | + Parameters |
| 24 | + ---------- |
| 25 | + workspace_dict : Dict |
| 26 | + A dictionary containing pane/window configuration data. |
| 27 | +
|
| 28 | + Returns |
| 29 | + ------- |
| 30 | + bool |
| 31 | + True if the window or pane should be included, False otherwise. |
| 32 | + """ |
| 33 | + if "if" not in workspace_dict: |
| 34 | + return True |
| 35 | + if_cond = workspace_dict["if"] |
| 36 | + if isinstance(if_cond, (str, bool)): |
| 37 | + # treat this as shell variable |
| 38 | + if_cond = {"shell": if_cond} |
| 39 | + if not isinstance(if_cond, dict) or not ("shell" in if_cond or "python" in if_cond): |
| 40 | + raise ValueError(f"if conditions does not contains valid expression: {if_cond}") |
| 41 | + if "shell" in if_cond: |
| 42 | + if isinstance(if_cond["shell"], str): |
| 43 | + if expandshell(if_cond["shell"]).lower() not in ("y", "yes", "1", "on", "true", "t"): |
| 44 | + return False |
| 45 | + elif isinstance(if_cond["shell"], bool): |
| 46 | + if not if_cond["shell"]: |
| 47 | + return False |
| 48 | + if "python" in if_cond: |
| 49 | + if if_cond["python"] and not eval(if_cond["python"]): # dangerous |
| 50 | + return False |
| 51 | + return True |
| 52 | + |
| 53 | + |
11 | 54 | def expandshell(value: str) -> str:
|
12 | 55 | """Resolve shell variables based on user's ``$HOME`` and ``env``.
|
13 | 56 |
|
@@ -170,18 +213,21 @@ def expand(
|
170 | 213 |
|
171 | 214 | # recurse into window and pane workspace items
|
172 | 215 | if "windows" in workspace_dict:
|
173 |
| - workspace_dict["windows"] = [ |
174 |
| - expand(window, parent=workspace_dict) |
175 |
| - for window in workspace_dict["windows"] |
176 |
| - ] |
| 216 | + window_dicts = workspace_dict["windows"] |
| 217 | + window_dicts = filter(optional_windows_and_pane, window_dicts) |
| 218 | + window_dicts = map(lambda x: expand(x, parent=workspace_dict), window_dicts) |
| 219 | + # remove windows that has no panels (e.g. due to if conditions) |
| 220 | + window_dicts = filter(lambda x: len(x["panes"]), window_dicts) |
| 221 | + workspace_dict["windows"] = list(window_dicts) |
| 222 | + |
177 | 223 | elif "panes" in workspace_dict:
|
178 | 224 | pane_dicts = workspace_dict["panes"]
|
179 | 225 | for pane_idx, pane_dict in enumerate(pane_dicts):
|
180 | 226 | pane_dicts[pane_idx] = {}
|
181 | 227 | pane_dicts[pane_idx].update(expand_cmd(pane_dict))
|
182 |
| - workspace_dict["panes"] = [ |
183 |
| - expand(pane, parent=workspace_dict) for pane in pane_dicts |
184 |
| - ] |
| 228 | + pane_dicts = filter(optional_windows_and_pane, pane_dicts) |
| 229 | + pane_dicts = map(lambda x: expand(x, parent=workspace_dict), pane_dicts) |
| 230 | + workspace_dict["panes"] = list(pane_dicts) |
185 | 231 |
|
186 | 232 | return workspace_dict
|
187 | 233 |
|
|
0 commit comments