libtmux-workspace 0.1.0.alpha.2 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +345 -163
- data/lib/libtmux/workspace/version.rb +1 -1
- metadata +4 -4
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 66d96c81c6ee85c0bc75c616571fd4a8184bdec03117d48424898a6bc5ca7513
|
|
4
|
+
data.tar.gz: f6677029749a5f5d3eeeea3e1df64a3f78d44243917d1192007de6db8ae2157a
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 741f07d62607be8fc81a90c88ff66f69addad12bb7dcbd196059563e4635d629f326048b878ff21d298fb1e00f3b0ef8b862a2c7a5cad88ce054be0727251598
|
|
7
|
+
data.tar.gz: 470f30b5b38a41c8dc4922b59d205c8ef88119838d0f68eedaba1157b1187b14d81fb45cef815afb15305b1cb23f56e67585ffb8b7e7ad90788ee71bed770144
|
data/README.md
CHANGED
|
@@ -11,33 +11,44 @@
|
|
|
11
11
|
|
|
12
12
|
# libtmux-workspace
|
|
13
13
|
|
|
14
|
-
Load bounded YAML or JSON, inspect an immutable
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
14
|
+
[Load][workspace-load] bounded YAML or JSON, inspect an immutable
|
|
15
|
+
[creation plan][workspace-plan-class], then explicitly
|
|
16
|
+
[apply][workspace-plan-apply] it to an open libtmux server.
|
|
17
|
+
|
|
18
|
+
[API reference](https://libtmux.org/en/ruby/latest/workspace/reference/) ·
|
|
19
|
+
[Command reference](https://libtmux.org/en/ruby/latest/workspace/cli/) ·
|
|
20
|
+
[Guides](https://libtmux.org/en/ruby/latest/workspace/guides/) ·
|
|
21
|
+
[RubyGems](https://rubygems.org/gems/libtmux-workspace)
|
|
19
22
|
|
|
20
23
|
</div>
|
|
21
24
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
`
|
|
25
|
+
Part of [libtmux for Ruby](https://github.com/libtmux/libtmux-ruby#readme).
|
|
26
|
+
Built on [libtmux](https://github.com/libtmux/libtmux-ruby/tree/master/gems/libtmux).
|
|
27
|
+
|
|
28
|
+
Check a workspace file, see the ordered steps a load would run, and create the
|
|
29
|
+
session on a running tmux server, from the `libtmux-workspace` command or from
|
|
30
|
+
Ruby.
|
|
31
|
+
|
|
32
|
+
Validation and offline planning need no running daemon, and imports start no
|
|
33
|
+
tmux process.
|
|
27
34
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
[
|
|
31
|
-
|
|
35
|
+
**Contents** — [Quick start](#quick-start) ·
|
|
36
|
+
[Write the file](#write-the-file) ·
|
|
37
|
+
[Create the session](#create-the-session) ·
|
|
38
|
+
[Failed apply](#recover-from-a-failed-apply) ·
|
|
39
|
+
[Attach or switch](#attach-or-switch-to-the-new-session) ·
|
|
40
|
+
[Scripts](#script-it) · [Leaves out](#what-it-leaves-out) ·
|
|
41
|
+
[Support](#support-and-status) · [Documentation](#documentation)
|
|
32
42
|
|
|
33
|
-
|
|
43
|
+
## Quick start
|
|
44
|
+
|
|
45
|
+
Install the gem and its `libtmux-workspace` executable. It needs Ruby 3.3 or
|
|
46
|
+
newer, and tmux 3.3a or newer to load a plan:
|
|
34
47
|
|
|
35
48
|
```console
|
|
36
|
-
$ gem install libtmux-workspace
|
|
49
|
+
$ gem install libtmux-workspace
|
|
37
50
|
```
|
|
38
51
|
|
|
39
|
-
## Example
|
|
40
|
-
|
|
41
52
|
Save this declared subset of tmuxp-style data as `workspace.yaml`. Relative
|
|
42
53
|
directories resolve against the configuration file's directory.
|
|
43
54
|
|
|
@@ -56,127 +67,235 @@ windows:
|
|
|
56
67
|
```
|
|
57
68
|
<!-- /example -->
|
|
58
69
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
70
|
+
Check the file. [`validate`][cli-validate] reads no tmux state:
|
|
71
|
+
|
|
72
|
+
```console
|
|
73
|
+
$ libtmux-workspace validate workspace.yaml
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
```text
|
|
77
|
+
Workspace configuration is valid.
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
Print the ordered operations a load would run. Offline [`plan`][cli-plan] does
|
|
81
|
+
not contact tmux either:
|
|
82
|
+
|
|
83
|
+
```console
|
|
84
|
+
$ libtmux-workspace plan workspace.yaml
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
```text
|
|
88
|
+
offline_create: 11 ordered steps
|
|
89
|
+
1. create_session session (creation)
|
|
90
|
+
2. set_session_option session (configuration)
|
|
91
|
+
3. set_window_option window:0 (configuration)
|
|
92
|
+
4. move_initial_window window:0 (configuration)
|
|
93
|
+
5. split_pane pane:0:0 (creation)
|
|
94
|
+
6. select_layout window:0 (configuration)
|
|
95
|
+
7. send_command pane:0:0 (dispatch_only)
|
|
96
|
+
8. unset_window_option window:0 (configuration)
|
|
97
|
+
9. select_pane pane:0:0 (configuration)
|
|
98
|
+
10. select_window window:0 (configuration)
|
|
99
|
+
11. unset_session_option session (configuration)
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
## Write the file
|
|
103
|
+
|
|
104
|
+
### [`Workspace.load`][workspace-load]: the declared subset
|
|
105
|
+
|
|
106
|
+
`load` reads a regular file of bounded size and infers JSON or YAML from its
|
|
107
|
+
extension. [`Workspace.parse`][workspace-parse] takes the text and a base
|
|
108
|
+
directory instead. Both return an immutable workspace:
|
|
109
|
+
|
|
110
|
+
- Root: `session_name`, nonempty `windows`, `options`, `window_options`.
|
|
111
|
+
- Window: `window_name`, nonempty `panes`, `window_index`, `focus`, `layout`,
|
|
112
|
+
`options`.
|
|
113
|
+
- Pane: a command string, or a mapping with `focus`, `split` and `size`.
|
|
114
|
+
- Root, windows and panes accept `start_directory`, `environment`,
|
|
115
|
+
`shell_command` and `shell_command_before`.
|
|
116
|
+
- Layouts are `even-horizontal`, `even-vertical`, `main-horizontal`,
|
|
117
|
+
`main-vertical` and `tiled`.
|
|
118
|
+
- At most one window and one pane per window declare focus.
|
|
119
|
+
- Without a filename, the command looks for exactly one `.tmuxp.yaml`,
|
|
120
|
+
`.tmuxp.yml` or `.tmuxp.json` in the current directory.
|
|
121
|
+
- An unknown field or an unsupported feature fails with a
|
|
122
|
+
[`ConfigError`][workspace-configerror] that names its position in the file.
|
|
123
|
+
- YAML tags, anchors and aliases are rejected, and no Ruby, ERB, plugins or
|
|
124
|
+
callbacks run.
|
|
125
|
+
- `${NAME}` substitution is opt-in: pass
|
|
126
|
+
`expand_environment: true, environment: {"NAME" => "value"}` to `load` or
|
|
127
|
+
`parse`, or `--expand-environment --env NAME=VALUE` to the command.
|
|
128
|
+
- [`workspace.to_h`][workspace-to_h] exports an immutable, normalized and
|
|
129
|
+
reloadable configuration, with expanded values and absolute directories.
|
|
130
|
+
|
|
131
|
+
The full field, option and limit lists are in
|
|
132
|
+
[Workspace parsing][behavior-workspace-parsing].
|
|
133
|
+
|
|
134
|
+
## Create the session
|
|
135
|
+
|
|
136
|
+
### [`libtmux-workspace load`][cli-load]: build it on a running server
|
|
137
|
+
|
|
138
|
+
`load` needs a running server. It never starts one, so start a private server
|
|
139
|
+
with a keepalive session and no user configuration:
|
|
140
|
+
|
|
141
|
+
```console
|
|
142
|
+
$ WORKSPACE_TMP=$(mktemp -d)
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
```console
|
|
146
|
+
$ tmux -S "$WORKSPACE_TMP/tmux.sock" -f /dev/null new-session -d -s keepalive
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
Create the workspace's session on that socket. It stays detached:
|
|
150
|
+
|
|
151
|
+
```console
|
|
152
|
+
$ libtmux-workspace load \
|
|
153
|
+
--socket "$WORKSPACE_TMP/tmux.sock" \
|
|
154
|
+
workspace.yaml
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
```text
|
|
158
|
+
Workspace created; 11 steps completed. Shell commands were dispatched.
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
The new `work` session holds the `editor` window:
|
|
162
|
+
|
|
163
|
+
```console
|
|
164
|
+
$ tmux -S "$WORKSPACE_TMP/tmux.sock" list-windows -t work
|
|
165
|
+
```
|
|
63
166
|
|
|
64
|
-
|
|
167
|
+
Stop only the private server and remove its directory:
|
|
168
|
+
|
|
169
|
+
```console
|
|
170
|
+
$ tmux -S "$WORKSPACE_TMP/tmux.sock" kill-server
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
```console
|
|
174
|
+
$ rm -rf "$WORKSPACE_TMP"
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
Loading the same file again fails with status 1: a plan creates a new session
|
|
178
|
+
and never reconciles an existing one.
|
|
179
|
+
|
|
180
|
+
### [`Plan#apply`][workspace-plan-apply]: the same from Ruby
|
|
181
|
+
|
|
182
|
+
[`Workspace.load`][workspace-load] reads the file,
|
|
183
|
+
[`workspace.plan`][workspace-plan-method] plans it against a snapshot, and
|
|
184
|
+
`apply` creates the session. Calling `apply` authorizes the configuration's
|
|
185
|
+
shell commands:
|
|
186
|
+
|
|
187
|
+
<!-- example: api_workspace_apply/main -->
|
|
65
188
|
```ruby
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
crowded.plan.apply(server: server, compensate: true)
|
|
189
|
+
require "libtmux"
|
|
190
|
+
require "libtmux/workspace"
|
|
191
|
+
|
|
192
|
+
LibTmux::Server.start do |server|
|
|
193
|
+
workspace = LibTmux::Workspace.load(File.expand_path("../workspace.yaml", __dir__))
|
|
194
|
+
plan = workspace.plan(snapshot: server.snapshot)
|
|
195
|
+
puts "planned steps: #{plan.steps.length}"
|
|
196
|
+
result = plan.apply(server: server)
|
|
197
|
+
puts "applied: #{result.success?}"
|
|
198
|
+
puts "sessions: #{server.list_sessions.map { |session| session.snapshot.name }.join(', ')}"
|
|
77
199
|
end
|
|
78
|
-
Example.check(!error.result.created_refs.empty?, "failure lost partial creation ledger")
|
|
79
|
-
Example.check(error.result.compensation == :completed, "owned compensation failed")
|
|
80
|
-
Example.check(server.list_sessions.map(&:ref).include?(borrowed.ref), "borrowed session was removed")
|
|
81
200
|
```
|
|
82
201
|
<!-- /example -->
|
|
83
202
|
|
|
84
|
-
|
|
203
|
+
The program runs next to the `workspace.yaml` above, on a private server, and
|
|
204
|
+
prints:
|
|
85
205
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
206
|
+
```text
|
|
207
|
+
planned steps: 11
|
|
208
|
+
applied: true
|
|
209
|
+
sessions: work
|
|
210
|
+
```
|
|
91
211
|
|
|
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
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
`
|
|
179
|
-
`.tmuxp.yaml`, `.tmuxp.yml` or `.tmuxp.json` in the current directory.
|
|
212
|
+
- A snapshot makes the plan reject a name that already exists, and every
|
|
213
|
+
`apply` takes a fresh snapshot and checks again.
|
|
214
|
+
- The plan creates a new session. It does not reconcile, replace or remove an
|
|
215
|
+
existing one.
|
|
216
|
+
- Success shows that tmux accepted the dispatch of each shell command. It does
|
|
217
|
+
not show that the command finished.
|
|
218
|
+
|
|
219
|
+
The [complete program](../../examples/workspace_apply.rb) also runs the
|
|
220
|
+
installed command with `--switch`. The contract is in
|
|
221
|
+
[Workspace apply][behavior-workspace-apply].
|
|
222
|
+
|
|
223
|
+
## Recover from a failed apply
|
|
224
|
+
|
|
225
|
+
### [`ApplyError#result`][workspace-applyerror-result]: what exists after a failure
|
|
226
|
+
|
|
227
|
+
A failed apply raises [`ApplyError`][workspace-applyerror]. Its immutable
|
|
228
|
+
`result` holds the completed step IDs, the
|
|
229
|
+
[`created_refs`][workspace-applyresult-created_refs] tmux returned, the
|
|
230
|
+
effects it observed, and the failed action. Pass `compensate: true` to remove
|
|
231
|
+
only the session the apply created:
|
|
232
|
+
|
|
233
|
+
<!-- example: api_workspace_failure/main -->
|
|
234
|
+
```ruby
|
|
235
|
+
require "json"
|
|
236
|
+
require "libtmux"
|
|
237
|
+
require "libtmux/workspace"
|
|
238
|
+
|
|
239
|
+
LibTmux::Server.start do |server|
|
|
240
|
+
server.new_session(name: "borrowed", command: ["/bin/cat"])
|
|
241
|
+
crowded = LibTmux::Workspace.parse(
|
|
242
|
+
JSON.generate({session_name: "crowded", windows: [{window_name: "small", panes: Array.new(40) { {} }}]}),
|
|
243
|
+
format: :json, base_directory: __dir__
|
|
244
|
+
)
|
|
245
|
+
begin
|
|
246
|
+
crowded.plan.apply(server: server, compensate: true)
|
|
247
|
+
rescue LibTmux::Workspace::ApplyError => error
|
|
248
|
+
puts "failed action: #{error.result.failed_action}"
|
|
249
|
+
puts "created a session: #{error.result.created_refs.key?('session')}"
|
|
250
|
+
puts "compensation: #{error.result.compensation}"
|
|
251
|
+
end
|
|
252
|
+
puts "sessions: #{server.list_sessions.map { |session| session.snapshot.name }.join(', ')}"
|
|
253
|
+
end
|
|
254
|
+
```
|
|
255
|
+
<!-- /example -->
|
|
256
|
+
|
|
257
|
+
That many panes do not fit in one window, so tmux refuses a split after the
|
|
258
|
+
session exists. It prints:
|
|
259
|
+
|
|
260
|
+
```text
|
|
261
|
+
failed action: split_pane
|
|
262
|
+
created a session: true
|
|
263
|
+
compensation: completed
|
|
264
|
+
sessions: borrowed
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
- Compensation removes the new session only after a tmux guard shows that
|
|
268
|
+
every window and pane in it has a positively identified created reference.
|
|
269
|
+
- An unknown initial entity, or a borrowed entity moved into the session,
|
|
270
|
+
makes it refuse.
|
|
271
|
+
- Compensation cannot undo what shell commands did. Without it, the partial
|
|
272
|
+
state stays for you to inspect.
|
|
273
|
+
- Diagnostics omit command payloads and paths. Names are never used to guess
|
|
274
|
+
ownership.
|
|
275
|
+
|
|
276
|
+
The command takes `--compensate`. The contracts are in
|
|
277
|
+
[Workspace results][behavior-workspace-results].
|
|
278
|
+
|
|
279
|
+
## Attach or switch to the new session
|
|
280
|
+
|
|
281
|
+
### [`load --switch`][cli-load]: move a client to the session
|
|
282
|
+
|
|
283
|
+
- `load --attach` opens the CLI's `/dev/tty` after creation and runs an owned
|
|
284
|
+
terminal client until you detach. It requires a valid `TERM`.
|
|
285
|
+
- `load --switch CLIENT` switches a current tmux client to the created session
|
|
286
|
+
after apply, keeping the session's environment.
|
|
287
|
+
- `CLIENT` is a client name, a full TTY path or a TTY path without `/dev/`.
|
|
288
|
+
Use `--switch=VALUE` for a selector that begins with `-`.
|
|
289
|
+
- A missing client, or a failure to open or attach the terminal, keeps the
|
|
290
|
+
created session and returns status 3.
|
|
291
|
+
- Attach and switch are mutually exclusive, and neither infers a latest
|
|
292
|
+
client. The library's [`Plan#apply`][workspace-plan-apply] does neither.
|
|
293
|
+
|
|
294
|
+
The selector rules are in [Client switching][behavior-client-switching].
|
|
295
|
+
|
|
296
|
+
## Script it
|
|
297
|
+
|
|
298
|
+
### [`--json`][cli-load]: one object on stdout
|
|
180
299
|
|
|
181
300
|
Check the installed gem version without reading a configuration or contacting
|
|
182
301
|
tmux:
|
|
@@ -185,12 +304,9 @@ tmux:
|
|
|
185
304
|
$ libtmux-workspace --version
|
|
186
305
|
```
|
|
187
306
|
|
|
188
|
-
```console
|
|
189
|
-
$ libtmux-workspace validate workspace.yaml
|
|
190
|
-
```
|
|
191
|
-
|
|
192
307
|
Human plans list ordered operations and their effects. `--json` prints the
|
|
193
|
-
same plan data as `Plan#to_h
|
|
308
|
+
same plan data as [`Plan#to_h`][workspace-plan-to_h], including configured
|
|
309
|
+
command text and paths:
|
|
194
310
|
|
|
195
311
|
```console
|
|
196
312
|
$ libtmux-workspace plan \
|
|
@@ -198,8 +314,9 @@ $ libtmux-workspace plan \
|
|
|
198
314
|
workspace.yaml
|
|
199
315
|
```
|
|
200
316
|
|
|
201
|
-
`load` and `plan --live` require `--socket` for an existing
|
|
202
|
-
detached creation example uses an explicitly supplied
|
|
317
|
+
[`load`][cli-load] and `plan --live` require `--socket` for an existing
|
|
318
|
+
server. This detached creation example uses an explicitly supplied
|
|
319
|
+
`TMUX_SOCKET` value:
|
|
203
320
|
|
|
204
321
|
```console
|
|
205
322
|
$ libtmux-workspace load \
|
|
@@ -208,27 +325,20 @@ $ libtmux-workspace load \
|
|
|
208
325
|
workspace.yaml
|
|
209
326
|
```
|
|
210
327
|
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
Missing or invalid selector arguments fail before creation. Use
|
|
226
|
-
`--switch=VALUE` for a selector beginning with `-`.
|
|
227
|
-
|
|
228
|
-
The selector is resolved at dispatch; a reconnect matching it is eligible.
|
|
229
|
-
It is not a captured client reference or proof of terminal ownership. Attach
|
|
230
|
-
and switch are mutually exclusive. Neither operation infers a latest client,
|
|
231
|
-
and library `Plan#apply` performs neither operation.
|
|
328
|
+
`libtmux-workspace --help` lists every option. The
|
|
329
|
+
[command reference][ws-cli] has a page for each command.
|
|
330
|
+
|
|
331
|
+
| Option | Effect |
|
|
332
|
+
| --- | --- |
|
|
333
|
+
| `--json` | Write one structured result or error object to stdout |
|
|
334
|
+
| `--socket PATH` | Select the existing server's socket for `load` or `plan --live` |
|
|
335
|
+
| `--live` | Capture a snapshot before planning |
|
|
336
|
+
| `--timeout SECONDS` | Bound each apply, live capture or switch operation; the default is 5 |
|
|
337
|
+
| `--compensate` | Run guarded cleanup after an apply failure |
|
|
338
|
+
| `--attach` | Attach this CLI's terminal after a successful `load` |
|
|
339
|
+
| `--switch CLIENT` | Switch an explicit current client to the new session after `load` |
|
|
340
|
+
| `--expand-environment` | Expand `${NAME}` in directories and environment values; requires `--env` |
|
|
341
|
+
| `--env NAME=VALUE` | Supply a value for expansion; ambient environment variables are not copied |
|
|
232
342
|
|
|
233
343
|
| Exit status | Meaning |
|
|
234
344
|
| --- | --- |
|
|
@@ -238,7 +348,79 @@ and library `Plan#apply` performs neither operation.
|
|
|
238
348
|
| 3 | Application was partial or uncertain, or a later attach/switch/cleanup failed |
|
|
239
349
|
| 130 | Interrupted; available effect ledger is retained |
|
|
240
350
|
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
351
|
+
Apply errors include [`ApplyResult#to_h`][workspace-applyresult-to_h]. Human
|
|
352
|
+
errors write the diagnostic and any ledger to stderr. Diagnostics omit
|
|
353
|
+
configuration payloads; plan rendering and canonical export contain those
|
|
354
|
+
values by design.
|
|
355
|
+
|
|
356
|
+
## What it leaves out
|
|
357
|
+
|
|
358
|
+
- **Reconciliation.** A plan creates a new session and never replaces or
|
|
359
|
+
removes an existing workspace. The contract is in
|
|
360
|
+
[Workspace plans][behavior-workspace-plans].
|
|
361
|
+
- **Shell command completion.** Apply records a shell command as dispatched.
|
|
362
|
+
Embedded newlines can execute while the text is inserted. See
|
|
363
|
+
[Workspace apply][behavior-workspace-apply].
|
|
364
|
+
- **Rollback of shell effects.** Compensation removes only tmux objects the
|
|
365
|
+
apply created. See [Workspace results][behavior-workspace-results].
|
|
366
|
+
- **Features beyond the declared subset.** Plugins, ERB and callbacks are
|
|
367
|
+
rejected, and a [`ConfigError`][workspace-configerror] names the position.
|
|
368
|
+
- **A guessed client.** Attach and switch need an explicit client. See
|
|
369
|
+
[Client switching][behavior-client-switching].
|
|
370
|
+
|
|
371
|
+
## Support and status
|
|
372
|
+
|
|
373
|
+
Releases are numbered `0.1.N`, and each release increments `N`. The API is not
|
|
374
|
+
settled: any release may change or remove exported identifiers, and the
|
|
375
|
+
changelog marks each break. Pin an exact version to avoid one.
|
|
376
|
+
|
|
377
|
+
- **Ruby 3.3 or newer.** The gem depends on the same version of `libtmux`,
|
|
378
|
+
JSON 3.0 and Psych 5.5.
|
|
379
|
+
- **tmux 3.3a or newer** to load or apply a plan.
|
|
380
|
+
- **Older daemons.** `load` creates nothing and prints the refusal with the
|
|
381
|
+
floor and the remedy. With `--json`, the refusal is in `error.message` and
|
|
382
|
+
`error.kind` is `tmux_unsupported`.
|
|
383
|
+
- **Linux, including WSL, and macOS.** The library and the command share the
|
|
384
|
+
core [compatibility workflow][compat]: Ruby 3.3, 3.4 and 4.0 with tmux 3.3a
|
|
385
|
+
through 3.8 on Ubuntu 24.04, with per-revision results. macOS is supported on
|
|
386
|
+
a best-effort basis, and CI coverage for it is highly limited.
|
|
387
|
+
- **History limit.** On tmux 3.3a to 3.6 the reused initial pane keeps the
|
|
388
|
+
global `history-limit`. Set the server's global value before you apply to
|
|
389
|
+
get one history size.
|
|
390
|
+
|
|
391
|
+
## Documentation
|
|
392
|
+
|
|
393
|
+
| | |
|
|
394
|
+
| --- | --- |
|
|
395
|
+
| [Reference](https://libtmux.org/en/ruby/latest/workspace/reference/) | Every public workspace class and method |
|
|
396
|
+
| [Command reference][ws-cli] | A page for `validate`, `plan` and `load` |
|
|
397
|
+
| [Guides][workspace-guides] | Validate, inspect and explicitly apply a plan |
|
|
398
|
+
| [Topics][workspace-topics] | Format, planning boundaries, effects and failure ledgers |
|
|
399
|
+
| [Public behavior][behavior-workspace-parsing] | Parsing, plans, apply, results and the command |
|
|
400
|
+
| [Recipes][doc-recipes] | The workspace plan, load and failure program |
|
|
401
|
+
|
|
402
|
+
[behavior-client-switching]: ../../docs/reference/behavior.md#client-switching
|
|
403
|
+
[behavior-workspace-apply]: ../../docs/reference/behavior.md#workspace-apply
|
|
404
|
+
[behavior-workspace-parsing]: ../../docs/reference/behavior.md#workspace-parsing
|
|
405
|
+
[behavior-workspace-plans]: ../../docs/reference/behavior.md#workspace-plans
|
|
406
|
+
[behavior-workspace-results]: ../../docs/reference/behavior.md#workspace-results
|
|
407
|
+
[cli-load]: https://libtmux.org/en/ruby/latest/workspace/cli/load/
|
|
408
|
+
[cli-plan]: https://libtmux.org/en/ruby/latest/workspace/cli/plan/
|
|
409
|
+
[cli-validate]: https://libtmux.org/en/ruby/latest/workspace/cli/validate/
|
|
410
|
+
[compat]: https://github.com/libtmux/libtmux-ruby/actions/workflows/compatibility.yml
|
|
411
|
+
[doc-recipes]: ../../docs/recipes.md
|
|
412
|
+
[workspace-applyerror]: https://libtmux.org/en/ruby/latest/workspace/reference/libtmux-workspace-applyerror/
|
|
413
|
+
[workspace-applyerror-result]: https://libtmux.org/en/ruby/latest/workspace/reference/libtmux-workspace-applyerror-result/
|
|
414
|
+
[workspace-applyresult-created_refs]: https://libtmux.org/en/ruby/latest/workspace/reference/libtmux-workspace-applyresult-created_refs/
|
|
415
|
+
[workspace-applyresult-to_h]: https://libtmux.org/en/ruby/latest/workspace/reference/libtmux-workspace-applyresult-to_h/
|
|
416
|
+
[workspace-configerror]: https://libtmux.org/en/ruby/latest/workspace/reference/libtmux-workspace-configerror/
|
|
417
|
+
[workspace-guides]: https://libtmux.org/en/ruby/latest/workspace/guides/
|
|
418
|
+
[workspace-load]: https://libtmux.org/en/ruby/latest/workspace/reference/libtmux-workspace-load/
|
|
419
|
+
[workspace-parse]: https://libtmux.org/en/ruby/latest/workspace/reference/libtmux-workspace-parse/
|
|
420
|
+
[workspace-plan-apply]: https://libtmux.org/en/ruby/latest/workspace/reference/libtmux-workspace-plan-apply/
|
|
421
|
+
[workspace-plan-class]: https://libtmux.org/en/ruby/latest/workspace/reference/libtmux-workspace-plan-1qko/
|
|
422
|
+
[workspace-plan-method]: https://libtmux.org/en/ruby/latest/workspace/reference/libtmux-workspace-plan-1c5c/
|
|
423
|
+
[workspace-plan-to_h]: https://libtmux.org/en/ruby/latest/workspace/reference/libtmux-workspace-plan-to_h/
|
|
424
|
+
[workspace-to_h]: https://libtmux.org/en/ruby/latest/workspace/reference/libtmux-workspace-to_h/
|
|
425
|
+
[workspace-topics]: https://libtmux.org/en/ruby/latest/workspace/topics/
|
|
426
|
+
[ws-cli]: https://libtmux.org/en/ruby/latest/workspace/cli/
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: libtmux-workspace
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.1.0
|
|
4
|
+
version: 0.1.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- libtmux contributors
|
|
@@ -15,14 +15,14 @@ dependencies:
|
|
|
15
15
|
requirements:
|
|
16
16
|
- - '='
|
|
17
17
|
- !ruby/object:Gem::Version
|
|
18
|
-
version: 0.1.0
|
|
18
|
+
version: 0.1.0
|
|
19
19
|
type: :runtime
|
|
20
20
|
prerelease: false
|
|
21
21
|
version_requirements: !ruby/object:Gem::Requirement
|
|
22
22
|
requirements:
|
|
23
23
|
- - '='
|
|
24
24
|
- !ruby/object:Gem::Version
|
|
25
|
-
version: 0.1.0
|
|
25
|
+
version: 0.1.0
|
|
26
26
|
- !ruby/object:Gem::Dependency
|
|
27
27
|
name: json
|
|
28
28
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -76,7 +76,7 @@ licenses:
|
|
|
76
76
|
- MIT
|
|
77
77
|
metadata:
|
|
78
78
|
source_code_uri: https://github.com/libtmux/libtmux-ruby
|
|
79
|
-
documentation_uri: https://libtmux.org/en/ruby/v0.1.0
|
|
79
|
+
documentation_uri: https://libtmux.org/en/ruby/v0.1.0/workspace/
|
|
80
80
|
rdoc_options: []
|
|
81
81
|
require_paths:
|
|
82
82
|
- lib
|