-
Notifications
You must be signed in to change notification settings - Fork 238
Expand file tree
/
Copy pathfreezer.py
More file actions
135 lines (105 loc) · 4.18 KB
/
freezer.py
File metadata and controls
135 lines (105 loc) · 4.18 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
"""Tmux session freezing functionality for tmuxp."""
from __future__ import annotations
import logging
import typing as t
logger = logging.getLogger(__name__)
if t.TYPE_CHECKING:
from libtmux.pane import Pane
from libtmux.session import Session
from libtmux.window import Window
def inline(workspace_dict: dict[str, t.Any]) -> t.Any:
"""Return workspace with inlined shorthands. Opposite of :meth:`loader.expand`.
Parameters
----------
workspace_dict : dict
Returns
-------
dict
workspace with shorthands inlined.
"""
if (
"shell_command" in workspace_dict
and isinstance(workspace_dict["shell_command"], list)
and len(workspace_dict["shell_command"]) == 1
):
workspace_dict["shell_command"] = workspace_dict["shell_command"][0]
if len(workspace_dict.keys()) == 1:
return workspace_dict["shell_command"]
if (
"shell_command_before" in workspace_dict
and isinstance(workspace_dict["shell_command_before"], list)
and len(workspace_dict["shell_command_before"]) == 1
):
workspace_dict["shell_command_before"] = workspace_dict["shell_command_before"][
0
]
# recurse into window and pane workspace items
if "windows" in workspace_dict:
workspace_dict["windows"] = [
inline(window) for window in workspace_dict["windows"]
]
if "panes" in workspace_dict:
workspace_dict["panes"] = [inline(pane) for pane in workspace_dict["panes"]]
return workspace_dict
def freeze(session: Session) -> dict[str, t.Any]:
"""Freeze live tmux session into a tmuxp workspace.
Parameters
----------
session : :class:`libtmux.Session`
session object
Returns
-------
dict
tmuxp compatible workspace
"""
logger.debug("freezing session", extra={"tmux_session": session.session_name})
session_config: dict[str, t.Any] = {
"session_name": session.session_name,
"windows": [],
}
for window in session.windows:
window_config: dict[str, t.Any] = {
"options": window.show_options(),
"window_name": window.name,
"layout": window.window_layout,
"panes": [],
}
if getattr(window, "window_active", "0") == "1":
window_config["focus"] = "true"
# If all panes have same path, set 'start_directory' instead
# of using 'cd' shell commands.
def pane_has_same_path(window: Window, pane: Pane) -> bool:
return window.panes[0].pane_current_path == pane.pane_current_path
if all(pane_has_same_path(window=window, pane=pane) for pane in window.panes):
window_config["start_directory"] = window.panes[0].pane_current_path
for pane in window.panes:
pane_config: str | dict[str, t.Any] = {"shell_command": []}
assert isinstance(pane_config, dict)
if "start_directory" not in window_config and pane.pane_current_path:
pane_config["shell_command"].append("cd " + pane.pane_current_path)
if getattr(pane, "pane_active", "0") == "1":
pane_config["focus"] = "true"
current_cmd = pane.pane_current_command
def filter_interpreters_and_shells(current_cmd: str | None) -> bool:
return current_cmd is not None and (
current_cmd.startswith("-")
or any(
current_cmd.endswith(cmd) for cmd in ["python", "ruby", "node"]
)
)
if filter_interpreters_and_shells(current_cmd=current_cmd):
current_cmd = None
if current_cmd:
pane_config["shell_command"].append(current_cmd)
elif not len(pane_config["shell_command"]):
pane_config = "pane"
window_config["panes"].append(pane_config)
session_config["windows"].append(window_config)
logger.debug(
"frozen window",
extra={
"tmux_session": session.session_name,
"tmux_window": window.name,
},
)
return session_config