mirror of
https://github.com/tmux/tmux.git
synced 2026-03-12 19:45:46 +00:00
Compare commits
567 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7536d690fd | ||
|
|
b8aec17af1 | ||
|
|
f4196138ce | ||
|
|
fe1aa9299e | ||
|
|
568f5ef3c6 | ||
|
|
bafe6f5a7c | ||
|
|
be6dc83277 | ||
|
|
c2bbaab2ac | ||
|
|
ffb83d23e1 | ||
|
|
4d05d88304 | ||
|
|
9ae2284726 | ||
|
|
b4750e4c35 | ||
|
|
1b2c62afe9 | ||
|
|
f28032b031 | ||
|
|
52756fb3c5 | ||
|
|
cb018a4212 | ||
|
|
833fe5bdee | ||
|
|
313f2263f8 | ||
|
|
8d94bb67ab | ||
|
|
03758a50dc | ||
|
|
83a8e1fd20 | ||
|
|
90bf7026f6 | ||
|
|
f1e68bfdd2 | ||
|
|
4946f74253 | ||
|
|
e5d9ceff18 | ||
|
|
c9642ee213 | ||
|
|
4e03239d1f | ||
|
|
144025e3e6 | ||
|
|
93c3fb78a3 | ||
|
|
51233d8b2a | ||
|
|
adcc71d4d5 | ||
|
|
68429cd0d3 | ||
|
|
c38f0d85da | ||
|
|
f9c7f9a17a | ||
|
|
16bdd970dc | ||
|
|
d451502676 | ||
|
|
df6488a470 | ||
|
|
776eef49d8 | ||
|
|
6e764fb53e | ||
|
|
86207ee676 | ||
|
|
66e8811c64 | ||
|
|
a9644c1f8b | ||
|
|
8a8e2eb04a | ||
|
|
da72a0b7a8 | ||
|
|
aae2b7aa89 | ||
|
|
fee096a406 | ||
|
|
be0ad01b7c | ||
|
|
daea0e4fff | ||
|
|
cc1bc9717c | ||
|
|
9cb5afe114 | ||
|
|
2a9a75a569 | ||
|
|
5f8138faf5 | ||
|
|
160e3e2be3 | ||
|
|
d88c381ce9 | ||
|
|
f495b150fa | ||
|
|
3771ab7c67 | ||
|
|
7a0c94b28a | ||
|
|
32f1ceddc9 | ||
|
|
ccbe2545d9 | ||
|
|
54ca7b230d | ||
|
|
575fd1e322 | ||
|
|
e52d791212 | ||
|
|
c8bf8ee931 | ||
|
|
c403bfc894 | ||
|
|
a3612a5472 | ||
|
|
3e8efcc555 | ||
|
|
e0929262db | ||
|
|
7cc4706646 | ||
|
|
d37f266524 | ||
|
|
bd803e82e9 | ||
|
|
f9308bc244 | ||
|
|
7697f5aa8f | ||
|
|
4429941668 | ||
|
|
fc05bf255a | ||
|
|
8f1302282b | ||
|
|
c6129f9c09 | ||
|
|
747cab4281 | ||
|
|
3c12b477d3 | ||
|
|
d2c9168954 | ||
|
|
218b181985 | ||
|
|
7445d303e0 | ||
|
|
6ca8c58462 | ||
|
|
e4bf1e5128 | ||
|
|
79f52825b5 | ||
|
|
d24c9d7d3e | ||
|
|
35ffd093d7 | ||
|
|
10a9440055 | ||
|
|
b496b1fe11 | ||
|
|
428b51e031 | ||
|
|
abfb9656ef | ||
|
|
68cb1c0e6b | ||
|
|
a02c2e55c0 | ||
|
|
85671a5bed | ||
|
|
201036ad80 | ||
|
|
65257b8e9b | ||
|
|
696b5a628f | ||
|
|
562af864bd | ||
|
|
0a1a88d63c | ||
|
|
4c42381410 | ||
|
|
900f6fc17e | ||
|
|
30bacf6f30 | ||
|
|
8a5ceac3a9 | ||
|
|
f5bc85591a | ||
|
|
7afe417a60 | ||
|
|
45dfc5a074 | ||
|
|
f0b69c7711 | ||
|
|
e44bdcce4c | ||
|
|
2e8f6805eb | ||
|
|
a77355b6bf | ||
|
|
a27ba6e380 | ||
|
|
77efcf8bdd | ||
|
|
6610e89689 | ||
|
|
d306bbe11e | ||
|
|
c011446e78 | ||
|
|
b6aef2490f | ||
|
|
2f19df09b1 | ||
|
|
931c17ed4f | ||
|
|
24d9dc518d | ||
|
|
045d0c3b9f | ||
|
|
a54b0055f6 | ||
|
|
304f86cdbb | ||
|
|
2874a431c0 | ||
|
|
5e7f1b9f0a | ||
|
|
16670410ca | ||
|
|
054a825ee2 | ||
|
|
b2224947fa | ||
|
|
4d53fd98a6 | ||
|
|
21062d74d5 | ||
|
|
938d91d2c3 | ||
|
|
93fe1b8659 | ||
|
|
9bda7e881a | ||
|
|
8a473b5757 | ||
|
|
733cea8847 | ||
|
|
4e956d545a | ||
|
|
e075198049 | ||
|
|
2b79d36652 | ||
|
|
29d20a55b6 | ||
|
|
f518a077b1 | ||
|
|
72797074f3 | ||
|
|
fab8ca0737 | ||
|
|
0e23ab4cce | ||
|
|
92997b781a | ||
|
|
a131b82e95 | ||
|
|
1ac96200a7 | ||
|
|
fd3b7f3572 | ||
|
|
b8b00aad5d | ||
|
|
8e4ae12b4d | ||
|
|
2056a9ef9e | ||
|
|
c5253ad8f7 | ||
|
|
2b67907176 | ||
|
|
f117c7d94a | ||
|
|
d1f939cede | ||
|
|
1aae53596d | ||
|
|
54782af616 | ||
|
|
61605c6883 | ||
|
|
f8481f93c5 | ||
|
|
cddf50b715 | ||
|
|
0c5ed177c4 | ||
|
|
814e40522c | ||
|
|
1544c688e6 | ||
|
|
8049baf0bd | ||
|
|
8d0819bff1 | ||
|
|
c8efffb4db | ||
|
|
19cb0a1a92 | ||
|
|
00ac1af43f | ||
|
|
fd9a53b4a4 | ||
|
|
a94696defa | ||
|
|
77f582ff13 | ||
|
|
f5973b7776 | ||
|
|
21ade85f24 | ||
|
|
74becbfd6f | ||
|
|
193b6bcf36 | ||
|
|
7160b8c2d5 | ||
|
|
191f695bad | ||
|
|
58c97695c9 | ||
|
|
53cbae544f | ||
|
|
b2e791b574 | ||
|
|
92af7f5901 | ||
|
|
bae95844d7 | ||
|
|
b3e8d440ed | ||
|
|
b1a06ef22e | ||
|
|
3dbacbb62b | ||
|
|
f4ffaf5a7f | ||
|
|
353d1825d5 | ||
|
|
94ccc6aeaa | ||
|
|
189017c078 | ||
|
|
540f0b3e45 | ||
|
|
6369ea10d7 | ||
|
|
ea5a223a2e | ||
|
|
5b2c8156d5 | ||
|
|
afb4dbd465 | ||
|
|
b096ad9f22 | ||
|
|
40cb4cb086 | ||
|
|
3f54c9292f | ||
|
|
bec6c807cd | ||
|
|
953c3ef47a | ||
|
|
7ab2690be8 | ||
|
|
12e9c974fa | ||
|
|
024846b4d8 | ||
|
|
64613b9d41 | ||
|
|
806520f025 | ||
|
|
a5d4b7f3d9 | ||
|
|
248ad8bdb2 | ||
|
|
f194f103a2 | ||
|
|
3e27be353d | ||
|
|
c3b2e5eed3 | ||
|
|
ada75af199 | ||
|
|
bce952777a | ||
|
|
2e98c9057d | ||
|
|
2740490e27 | ||
|
|
877bdb46ed | ||
|
|
ebc5cb447f | ||
|
|
992ef70fb6 | ||
|
|
5acee1c04e | ||
|
|
871b83cbab | ||
|
|
14a96df9ee | ||
|
|
e5d85c6c3c | ||
|
|
4abc8f717a | ||
|
|
8e1cef4040 | ||
|
|
a47d2397df | ||
|
|
b8bda67f30 | ||
|
|
73c5a487c1 | ||
|
|
57c514d2f8 | ||
|
|
0c99c7dbff | ||
|
|
acef311fe3 | ||
|
|
8824dae6f7 | ||
|
|
252a7373d6 | ||
|
|
82f3e0e9e6 | ||
|
|
8880bdb67c | ||
|
|
806d5dcb17 | ||
|
|
b52b40b2bc | ||
|
|
d9960b2d4d | ||
|
|
3c06bec03f | ||
|
|
ee19d304ff | ||
|
|
48478ea0a9 | ||
|
|
7bdb675469 | ||
|
|
f155316be7 | ||
|
|
dca7d1c0fd | ||
|
|
1704d4a6b7 | ||
|
|
46593e7aa2 | ||
|
|
fcdae6925a | ||
|
|
0e4d1d8493 | ||
|
|
b11de5adc7 | ||
|
|
9368914ee7 | ||
|
|
175f215187 | ||
|
|
18cb135218 | ||
|
|
04f469a324 | ||
|
|
26c42ad1e4 | ||
|
|
77603c4f2d | ||
|
|
7019f77c05 | ||
|
|
9880114aff | ||
|
|
3625bcba24 | ||
|
|
b1a87b2ee4 | ||
|
|
c5a30513ed | ||
|
|
ebe7bd7c8b | ||
|
|
683ca270d4 | ||
|
|
78e783e786 | ||
|
|
cbd360b7dd | ||
|
|
23e944c91d | ||
|
|
f15fcb6a1d | ||
|
|
8c0edcbfa3 | ||
|
|
b7f6356053 | ||
|
|
b65c72c45c | ||
|
|
19c534e325 | ||
|
|
5f05c41126 | ||
|
|
9134e4de1e | ||
|
|
582c2671dd | ||
|
|
0bb9d51965 | ||
|
|
6d9f936ff2 | ||
|
|
594348440e | ||
|
|
091cd0109f | ||
|
|
225164a9d6 | ||
|
|
f3152079e1 | ||
|
|
bf82f15bba | ||
|
|
4273c1b80e | ||
|
|
488583dc8d | ||
|
|
f1828921df | ||
|
|
7eed5ad97b | ||
|
|
80d9964a30 | ||
|
|
150ef86800 | ||
|
|
315d45a0eb | ||
|
|
2a412fad04 | ||
|
|
fe6f520054 | ||
|
|
c7f3599ebc | ||
|
|
b7589750a1 | ||
|
|
c310212d28 | ||
|
|
94d99d5462 | ||
|
|
9120df33ef | ||
|
|
1ab0745f8e | ||
|
|
c5d2de7ec0 | ||
|
|
ca1d78f523 | ||
|
|
6daf06b1ad | ||
|
|
69b7c496ac | ||
|
|
1e981f4c6d | ||
|
|
d325104d10 | ||
|
|
b3de4a3dec | ||
|
|
81db6bab91 | ||
|
|
f2e54e1e2f | ||
|
|
e9d32f901a | ||
|
|
f835be4bb2 | ||
|
|
3aadc9d665 | ||
|
|
bfb700cf41 | ||
|
|
d0accdba88 | ||
|
|
f58721a9e8 | ||
|
|
325396046a | ||
|
|
c52548f6fd | ||
|
|
8edbbb9865 | ||
|
|
73c125f248 | ||
|
|
1721056f35 | ||
|
|
6eef24c37a | ||
|
|
973de5a704 | ||
|
|
57332be8da | ||
|
|
44737b06db | ||
|
|
d50e47fc4a | ||
|
|
9f02feb9d0 | ||
|
|
72d1be5ddd | ||
|
|
1935eb5c1e | ||
|
|
62e0ed5d7e | ||
|
|
945339b443 | ||
|
|
c930fd5ff6 | ||
|
|
dda70d4ef1 | ||
|
|
7d3d996383 | ||
|
|
d23561f381 | ||
|
|
cbf9224c5f | ||
|
|
c965870585 | ||
|
|
9ee93b3ea3 | ||
|
|
df680d7257 | ||
|
|
d02c4bda3a | ||
|
|
938768ed3d | ||
|
|
3368b602a8 | ||
|
|
b185449d07 | ||
|
|
c2cac69a22 | ||
|
|
1a0d3cd5d3 | ||
|
|
adc1f21eae | ||
|
|
994cb872cf | ||
|
|
66829ee12e | ||
|
|
1751da76d5 | ||
|
|
ba014c1a60 | ||
|
|
886c282679 | ||
|
|
ccf39fcdc1 | ||
|
|
ee65bde130 | ||
|
|
b091790622 | ||
|
|
a352570e9f | ||
|
|
d459314517 | ||
|
|
1286c56188 | ||
|
|
40982a01fb | ||
|
|
7aeb4473ad | ||
|
|
72a4602b88 | ||
|
|
30275bc610 | ||
|
|
3e498cdb49 | ||
|
|
7624800ddc | ||
|
|
f0ed61f53c | ||
|
|
a6cd84869e | ||
|
|
7fa55b0419 | ||
|
|
bf35441608 | ||
|
|
f52eac6225 | ||
|
|
2c08a3a559 | ||
|
|
2eb6d6e31b | ||
|
|
334c28afe7 | ||
|
|
5944230c50 | ||
|
|
8bcdd8fc21 | ||
|
|
d518067be6 | ||
|
|
f703a30dfe | ||
|
|
1a0951959f | ||
|
|
b347a994fd | ||
|
|
6126fa0995 | ||
|
|
85df418728 | ||
|
|
558e5639d0 | ||
|
|
d8d746b4b8 | ||
|
|
570028e9c0 | ||
|
|
7c3e7d6535 | ||
|
|
5b065e93b3 | ||
|
|
d3f37566e2 | ||
|
|
b8b31ad53e | ||
|
|
7f479ffdce | ||
|
|
4901d9ddc8 | ||
|
|
ffba21a60c | ||
|
|
98b81e9834 | ||
|
|
17ec688ced | ||
|
|
0b77d17b35 | ||
|
|
d0566a474a | ||
|
|
99e3cbc526 | ||
|
|
b85de1ddb3 | ||
|
|
c1ccefc62d | ||
|
|
6ac7abe8f0 | ||
|
|
909e1c1a86 | ||
|
|
7936ce3874 | ||
|
|
b8b85fbb0c | ||
|
|
282c5f9644 | ||
|
|
165aa59760 | ||
|
|
10c38436aa | ||
|
|
a0404b6902 | ||
|
|
eb26dbd072 | ||
|
|
6c093010e0 | ||
|
|
d2160e3f83 | ||
|
|
b822d24b15 | ||
|
|
fc54bfe6b0 | ||
|
|
1a49ebaa9f | ||
|
|
e4dc1568ce | ||
|
|
1bd0851ee8 | ||
|
|
1b7c2dd056 | ||
|
|
d45c12b6c9 | ||
|
|
90ae7682ed | ||
|
|
e6af0ad23e | ||
|
|
34674bb180 | ||
|
|
784b711393 | ||
|
|
81a548bcc4 | ||
|
|
fd1750af49 | ||
|
|
2bf2f5d58e | ||
|
|
40811eb8d4 | ||
|
|
2756d12750 | ||
|
|
7839993fe7 | ||
|
|
47a4a9992c | ||
|
|
d75dd2ab1c | ||
|
|
6e665708fc | ||
|
|
d3830e622f | ||
|
|
0538676aa3 | ||
|
|
4c9f41f1ad | ||
|
|
e588ddb5d6 | ||
|
|
f3ec8693e3 | ||
|
|
e9b09faab2 | ||
|
|
5ea6148362 | ||
|
|
9e0d7bddc0 | ||
|
|
aa0a57fd56 | ||
|
|
d86c70af96 | ||
|
|
4538c269d0 | ||
|
|
446eb11cde | ||
|
|
fa1375c09f | ||
|
|
f141e9b37a | ||
|
|
3fba377ddd | ||
|
|
01a4752503 | ||
|
|
d66cbf20f7 | ||
|
|
7e4314eccb | ||
|
|
7c71c3e27d | ||
|
|
5eeee39cc1 | ||
|
|
796974ddf6 | ||
|
|
75f5b3dab6 | ||
|
|
9f330897a8 | ||
|
|
710eeb2a33 | ||
|
|
3493b7dac7 | ||
|
|
d51b4f92d7 | ||
|
|
3d8a8ea0c6 | ||
|
|
2057812c8f | ||
|
|
13360ad541 | ||
|
|
9389cfbec9 | ||
|
|
7be152412e | ||
|
|
d0fa48db1e | ||
|
|
884a21d0f5 | ||
|
|
21bca549d3 | ||
|
|
bda970b3b1 | ||
|
|
75ec17f0b5 | ||
|
|
d62121e7bb | ||
|
|
06d101657f | ||
|
|
2f7ffab0e8 | ||
|
|
3ed5e56a39 | ||
|
|
a0802dd486 | ||
|
|
f2675cdf04 | ||
|
|
e3864c383f | ||
|
|
25c0dc5e6e | ||
|
|
8954d01f96 | ||
|
|
b2fe9bff3f | ||
|
|
a36da3a878 | ||
|
|
c103f2fbcb | ||
|
|
aa4920fea3 | ||
|
|
5532766b19 | ||
|
|
5dbf3cb036 | ||
|
|
ddf929390e | ||
|
|
23519fc0b4 | ||
|
|
04288fcd4c | ||
|
|
84c22d053b | ||
|
|
7581762c8e | ||
|
|
7673732c0f | ||
|
|
2dfd3fbd71 | ||
|
|
3a13e066ba | ||
|
|
bcd9bcae2a | ||
|
|
939f796f08 | ||
|
|
27364345bf | ||
|
|
35c19ffc28 | ||
|
|
b0b5cad496 | ||
|
|
965edf8a5c | ||
|
|
1c271852fc | ||
|
|
7ea560261c | ||
|
|
304ea079d2 | ||
|
|
c190c73240 | ||
|
|
e8567098a4 | ||
|
|
a9ebb62d54 | ||
|
|
bdea2f9eda | ||
|
|
f5b041e394 | ||
|
|
e496a548d7 | ||
|
|
3d39b18e31 | ||
|
|
a96a8a1aab | ||
|
|
064124cc5f | ||
|
|
7af5fec038 | ||
|
|
f884fff869 | ||
|
|
c7a121cfc0 | ||
|
|
777be296ee | ||
|
|
a0172a6ae5 | ||
|
|
1099442c0a | ||
|
|
18989cd430 | ||
|
|
828145456c | ||
|
|
097a046e4a | ||
|
|
3977dba761 | ||
|
|
a41cd8d75b | ||
|
|
662d471215 | ||
|
|
06b5805479 | ||
|
|
d6debc21c7 | ||
|
|
ddb52a2b15 | ||
|
|
13441e8cb8 | ||
|
|
a97d5b8e60 | ||
|
|
399d7380a5 | ||
|
|
c231381aa3 | ||
|
|
c30d60f7ae | ||
|
|
9fb9f78e43 | ||
|
|
a0cf65db77 | ||
|
|
2ee9c4df12 | ||
|
|
e6c77e7afb | ||
|
|
76cb088d16 | ||
|
|
907ad00300 | ||
|
|
88a4da9747 | ||
|
|
25c430b1cd | ||
|
|
772d61f3ed | ||
|
|
5b1cf02f2e | ||
|
|
66f4c60a84 | ||
|
|
fce095665c | ||
|
|
2555ac58cc | ||
|
|
e323101ede | ||
|
|
ce52e45d44 | ||
|
|
4f3c31a6b6 | ||
|
|
70bc8ef845 | ||
|
|
cd60e57b6a | ||
|
|
3d2b7d5bce | ||
|
|
04f54ab38f | ||
|
|
46c7dbef0f | ||
|
|
11b90bc959 | ||
|
|
792e2856c9 | ||
|
|
d89b35e682 | ||
|
|
a46ccbd883 | ||
|
|
5dda1abc32 | ||
|
|
55640a31b3 | ||
|
|
88428cff3a | ||
|
|
c24b58e2ee | ||
|
|
9e537c808b | ||
|
|
2c4543b9e9 | ||
|
|
b58bca9a72 | ||
|
|
27dcf470dc | ||
|
|
caa8290510 | ||
|
|
7f9b225cc2 | ||
|
|
4ccb2e2c21 | ||
|
|
cbee283c26 | ||
|
|
9fcda95a6f | ||
|
|
7ada64d5f8 | ||
|
|
20f0d917be | ||
|
|
e312db1408 | ||
|
|
743bd1275f | ||
|
|
69c86379e3 | ||
|
|
46b3c1a025 | ||
|
|
3ea893464f | ||
|
|
738e789dbd | ||
|
|
66afcf5be0 | ||
|
|
4b0ed56e32 | ||
|
|
dc2af8347b | ||
|
|
64ea8829af | ||
|
|
629cfec8a3 | ||
|
|
7f63658709 | ||
|
|
5e4d9a3197 | ||
|
|
982354765b | ||
|
|
5fe0576dcb |
2
.gitignore
vendored
2
.gitignore
vendored
@@ -6,6 +6,7 @@
|
||||
core
|
||||
tags
|
||||
.deps/
|
||||
compat/.dirstamp
|
||||
aclocal.m4
|
||||
autom4te.cache/
|
||||
config.log
|
||||
@@ -15,3 +16,4 @@ tmux
|
||||
Makefile
|
||||
Makefile.in
|
||||
configure
|
||||
tmux.1.*
|
||||
|
||||
77
CHANGES
77
CHANGES
@@ -1,3 +1,69 @@
|
||||
CHANGES FROM 1.9 to 1.9a 22 February 2014
|
||||
|
||||
NOTE: This is a bug-fix release to address some important bugs which just
|
||||
missed the 1.9 deadline, but were found afterwards.
|
||||
|
||||
Normal Changes
|
||||
==============
|
||||
|
||||
* Fix crash due to uninitialized lastwp member of layout_cell
|
||||
* Fix -fg/-bg/-style with 256 colour terminals.
|
||||
|
||||
CHANGES FROM 1.8 to 1.9, 20 February 2014
|
||||
|
||||
NOTE: This release has bumped the tmux protocol version. It is therefore
|
||||
advised that the prior tmux server is restarted when this version of tmux is
|
||||
installed, to avoid protocol mismatch errors for newer clients trying to
|
||||
talk to an older running tmux server.
|
||||
|
||||
Incompatible Changes
|
||||
====================
|
||||
|
||||
* 88 colour support has been removed.
|
||||
* 'default-path' has been removed. The new-window command accepts '-c' to
|
||||
cater for this. The previous value of "." can be replaced with: 'neww -c
|
||||
$PWD', the previous value of '' which meant current path of the pane can
|
||||
be specified as: 'neww -c "#{pane_current_path}"'
|
||||
|
||||
Deprecated Changes
|
||||
==================
|
||||
|
||||
* The single format specifiers: #A -> #Z (where defined) have been
|
||||
deprecated and replaced with longer-named equivalents, as listed in the
|
||||
FORMATS section of the tmux manpage.
|
||||
* The various foo-{fg,bg,attr} commands have been deprecated and replaced
|
||||
with equivalent foo-style option instead. Currently this is still
|
||||
backwards-compatible, but will be removed over time.
|
||||
|
||||
Normal Changes
|
||||
==============
|
||||
|
||||
* A new environment variable TMUX_TMPDIR is now honoured, allowing the
|
||||
socket directory to be set outside of TMPDIR (/tmp/ if not set).
|
||||
* If -s not given to swap-pane the current pane is assumed.
|
||||
* A #{pane_syncronized} format specifier has been added to be a conditional
|
||||
format if a pane is in a syncronised mode (c.f. syncronize-panes)
|
||||
* Tmux now runs under Cygwin natively.
|
||||
* Formats can now be nested within each other and expanded accordingly.
|
||||
* Added 'automatic-rename-format' option to allow the automatic rename
|
||||
mechanism to use something other than the default of
|
||||
#{pane_current_command}.
|
||||
* new-session learnt '-c' to specify the starting directory for that session
|
||||
and all subsequent windows therein.
|
||||
* The session name is now shown in the message printed to the terminal when
|
||||
a session is detached.
|
||||
* Lots more format specifiers have been added.
|
||||
* Server race conditions have been fixed; in particular commands are not run
|
||||
until after the configuration file is read completely.
|
||||
* Case insensitive searching in tmux's copy-mode is now possible.
|
||||
* attach-session and switch-client learnt the '-t' option to accept a window
|
||||
and/or a pane to use.
|
||||
* Copy-mode is only exited if no selection is in progress.
|
||||
* Paste key in copy-mode is now possible to enter text from the clipboard.
|
||||
* status-interval set to '0' now works as intended.
|
||||
* tmux now supports 256 colours running under fbterm.
|
||||
* Many bug fixes!
|
||||
|
||||
CHANGES FROM 1.7 to 1.8, 26 March 2013
|
||||
|
||||
Incompatible Changes
|
||||
@@ -17,7 +83,7 @@ Normal Changes
|
||||
* run-shell learnt '-t' to specify the pane to use when displaying output.
|
||||
* Support for middle-click pasting.
|
||||
* choose-tree learns '-u' to start uncollapsed.
|
||||
* select-window learnt '-T; to toggle to the last window if it's already
|
||||
* select-window learnt '-T' to toggle to the last window if it's already
|
||||
current.
|
||||
* New session option 'assume-paste-time' for pasting text versus key-binding
|
||||
actions.
|
||||
@@ -37,9 +103,9 @@ Normal Changes
|
||||
the 'source-file' command.
|
||||
* 'copy-pipe' mode command to copy selection and pipe the selection to a
|
||||
command.
|
||||
* Changes panes can now emit focus notifications for certain applications
|
||||
* Panes can now emit focus notifications for certain applications
|
||||
which use those.
|
||||
* run-shell and if-shell now accept format placeholders.
|
||||
* run-shell and if-shell now accept formats.
|
||||
* resize-pane learnt '-Z' for zooming a pane temporarily.
|
||||
* new-session learnt '-A' to make it behave like attach-session.
|
||||
* set-option learnt '-o' to prevent setting an option which is already set.
|
||||
@@ -1801,8 +1867,3 @@ The list of older changes is below.
|
||||
customisation.
|
||||
|
||||
$Id$
|
||||
|
||||
LocalWords: showw utf UTF fulvio ciriaco joshe OSC APC gettime abc DEF OA clr
|
||||
LocalWords: rivo nurges lscm Erdely eol smysession mysession ek dstname RB ms
|
||||
LocalWords: dstidx srcname srcidx winlink lsw nabc sabc Exp Tiago Cunha dch
|
||||
LocalWords: setw Chisnall renamew merdely eg Maier newname selectw neww Gass
|
||||
|
||||
21
COPYING
Normal file
21
COPYING
Normal file
@@ -0,0 +1,21 @@
|
||||
THIS IS FOR INFORMATION ONLY, CODE IS UNDER THE LICENCE AT THE TOP OF ITS FILE.
|
||||
|
||||
The README, CHANGES, FAQ and TODO files are licensed under the ISC
|
||||
license. Files under examples/ remain copyright their authors unless otherwise
|
||||
stated in the file but permission has been received to distribute them with
|
||||
tmux. All other files have a license and copyright notice at their start,
|
||||
typically:
|
||||
|
||||
Copyright (c) <author>
|
||||
|
||||
Permission to use, copy, modify, and distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
|
||||
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
||||
OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
73
FAQ
73
FAQ
@@ -95,9 +95,6 @@ aware of are (bearing in mind I haven't used screen for a few years now):
|
||||
- screen has builtin serial and telnet support; this is bloat and is unlikely
|
||||
to be added to tmux.
|
||||
|
||||
- screen has support for updating utmp. Nobody has really come up with a clean,
|
||||
portable way to do this without making tmux setuid or setgid yet.
|
||||
|
||||
- Environment handling is different.
|
||||
|
||||
- tmux tends to be more demanding on the terminal so tends to show up terminal
|
||||
@@ -107,6 +104,10 @@ aware of are (bearing in mind I haven't used screen for a few years now):
|
||||
|
||||
* I found a bug! What do I do?
|
||||
|
||||
Check the latest version of tmux from Git to see if the problem is still
|
||||
reproducible. Sometimes the length of time between releases means a lot of
|
||||
fixes can be sitting in Git and the problem might already be fixed.
|
||||
|
||||
Please send bug reports by email to nicm@users.sourceforge.net or
|
||||
tmux-users@lists.sourceforge.net. Please include as much of the following
|
||||
information as possible:
|
||||
@@ -238,6 +239,31 @@ would be welcome.
|
||||
|
||||
vim users may also want to set the "ttyfast" option inside tmux.
|
||||
|
||||
* How do I make ctrl and shift arrow keys work in emacs?
|
||||
|
||||
The terminal-init-screen function in term/screen.el is called for new frames,
|
||||
but it doesn't configure any function keys.
|
||||
|
||||
If the tmux xterm-keys option is on, it is enough to define the same keys as
|
||||
xterm. Add the following to init.el or .emacs to do this:
|
||||
|
||||
(defadvice terminal-init-screen
|
||||
;; The advice is named `tmux', and is run before `terminal-init-screen' runs.
|
||||
(before tmux activate)
|
||||
;; Docstring. This describes the advice and is made available inside emacs;
|
||||
;; for example when doing C-h f terminal-init-screen RET
|
||||
"Apply xterm keymap, allowing use of keys passed through tmux."
|
||||
;; This is the elisp code that is run before `terminal-init-screen'.
|
||||
(if (getenv "TMUX")
|
||||
(let ((map (copy-keymap xterm-function-map)))
|
||||
(set-keymap-parent map (keymap-parent input-decode-map))
|
||||
(set-keymap-parent input-decode-map map))))
|
||||
|
||||
And ensure .tmux.conf contains "set -g xterm-keys on".
|
||||
|
||||
Alternatively, the screen.el file can be copied to the load path and
|
||||
customized.
|
||||
|
||||
* Why doesn't elinks set the window title inside tmux?
|
||||
|
||||
There isn't a way to detect if a terminal supports setting the window title, so
|
||||
@@ -377,7 +403,7 @@ always (or ever) be added to the scrollback.
|
||||
You can make tmux use the normal screen by telling it that your terminal does
|
||||
not have an alternate screen. Put the following in ~/.tmux.conf:
|
||||
|
||||
set -g terminal-overrides 'xterm*:smcup@:rmcup@'
|
||||
set -ga terminal-overrides ',xterm*:smcup@:rmcup@'
|
||||
|
||||
Adjust if your $TERM does not start with xterm.
|
||||
|
||||
@@ -396,5 +422,44 @@ configuration file:
|
||||
Or the default window options:
|
||||
|
||||
$ tmux -Lfoo -f/dev/null start\; show -gw
|
||||
|
||||
* How do I copy a selection from tmux to the system's clipboard?
|
||||
|
||||
When running in xterm(1), tmux can automatically send copied text to the
|
||||
clipboard. This is controlled by the set-clipboard option and also needs this
|
||||
X resource to be set:
|
||||
|
||||
XTerm*disallowedWindowOps: 20,21,SetXprop
|
||||
|
||||
For rxvt-unicode (urxvt), there is an unofficial Perl extension here:
|
||||
|
||||
http://anti.teamidiot.de/static/nei/*/Code/urxvt/
|
||||
|
||||
Otherwise a key binding for copy mode using xclip (or xsel) works:
|
||||
|
||||
bind -temacs-copy C-y copy-pipe "xclip -i >/dev/null"
|
||||
|
||||
Or for inside and outside copy mode with the prefix key:
|
||||
|
||||
bind C-y run -b "tmux save-buffer - | xclip -i"
|
||||
|
||||
On OS X, reattach-to-usernamespace lets pbcopy/pbpaste work:
|
||||
|
||||
https://github.com/ChrisJohnsen/tmux-MacOSX-pasteboard
|
||||
|
||||
* Why do I see dots around a session when I attach to it?
|
||||
|
||||
tmux limits the size of the window to the smallest attached session. If
|
||||
it didn't do this then it would be impossible to see the entire window.
|
||||
The dots mark the size of the window tmux can display.
|
||||
|
||||
To avoid this, detach all other clients when attaching:
|
||||
|
||||
$ tmux attach -d
|
||||
|
||||
Or from inside tmux by detaching individual clients with C-b D or all
|
||||
using:
|
||||
|
||||
C-b : attach -d
|
||||
|
||||
$Id$
|
||||
|
||||
58
Makefile.am
58
Makefile.am
@@ -2,18 +2,19 @@
|
||||
|
||||
# Obvious program stuff.
|
||||
bin_PROGRAMS = tmux
|
||||
dist_man1_MANS = tmux.1
|
||||
CLEANFILES = tmux.1.mdoc tmux.1.man
|
||||
|
||||
# Distribution tarball options.
|
||||
EXTRA_DIST = \
|
||||
CHANGES FAQ README TODO examples compat \
|
||||
array.h compat.h tmux.h osdep-*.c
|
||||
CHANGES FAQ README TODO COPYING examples compat \
|
||||
array.h compat.h tmux.h osdep-*.c mdoc2man.awk tmux.1
|
||||
dist-hook:
|
||||
make clean
|
||||
grep "^#found_debug=" configure
|
||||
find $(distdir) -name .svn -type d|xargs rm -Rf
|
||||
|
||||
# Preprocessor flags.
|
||||
CPPFLAGS += @XOPEN_DEFINES@
|
||||
CPPFLAGS += @XOPEN_DEFINES@ -DTMUX_CONF="\"$(sysconfdir)/tmux.conf\""
|
||||
|
||||
# glibc as usual does things ass-backwards and hides useful things by default,
|
||||
# so everyone has to add this.
|
||||
@@ -24,32 +25,34 @@ endif
|
||||
# Set flags for gcc. gcc4 whines abouts silly stuff so it needs slightly
|
||||
# different flags.
|
||||
if IS_GCC
|
||||
CFLAGS += -std=gnu99
|
||||
CFLAGS += -std=gnu99 -O2
|
||||
if IS_DEBUG
|
||||
CFLAGS += -O0 -g
|
||||
CFLAGS += -g
|
||||
CFLAGS += -Wno-long-long -Wall -W -Wnested-externs -Wformat=2
|
||||
CFLAGS += -Wmissing-prototypes -Wstrict-prototypes -Wmissing-declarations
|
||||
CFLAGS += -Wwrite-strings -Wshadow -Wpointer-arith -Wsign-compare
|
||||
CFLAGS += -Wundef -Wbad-function-cast -Winline -Wcast-align
|
||||
CFLAGS += -Wdeclaration-after-statement
|
||||
CPPFLAGS += -DDEBUG
|
||||
else
|
||||
CFLAGS += -O2
|
||||
endif
|
||||
if IS_GCC4
|
||||
CPPFLAGS += -iquote. -I/usr/local/include
|
||||
CPPFLAGS += -iquote.
|
||||
if IS_DEBUG
|
||||
CFLAGS += -Wno-pointer-sign
|
||||
endif
|
||||
else
|
||||
CPPFLAGS += -I. -I- -I/usr/local/include
|
||||
CPPFLAGS += -I. -I-
|
||||
endif
|
||||
endif
|
||||
|
||||
# Set flags for Solaris.
|
||||
if IS_SUNOS
|
||||
if IS_GCC
|
||||
CPPFLAGS += -D_XPG6 -D__EXTENSIONS__ -D_POSIX_PTHREAD_SEMANTICS
|
||||
else
|
||||
CPPFLAGS += -D_XPG4_2 -D__EXTENSIONS__ -D_POSIX_PTHREAD_SEMANTICS
|
||||
endif
|
||||
endif
|
||||
|
||||
# Set flags for Sun CC.
|
||||
if IS_SUNCC
|
||||
@@ -62,17 +65,14 @@ dist_tmux_SOURCES = \
|
||||
attributes.c \
|
||||
cfg.c \
|
||||
client.c \
|
||||
clock.c \
|
||||
cmd-attach-session.c \
|
||||
cmd-bind-key.c \
|
||||
cmd-break-pane.c \
|
||||
cmd-capture-pane.c \
|
||||
cmd-choose-buffer.c \
|
||||
cmd-choose-client.c \
|
||||
cmd-choose-list.c \
|
||||
cmd-choose-tree.c \
|
||||
cmd-clear-history.c \
|
||||
cmd-clock-mode.c \
|
||||
cmd-command-prompt.c \
|
||||
cmd-confirm-before.c \
|
||||
cmd-copy-mode.c \
|
||||
@@ -81,17 +81,14 @@ dist_tmux_SOURCES = \
|
||||
cmd-display-message.c \
|
||||
cmd-display-panes.c \
|
||||
cmd-find-window.c \
|
||||
cmd-has-session.c \
|
||||
cmd-if-shell.c \
|
||||
cmd-join-pane.c \
|
||||
cmd-kill-pane.c \
|
||||
cmd-kill-server.c \
|
||||
cmd-kill-session.c \
|
||||
cmd-kill-window.c \
|
||||
cmd-link-window.c \
|
||||
cmd-list-buffers.c \
|
||||
cmd-list-clients.c \
|
||||
cmd-list-commands.c \
|
||||
cmd-list-keys.c \
|
||||
cmd-list-panes.c \
|
||||
cmd-list-sessions.c \
|
||||
@@ -118,7 +115,6 @@ dist_tmux_SOURCES = \
|
||||
cmd-select-pane.c \
|
||||
cmd-select-window.c \
|
||||
cmd-send-keys.c \
|
||||
cmd-server-info.c \
|
||||
cmd-set-buffer.c \
|
||||
cmd-set-environment.c \
|
||||
cmd-set-option.c \
|
||||
@@ -127,14 +123,11 @@ dist_tmux_SOURCES = \
|
||||
cmd-show-options.c \
|
||||
cmd-source-file.c \
|
||||
cmd-split-window.c \
|
||||
cmd-start-server.c \
|
||||
cmd-string.c \
|
||||
cmd-suspend-client.c \
|
||||
cmd-swap-pane.c \
|
||||
cmd-swap-window.c \
|
||||
cmd-switch-client.c \
|
||||
cmd-unbind-key.c \
|
||||
cmd-unlink-window.c \
|
||||
cmd-wait-for.c \
|
||||
cmd.c \
|
||||
colour.c \
|
||||
@@ -171,6 +164,7 @@ dist_tmux_SOURCES = \
|
||||
session.c \
|
||||
signal.c \
|
||||
status.c \
|
||||
style.c \
|
||||
tmux.c \
|
||||
tty-acs.c \
|
||||
tty-keys.c \
|
||||
@@ -213,6 +207,9 @@ endif
|
||||
if NO_FGETLN
|
||||
nodist_tmux_SOURCES += compat/fgetln.c
|
||||
endif
|
||||
if NO_FPARSELN
|
||||
nodist_tmux_SOURCES += compat/fparseln.c
|
||||
endif
|
||||
if NO_GETOPT
|
||||
nodist_tmux_SOURCES += compat/getopt.c
|
||||
endif
|
||||
@@ -231,6 +228,25 @@ endif
|
||||
if NO_B64_NTOP
|
||||
nodist_tmux_SOURCES += compat/b64_ntop.c
|
||||
endif
|
||||
if NO_CFMAKERAW
|
||||
nodist_tmux_SOURCES += compat/cfmakeraw.c
|
||||
endif
|
||||
if NO_OPENAT
|
||||
nodist_tmux_SOURCES += compat/openat.c
|
||||
endif
|
||||
|
||||
# Install tmux.1 in the right format.
|
||||
install-exec-hook:
|
||||
if test x@MANFORMAT@ = xmdoc; then \
|
||||
sed -e "s|@SYSCONFDIR@|$(sysconfdir)|g" $(srcdir)/tmux.1 \
|
||||
>$(srcdir)/tmux.1.mdoc; \
|
||||
else \
|
||||
sed -e "s|@SYSCONFDIR@|$(sysconfdir)|g" $(srcdir)/tmux.1| \
|
||||
$(AWK) -f$(srcdir)/mdoc2man.awk >$(srcdir)/tmux.1.man; \
|
||||
fi
|
||||
$(mkdir_p) $(DESTDIR)$(mandir)/man1
|
||||
$(INSTALL_DATA) $(srcdir)/tmux.1.@MANFORMAT@ \
|
||||
$(DESTDIR)$(mandir)/man1/tmux.1
|
||||
|
||||
# Update SF web site.
|
||||
upload-index.html: update-index.html
|
||||
@@ -245,4 +261,4 @@ update-index.html:
|
||||
convert "$$i" -resize 200x150 "small-$$i"; \
|
||||
done \
|
||||
)
|
||||
sed "s/%%VERSION%%/${VERSION}/g" www/index.html.in >www/index.html
|
||||
sed "s/%%RELEASE%%/${RELEASE}/g" www/index.html.in >www/index.html
|
||||
|
||||
2
README
2
README
@@ -7,7 +7,7 @@ simple, modern, BSD-licensed alternative to programs such as GNU screen.
|
||||
This release runs on OpenBSD, FreeBSD, NetBSD, Linux and OS X and may still
|
||||
run on Solaris and AIX (although they haven't been tested in a while).
|
||||
|
||||
Since the 1.2 release tmux depends on libevent. Download it from:
|
||||
tmux depends on libevent 2.x. Download it from:
|
||||
|
||||
http://www.monkey.org/~provos/libevent/
|
||||
|
||||
|
||||
9
SYNCING
9
SYNCING
@@ -131,6 +131,15 @@ And if happy:
|
||||
|
||||
% git push origin master
|
||||
|
||||
Keeping an eye on libutil in OpenBSD
|
||||
====================================
|
||||
|
||||
A lot of the compat/ code in tmux comes from libutil, especially imsg.
|
||||
Sometimes the API can change, etc., which might cause interesting problems
|
||||
trying to run the portable version of tmux. It's worth checking
|
||||
periodically for any changes to libutil in OpenBSD and syncing those files
|
||||
to compat/ as and when appropriate.
|
||||
|
||||
Release tmux for next version
|
||||
=============================
|
||||
|
||||
|
||||
294
TODO
294
TODO
@@ -1,155 +1,155 @@
|
||||
NOTES
|
||||
=====
|
||||
- command bits and pieces:
|
||||
* why doesn't command-prompt work if made read-only?
|
||||
* allow multiple targets: fnmatch for -t/-c, for example detach all
|
||||
clients with -t*
|
||||
* add -c for new-session like new-window
|
||||
* attach should take a pane and select it as well as attaching
|
||||
* ' and " should be parsed the same (eg "\e" vs '\e') in config
|
||||
and command prompt
|
||||
* last-pane across sessions
|
||||
* exact match operator for targets (or break the substring match
|
||||
and require eg x* instead of just x)
|
||||
|
||||
This file describes rough notes regarding ideas for potential future tmux
|
||||
development. It's not necessarily guaranteed that items in this TODO file
|
||||
will ever get implemented.
|
||||
- make command sequences more usable
|
||||
* don't require space after ;
|
||||
* options for error handling: && and ||?
|
||||
|
||||
It is asked therefore, that anyone thinking of undertaking a task in this
|
||||
TODO file, email tmux-users@lists.sf.net to discuss the feature.
|
||||
- options bits and pieces:
|
||||
* set-remain-on-exit is a complete hack
|
||||
* way to set socket path from config file
|
||||
|
||||
Thie file is split up between tmux user interface (UI) issues, and terminal
|
||||
compatibility issues.
|
||||
- format improvements:
|
||||
* last bits of status_replace into formats?
|
||||
* option to quote format (#{session_name:quoted})
|
||||
* formats need conditions for >0 (for #P)
|
||||
* some way to pad # stuff with spaces, #!2T maybe
|
||||
* last window update time and format for it
|
||||
* formats to show if a window is linked into multiple sessions, into
|
||||
multiple attached sessions, and is the active window in multiple
|
||||
attached sessions?
|
||||
|
||||
TMUX UI ISSUES
|
||||
==============
|
||||
- choose mode improvements:
|
||||
* choose-pane command (augment choose-tree to do this?)
|
||||
* choose-mode and copy-mode are very similar, make choose-mode a subset?
|
||||
* flag to choose-* for sort order
|
||||
* choose mode would be better per client than per window?
|
||||
* two choices (first one then second, for swap-pane and join-pane)
|
||||
|
||||
- improve monitor-*:
|
||||
* straighten out rules for multiple clients
|
||||
* think about what happens across sessions
|
||||
* monitor changes within a region
|
||||
* perhaps monitor /all/ panes in the window not just one
|
||||
|
||||
- improve mouse support:
|
||||
* bind commands to mouse in different areas?
|
||||
* more fine-grained options?
|
||||
* commands executed when clicking on a pattern (URL)
|
||||
* mouse-select-pane will screw up with !MODE_MOUSE_STANDARD (it sets
|
||||
the flag on w/o checking the others before calling tty_update_mode)
|
||||
* mouse can be like normal key bindings?
|
||||
- {button-{1,2,3},wheel-{up,down}}-{status,pane,border} and
|
||||
drag-{start,end}-{status,pane,border} plus the modifiers
|
||||
- resize and copy can be special cases - once you call something
|
||||
like copy-mode -M or resize-pane -M to start the drag, it tracks
|
||||
mouse until you call -m to stop the drag. or just keep drags
|
||||
entirely special?
|
||||
- what happens with stuff that wants mouse inside? especially for
|
||||
pane clicks which need to run command AND pass event through
|
||||
(like mouse-select-pane). maybe just a flag to say whether it
|
||||
always runs or only if pane hasn't taken mouse? or it could be
|
||||
eg bind Button1Pane "select-pane -t=; send-keys -Mt='
|
||||
- also need a) some way to tell commands bound to key which
|
||||
window or pane the mouse key binding applies to (maybe a new
|
||||
special char in target, or pass targets through formats?) b) a
|
||||
way to bind repeat count to mode keys so that wheel up/down can
|
||||
do multiple lines c) send-keys -M to pass a mouse event through?
|
||||
- what does the mouse->KEYC_* conversion and find-the-pane bit?
|
||||
server_client_handle_key?
|
||||
|
||||
- hooks!
|
||||
|
||||
- implicitly add exec to the commands for new windows (switch to disable it)?
|
||||
- bring back detach-session to detach all clients on a session?
|
||||
- allow fnmatch for -c, so that you can, eg, detach all clients
|
||||
- garbage collect window history (100 lines at a time?) if it hasn't been used
|
||||
in $x time
|
||||
- flags to centre screen in window
|
||||
- activity/bell should be per-window not per-link? what if it is cur win in
|
||||
session not being watched?
|
||||
- should be able to move to a hidden pane and it would be moved into view. pane
|
||||
number in status line/top-right would be cool for this
|
||||
- support other mouse modes (highlight etc) and use it in copy mode
|
||||
- set-remain-on-exit is a bit of a hack, some way to do it generically?
|
||||
- would be nice to be able to use "--" to mark start of command w/ neww etc
|
||||
to avoid quoting
|
||||
- make command sequences more usable: don't require space after ;, handle
|
||||
errors better
|
||||
- choice and more mode would be better per client than per window?
|
||||
- hooks to which commands may be attached, for example: tmux add-hook
|
||||
"new-session" if-shell "[ -e $HOME/.tmux-session.conf ]" source-file
|
||||
$HOME/.tmux-session.conf
|
||||
- way to set socket path from config file
|
||||
- warts on current naming:
|
||||
- display-time but message-fg/bg/attr
|
||||
- list-* vs show-*
|
||||
- server-info
|
||||
- up-pane/down-pane/swap-pane -U/swap-pane -D vs next-*/previous-*
|
||||
- split-window -> split-pane??
|
||||
- some way to force a screen to use the entire terminal even if it is forced
|
||||
to be smaller by other clients. pan smaller terminal? (like screen F)
|
||||
-- idea of a "view" onto a window, need base x/y offsets for redraw
|
||||
- commands should be able to succeed or fail and have || or && for command
|
||||
lists
|
||||
- some way to keep a command running continually and just use its last line of
|
||||
output
|
||||
- UTF-8 to a non-UTF-8 terminal should not be able to balls up
|
||||
the terminal - www/ruby-addressable; make regress
|
||||
- support esc-esc to quit in modes
|
||||
- fix ctrl+F1-F4 output. to what?
|
||||
- better utf8 support: window names, prompt input, message display
|
||||
- option to move copy mode indicator into status line
|
||||
- selection behaviour closer to vi in vi mode
|
||||
- live update: server started with -U connects to server, requests sessions and
|
||||
windows, receives fds
|
||||
- sort out inheriting config from shell on new sessions/windows:
|
||||
should pick up default-path/termios/etc from client if possible,
|
||||
else leave empty/default
|
||||
- link panes into multiple windows
|
||||
- bells should be passed between sessions with visual-bell etc
|
||||
sequence until its shell exits, to allow them to be used from the config file
|
||||
- better session sharing: create-socket command to create socket somewhere (-r
|
||||
flag for readonly)
|
||||
- multiline status line (no?)
|
||||
- support title stack, both internally and externally
|
||||
http://docs.freebsd.org/cgi/getmsg.cgi?fetch=1149299+0+archive/2010/freebsd-questions/20100207.freebsd-questions
|
||||
- some way to pad # stuff with spaces, #!2T maybe
|
||||
- a binding to "scroll down and exit at bottom" copy mode
|
||||
- some way to pass keystrokes in copy mode through to underlying window. why?
|
||||
- last window update time and # replacement for it for display-message
|
||||
- find-window across sessions - other ways to make session handling easier?
|
||||
- ' and " should be parsed the same (eg "\e" vs '\e') in config and command
|
||||
prompt?
|
||||
- command to toggle selection not to move it in copy-mode
|
||||
- audit of escape sequence support vs xterm
|
||||
- support binding keys to mouse (mouse-select-pane -> mouse-keys or something,
|
||||
mouse click == select-pane -t %%, mouse scroll up == copy-mode)
|
||||
- bind commands to key sequences? -- make it so ALL keys go through a table,
|
||||
first an implicit table in which C-b is the only default binding to a
|
||||
command that says "next key from $othertable" and so on. means -n can
|
||||
go away as well
|
||||
- monitor, bell etc should monitor /all/ panes in the window not just one
|
||||
- a history of commands that can be reversed (reverse member of each command,
|
||||
and a buffer)
|
||||
- info() when changing to same window
|
||||
- way to add dest for break-pane; maybe some easier way to unbreak-pane
|
||||
- case insensitive searching
|
||||
- incremental searching in copy mode.
|
||||
- configurable borders and empty space filler for when panes < window?
|
||||
- mouse-select-pane will screw up with !MODE_MOUSE_STANDARD (it sets the
|
||||
flag on w/o checking the others before calling tty_update_mode)
|
||||
- pass shell commands as argv rather than strings, allow them to be specified
|
||||
in commands without quotes
|
||||
- named buffers and allow gaps in the stack
|
||||
- monitor-activity is broken in several ways with multiple clients
|
||||
- monitor-activity should be more powerful (eg set a region)
|
||||
- maybe a way to put pane names instead of window names in status line
|
||||
- support for borderless panes
|
||||
- wait-for command 20130222153957.GY6782@yelena.nicm.ath.cx
|
||||
- last-pane across sessions
|
||||
- panes should have names like windows
|
||||
- command-prompt doesn't work if made read-only. why?
|
||||
- option to quote format eg #{session_name:quoted}
|
||||
- formats need conditions for >0 (for #P)
|
||||
- fetch full command line on !Linux, and add option to strip prefixes
|
||||
such as "sh " "/bin/sh " etc etc
|
||||
- synchronize-windows option
|
||||
- append to buffer in copy mode
|
||||
- way to paste w/o trailing whitespace
|
||||
- flag to switch-client to switch all clients
|
||||
- history of layouts and undo/redo flags to selectl
|
||||
- way to tag a layout as a number/name
|
||||
- optimize pane redraws, 20120318184853.GK10965@yelena.nicm.ath.cx
|
||||
- support multibyte key strings
|
||||
- allow commands to be executed when certain patterns in a screen
|
||||
are clicked on with the mouse
|
||||
- flag to make next/previous commands skip a window
|
||||
- way to do tmux command/run-shell from mode keys
|
||||
- send command to all windows
|
||||
- choose-pane command (augment choose-tree to do this?)
|
||||
- choose-mode and copy-mode are very similar. Perhaps make choose-mode a subset
|
||||
of copy-mode in that it inherits key-bindings and other traits but not all
|
||||
- add -c for new-session like new-window
|
||||
- flag to choose-* for sort order (eg sort windows/sessions/clients by last
|
||||
used time) - perhaps using formats (but what about numeric sort)?
|
||||
- instead of separate window and session options, just one master options list
|
||||
with each option having a type (window or session), then options on window,
|
||||
on session, and global. for window options we look window->session->global,
|
||||
and for session we look session->global
|
||||
- maybe keep last layout + size around and if size reverts just put it back
|
||||
- way to set hints/limits about pane size for resizing
|
||||
- revamp layouts: they are too complicated, should be more closely integrated,
|
||||
should support hints, layout sets should just be a special case of custom
|
||||
layouts, and we should support panes that are not attached to a cell at
|
||||
all. this could be the time to introduce panelink to replace layout_cell
|
||||
- run-shell/if-shell should support formats
|
||||
- attach should take a pane and select it as well as attaching
|
||||
- attach should have a flag to create session if it doesn't exist. or better
|
||||
new a flag to attach it
|
||||
* display-time but message-fg/bg/attr
|
||||
* list-* vs show-*
|
||||
* split-window -> split-pane??
|
||||
|
||||
TERMINAL ISSUES
|
||||
================
|
||||
- better UTF-8 support:
|
||||
* window names and titles
|
||||
* message display
|
||||
* prompt input
|
||||
* multibyte key input
|
||||
|
||||
- use a better termcap internally instead of screen, perhaps xterm
|
||||
- clear window title on exit (see using xterm title stack)
|
||||
- get it passing all the vttest tests that don't require resizing the terminal
|
||||
- support for bce
|
||||
- use screen-256color when started on 256 colour terminal?
|
||||
* We need a tmux terminfo entry to document the extensions we are using in
|
||||
upstream terminfo. Must NOT change (only add or remove) anything from
|
||||
TERM=screen so we can fallback!
|
||||
- copy/paste improvements:
|
||||
* incremental searching
|
||||
* append to buffer
|
||||
* paste w/o trailing whitespace
|
||||
* command to toggle selection not to move it in copy-mode
|
||||
|
||||
- layout stuff
|
||||
* way to tag a layout as a number/name
|
||||
* maybe keep last layout + size around and if size reverts just put it
|
||||
back
|
||||
* revamp layouts: they are too complicated, should be more closely
|
||||
integrated, should support hints, layout sets should just be a
|
||||
special case of custom layouts, and we should support panes that are
|
||||
not attached to a cell at all. this could be the time to introduce
|
||||
panelink to replace layout_cell
|
||||
* way to set hints/limits about pane size for resizing
|
||||
* panning over window (window larger than visible)
|
||||
* a mode where one application can cross two panes (ie x|y, width =
|
||||
COLUMNS/2 but height = ROWS * 2)
|
||||
* general key to space cells out evenly (horiz or vert) within their
|
||||
parent cell (could replace even-vert/even-horiz layouts)
|
||||
|
||||
- terminfo bits
|
||||
* use a better termcap internally instead of screen, perhaps xterm
|
||||
* use screen-256color when started on 256 colour terminal?
|
||||
* need a tmux terminfo entry to document the extensions we are using in
|
||||
upstream terminfo
|
||||
|
||||
- code cleanup
|
||||
* instead of separate window and session options, just one master
|
||||
options list with each option having a type (window or session), then
|
||||
options on window, on session, and global. for window options we look
|
||||
window->session->global, and for session we look session->global
|
||||
* the way pane, window, session destroy is handled is too complicated
|
||||
and the distinction between session.c, window.c and server-fn.c
|
||||
functions is not clear. could we just have kill_pane(),
|
||||
kill_window(), unlink_window(), kill_session() that fix up all data
|
||||
structures (flagging sessions as dead) and return a value to say
|
||||
whether clients need to be checked for dead sessions? sort of like
|
||||
session_detach now but more so. or some other scheme to make it
|
||||
simpler and clearer? also would be nice to remove/rename server-fn.c
|
||||
* more readable way to work out the various things commands need to
|
||||
know about the client, notably:
|
||||
- is this the config file? (cmdq->c == NULL)
|
||||
- is this a command client? (cmdq->c != NULL &&
|
||||
cmdq->c->session == NULL)
|
||||
- is this a control client?
|
||||
- can i do stdin or stdout to this client?
|
||||
or even guarantee that cmdq->c != NULL and provide a better way to
|
||||
tell when in the config file - then we use cmdq->c if we need a
|
||||
client w/o a session else cmd_current_client
|
||||
* optimize pane redraws, 20120318184853.GK10965@yelena.nicm.ath.cx
|
||||
* cmd_find_* could be much simpler - parse everything the same, only
|
||||
difference is what to choose when not given a ":" or "." (such as a
|
||||
plain "0" could be session, window or pane). So just cmd_find_target
|
||||
with a type (session, window, or pane)..
|
||||
|
||||
- miscellaneous
|
||||
* way to keep a job running just read its last line of output for #()
|
||||
* link panes into multiple windows
|
||||
* live update: server started with -U connects to server, requests
|
||||
sessions and windows, receives file descriptors
|
||||
* there are inconsistencies in what we get from old shell and what
|
||||
comes from config for new sessions and windows. likewise, panes and
|
||||
jobs and run-shell and lock command all start with slightly different
|
||||
environments
|
||||
* multiline status line?
|
||||
* bind commands to key sequences -- make it so ALL keys go through a
|
||||
table, first an implicit table in which C-b is the only default
|
||||
binding to a command that says "next key from $othertable" and so
|
||||
on. means -n can go away as well
|
||||
* customizable command aliases
|
||||
* any remaining clients in wait-for should be woken when server exits
|
||||
|
||||
132
arguments.c
132
arguments.c
@@ -1,4 +1,4 @@
|
||||
/* $Id$ */
|
||||
/* $OpenBSD$ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2010 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||
@@ -18,11 +18,28 @@
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <getopt.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "tmux.h"
|
||||
|
||||
/*
|
||||
* Manipulate command arguments.
|
||||
*/
|
||||
|
||||
struct args_entry *args_find(struct args *, u_char);
|
||||
|
||||
RB_GENERATE(args_tree, args_entry, entry, args_cmp);
|
||||
|
||||
/* Arguments tree comparison function. */
|
||||
int
|
||||
args_cmp(struct args_entry *a1, struct args_entry *a2)
|
||||
{
|
||||
return (a1->flag - a2->flag);
|
||||
}
|
||||
|
||||
/* Create an arguments set with no flags. */
|
||||
struct args *
|
||||
args_create(int argc, ...)
|
||||
@@ -32,8 +49,6 @@ args_create(int argc, ...)
|
||||
int i;
|
||||
|
||||
args = xcalloc(1, sizeof *args);
|
||||
if ((args->flags = bit_alloc(SCHAR_MAX)) == NULL)
|
||||
fatal("bit_alloc failed");
|
||||
|
||||
args->argc = argc;
|
||||
if (argc == 0)
|
||||
@@ -49,35 +64,36 @@ args_create(int argc, ...)
|
||||
return (args);
|
||||
}
|
||||
|
||||
/* Find a flag in the arguments tree. */
|
||||
struct args_entry *
|
||||
args_find(struct args *args, u_char ch)
|
||||
{
|
||||
struct args_entry entry;
|
||||
|
||||
entry.flag = ch;
|
||||
return (RB_FIND(args_tree, &args->tree, &entry));
|
||||
}
|
||||
|
||||
/* Parse an argv and argc into a new argument set. */
|
||||
struct args *
|
||||
args_parse(const char *template, int argc, char **argv)
|
||||
{
|
||||
struct args *args;
|
||||
char *ptr;
|
||||
int opt;
|
||||
|
||||
args = xcalloc(1, sizeof *args);
|
||||
if ((args->flags = bit_alloc(SCHAR_MAX)) == NULL)
|
||||
fatal("bit_alloc failed");
|
||||
|
||||
optreset = 1;
|
||||
optind = 1;
|
||||
|
||||
while ((opt = getopt(argc, argv, template)) != -1) {
|
||||
if (opt < 0 || opt >= SCHAR_MAX)
|
||||
if (opt < 0)
|
||||
continue;
|
||||
if (opt == '?' || (ptr = strchr(template, opt)) == NULL) {
|
||||
free(args->flags);
|
||||
free(args);
|
||||
if (opt == '?' || strchr(template, opt) == NULL) {
|
||||
args_free(args);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
bit_set(args->flags, opt);
|
||||
if (ptr[1] == ':') {
|
||||
free(args->values[opt]);
|
||||
args->values[opt] = xstrdup(optarg);
|
||||
}
|
||||
args_set(args, opt, optarg);
|
||||
}
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
@@ -92,14 +108,17 @@ args_parse(const char *template, int argc, char **argv)
|
||||
void
|
||||
args_free(struct args *args)
|
||||
{
|
||||
u_int i;
|
||||
struct args_entry *entry;
|
||||
struct args_entry *entry1;
|
||||
|
||||
cmd_free_argv(args->argc, args->argv);
|
||||
|
||||
for (i = 0; i < SCHAR_MAX; i++)
|
||||
free(args->values[i]);
|
||||
RB_FOREACH_SAFE(entry, args_tree, &args->tree, entry1) {
|
||||
RB_REMOVE(args_tree, &args->tree, entry);
|
||||
free(entry->value);
|
||||
free(entry);
|
||||
}
|
||||
|
||||
free(args->flags);
|
||||
free(args);
|
||||
}
|
||||
|
||||
@@ -107,9 +126,10 @@ args_free(struct args *args)
|
||||
size_t
|
||||
args_print(struct args *args, char *buf, size_t len)
|
||||
{
|
||||
size_t off;
|
||||
int i;
|
||||
const char *quotes;
|
||||
size_t off, used;
|
||||
int i;
|
||||
const char *quotes;
|
||||
struct args_entry *entry;
|
||||
|
||||
/* There must be at least one byte at the start. */
|
||||
if (len == 0)
|
||||
@@ -118,23 +138,23 @@ args_print(struct args *args, char *buf, size_t len)
|
||||
|
||||
/* Process the flags first. */
|
||||
buf[off++] = '-';
|
||||
for (i = 0; i < SCHAR_MAX; i++) {
|
||||
if (!bit_test(args->flags, i) || args->values[i] != NULL)
|
||||
RB_FOREACH(entry, args_tree, &args->tree) {
|
||||
if (entry->value != NULL)
|
||||
continue;
|
||||
|
||||
if (off == len - 1) {
|
||||
buf[off] = '\0';
|
||||
return (len);
|
||||
}
|
||||
buf[off++] = i;
|
||||
buf[off++] = entry->flag;
|
||||
buf[off] = '\0';
|
||||
}
|
||||
if (off == 1)
|
||||
buf[--off] = '\0';
|
||||
|
||||
/* Then the flags with arguments. */
|
||||
for (i = 0; i < SCHAR_MAX; i++) {
|
||||
if (!bit_test(args->flags, i) || args->values[i] == NULL)
|
||||
RB_FOREACH(entry, args_tree, &args->tree) {
|
||||
if (entry->value == NULL)
|
||||
continue;
|
||||
|
||||
if (off >= len) {
|
||||
@@ -142,12 +162,16 @@ args_print(struct args *args, char *buf, size_t len)
|
||||
return (len);
|
||||
}
|
||||
|
||||
if (strchr(args->values[i], ' ') != NULL)
|
||||
if (strchr(entry->value, ' ') != NULL)
|
||||
quotes = "\"";
|
||||
else
|
||||
quotes = "";
|
||||
off += xsnprintf(buf + off, len - off, "%s-%c %s%s%s",
|
||||
off != 0 ? " " : "", i, quotes, args->values[i], quotes);
|
||||
used = xsnprintf(buf + off, len - off, "%s-%c %s%s%s",
|
||||
off != 0 ? " " : "", entry->flag, quotes, entry->value,
|
||||
quotes);
|
||||
if (used > len - off)
|
||||
used = len - off;
|
||||
off += used;
|
||||
}
|
||||
|
||||
/* And finally the argument vector. */
|
||||
@@ -161,8 +185,11 @@ args_print(struct args *args, char *buf, size_t len)
|
||||
quotes = "\"";
|
||||
else
|
||||
quotes = "";
|
||||
off += xsnprintf(buf + off, len - off, "%s%s%s%s",
|
||||
used = xsnprintf(buf + off, len - off, "%s%s%s%s",
|
||||
off != 0 ? " " : "", quotes, args->argv[i], quotes);
|
||||
if (used > len - off)
|
||||
used = len - off;
|
||||
off += used;
|
||||
}
|
||||
|
||||
return (off);
|
||||
@@ -172,42 +199,55 @@ args_print(struct args *args, char *buf, size_t len)
|
||||
int
|
||||
args_has(struct args *args, u_char ch)
|
||||
{
|
||||
return (bit_test(args->flags, ch));
|
||||
return (args_find(args, ch) == NULL ? 0 : 1);
|
||||
}
|
||||
|
||||
/* Set argument value. */
|
||||
/* Set argument value in the arguments tree. */
|
||||
void
|
||||
args_set(struct args *args, u_char ch, const char *value)
|
||||
{
|
||||
free(args->values[ch]);
|
||||
struct args_entry *entry;
|
||||
|
||||
/* Replace existing argument. */
|
||||
if ((entry = args_find(args, ch)) != NULL) {
|
||||
free(entry->value);
|
||||
entry->value = NULL;
|
||||
} else {
|
||||
entry = xcalloc(1, sizeof *entry);
|
||||
entry->flag = ch;
|
||||
RB_INSERT(args_tree, &args->tree, entry);
|
||||
}
|
||||
|
||||
if (value != NULL)
|
||||
args->values[ch] = xstrdup(value);
|
||||
else
|
||||
args->values[ch] = NULL;
|
||||
bit_set(args->flags, ch);
|
||||
entry->value = xstrdup(value);
|
||||
}
|
||||
|
||||
/* Get argument value. Will be NULL if it isn't present. */
|
||||
const char *
|
||||
args_get(struct args *args, u_char ch)
|
||||
{
|
||||
return (args->values[ch]);
|
||||
struct args_entry *entry;
|
||||
|
||||
if ((entry = args_find(args, ch)) == NULL)
|
||||
return (NULL);
|
||||
return (entry->value);
|
||||
}
|
||||
|
||||
/* Convert an argument value to a number. */
|
||||
long long
|
||||
args_strtonum(struct args *args,
|
||||
u_char ch, long long minval, long long maxval, char **cause)
|
||||
args_strtonum(struct args *args, u_char ch, long long minval, long long maxval,
|
||||
char **cause)
|
||||
{
|
||||
const char *errstr;
|
||||
long long ll;
|
||||
const char *errstr;
|
||||
long long ll;
|
||||
struct args_entry *entry;
|
||||
|
||||
if (!args_has(args, ch)) {
|
||||
if ((entry = args_find(args, ch)) == NULL) {
|
||||
*cause = xstrdup("missing");
|
||||
return (0);
|
||||
}
|
||||
|
||||
ll = strtonum(args->values[ch], minval, maxval, &errstr);
|
||||
ll = strtonum(entry->value, minval, maxval, &errstr);
|
||||
if (errstr != NULL) {
|
||||
*cause = xstrdup(errstr);
|
||||
return (0);
|
||||
|
||||
4
array.h
4
array.h
@@ -39,10 +39,10 @@
|
||||
fatalx("size too big"); \
|
||||
if ((a)->space == 0) { \
|
||||
(a)->space = ARRAY_INITIALSPACE(a); \
|
||||
(a)->list = xrealloc((a)->list, 1, (a)->space); \
|
||||
(a)->list = xrealloc((a)->list, (a)->space); \
|
||||
} \
|
||||
while ((a)->space <= ((a)->num + (n)) * ARRAY_ITEMSIZE(a)) { \
|
||||
(a)->list = xrealloc((a)->list, 2, (a)->space); \
|
||||
(a)->list = xreallocarray((a)->list, 2, (a)->space); \
|
||||
(a)->space *= 2; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $Id$ */
|
||||
/* $OpenBSD$ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2009 Joshua Elsasser <josh@elsasser.org>
|
||||
|
||||
111
cfg.c
111
cfg.c
@@ -1,4 +1,4 @@
|
||||
/* $Id$ */
|
||||
/* $OpenBSD$ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||
@@ -17,7 +17,6 @@
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
@@ -30,15 +29,17 @@
|
||||
struct cmd_q *cfg_cmd_q;
|
||||
int cfg_finished;
|
||||
int cfg_references;
|
||||
struct causelist cfg_causes;
|
||||
ARRAY_DECL (, char *) cfg_causes = ARRAY_INITIALIZER;
|
||||
struct client *cfg_client;
|
||||
|
||||
int
|
||||
load_cfg(const char *path, struct cmd_q *cmdq, char **cause)
|
||||
{
|
||||
FILE *f;
|
||||
u_int n, found;
|
||||
char *buf, *copy, *line, *cause1, *msg;
|
||||
size_t len, oldlen;
|
||||
char delim[3] = { '\\', '\\', '\0' };
|
||||
u_int found;
|
||||
size_t line = 0;
|
||||
char *buf, *cause1, *p;
|
||||
struct cmd_list *cmdlist;
|
||||
|
||||
log_debug("loading %s", path);
|
||||
@@ -47,60 +48,29 @@ load_cfg(const char *path, struct cmd_q *cmdq, char **cause)
|
||||
return (-1);
|
||||
}
|
||||
|
||||
n = found = 0;
|
||||
line = NULL;
|
||||
while ((buf = fgetln(f, &len))) {
|
||||
/* Trim \n. */
|
||||
if (buf[len - 1] == '\n')
|
||||
len--;
|
||||
log_debug("%s: %.*s", path, (int)len, buf);
|
||||
|
||||
/* Current line is the continuation of the previous one. */
|
||||
if (line != NULL) {
|
||||
oldlen = strlen(line);
|
||||
line = xrealloc(line, 1, oldlen + len + 1);
|
||||
} else {
|
||||
oldlen = 0;
|
||||
line = xmalloc(len + 1);
|
||||
}
|
||||
|
||||
/* Append current line to the previous. */
|
||||
memcpy(line + oldlen, buf, len);
|
||||
line[oldlen + len] = '\0';
|
||||
n++;
|
||||
|
||||
/* Continuation: get next line? */
|
||||
len = strlen(line);
|
||||
if (len > 0 && line[len - 1] == '\\') {
|
||||
line[len - 1] = '\0';
|
||||
|
||||
/* Ignore escaped backslash at EOL. */
|
||||
if (len > 1 && line[len - 2] != '\\')
|
||||
continue;
|
||||
}
|
||||
copy = line;
|
||||
line = NULL;
|
||||
found = 0;
|
||||
while ((buf = fparseln(f, NULL, &line, delim, 0))) {
|
||||
log_debug("%s: %s", path, buf);
|
||||
|
||||
/* Skip empty lines. */
|
||||
buf = copy;
|
||||
while (isspace((u_char)*buf))
|
||||
buf++;
|
||||
if (*buf == '\0') {
|
||||
free(copy);
|
||||
p = buf;
|
||||
while (isspace((u_char) *p))
|
||||
p++;
|
||||
if (*p == '\0') {
|
||||
free(buf);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Parse and run the command. */
|
||||
if (cmd_string_parse(buf, &cmdlist, path, n, &cause1) != 0) {
|
||||
free(copy);
|
||||
if (cmd_string_parse(p, &cmdlist, path, line, &cause1) != 0) {
|
||||
free(buf);
|
||||
if (cause1 == NULL)
|
||||
continue;
|
||||
xasprintf(&msg, "%s:%u: %s", path, n, cause1);
|
||||
ARRAY_ADD(&cfg_causes, msg);
|
||||
cfg_add_cause("%s:%zu: %s", path, line, cause1);
|
||||
free(cause1);
|
||||
continue;
|
||||
}
|
||||
free(copy);
|
||||
free(buf);
|
||||
|
||||
if (cmdlist == NULL)
|
||||
continue;
|
||||
@@ -108,8 +78,6 @@ load_cfg(const char *path, struct cmd_q *cmdq, char **cause)
|
||||
cmd_list_free(cmdlist);
|
||||
found++;
|
||||
}
|
||||
if (line != NULL)
|
||||
free(line);
|
||||
fclose(f);
|
||||
|
||||
return (found);
|
||||
@@ -127,6 +95,47 @@ cfg_default_done(unused struct cmd_q *cmdq)
|
||||
|
||||
cmdq_free(cfg_cmd_q);
|
||||
cfg_cmd_q = NULL;
|
||||
|
||||
if (cfg_client != NULL) {
|
||||
/*
|
||||
* The client command queue starts with client_exit set to 1 so
|
||||
* only continue if not empty (that is, we have been delayed
|
||||
* during configuration parsing for long enough that the
|
||||
* MSG_COMMAND has arrived), else the client will exit before
|
||||
* the MSG_COMMAND which might tell it not to.
|
||||
*/
|
||||
if (!TAILQ_EMPTY(&cfg_client->cmdq->queue))
|
||||
cmdq_continue(cfg_client->cmdq);
|
||||
cfg_client->references--;
|
||||
cfg_client = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
cfg_add_cause(const char* fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
char* msg;
|
||||
|
||||
va_start(ap, fmt);
|
||||
xvasprintf(&msg, fmt, ap);
|
||||
va_end (ap);
|
||||
|
||||
ARRAY_ADD(&cfg_causes, msg);
|
||||
}
|
||||
|
||||
void
|
||||
cfg_print_causes(struct cmd_q *cmdq)
|
||||
{
|
||||
char *cause;
|
||||
u_int i;
|
||||
|
||||
for (i = 0; i < ARRAY_LENGTH(&cfg_causes); i++) {
|
||||
cause = ARRAY_ITEM(&cfg_causes, i);
|
||||
cmdq_print(cmdq, "%s", cause);
|
||||
free(cause);
|
||||
}
|
||||
ARRAY_FREE(&cfg_causes);
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
283
client.c
283
client.c
@@ -1,4 +1,4 @@
|
||||
/* $Id$ */
|
||||
/* $OpenBSD$ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||
@@ -26,7 +26,7 @@
|
||||
#include <errno.h>
|
||||
#include <event.h>
|
||||
#include <fcntl.h>
|
||||
#include <pwd.h>
|
||||
#include <signal.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
@@ -48,13 +48,14 @@ enum {
|
||||
} client_exitreason = CLIENT_EXIT_NONE;
|
||||
int client_exitval;
|
||||
enum msgtype client_exittype;
|
||||
const char *client_exitsession;
|
||||
int client_attached;
|
||||
|
||||
int client_get_lock(char *);
|
||||
int client_connect(char *, int);
|
||||
void client_send_identify(int);
|
||||
void client_send_environ(void);
|
||||
void client_write_server(enum msgtype, void *, size_t);
|
||||
int client_write_one(enum msgtype, int, const void *, size_t);
|
||||
int client_write_server(enum msgtype, const void *, size_t);
|
||||
void client_update_event(void);
|
||||
void client_signal(int, short, void *);
|
||||
void client_stdin_callback(int, short, void *);
|
||||
@@ -77,13 +78,18 @@ client_get_lock(char *lockfile)
|
||||
|
||||
if ((lockfd = open(lockfile, O_WRONLY|O_CREAT, 0600)) == -1)
|
||||
fatal("open failed");
|
||||
log_debug("lock file is %s", lockfile);
|
||||
|
||||
if (flock(lockfd, LOCK_EX|LOCK_NB) == -1 && errno == EWOULDBLOCK) {
|
||||
if (flock(lockfd, LOCK_EX|LOCK_NB) == -1) {
|
||||
log_debug("flock failed: %s", strerror(errno));
|
||||
if (errno != EAGAIN)
|
||||
return (lockfd);
|
||||
while (flock(lockfd, LOCK_EX) == -1 && errno == EINTR)
|
||||
/* nothing */;
|
||||
close(lockfd);
|
||||
return (-1);
|
||||
}
|
||||
log_debug("flock succeeded");
|
||||
|
||||
return (lockfd);
|
||||
}
|
||||
@@ -94,8 +100,8 @@ client_connect(char *path, int start_server)
|
||||
{
|
||||
struct sockaddr_un sa;
|
||||
size_t size;
|
||||
int fd, lockfd;
|
||||
char *lockfile;
|
||||
int fd, lockfd = -1, locked = 0;
|
||||
char *lockfile = NULL;
|
||||
|
||||
memset(&sa, 0, sizeof sa);
|
||||
sa.sun_family = AF_UNIX;
|
||||
@@ -104,24 +110,48 @@ client_connect(char *path, int start_server)
|
||||
errno = ENAMETOOLONG;
|
||||
return (-1);
|
||||
}
|
||||
log_debug("socket is %s", path);
|
||||
|
||||
retry:
|
||||
if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1)
|
||||
fatal("socket failed");
|
||||
|
||||
log_debug("trying connect");
|
||||
if (connect(fd, (struct sockaddr *) &sa, SUN_LEN(&sa)) == -1) {
|
||||
log_debug("connect failed: %s", strerror(errno));
|
||||
if (errno != ECONNREFUSED && errno != ENOENT)
|
||||
goto failed;
|
||||
if (!start_server)
|
||||
goto failed;
|
||||
close(fd);
|
||||
|
||||
xasprintf(&lockfile, "%s.lock", path);
|
||||
if ((lockfd = client_get_lock(lockfile)) == -1)
|
||||
if (!locked) {
|
||||
xasprintf(&lockfile, "%s.lock", path);
|
||||
if ((lockfd = client_get_lock(lockfile)) == -1) {
|
||||
log_debug("didn't get lock");
|
||||
free(lockfile);
|
||||
goto retry;
|
||||
}
|
||||
log_debug("got lock");
|
||||
|
||||
/*
|
||||
* Always retry at least once, even if we got the lock,
|
||||
* because another client could have taken the lock,
|
||||
* started the server and released the lock between our
|
||||
* connect() and flock().
|
||||
*/
|
||||
locked = 1;
|
||||
goto retry;
|
||||
if (unlink(path) != 0 && errno != ENOENT)
|
||||
}
|
||||
|
||||
if (unlink(path) != 0 && errno != ENOENT) {
|
||||
free(lockfile);
|
||||
close(lockfd);
|
||||
return (-1);
|
||||
}
|
||||
fd = server_start(lockfd, lockfile);
|
||||
}
|
||||
if (locked) {
|
||||
free(lockfile);
|
||||
close(lockfd);
|
||||
}
|
||||
@@ -138,12 +168,24 @@ failed:
|
||||
const char *
|
||||
client_exit_message(void)
|
||||
{
|
||||
static char msg[256];
|
||||
|
||||
switch (client_exitreason) {
|
||||
case CLIENT_EXIT_NONE:
|
||||
break;
|
||||
case CLIENT_EXIT_DETACHED:
|
||||
if (client_exitsession != NULL) {
|
||||
xsnprintf(msg, sizeof msg, "detached "
|
||||
"(from session %s)", client_exitsession);
|
||||
return (msg);
|
||||
}
|
||||
return ("detached");
|
||||
case CLIENT_EXIT_DETACHED_HUP:
|
||||
if (client_exitsession != NULL) {
|
||||
xsnprintf(msg, sizeof msg, "detached and SIGHUP "
|
||||
"(from session %s)", client_exitsession);
|
||||
return (msg);
|
||||
}
|
||||
return ("detached and SIGHUP");
|
||||
case CLIENT_EXIT_LOST_TTY:
|
||||
return ("lost tty");
|
||||
@@ -165,12 +207,13 @@ client_main(int argc, char **argv, int flags)
|
||||
{
|
||||
struct cmd *cmd;
|
||||
struct cmd_list *cmdlist;
|
||||
struct msg_command_data cmddata;
|
||||
int cmdflags, fd;
|
||||
struct msg_command_data *data;
|
||||
int cmdflags, fd, i;
|
||||
pid_t ppid;
|
||||
enum msgtype msg;
|
||||
char *cause;
|
||||
struct termios tio, saved_tio;
|
||||
size_t size;
|
||||
|
||||
/* Set up the initial command. */
|
||||
cmdflags = 0;
|
||||
@@ -179,7 +222,7 @@ client_main(int argc, char **argv, int flags)
|
||||
cmdflags = CMD_STARTSERVER;
|
||||
} else if (argc == 0) {
|
||||
msg = MSG_COMMAND;
|
||||
cmdflags = CMD_STARTSERVER|CMD_SENDENVIRON|CMD_CANTNEST;
|
||||
cmdflags = CMD_STARTSERVER|CMD_CANTNEST;
|
||||
} else {
|
||||
msg = MSG_COMMAND;
|
||||
|
||||
@@ -197,8 +240,6 @@ client_main(int argc, char **argv, int flags)
|
||||
TAILQ_FOREACH(cmd, &cmdlist->list, qentry) {
|
||||
if (cmd->entry->flags & CMD_STARTSERVER)
|
||||
cmdflags |= CMD_STARTSERVER;
|
||||
if (cmd->entry->flags & CMD_SENDENVIRON)
|
||||
cmdflags |= CMD_SENDENVIRON;
|
||||
if (cmd->entry->flags & CMD_CANTNEST)
|
||||
cmdflags |= CMD_CANTNEST;
|
||||
}
|
||||
@@ -217,10 +258,11 @@ client_main(int argc, char **argv, int flags)
|
||||
return (1);
|
||||
}
|
||||
|
||||
/* Initialise the client socket and start the server. */
|
||||
/* Initialize the client socket and start the server. */
|
||||
fd = client_connect(socket_path, cmdflags & CMD_STARTSERVER);
|
||||
if (fd == -1) {
|
||||
fprintf(stderr, "failed to connect to server\n");
|
||||
fprintf(stderr, "failed to connect to server: %s\n",
|
||||
strerror(errno));
|
||||
return (1);
|
||||
}
|
||||
|
||||
@@ -238,7 +280,7 @@ client_main(int argc, char **argv, int flags)
|
||||
setblocking(STDIN_FILENO, 0);
|
||||
event_set(&client_stdin, STDIN_FILENO, EV_READ|EV_PERSIST,
|
||||
client_stdin_callback, NULL);
|
||||
if (flags & IDENTIFY_TERMIOS) {
|
||||
if (flags & CLIENT_CONTROLCONTROL) {
|
||||
if (tcgetattr(STDIN_FILENO, &saved_tio) != 0) {
|
||||
fprintf(stderr, "tcgetattr failed: %s\n",
|
||||
strerror(errno));
|
||||
@@ -261,26 +303,33 @@ client_main(int argc, char **argv, int flags)
|
||||
/* Establish signal handlers. */
|
||||
set_signals(client_signal);
|
||||
|
||||
/* Send initial environment. */
|
||||
if (cmdflags & CMD_SENDENVIRON)
|
||||
client_send_environ();
|
||||
/* Send identify messages. */
|
||||
client_send_identify(flags);
|
||||
|
||||
/* Send first command. */
|
||||
if (msg == MSG_COMMAND) {
|
||||
/* Fill in command line arguments. */
|
||||
cmddata.pid = environ_pid;
|
||||
cmddata.session_id = environ_session_id;
|
||||
/* How big is the command? */
|
||||
size = 0;
|
||||
for (i = 0; i < argc; i++)
|
||||
size += strlen(argv[i]) + 1;
|
||||
data = xmalloc((sizeof *data) + size);
|
||||
|
||||
/* Prepare command for server. */
|
||||
cmddata.argc = argc;
|
||||
if (cmd_pack_argv(
|
||||
argc, argv, cmddata.argv, sizeof cmddata.argv) != 0) {
|
||||
data->argc = argc;
|
||||
if (cmd_pack_argv(argc, argv, (char *)(data + 1), size) != 0) {
|
||||
fprintf(stderr, "command too long\n");
|
||||
free(data);
|
||||
return (1);
|
||||
}
|
||||
size += sizeof *data;
|
||||
|
||||
client_write_server(msg, &cmddata, sizeof cmddata);
|
||||
/* Send the command. */
|
||||
if (client_write_server(msg, data, size) != 0) {
|
||||
fprintf(stderr, "failed to send command\n");
|
||||
free(data);
|
||||
return (1);
|
||||
}
|
||||
free(data);
|
||||
} else if (msg == MSG_SHELL)
|
||||
client_write_server(msg, NULL, 0);
|
||||
|
||||
@@ -296,65 +345,75 @@ client_main(int argc, char **argv, int flags)
|
||||
ppid = getppid();
|
||||
if (client_exittype == MSG_DETACHKILL && ppid > 1)
|
||||
kill(ppid, SIGHUP);
|
||||
} else if (flags & IDENTIFY_TERMIOS) {
|
||||
if (flags & IDENTIFY_CONTROL) {
|
||||
if (client_exitreason != CLIENT_EXIT_NONE)
|
||||
printf("%%exit %s\n", client_exit_message());
|
||||
else
|
||||
printf("%%exit\n");
|
||||
printf("\033\\");
|
||||
}
|
||||
} else if (flags & CLIENT_CONTROLCONTROL) {
|
||||
if (client_exitreason != CLIENT_EXIT_NONE)
|
||||
printf("%%exit %s\n", client_exit_message());
|
||||
else
|
||||
printf("%%exit\n");
|
||||
printf("\033\\");
|
||||
tcsetattr(STDOUT_FILENO, TCSAFLUSH, &saved_tio);
|
||||
}
|
||||
setblocking(STDIN_FILENO, 1);
|
||||
return (client_exitval);
|
||||
}
|
||||
|
||||
/* Send identify message to server with the file descriptors. */
|
||||
/* Send identify messages to server. */
|
||||
void
|
||||
client_send_identify(int flags)
|
||||
{
|
||||
struct msg_identify_data data;
|
||||
char *term;
|
||||
int fd;
|
||||
const char *s;
|
||||
char **ss;
|
||||
int fd;
|
||||
|
||||
data.flags = flags;
|
||||
client_write_one(MSG_IDENTIFY_FLAGS, -1, &flags, sizeof flags);
|
||||
|
||||
if (getcwd(data.cwd, sizeof data.cwd) == NULL)
|
||||
*data.cwd = '\0';
|
||||
if ((s = getenv("TERM")) == NULL)
|
||||
s = "";
|
||||
client_write_one(MSG_IDENTIFY_TERM, -1, s, strlen(s) + 1);
|
||||
|
||||
term = getenv("TERM");
|
||||
if (term == NULL ||
|
||||
strlcpy(data.term, term, sizeof data.term) >= sizeof data.term)
|
||||
*data.term = '\0';
|
||||
if ((s = ttyname(STDIN_FILENO)) == NULL)
|
||||
s = "";
|
||||
client_write_one(MSG_IDENTIFY_TTYNAME, -1, s, strlen(s) + 1);
|
||||
|
||||
if ((fd = open(".", O_RDONLY)) == -1)
|
||||
fd = open("/", O_RDONLY);
|
||||
client_write_one(MSG_IDENTIFY_CWD, fd, NULL, 0);
|
||||
|
||||
if ((fd = dup(STDIN_FILENO)) == -1)
|
||||
fatal("dup failed");
|
||||
imsg_compose(&client_ibuf,
|
||||
MSG_IDENTIFY, PROTOCOL_VERSION, -1, fd, &data, sizeof data);
|
||||
client_write_one(MSG_IDENTIFY_STDIN, fd, NULL, 0);
|
||||
|
||||
for (ss = environ; *ss != NULL; ss++)
|
||||
client_write_one(MSG_IDENTIFY_ENVIRON, -1, *ss, strlen(*ss) + 1);
|
||||
|
||||
client_write_one(MSG_IDENTIFY_DONE, -1, NULL, 0);
|
||||
|
||||
client_update_event();
|
||||
}
|
||||
|
||||
/* Forward entire environment to server. */
|
||||
void
|
||||
client_send_environ(void)
|
||||
/* Helper to send one message. */
|
||||
int
|
||||
client_write_one(enum msgtype type, int fd, const void *buf, size_t len)
|
||||
{
|
||||
struct msg_environ_data data;
|
||||
char **var;
|
||||
int retval;
|
||||
|
||||
for (var = environ; *var != NULL; var++) {
|
||||
if (strlcpy(data.var, *var, sizeof data.var) >= sizeof data.var)
|
||||
continue;
|
||||
client_write_server(MSG_ENVIRON, &data, sizeof data);
|
||||
}
|
||||
retval = imsg_compose(&client_ibuf, type, PROTOCOL_VERSION, -1, fd,
|
||||
(void *)buf, len);
|
||||
if (retval != 1)
|
||||
return (-1);
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* Write a message to the server without a file descriptor. */
|
||||
void
|
||||
client_write_server(enum msgtype type, void *buf, size_t len)
|
||||
int
|
||||
client_write_server(enum msgtype type, const void *buf, size_t len)
|
||||
{
|
||||
imsg_compose(&client_ibuf, type, PROTOCOL_VERSION, -1, -1, buf, len);
|
||||
client_update_event();
|
||||
int retval;
|
||||
|
||||
retval = client_write_one(type, -1, buf, len);
|
||||
if (retval == 0)
|
||||
client_update_event();
|
||||
return (retval);
|
||||
}
|
||||
|
||||
/* Update client event based on whether it needs to read or read and write. */
|
||||
@@ -379,15 +438,11 @@ client_signal(int sig, unused short events, unused void *data)
|
||||
struct sigaction sigact;
|
||||
int status;
|
||||
|
||||
if (!client_attached) {
|
||||
switch (sig) {
|
||||
case SIGCHLD:
|
||||
waitpid(WAIT_ANY, &status, WNOHANG);
|
||||
break;
|
||||
case SIGTERM:
|
||||
if (sig == SIGCHLD)
|
||||
waitpid(WAIT_ANY, &status, WNOHANG);
|
||||
else if (!client_attached) {
|
||||
if (sig == SIGTERM)
|
||||
event_loopexit(NULL);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
switch (sig) {
|
||||
case SIGHUP:
|
||||
@@ -439,7 +494,7 @@ client_callback(unused int fd, short events, void *data)
|
||||
}
|
||||
|
||||
if (events & EV_WRITE) {
|
||||
if (msgbuf_write(&client_ibuf.w) < 0)
|
||||
if (msgbuf_write(&client_ibuf.w) <= 0 && errno != EAGAIN)
|
||||
goto lost_server;
|
||||
}
|
||||
|
||||
@@ -488,33 +543,33 @@ client_write(int fd, const char *data, size_t size)
|
||||
|
||||
/* Dispatch imsgs when in wait state (before MSG_READY). */
|
||||
int
|
||||
client_dispatch_wait(void *data)
|
||||
client_dispatch_wait(void *data0)
|
||||
{
|
||||
struct imsg imsg;
|
||||
ssize_t n, datalen;
|
||||
struct msg_shell_data shelldata;
|
||||
struct msg_exit_data exitdata;
|
||||
struct msg_stdout_data stdoutdata;
|
||||
struct msg_stderr_data stderrdata;
|
||||
const char *shellcmd = data;
|
||||
struct imsg imsg;
|
||||
char *data;
|
||||
ssize_t n, datalen;
|
||||
struct msg_stdout_data stdoutdata;
|
||||
struct msg_stderr_data stderrdata;
|
||||
int retval;
|
||||
|
||||
for (;;) {
|
||||
if ((n = imsg_get(&client_ibuf, &imsg)) == -1)
|
||||
fatalx("imsg_get failed");
|
||||
if (n == 0)
|
||||
return (0);
|
||||
|
||||
data = imsg.data;
|
||||
datalen = imsg.hdr.len - IMSG_HEADER_SIZE;
|
||||
|
||||
log_debug("got %d from server", imsg.hdr.type);
|
||||
switch (imsg.hdr.type) {
|
||||
case MSG_EXIT:
|
||||
case MSG_SHUTDOWN:
|
||||
if (datalen != sizeof exitdata) {
|
||||
if (datalen != 0)
|
||||
fatalx("bad MSG_EXIT size");
|
||||
} else {
|
||||
memcpy(&exitdata, imsg.data, sizeof exitdata);
|
||||
client_exitval = exitdata.retcode;
|
||||
if (datalen != sizeof retval && datalen != 0)
|
||||
fatalx("bad MSG_EXIT size");
|
||||
if (datalen == sizeof retval) {
|
||||
memcpy(&retval, data, sizeof retval);
|
||||
client_exitval = retval;
|
||||
}
|
||||
imsg_free(&imsg);
|
||||
return (-1);
|
||||
@@ -534,17 +589,19 @@ client_dispatch_wait(void *data)
|
||||
break;
|
||||
case MSG_STDOUT:
|
||||
if (datalen != sizeof stdoutdata)
|
||||
fatalx("bad MSG_STDOUT");
|
||||
memcpy(&stdoutdata, imsg.data, sizeof stdoutdata);
|
||||
fatalx("bad MSG_STDOUT size");
|
||||
memcpy(&stdoutdata, data, sizeof stdoutdata);
|
||||
|
||||
client_write(STDOUT_FILENO, stdoutdata.data, stdoutdata.size);
|
||||
client_write(STDOUT_FILENO, stdoutdata.data,
|
||||
stdoutdata.size);
|
||||
break;
|
||||
case MSG_STDERR:
|
||||
if (datalen != sizeof stderrdata)
|
||||
fatalx("bad MSG_STDERR");
|
||||
memcpy(&stderrdata, imsg.data, sizeof stderrdata);
|
||||
fatalx("bad MSG_STDERR size");
|
||||
memcpy(&stderrdata, data, sizeof stderrdata);
|
||||
|
||||
client_write(STDERR_FILENO, stderrdata.data, stderrdata.size);
|
||||
client_write(STDERR_FILENO, stderrdata.data,
|
||||
stderrdata.size);
|
||||
break;
|
||||
case MSG_VERSION:
|
||||
if (datalen != 0)
|
||||
@@ -558,23 +615,19 @@ client_dispatch_wait(void *data)
|
||||
imsg_free(&imsg);
|
||||
return (-1);
|
||||
case MSG_SHELL:
|
||||
if (datalen != sizeof shelldata)
|
||||
fatalx("bad MSG_SHELL size");
|
||||
memcpy(&shelldata, imsg.data, sizeof shelldata);
|
||||
shelldata.shell[(sizeof shelldata.shell) - 1] = '\0';
|
||||
if (datalen == 0 || data[datalen - 1] != '\0')
|
||||
fatalx("bad MSG_SHELL string");
|
||||
|
||||
clear_signals(0);
|
||||
|
||||
shell_exec(shelldata.shell, shellcmd);
|
||||
shell_exec(data, data0);
|
||||
/* NOTREACHED */
|
||||
case MSG_DETACH:
|
||||
case MSG_DETACHKILL:
|
||||
client_write_server(MSG_EXITING, NULL, 0);
|
||||
break;
|
||||
case MSG_EXITED:
|
||||
imsg_free(&imsg);
|
||||
return (-1);
|
||||
default:
|
||||
fatalx("unexpected message");
|
||||
}
|
||||
|
||||
imsg_free(&imsg);
|
||||
@@ -585,25 +638,28 @@ client_dispatch_wait(void *data)
|
||||
int
|
||||
client_dispatch_attached(void)
|
||||
{
|
||||
struct imsg imsg;
|
||||
struct msg_lock_data lockdata;
|
||||
struct sigaction sigact;
|
||||
ssize_t n, datalen;
|
||||
struct imsg imsg;
|
||||
struct sigaction sigact;
|
||||
char *data;
|
||||
ssize_t n, datalen;
|
||||
|
||||
for (;;) {
|
||||
if ((n = imsg_get(&client_ibuf, &imsg)) == -1)
|
||||
fatalx("imsg_get failed");
|
||||
if (n == 0)
|
||||
return (0);
|
||||
|
||||
data = imsg.data;
|
||||
datalen = imsg.hdr.len - IMSG_HEADER_SIZE;
|
||||
|
||||
log_debug("got %d from server", imsg.hdr.type);
|
||||
switch (imsg.hdr.type) {
|
||||
case MSG_DETACHKILL:
|
||||
case MSG_DETACH:
|
||||
if (datalen != 0)
|
||||
fatalx("bad MSG_DETACH size");
|
||||
case MSG_DETACHKILL:
|
||||
if (datalen == 0 || data[datalen - 1] != '\0')
|
||||
fatalx("bad MSG_DETACH string");
|
||||
|
||||
client_exitsession = xstrdup(data);
|
||||
client_exittype = imsg.hdr.type;
|
||||
if (imsg.hdr.type == MSG_DETACHKILL)
|
||||
client_exitreason = CLIENT_EXIT_DETACHED_HUP;
|
||||
@@ -612,8 +668,7 @@ client_dispatch_attached(void)
|
||||
client_write_server(MSG_EXITING, NULL, 0);
|
||||
break;
|
||||
case MSG_EXIT:
|
||||
if (datalen != 0 &&
|
||||
datalen != sizeof (struct msg_exit_data))
|
||||
if (datalen != 0 && datalen != sizeof (int))
|
||||
fatalx("bad MSG_EXIT size");
|
||||
|
||||
client_write_server(MSG_EXITING, NULL, 0);
|
||||
@@ -646,16 +701,12 @@ client_dispatch_attached(void)
|
||||
kill(getpid(), SIGTSTP);
|
||||
break;
|
||||
case MSG_LOCK:
|
||||
if (datalen != sizeof lockdata)
|
||||
fatalx("bad MSG_LOCK size");
|
||||
memcpy(&lockdata, imsg.data, sizeof lockdata);
|
||||
if (datalen == 0 || data[datalen - 1] != '\0')
|
||||
fatalx("bad MSG_LOCK string");
|
||||
|
||||
lockdata.cmd[(sizeof lockdata.cmd) - 1] = '\0';
|
||||
system(lockdata.cmd);
|
||||
system(data);
|
||||
client_write_server(MSG_UNLOCK, NULL, 0);
|
||||
break;
|
||||
default:
|
||||
fatalx("unexpected message");
|
||||
}
|
||||
|
||||
imsg_free(&imsg);
|
||||
|
||||
159
clock.c
159
clock.c
@@ -1,159 +0,0 @@
|
||||
/* $Id$ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
||||
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "tmux.h"
|
||||
|
||||
const char clock_table[14][5][5] = {
|
||||
{ { 1,1,1,1,1 }, /* 0 */
|
||||
{ 1,0,0,0,1 },
|
||||
{ 1,0,0,0,1 },
|
||||
{ 1,0,0,0,1 },
|
||||
{ 1,1,1,1,1 } },
|
||||
{ { 0,0,0,0,1 }, /* 1 */
|
||||
{ 0,0,0,0,1 },
|
||||
{ 0,0,0,0,1 },
|
||||
{ 0,0,0,0,1 },
|
||||
{ 0,0,0,0,1 } },
|
||||
{ { 1,1,1,1,1 }, /* 2 */
|
||||
{ 0,0,0,0,1 },
|
||||
{ 1,1,1,1,1 },
|
||||
{ 1,0,0,0,0 },
|
||||
{ 1,1,1,1,1 } },
|
||||
{ { 1,1,1,1,1 }, /* 3 */
|
||||
{ 0,0,0,0,1 },
|
||||
{ 1,1,1,1,1 },
|
||||
{ 0,0,0,0,1 },
|
||||
{ 1,1,1,1,1 } },
|
||||
{ { 1,0,0,0,1 }, /* 4 */
|
||||
{ 1,0,0,0,1 },
|
||||
{ 1,1,1,1,1 },
|
||||
{ 0,0,0,0,1 },
|
||||
{ 0,0,0,0,1 } },
|
||||
{ { 1,1,1,1,1 }, /* 5 */
|
||||
{ 1,0,0,0,0 },
|
||||
{ 1,1,1,1,1 },
|
||||
{ 0,0,0,0,1 },
|
||||
{ 1,1,1,1,1 } },
|
||||
{ { 1,1,1,1,1 }, /* 6 */
|
||||
{ 1,0,0,0,0 },
|
||||
{ 1,1,1,1,1 },
|
||||
{ 1,0,0,0,1 },
|
||||
{ 1,1,1,1,1 } },
|
||||
{ { 1,1,1,1,1 }, /* 7 */
|
||||
{ 0,0,0,0,1 },
|
||||
{ 0,0,0,0,1 },
|
||||
{ 0,0,0,0,1 },
|
||||
{ 0,0,0,0,1 } },
|
||||
{ { 1,1,1,1,1 }, /* 8 */
|
||||
{ 1,0,0,0,1 },
|
||||
{ 1,1,1,1,1 },
|
||||
{ 1,0,0,0,1 },
|
||||
{ 1,1,1,1,1 } },
|
||||
{ { 1,1,1,1,1 }, /* 9 */
|
||||
{ 1,0,0,0,1 },
|
||||
{ 1,1,1,1,1 },
|
||||
{ 0,0,0,0,1 },
|
||||
{ 1,1,1,1,1 } },
|
||||
{ { 0,0,0,0,0 }, /* : */
|
||||
{ 0,0,1,0,0 },
|
||||
{ 0,0,0,0,0 },
|
||||
{ 0,0,1,0,0 },
|
||||
{ 0,0,0,0,0 } },
|
||||
{ { 1,1,1,1,1 }, /* A */
|
||||
{ 1,0,0,0,1 },
|
||||
{ 1,1,1,1,1 },
|
||||
{ 1,0,0,0,1 },
|
||||
{ 1,0,0,0,1 } },
|
||||
{ { 1,1,1,1,1 }, /* P */
|
||||
{ 1,0,0,0,1 },
|
||||
{ 1,1,1,1,1 },
|
||||
{ 1,0,0,0,0 },
|
||||
{ 1,0,0,0,0 } },
|
||||
{ { 1,0,0,0,1 }, /* M */
|
||||
{ 1,1,0,1,1 },
|
||||
{ 1,0,1,0,1 },
|
||||
{ 1,0,0,0,1 },
|
||||
{ 1,0,0,0,1 } },
|
||||
};
|
||||
|
||||
void
|
||||
clock_draw(struct screen_write_ctx *ctx, int colour, int style)
|
||||
{
|
||||
struct screen *s = ctx->s;
|
||||
struct grid_cell gc;
|
||||
char tim[64], *ptr;
|
||||
time_t t;
|
||||
u_int i, j, x, y, idx;
|
||||
|
||||
t = time(NULL);
|
||||
if (style == 0)
|
||||
strftime(tim, sizeof tim, "%l:%M %p", localtime(&t));
|
||||
else
|
||||
strftime(tim, sizeof tim, "%H:%M", localtime(&t));
|
||||
|
||||
screen_write_clearscreen(ctx);
|
||||
|
||||
if (screen_size_x(s) < 6 * strlen(tim) || screen_size_y(s) < 6) {
|
||||
if (screen_size_x(s) >= strlen(tim) && screen_size_y(s) != 0) {
|
||||
x = (screen_size_x(s) / 2) - (strlen(tim) / 2);
|
||||
y = screen_size_y(s) / 2;
|
||||
screen_write_cursormove(ctx, x, y);
|
||||
|
||||
memcpy(&gc, &grid_default_cell, sizeof gc);
|
||||
colour_set_fg(&gc, colour);
|
||||
screen_write_puts(ctx, &gc, "%s", tim);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
x = (screen_size_x(s) / 2) - 3 * strlen(tim);
|
||||
y = (screen_size_y(s) / 2) - 3;
|
||||
|
||||
memcpy(&gc, &grid_default_cell, sizeof gc);
|
||||
colour_set_bg(&gc, colour);
|
||||
for (ptr = tim; *ptr != '\0'; ptr++) {
|
||||
if (*ptr >= '0' && *ptr <= '9')
|
||||
idx = *ptr - '0';
|
||||
else if (*ptr == ':')
|
||||
idx = 10;
|
||||
else if (*ptr == 'A')
|
||||
idx = 11;
|
||||
else if (*ptr == 'P')
|
||||
idx = 12;
|
||||
else if (*ptr == 'M')
|
||||
idx = 13;
|
||||
else {
|
||||
x += 6;
|
||||
continue;
|
||||
}
|
||||
|
||||
for (j = 0; j < 5; j++) {
|
||||
for (i = 0; i < 5; i++) {
|
||||
screen_write_cursormove(ctx, x + i, y + j);
|
||||
if (clock_table[idx][j][i])
|
||||
screen_write_putc(ctx, &gc, ' ');
|
||||
}
|
||||
}
|
||||
x += 6;
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $Id$ */
|
||||
/* $OpenBSD$ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||
@@ -18,7 +18,11 @@
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "tmux.h"
|
||||
|
||||
@@ -30,34 +34,58 @@ enum cmd_retval cmd_attach_session_exec(struct cmd *, struct cmd_q *);
|
||||
|
||||
const struct cmd_entry cmd_attach_session_entry = {
|
||||
"attach-session", "attach",
|
||||
"drt:", 0, 0,
|
||||
"[-dr] " CMD_TARGET_SESSION_USAGE,
|
||||
CMD_CANTNEST|CMD_STARTSERVER|CMD_SENDENVIRON,
|
||||
NULL,
|
||||
NULL,
|
||||
"c:drt:", 0, 0,
|
||||
"[-dr] [-c working-directory] " CMD_TARGET_SESSION_USAGE,
|
||||
CMD_CANTNEST|CMD_STARTSERVER,
|
||||
cmd_attach_session_exec
|
||||
};
|
||||
|
||||
enum cmd_retval
|
||||
cmd_attach_session(struct cmd_q *cmdq, const char* tflag, int dflag, int rflag)
|
||||
cmd_attach_session(struct cmd_q *cmdq, const char *tflag, int dflag, int rflag,
|
||||
const char *cflag)
|
||||
{
|
||||
struct session *s;
|
||||
struct client *c;
|
||||
const char *update;
|
||||
char *cause;
|
||||
u_int i;
|
||||
struct session *s;
|
||||
struct client *c;
|
||||
struct winlink *wl = NULL;
|
||||
struct window *w = NULL;
|
||||
struct window_pane *wp = NULL;
|
||||
const char *update;
|
||||
char *cause;
|
||||
u_int i;
|
||||
int fd;
|
||||
struct format_tree *ft;
|
||||
char *cp;
|
||||
|
||||
if (RB_EMPTY(&sessions)) {
|
||||
cmdq_error(cmdq, "no sessions");
|
||||
return (CMD_RETURN_ERROR);
|
||||
}
|
||||
|
||||
if ((s = cmd_find_session(cmdq, tflag, 1)) == NULL)
|
||||
return (CMD_RETURN_ERROR);
|
||||
if (tflag == NULL) {
|
||||
if ((s = cmd_find_session(cmdq, tflag, 1)) == NULL)
|
||||
return (CMD_RETURN_ERROR);
|
||||
} else if (tflag[strcspn(tflag, ":.")] != '\0') {
|
||||
if ((wl = cmd_find_pane(cmdq, tflag, &s, &wp)) == NULL)
|
||||
return (CMD_RETURN_ERROR);
|
||||
} else {
|
||||
if ((s = cmd_find_session(cmdq, tflag, 1)) == NULL)
|
||||
return (CMD_RETURN_ERROR);
|
||||
w = cmd_lookup_windowid(tflag);
|
||||
if (w == NULL && (wp = cmd_lookup_paneid(tflag)) != NULL)
|
||||
w = wp->window;
|
||||
if (w != NULL)
|
||||
wl = winlink_find_by_window(&s->windows, w);
|
||||
}
|
||||
|
||||
if (cmdq->client == NULL)
|
||||
return (CMD_RETURN_NORMAL);
|
||||
|
||||
if (wl != NULL) {
|
||||
if (wp != NULL)
|
||||
window_set_active_pane(wp->window, wp);
|
||||
session_set_current(s, wl);
|
||||
}
|
||||
|
||||
if (cmdq->client->session != NULL) {
|
||||
if (dflag) {
|
||||
/*
|
||||
@@ -70,27 +98,67 @@ cmd_attach_session(struct cmd_q *cmdq, const char* tflag, int dflag, int rflag)
|
||||
continue;
|
||||
if (c == cmdq->client)
|
||||
continue;
|
||||
server_write_client(c, MSG_DETACH, NULL, 0);
|
||||
server_write_client(c, MSG_DETACH,
|
||||
c->session->name,
|
||||
strlen(c->session->name) + 1);
|
||||
}
|
||||
}
|
||||
|
||||
if (cflag != NULL) {
|
||||
ft = format_create();
|
||||
format_defaults(ft, cmd_find_client(cmdq, NULL, 1), s,
|
||||
NULL, NULL);
|
||||
cp = format_expand(ft, cflag);
|
||||
format_free(ft);
|
||||
|
||||
fd = open(cp, O_RDONLY|O_DIRECTORY);
|
||||
free(cp);
|
||||
if (fd == -1) {
|
||||
cmdq_error(cmdq, "bad working directory: %s",
|
||||
strerror(errno));
|
||||
return (CMD_RETURN_ERROR);
|
||||
}
|
||||
close(s->cwd);
|
||||
s->cwd = fd;
|
||||
}
|
||||
|
||||
cmdq->client->session = s;
|
||||
notify_attached_session_changed(cmdq->client);
|
||||
session_update_activity(s);
|
||||
server_redraw_client(cmdq->client);
|
||||
s->curw->flags &= ~WINLINK_ALERTFLAGS;
|
||||
} else {
|
||||
if (server_client_open(cmdq->client, s, &cause) != 0) {
|
||||
if (server_client_open(cmdq->client, &cause) != 0) {
|
||||
cmdq_error(cmdq, "open terminal failed: %s", cause);
|
||||
free(cause);
|
||||
return (CMD_RETURN_ERROR);
|
||||
}
|
||||
|
||||
if (cflag != NULL) {
|
||||
ft = format_create();
|
||||
format_defaults(ft, cmd_find_client(cmdq, NULL, 1), s,
|
||||
NULL, NULL);
|
||||
cp = format_expand(ft, cflag);
|
||||
format_free(ft);
|
||||
|
||||
fd = open(cp, O_RDONLY|O_DIRECTORY);
|
||||
free(cp);
|
||||
if (fd == -1) {
|
||||
cmdq_error(cmdq, "bad working directory: %s",
|
||||
strerror(errno));
|
||||
return (CMD_RETURN_ERROR);
|
||||
}
|
||||
close(s->cwd);
|
||||
s->cwd = fd;
|
||||
}
|
||||
|
||||
if (rflag)
|
||||
cmdq->client->flags |= CLIENT_READONLY;
|
||||
|
||||
if (dflag)
|
||||
server_write_session(s, MSG_DETACH, NULL, 0);
|
||||
if (dflag) {
|
||||
server_write_session(s, MSG_DETACH, s->name,
|
||||
strlen(s->name) + 1);
|
||||
}
|
||||
|
||||
update = options_get_string(&s->options, "update-environment");
|
||||
environ_update(update, &cmdq->client->environ, &s->environ);
|
||||
@@ -116,5 +184,5 @@ cmd_attach_session_exec(struct cmd *self, struct cmd_q *cmdq)
|
||||
struct args *args = self->args;
|
||||
|
||||
return (cmd_attach_session(cmdq, args_get(args, 't'),
|
||||
args_has(args, 'd'), args_has(args, 'r')));
|
||||
args_has(args, 'd'), args_has(args, 'r'), args_get(args, 'c')));
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $Id$ */
|
||||
/* $OpenBSD$ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||
@@ -27,34 +27,18 @@
|
||||
* Bind a key to a command, this recurses through cmd_*.
|
||||
*/
|
||||
|
||||
enum cmd_retval cmd_bind_key_check(struct args *);
|
||||
enum cmd_retval cmd_bind_key_exec(struct cmd *, struct cmd_q *);
|
||||
|
||||
enum cmd_retval cmd_bind_key_table(struct cmd *, struct cmd_q *, int);
|
||||
enum cmd_retval cmd_bind_key_mode_table(struct cmd *, struct cmd_q *, int);
|
||||
|
||||
const struct cmd_entry cmd_bind_key_entry = {
|
||||
"bind-key", "bind",
|
||||
"cnrt:", 1, -1,
|
||||
"[-cnr] [-t key-table] key command [arguments]",
|
||||
"[-cnr] [-t mode-table] key command [arguments]",
|
||||
0,
|
||||
NULL,
|
||||
cmd_bind_key_check,
|
||||
cmd_bind_key_exec
|
||||
};
|
||||
|
||||
enum cmd_retval
|
||||
cmd_bind_key_check(struct args *args)
|
||||
{
|
||||
if (args_has(args, 't')) {
|
||||
if (args->argc != 2 && args->argc != 3)
|
||||
return (CMD_RETURN_ERROR);
|
||||
} else {
|
||||
if (args->argc < 2)
|
||||
return (CMD_RETURN_ERROR);
|
||||
}
|
||||
return (CMD_RETURN_NORMAL);
|
||||
}
|
||||
|
||||
enum cmd_retval
|
||||
cmd_bind_key_exec(struct cmd *self, struct cmd_q *cmdq)
|
||||
{
|
||||
@@ -63,6 +47,18 @@ cmd_bind_key_exec(struct cmd *self, struct cmd_q *cmdq)
|
||||
struct cmd_list *cmdlist;
|
||||
int key;
|
||||
|
||||
if (args_has(args, 't')) {
|
||||
if (args->argc != 2 && args->argc != 3) {
|
||||
cmdq_error(cmdq, "not enough arguments");
|
||||
return (CMD_RETURN_ERROR);
|
||||
}
|
||||
} else {
|
||||
if (args->argc < 2) {
|
||||
cmdq_error(cmdq, "not enough arguments");
|
||||
return (CMD_RETURN_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
key = key_string_lookup_string(args->argv[0]);
|
||||
if (key == KEYC_NONE) {
|
||||
cmdq_error(cmdq, "unknown key: %s", args->argv[0]);
|
||||
@@ -70,7 +66,7 @@ cmd_bind_key_exec(struct cmd *self, struct cmd_q *cmdq)
|
||||
}
|
||||
|
||||
if (args_has(args, 't'))
|
||||
return (cmd_bind_key_table(self, cmdq, key));
|
||||
return (cmd_bind_key_mode_table(self, cmdq, key));
|
||||
|
||||
cmdlist = cmd_list_parse(args->argc - 1, args->argv + 1, NULL, 0,
|
||||
&cause);
|
||||
@@ -87,7 +83,7 @@ cmd_bind_key_exec(struct cmd *self, struct cmd_q *cmdq)
|
||||
}
|
||||
|
||||
enum cmd_retval
|
||||
cmd_bind_key_table(struct cmd *self, struct cmd_q *cmdq, int key)
|
||||
cmd_bind_key_mode_table(struct cmd *self, struct cmd_q *cmdq, int key)
|
||||
{
|
||||
struct args *args = self->args;
|
||||
const char *tablename;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $Id$ */
|
||||
/* $OpenBSD$ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||
@@ -26,6 +26,8 @@
|
||||
* Break pane off into a window.
|
||||
*/
|
||||
|
||||
#define BREAK_PANE_TEMPLATE "#{session_name}:#{window_index}.#{pane_index}"
|
||||
|
||||
enum cmd_retval cmd_break_pane_exec(struct cmd *, struct cmd_q *);
|
||||
|
||||
const struct cmd_entry cmd_break_pane_entry = {
|
||||
@@ -33,8 +35,6 @@ const struct cmd_entry cmd_break_pane_entry = {
|
||||
"dPF:t:", 0, 0,
|
||||
"[-dP] [-F format] " CMD_TARGET_PANE_USAGE,
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
cmd_break_pane_exec
|
||||
};
|
||||
|
||||
@@ -49,7 +49,6 @@ cmd_break_pane_exec(struct cmd *self, struct cmd_q *cmdq)
|
||||
char *name;
|
||||
char *cause;
|
||||
int base_idx;
|
||||
struct client *c;
|
||||
struct format_tree *ft;
|
||||
const char *template;
|
||||
char *cp;
|
||||
@@ -66,16 +65,7 @@ cmd_break_pane_exec(struct cmd *self, struct cmd_q *cmdq)
|
||||
server_unzoom_window(w);
|
||||
|
||||
TAILQ_REMOVE(&w->panes, wp, entry);
|
||||
if (wp == w->active) {
|
||||
w->active = w->last;
|
||||
w->last = NULL;
|
||||
if (w->active == NULL) {
|
||||
w->active = TAILQ_PREV(wp, window_panes, entry);
|
||||
if (w->active == NULL)
|
||||
w->active = TAILQ_NEXT(wp, entry);
|
||||
}
|
||||
} else if (wp == w->last)
|
||||
w->last = NULL;
|
||||
window_lost_pane(w, wp);
|
||||
layout_close_pane(wp);
|
||||
|
||||
w = wp->window = window_create1(s->sx, s->sy);
|
||||
@@ -99,11 +89,7 @@ cmd_break_pane_exec(struct cmd *self, struct cmd_q *cmdq)
|
||||
template = BREAK_PANE_TEMPLATE;
|
||||
|
||||
ft = format_create();
|
||||
if ((c = cmd_find_client(cmdq, NULL, 1)) != NULL)
|
||||
format_client(ft, c);
|
||||
format_session(ft, s);
|
||||
format_winlink(ft, s, wl);
|
||||
format_window_pane(ft, wp);
|
||||
format_defaults(ft, cmd_find_client(cmdq, NULL, 1), s, wl, wp);
|
||||
|
||||
cp = format_expand(ft, template);
|
||||
cmdq_print(cmdq, "%s", cp);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $Id$ */
|
||||
/* $OpenBSD$ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2009 Jonathan Alvarado <radobobo@users.sourceforge.net>
|
||||
@@ -38,18 +38,16 @@ char *cmd_capture_pane_history(struct args *, struct cmd_q *,
|
||||
const struct cmd_entry cmd_capture_pane_entry = {
|
||||
"capture-pane", "capturep",
|
||||
"ab:CeE:JpPqS:t:", 0, 0,
|
||||
"[-aCeJpPq] [-b buffer-index] [-E end-line] [-S start-line]"
|
||||
"[-aCeJpPq] " CMD_BUFFER_USAGE " [-E end-line] [-S start-line]"
|
||||
CMD_TARGET_PANE_USAGE,
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
cmd_capture_pane_exec
|
||||
};
|
||||
|
||||
char *
|
||||
cmd_capture_pane_append(char *buf, size_t *len, char *line, size_t linelen)
|
||||
{
|
||||
buf = xrealloc(buf, 1, *len + linelen + 1);
|
||||
buf = xrealloc(buf, *len + linelen + 1);
|
||||
memcpy(buf + *len, line, linelen);
|
||||
*len += linelen;
|
||||
return (buf);
|
||||
@@ -95,6 +93,7 @@ cmd_capture_pane_history(struct args *args, struct cmd_q *cmdq,
|
||||
int n, with_codes, escape_c0, join_lines;
|
||||
u_int i, sx, top, bottom, tmp;
|
||||
char *cause, *buf, *line;
|
||||
const char *Sflag, *Eflag;
|
||||
size_t linelen;
|
||||
|
||||
sx = screen_size_x(&wp->base);
|
||||
@@ -110,27 +109,37 @@ cmd_capture_pane_history(struct args *args, struct cmd_q *cmdq,
|
||||
} else
|
||||
gd = wp->base.grid;
|
||||
|
||||
n = args_strtonum(args, 'S', INT_MIN, SHRT_MAX, &cause);
|
||||
if (cause != NULL) {
|
||||
top = gd->hsize;
|
||||
free(cause);
|
||||
} else if (n < 0 && (u_int) -n > gd->hsize)
|
||||
Sflag = args_get(args, 'S');
|
||||
if (Sflag != NULL && strcmp(Sflag, "-") == 0)
|
||||
top = 0;
|
||||
else
|
||||
top = gd->hsize + n;
|
||||
if (top > gd->hsize + gd->sy - 1)
|
||||
top = gd->hsize + gd->sy - 1;
|
||||
else {
|
||||
n = args_strtonum(args, 'S', INT_MIN, SHRT_MAX, &cause);
|
||||
if (cause != NULL) {
|
||||
top = gd->hsize;
|
||||
free(cause);
|
||||
} else if (n < 0 && (u_int) -n > gd->hsize)
|
||||
top = 0;
|
||||
else
|
||||
top = gd->hsize + n;
|
||||
if (top > gd->hsize + gd->sy - 1)
|
||||
top = gd->hsize + gd->sy - 1;
|
||||
}
|
||||
|
||||
n = args_strtonum(args, 'E', INT_MIN, SHRT_MAX, &cause);
|
||||
if (cause != NULL) {
|
||||
bottom = gd->hsize + gd->sy - 1;
|
||||
free(cause);
|
||||
} else if (n < 0 && (u_int) -n > gd->hsize)
|
||||
bottom = 0;
|
||||
else
|
||||
bottom = gd->hsize + n;
|
||||
if (bottom > gd->hsize + gd->sy - 1)
|
||||
Eflag = args_get(args, 'E');
|
||||
if (Eflag != NULL && strcmp(Eflag, "-") == 0)
|
||||
bottom = gd->hsize + gd->sy - 1;
|
||||
else {
|
||||
n = args_strtonum(args, 'E', INT_MIN, SHRT_MAX, &cause);
|
||||
if (cause != NULL) {
|
||||
bottom = gd->hsize + gd->sy - 1;
|
||||
free(cause);
|
||||
} else if (n < 0 && (u_int) -n > gd->hsize)
|
||||
bottom = 0;
|
||||
else
|
||||
bottom = gd->hsize + n;
|
||||
if (bottom > gd->hsize + gd->sy - 1)
|
||||
bottom = gd->hsize + gd->sy - 1;
|
||||
}
|
||||
|
||||
if (bottom < top) {
|
||||
tmp = bottom;
|
||||
@@ -166,8 +175,7 @@ cmd_capture_pane_exec(struct cmd *self, struct cmd_q *cmdq)
|
||||
struct client *c;
|
||||
struct window_pane *wp;
|
||||
char *buf, *cause;
|
||||
int buffer;
|
||||
u_int limit;
|
||||
const char *bufname;
|
||||
size_t len;
|
||||
|
||||
if (cmd_find_pane(cmdq, args_get(args, 't'), NULL, &wp) == NULL)
|
||||
@@ -193,25 +201,17 @@ cmd_capture_pane_exec(struct cmd *self, struct cmd_q *cmdq)
|
||||
evbuffer_add(c->stdout_data, "\n", 1);
|
||||
server_push_stdout(c);
|
||||
} else {
|
||||
limit = options_get_number(&global_options, "buffer-limit");
|
||||
if (!args_has(args, 'b')) {
|
||||
paste_add(&global_buffers, buf, len, limit);
|
||||
return (CMD_RETURN_NORMAL);
|
||||
}
|
||||
|
||||
buffer = args_strtonum(args, 'b', 0, INT_MAX, &cause);
|
||||
if (cause != NULL) {
|
||||
cmdq_error(cmdq, "buffer %s", cause);
|
||||
bufname = NULL;
|
||||
if (args_has(args, 'b'))
|
||||
bufname = args_get(args, 'b');
|
||||
|
||||
if (paste_set(buf, len, bufname, &cause) != 0) {
|
||||
cmdq_error(cmdq, "%s", cause);
|
||||
free(buf);
|
||||
free(cause);
|
||||
return (CMD_RETURN_ERROR);
|
||||
}
|
||||
|
||||
if (paste_replace(&global_buffers, buffer, buf, len) != 0) {
|
||||
cmdq_error(cmdq, "no buffer %d", buffer);
|
||||
free(buf);
|
||||
return (CMD_RETURN_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
return (CMD_RETURN_NORMAL);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $Id$ */
|
||||
/* $OpenBSD$ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2010 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||
@@ -27,6 +27,9 @@
|
||||
* Enter choice mode to choose a buffer.
|
||||
*/
|
||||
|
||||
#define CHOOSE_BUFFER_TEMPLATE \
|
||||
"#{buffer_name}: #{buffer_size} bytes: #{buffer_sample}"
|
||||
|
||||
enum cmd_retval cmd_choose_buffer_exec(struct cmd *, struct cmd_q *);
|
||||
|
||||
const struct cmd_entry cmd_choose_buffer_entry = {
|
||||
@@ -34,8 +37,6 @@ const struct cmd_entry cmd_choose_buffer_entry = {
|
||||
"F:t:", 0, 1,
|
||||
CMD_TARGET_WINDOW_USAGE " [-F format] [template]",
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
cmd_choose_buffer_exec
|
||||
};
|
||||
|
||||
@@ -50,6 +51,7 @@ cmd_choose_buffer_exec(struct cmd *self, struct cmd_q *cmdq)
|
||||
char *action, *action_data;
|
||||
const char *template;
|
||||
u_int idx;
|
||||
int utf8flag;
|
||||
|
||||
if ((c = cmd_current_client(cmdq)) == NULL) {
|
||||
cmdq_error(cmdq, "no client available");
|
||||
@@ -61,8 +63,9 @@ cmd_choose_buffer_exec(struct cmd *self, struct cmd_q *cmdq)
|
||||
|
||||
if ((wl = cmd_find_window(cmdq, args_get(args, 't'), NULL)) == NULL)
|
||||
return (CMD_RETURN_ERROR);
|
||||
utf8flag = options_get_number(&wl->window->options, "utf8");
|
||||
|
||||
if (paste_get_top(&global_buffers) == NULL)
|
||||
if (paste_get_top() == NULL)
|
||||
return (CMD_RETURN_NORMAL);
|
||||
|
||||
if (window_pane_set_mode(wl->window->active, &window_choose_mode) != 0)
|
||||
@@ -74,19 +77,20 @@ cmd_choose_buffer_exec(struct cmd *self, struct cmd_q *cmdq)
|
||||
action = xstrdup("paste-buffer -b '%%'");
|
||||
|
||||
idx = 0;
|
||||
while ((pb = paste_walk_stack(&global_buffers, &idx)) != NULL) {
|
||||
pb = NULL;
|
||||
while ((pb = paste_walk(pb)) != NULL) {
|
||||
cdata = window_choose_data_create(TREE_OTHER, c, c->session);
|
||||
cdata->idx = idx - 1;
|
||||
cdata->idx = idx;
|
||||
|
||||
cdata->ft_template = xstrdup(template);
|
||||
format_add(cdata->ft, "line", "%u", idx - 1);
|
||||
format_paste_buffer(cdata->ft, pb);
|
||||
format_defaults_paste_buffer(cdata->ft, pb, utf8flag);
|
||||
|
||||
xasprintf(&action_data, "%u", idx - 1);
|
||||
xasprintf(&action_data, "%s", pb->name);
|
||||
cdata->command = cmd_template_replace(action, action_data, 1);
|
||||
free(action_data);
|
||||
|
||||
window_choose_add(wl->window->active, cdata);
|
||||
idx++;
|
||||
}
|
||||
free(action);
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $Id$ */
|
||||
/* $OpenBSD$ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||
@@ -27,6 +27,12 @@
|
||||
* Enter choice mode to choose a client.
|
||||
*/
|
||||
|
||||
#define CHOOSE_CLIENT_TEMPLATE \
|
||||
"#{client_tty}: #{session_name} " \
|
||||
"[#{client_width}x#{client_height} #{client_termname}]" \
|
||||
"#{?client_utf8, (utf8),}#{?client_readonly, (ro),} " \
|
||||
"(last used #{client_activity_string})"
|
||||
|
||||
enum cmd_retval cmd_choose_client_exec(struct cmd *, struct cmd_q *);
|
||||
|
||||
void cmd_choose_client_callback(struct window_choose_data *);
|
||||
@@ -36,8 +42,6 @@ const struct cmd_entry cmd_choose_client_entry = {
|
||||
"F:t:", 0, 1,
|
||||
CMD_TARGET_WINDOW_USAGE " [-F format] [template]",
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
cmd_choose_client_exec
|
||||
};
|
||||
|
||||
@@ -90,8 +94,7 @@ cmd_choose_client_exec(struct cmd *self, struct cmd_q *cmdq)
|
||||
|
||||
cdata->ft_template = xstrdup(template);
|
||||
format_add(cdata->ft, "line", "%u", i);
|
||||
format_session(cdata->ft, c1->session);
|
||||
format_client(cdata->ft, c1);
|
||||
format_defaults(cdata->ft, c1, NULL, NULL, NULL);
|
||||
|
||||
cdata->command = cmd_template_replace(action, c1->tty.path, 1);
|
||||
|
||||
|
||||
@@ -1,98 +0,0 @@
|
||||
/* $Id$ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2012 Thomas Adam <thomas@xteddy.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
||||
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <ctype.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "tmux.h"
|
||||
|
||||
#define CMD_CHOOSE_LIST_DEFAULT_TEMPLATE "run-shell '%%'"
|
||||
|
||||
/*
|
||||
* Enter choose mode to choose a custom list.
|
||||
*/
|
||||
|
||||
enum cmd_retval cmd_choose_list_exec(struct cmd *, struct cmd_q *);
|
||||
|
||||
const struct cmd_entry cmd_choose_list_entry = {
|
||||
"choose-list", NULL,
|
||||
"l:t:", 0, 1,
|
||||
"[-l items] " CMD_TARGET_WINDOW_USAGE "[template]",
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
cmd_choose_list_exec
|
||||
};
|
||||
|
||||
enum cmd_retval
|
||||
cmd_choose_list_exec(struct cmd *self, struct cmd_q *cmdq)
|
||||
{
|
||||
struct args *args = self->args;
|
||||
struct client *c;
|
||||
struct winlink *wl;
|
||||
const char *list1;
|
||||
char *template, *item, *copy, *list;
|
||||
u_int idx;
|
||||
|
||||
if ((c = cmd_current_client(cmdq)) == NULL) {
|
||||
cmdq_error(cmdq, "no client available");
|
||||
return (CMD_RETURN_ERROR);
|
||||
}
|
||||
|
||||
if ((list1 = args_get(args, 'l')) == NULL)
|
||||
return (CMD_RETURN_ERROR);
|
||||
|
||||
if ((wl = cmd_find_window(cmdq, args_get(args, 't'), NULL)) == NULL)
|
||||
return (CMD_RETURN_ERROR);
|
||||
|
||||
if (window_pane_set_mode(wl->window->active, &window_choose_mode) != 0)
|
||||
return (CMD_RETURN_NORMAL);
|
||||
|
||||
if (args->argc != 0)
|
||||
template = xstrdup(args->argv[0]);
|
||||
else
|
||||
template = xstrdup(CMD_CHOOSE_LIST_DEFAULT_TEMPLATE);
|
||||
|
||||
copy = list = xstrdup(list1);
|
||||
idx = 0;
|
||||
while ((item = strsep(&list, ",")) != NULL)
|
||||
{
|
||||
if (*item == '\0') /* no empty entries */
|
||||
continue;
|
||||
window_choose_add_item(wl->window->active, c, wl, item,
|
||||
template, idx);
|
||||
idx++;
|
||||
}
|
||||
free(copy);
|
||||
|
||||
if (idx == 0) {
|
||||
free(template);
|
||||
window_pane_reset_mode(wl->window->active);
|
||||
return (CMD_RETURN_ERROR);
|
||||
}
|
||||
|
||||
window_choose_ready(wl->window->active, 0, NULL);
|
||||
|
||||
free(template);
|
||||
|
||||
return (CMD_RETURN_NORMAL);
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $Id$ */
|
||||
/* $OpenBSD$ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2012 Thomas Adam <thomas@xteddy.org>
|
||||
@@ -32,6 +32,15 @@
|
||||
* Enter choice mode to choose a session and/or window.
|
||||
*/
|
||||
|
||||
#define CHOOSE_TREE_SESSION_TEMPLATE \
|
||||
"#{session_name}: #{session_windows} windows" \
|
||||
"#{?session_grouped, (group ,}" \
|
||||
"#{session_group}#{?session_grouped,),}" \
|
||||
"#{?session_attached, (attached),}"
|
||||
#define CHOOSE_TREE_WINDOW_TEMPLATE \
|
||||
"#{window_index}: #{window_name}#{window_flags} " \
|
||||
"\"#{pane_title}\""
|
||||
|
||||
enum cmd_retval cmd_choose_tree_exec(struct cmd *, struct cmd_q *);
|
||||
|
||||
const struct cmd_entry cmd_choose_tree_entry = {
|
||||
@@ -40,8 +49,6 @@ const struct cmd_entry cmd_choose_tree_entry = {
|
||||
"[-suw] [-b session-template] [-c window template] [-S format] " \
|
||||
"[-W format] " CMD_TARGET_WINDOW_USAGE,
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
cmd_choose_tree_exec
|
||||
};
|
||||
|
||||
@@ -50,8 +57,6 @@ const struct cmd_entry cmd_choose_session_entry = {
|
||||
"F:t:", 0, 1,
|
||||
CMD_TARGET_WINDOW_USAGE " [-F format] [template]",
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
cmd_choose_tree_exec
|
||||
};
|
||||
|
||||
@@ -60,8 +65,6 @@ const struct cmd_entry cmd_choose_window_entry = {
|
||||
"F:t:", 0, 1,
|
||||
CMD_TARGET_WINDOW_USAGE "[-F format] [template]",
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
cmd_choose_tree_exec
|
||||
};
|
||||
|
||||
@@ -89,10 +92,7 @@ cmd_choose_tree_exec(struct cmd *self, struct cmd_q *cmdq)
|
||||
return (CMD_RETURN_ERROR);
|
||||
}
|
||||
|
||||
if ((s = c->session) == NULL)
|
||||
return (CMD_RETURN_ERROR);
|
||||
|
||||
if ((wl = cmd_find_window(cmdq, args_get(args, 't'), NULL)) == NULL)
|
||||
if ((wl = cmd_find_window(cmdq, args_get(args, 't'), &s)) == NULL)
|
||||
return (CMD_RETURN_ERROR);
|
||||
|
||||
if (window_pane_set_mode(wl->window->active, &window_choose_mode) != 0)
|
||||
@@ -232,8 +232,10 @@ windows_only:
|
||||
|
||||
window_choose_ready(wl->window->active, cur_win, NULL);
|
||||
|
||||
if (args_has(args, 'u'))
|
||||
if (args_has(args, 'u')) {
|
||||
window_choose_expand_all(wl->window->active);
|
||||
window_choose_set_current(wl->window->active, cur_win);
|
||||
}
|
||||
|
||||
return (CMD_RETURN_NORMAL);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $Id$ */
|
||||
/* $OpenBSD$ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||
@@ -31,8 +31,6 @@ const struct cmd_entry cmd_clear_history_entry = {
|
||||
"t:", 0, 0,
|
||||
CMD_TARGET_PANE_USAGE,
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
cmd_clear_history_exec
|
||||
};
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $Id$ */
|
||||
/* $OpenBSD$ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||
@@ -29,8 +29,6 @@
|
||||
* Prompt for command in client.
|
||||
*/
|
||||
|
||||
void cmd_command_prompt_key_binding(struct cmd *, int);
|
||||
int cmd_command_prompt_check(struct args *);
|
||||
enum cmd_retval cmd_command_prompt_exec(struct cmd *, struct cmd_q *);
|
||||
|
||||
int cmd_command_prompt_callback(void *, const char *);
|
||||
@@ -41,8 +39,6 @@ const struct cmd_entry cmd_command_prompt_entry = {
|
||||
"I:p:t:", 0, 1,
|
||||
"[-I inputs] [-p prompts] " CMD_TARGET_CLIENT_USAGE " [template]",
|
||||
0,
|
||||
cmd_command_prompt_key_binding,
|
||||
NULL,
|
||||
cmd_command_prompt_exec
|
||||
};
|
||||
|
||||
@@ -56,34 +52,6 @@ struct cmd_command_prompt_cdata {
|
||||
int idx;
|
||||
};
|
||||
|
||||
void
|
||||
cmd_command_prompt_key_binding(struct cmd *self, int key)
|
||||
{
|
||||
switch (key) {
|
||||
case '$':
|
||||
self->args = args_create(1, "rename-session '%%'");
|
||||
args_set(self->args, 'I', "#S");
|
||||
break;
|
||||
case ',':
|
||||
self->args = args_create(1, "rename-window '%%'");
|
||||
args_set(self->args, 'I', "#W");
|
||||
break;
|
||||
case '.':
|
||||
self->args = args_create(1, "move-window -t '%%'");
|
||||
break;
|
||||
case 'f':
|
||||
self->args = args_create(1, "find-window '%%'");
|
||||
break;
|
||||
case '\'':
|
||||
self->args = args_create(1, "select-window -t ':%%'");
|
||||
args_set(self->args, 'p', "index");
|
||||
break;
|
||||
default:
|
||||
self->args = args_create(0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
enum cmd_retval
|
||||
cmd_command_prompt_exec(struct cmd *self, struct cmd_q *cmdq)
|
||||
{
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $Id$ */
|
||||
/* $OpenBSD$ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2009 Tiago Cunha <me@tiagocunha.org>
|
||||
@@ -16,6 +16,8 @@
|
||||
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <ctype.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@@ -26,7 +28,6 @@
|
||||
* Asks for confirmation before executing a command.
|
||||
*/
|
||||
|
||||
void cmd_confirm_before_key_binding(struct cmd *, int);
|
||||
enum cmd_retval cmd_confirm_before_exec(struct cmd *, struct cmd_q *);
|
||||
|
||||
int cmd_confirm_before_callback(void *, const char *);
|
||||
@@ -37,8 +38,6 @@ const struct cmd_entry cmd_confirm_before_entry = {
|
||||
"p:t:", 1, 1,
|
||||
"[-p prompt] " CMD_TARGET_CLIENT_USAGE " command",
|
||||
0,
|
||||
cmd_confirm_before_key_binding,
|
||||
NULL,
|
||||
cmd_confirm_before_exec
|
||||
};
|
||||
|
||||
@@ -47,24 +46,6 @@ struct cmd_confirm_before_data {
|
||||
struct client *client;
|
||||
};
|
||||
|
||||
void
|
||||
cmd_confirm_before_key_binding(struct cmd *self, int key)
|
||||
{
|
||||
switch (key) {
|
||||
case '&':
|
||||
self->args = args_create(1, "kill-window");
|
||||
args_set(self->args, 'p', "kill-window #W? (y/n)");
|
||||
break;
|
||||
case 'x':
|
||||
self->args = args_create(1, "kill-pane");
|
||||
args_set(self->args, 'p', "kill-pane #P? (y/n)");
|
||||
break;
|
||||
default:
|
||||
self->args = args_create(0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
enum cmd_retval
|
||||
cmd_confirm_before_exec(struct cmd *self, struct cmd_q *cmdq)
|
||||
{
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $Id$ */
|
||||
/* $OpenBSD$ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||
@@ -21,10 +21,9 @@
|
||||
#include "tmux.h"
|
||||
|
||||
/*
|
||||
* Enter copy mode.
|
||||
* Enter copy or clock mode.
|
||||
*/
|
||||
|
||||
void cmd_copy_mode_key_binding(struct cmd *, int);
|
||||
enum cmd_retval cmd_copy_mode_exec(struct cmd *, struct cmd_q *);
|
||||
|
||||
const struct cmd_entry cmd_copy_mode_entry = {
|
||||
@@ -32,18 +31,16 @@ const struct cmd_entry cmd_copy_mode_entry = {
|
||||
"t:u", 0, 0,
|
||||
"[-u] " CMD_TARGET_PANE_USAGE,
|
||||
0,
|
||||
cmd_copy_mode_key_binding,
|
||||
NULL,
|
||||
cmd_copy_mode_exec
|
||||
};
|
||||
|
||||
void
|
||||
cmd_copy_mode_key_binding(struct cmd *self, int key)
|
||||
{
|
||||
self->args = args_create(0);
|
||||
if (key == KEYC_PPAGE)
|
||||
args_set(self->args, 'u', NULL);
|
||||
}
|
||||
const struct cmd_entry cmd_clock_mode_entry = {
|
||||
"clock-mode", NULL,
|
||||
"t:", 0, 0,
|
||||
CMD_TARGET_PANE_USAGE,
|
||||
0,
|
||||
cmd_copy_mode_exec
|
||||
};
|
||||
|
||||
enum cmd_retval
|
||||
cmd_copy_mode_exec(struct cmd *self, struct cmd_q *cmdq)
|
||||
@@ -54,9 +51,16 @@ cmd_copy_mode_exec(struct cmd *self, struct cmd_q *cmdq)
|
||||
if (cmd_find_pane(cmdq, args_get(args, 't'), NULL, &wp) == NULL)
|
||||
return (CMD_RETURN_ERROR);
|
||||
|
||||
if (window_pane_set_mode(wp, &window_copy_mode) != 0)
|
||||
if (self->entry == &cmd_clock_mode_entry) {
|
||||
window_pane_set_mode(wp, &window_clock_mode);
|
||||
return (CMD_RETURN_NORMAL);
|
||||
window_copy_init_from_pane(wp);
|
||||
}
|
||||
|
||||
if (wp->mode != &window_copy_mode) {
|
||||
if (window_pane_set_mode(wp, &window_copy_mode) != 0)
|
||||
return (CMD_RETURN_NORMAL);
|
||||
window_copy_init_from_pane(wp);
|
||||
}
|
||||
if (wp->mode == &window_copy_mode && args_has(self->args, 'u'))
|
||||
window_copy_pageup(wp);
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $Id$ */
|
||||
/* $OpenBSD$ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||
@@ -33,8 +33,6 @@ const struct cmd_entry cmd_delete_buffer_entry = {
|
||||
"b:", 0, 0,
|
||||
CMD_BUFFER_USAGE,
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
cmd_delete_buffer_exec
|
||||
};
|
||||
|
||||
@@ -42,23 +40,16 @@ enum cmd_retval
|
||||
cmd_delete_buffer_exec(struct cmd *self, struct cmd_q *cmdq)
|
||||
{
|
||||
struct args *args = self->args;
|
||||
char *cause;
|
||||
int buffer;
|
||||
const char *bufname;
|
||||
|
||||
if (!args_has(args, 'b')) {
|
||||
paste_free_top(&global_buffers);
|
||||
paste_free_top();
|
||||
return (CMD_RETURN_NORMAL);
|
||||
}
|
||||
bufname = args_get(args, 'b');
|
||||
|
||||
buffer = args_strtonum(args, 'b', 0, INT_MAX, &cause);
|
||||
if (cause != NULL) {
|
||||
cmdq_error(cmdq, "buffer %s", cause);
|
||||
free(cause);
|
||||
return (CMD_RETURN_ERROR);
|
||||
}
|
||||
|
||||
if (paste_free_index(&global_buffers, buffer) != 0) {
|
||||
cmdq_error(cmdq, "no buffer %d", buffer);
|
||||
if (paste_free_name(bufname) != 0) {
|
||||
cmdq_error(cmdq, "no buffer %s", bufname);
|
||||
return (CMD_RETURN_ERROR);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $Id$ */
|
||||
/* $OpenBSD$ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||
@@ -18,6 +18,8 @@
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "tmux.h"
|
||||
|
||||
/*
|
||||
@@ -31,8 +33,14 @@ const struct cmd_entry cmd_detach_client_entry = {
|
||||
"as:t:P", 0, 0,
|
||||
"[-P] [-a] [-s target-session] " CMD_TARGET_CLIENT_USAGE,
|
||||
CMD_READONLY,
|
||||
NULL,
|
||||
NULL,
|
||||
cmd_detach_client_exec
|
||||
};
|
||||
|
||||
const struct cmd_entry cmd_suspend_client_entry = {
|
||||
"suspend-client", "suspendc",
|
||||
"t:", 0, 0,
|
||||
CMD_TARGET_CLIENT_USAGE,
|
||||
0,
|
||||
cmd_detach_client_exec
|
||||
};
|
||||
|
||||
@@ -40,11 +48,20 @@ enum cmd_retval
|
||||
cmd_detach_client_exec(struct cmd *self, struct cmd_q *cmdq)
|
||||
{
|
||||
struct args *args = self->args;
|
||||
struct client *c, *c2;
|
||||
struct session *s;
|
||||
enum msgtype msgtype;
|
||||
struct client *c, *cloop;
|
||||
struct session *s;
|
||||
enum msgtype msgtype;
|
||||
u_int i;
|
||||
|
||||
if (self->entry == &cmd_suspend_client_entry) {
|
||||
if ((c = cmd_find_client(cmdq, args_get(args, 't'), 0)) == NULL)
|
||||
return (CMD_RETURN_ERROR);
|
||||
tty_stop_tty(&c->tty);
|
||||
c->flags |= CLIENT_SUSPENDED;
|
||||
server_write_client(c, MSG_SUSPEND, NULL, 0);
|
||||
return (CMD_RETURN_NORMAL);
|
||||
}
|
||||
|
||||
if (args_has(args, 'P'))
|
||||
msgtype = MSG_DETACHKILL;
|
||||
else
|
||||
@@ -56,25 +73,35 @@ cmd_detach_client_exec(struct cmd *self, struct cmd_q *cmdq)
|
||||
return (CMD_RETURN_ERROR);
|
||||
|
||||
for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
|
||||
c = ARRAY_ITEM(&clients, i);
|
||||
if (c != NULL && c->session == s)
|
||||
server_write_client(c, msgtype, NULL, 0);
|
||||
cloop = ARRAY_ITEM(&clients, i);
|
||||
if (cloop == NULL || cloop->session != s)
|
||||
continue;
|
||||
server_write_client(cloop, msgtype,
|
||||
cloop->session->name,
|
||||
strlen(cloop->session->name) + 1);
|
||||
}
|
||||
} else {
|
||||
c = cmd_find_client(cmdq, args_get(args, 't'), 0);
|
||||
if (c == NULL)
|
||||
return (CMD_RETURN_ERROR);
|
||||
|
||||
if (args_has(args, 'a')) {
|
||||
for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
|
||||
c2 = ARRAY_ITEM(&clients, i);
|
||||
if (c2 == NULL || c == c2)
|
||||
continue;
|
||||
server_write_client(c2, msgtype, NULL, 0);
|
||||
}
|
||||
} else
|
||||
server_write_client(c, msgtype, NULL, 0);
|
||||
return (CMD_RETURN_STOP);
|
||||
}
|
||||
|
||||
c = cmd_find_client(cmdq, args_get(args, 't'), 0);
|
||||
if (c == NULL)
|
||||
return (CMD_RETURN_ERROR);
|
||||
|
||||
if (args_has(args, 'a')) {
|
||||
for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
|
||||
cloop = ARRAY_ITEM(&clients, i);
|
||||
if (cloop == NULL || cloop->session == NULL)
|
||||
continue;
|
||||
if (cloop == c)
|
||||
continue;
|
||||
server_write_client(cloop, msgtype,
|
||||
cloop->session->name,
|
||||
strlen(cloop->session->name) + 1);
|
||||
}
|
||||
return (CMD_RETURN_NORMAL);
|
||||
}
|
||||
|
||||
server_write_client(c, msgtype, c->session->name,
|
||||
strlen(c->session->name) + 1);
|
||||
return (CMD_RETURN_STOP);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $Id$ */
|
||||
/* $OpenBSD$ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2009 Tiago Cunha <me@tiagocunha.org>
|
||||
@@ -27,6 +27,11 @@
|
||||
* Displays a message in the status line.
|
||||
*/
|
||||
|
||||
#define DISPLAY_MESSAGE_TEMPLATE \
|
||||
"[#{session_name}] #{window_index}:" \
|
||||
"#{window_name}, current pane #{pane_index} " \
|
||||
"- (%H:%M %d-%b-%y)"
|
||||
|
||||
enum cmd_retval cmd_display_message_exec(struct cmd *, struct cmd_q *);
|
||||
|
||||
const struct cmd_entry cmd_display_message_entry = {
|
||||
@@ -35,8 +40,6 @@ const struct cmd_entry cmd_display_message_entry = {
|
||||
"[-p] [-c target-client] [-F format] " CMD_TARGET_PANE_USAGE
|
||||
" [message]",
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
cmd_display_message_exec
|
||||
};
|
||||
|
||||
@@ -71,9 +74,9 @@ cmd_display_message_exec(struct cmd *self, struct cmd_q *cmdq)
|
||||
}
|
||||
|
||||
if (args_has(args, 'c')) {
|
||||
c = cmd_find_client(cmdq, args_get(args, 'c'), 0);
|
||||
if (c == NULL)
|
||||
return (CMD_RETURN_ERROR);
|
||||
c = cmd_find_client(cmdq, args_get(args, 'c'), 0);
|
||||
if (c == NULL)
|
||||
return (CMD_RETURN_ERROR);
|
||||
} else {
|
||||
c = cmd_current_client(cmdq);
|
||||
if (c == NULL && !args_has(self->args, 'p')) {
|
||||
@@ -89,11 +92,7 @@ cmd_display_message_exec(struct cmd *self, struct cmd_q *cmdq)
|
||||
template = DISPLAY_MESSAGE_TEMPLATE;
|
||||
|
||||
ft = format_create();
|
||||
if (c != NULL)
|
||||
format_client(ft, c);
|
||||
format_session(ft, s);
|
||||
format_winlink(ft, s, wl);
|
||||
format_window_pane(ft, wp);
|
||||
format_defaults(ft, c, s, wl, wp);
|
||||
|
||||
t = time(NULL);
|
||||
len = strftime(out, sizeof out, template, localtime(&t));
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $Id$ */
|
||||
/* $OpenBSD$ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||
@@ -31,8 +31,6 @@ const struct cmd_entry cmd_display_panes_entry = {
|
||||
"t:", 0, 0,
|
||||
CMD_TARGET_CLIENT_USAGE,
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
cmd_display_panes_exec
|
||||
};
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $Id$ */
|
||||
/* $OpenBSD$ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||
@@ -28,6 +28,11 @@
|
||||
* Find window containing text.
|
||||
*/
|
||||
|
||||
#define FIND_WINDOW_TEMPLATE \
|
||||
"#{window_index}: #{window_name} " \
|
||||
"[#{window_width}x#{window_height}] " \
|
||||
"(#{window_panes} panes) #{window_find_matches}"
|
||||
|
||||
enum cmd_retval cmd_find_window_exec(struct cmd *, struct cmd_q *);
|
||||
|
||||
void cmd_find_window_callback(struct window_choose_data *);
|
||||
@@ -47,8 +52,6 @@ const struct cmd_entry cmd_find_window_entry = {
|
||||
"F:CNt:T", 1, 4,
|
||||
"[-CNT] [-F format] " CMD_TARGET_WINDOW_USAGE " match-string",
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
cmd_find_window_exec
|
||||
};
|
||||
|
||||
@@ -85,7 +88,8 @@ cmd_find_window_match_flags(struct args *args)
|
||||
|
||||
void
|
||||
cmd_find_window_match(struct cmd_find_window_data_list *find_list,
|
||||
int match_flags, struct winlink *wl, const char *str, const char *searchstr)
|
||||
int match_flags, struct winlink *wl, const char *str,
|
||||
const char *searchstr)
|
||||
{
|
||||
struct cmd_find_window_data find_data;
|
||||
struct window_pane *wp;
|
||||
@@ -158,7 +162,7 @@ cmd_find_window_exec(struct cmd *self, struct cmd_q *cmdq)
|
||||
|
||||
xasprintf(&searchstr, "*%s*", str);
|
||||
RB_FOREACH(wm, winlinks, &s->windows)
|
||||
cmd_find_window_match (&find_list, match_flags, wm, str, searchstr);
|
||||
cmd_find_window_match(&find_list, match_flags, wm, str, searchstr);
|
||||
free(searchstr);
|
||||
|
||||
if (ARRAY_LENGTH(&find_list) == 0) {
|
||||
@@ -190,9 +194,7 @@ cmd_find_window_exec(struct cmd *self, struct cmd_q *cmdq)
|
||||
format_add(cdata->ft, "line", "%u", i);
|
||||
format_add(cdata->ft, "window_find_matches", "%s",
|
||||
ARRAY_ITEM(&find_list, i).list_ctx);
|
||||
format_session(cdata->ft, s);
|
||||
format_winlink(cdata->ft, s, wm);
|
||||
format_window_pane(cdata->ft, wm->window->active);
|
||||
format_defaults(cdata->ft, NULL, s, wm, NULL);
|
||||
|
||||
window_choose_add(wl->window->active, cdata);
|
||||
}
|
||||
@@ -200,6 +202,8 @@ cmd_find_window_exec(struct cmd *self, struct cmd_q *cmdq)
|
||||
window_choose_ready(wl->window->active, 0, cmd_find_window_callback);
|
||||
|
||||
out:
|
||||
for (i = 0; i < ARRAY_LENGTH(&find_list); i++)
|
||||
free(ARRAY_ITEM(&find_list, i).list_ctx);
|
||||
ARRAY_FREE(&find_list);
|
||||
return (CMD_RETURN_NORMAL);
|
||||
}
|
||||
|
||||
@@ -1,48 +0,0 @@
|
||||
/* $Id$ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
||||
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "tmux.h"
|
||||
|
||||
/*
|
||||
* Cause client to report an error and exit with 1 if session doesn't exist.
|
||||
*/
|
||||
|
||||
enum cmd_retval cmd_has_session_exec(struct cmd *, struct cmd_q *);
|
||||
|
||||
const struct cmd_entry cmd_has_session_entry = {
|
||||
"has-session", "has",
|
||||
"t:", 0, 0,
|
||||
CMD_TARGET_SESSION_USAGE,
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
cmd_has_session_exec
|
||||
};
|
||||
|
||||
enum cmd_retval
|
||||
cmd_has_session_exec(struct cmd *self, struct cmd_q *cmdq)
|
||||
{
|
||||
struct args *args = self->args;
|
||||
|
||||
if (cmd_find_session(cmdq, args_get(args, 't'), 0) == NULL)
|
||||
return (CMD_RETURN_ERROR);
|
||||
|
||||
return (CMD_RETURN_NORMAL);
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $Id$ */
|
||||
/* $OpenBSD$ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2009 Tiago Cunha <me@tiagocunha.org>
|
||||
@@ -37,11 +37,9 @@ void cmd_if_shell_free(void *);
|
||||
|
||||
const struct cmd_entry cmd_if_shell_entry = {
|
||||
"if-shell", "if",
|
||||
"bt:", 2, 3,
|
||||
"[-b] " CMD_TARGET_PANE_USAGE " shell-command command [command]",
|
||||
"bFt:", 2, 3,
|
||||
"[-bF] " CMD_TARGET_PANE_USAGE " shell-command command [command]",
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
cmd_if_shell_exec
|
||||
};
|
||||
|
||||
@@ -58,7 +56,8 @@ cmd_if_shell_exec(struct cmd *self, struct cmd_q *cmdq)
|
||||
{
|
||||
struct args *args = self->args;
|
||||
struct cmd_if_shell_data *cdata;
|
||||
char *shellcmd;
|
||||
char *shellcmd, *cmd, *cause;
|
||||
struct cmd_list *cmdlist;
|
||||
struct client *c;
|
||||
struct session *s = NULL;
|
||||
struct winlink *wl = NULL;
|
||||
@@ -77,15 +76,30 @@ cmd_if_shell_exec(struct cmd *self, struct cmd_q *cmdq)
|
||||
}
|
||||
|
||||
ft = format_create();
|
||||
if (s != NULL)
|
||||
format_session(ft, s);
|
||||
if (s != NULL && wl != NULL)
|
||||
format_winlink(ft, s, wl);
|
||||
if (wp != NULL)
|
||||
format_window_pane(ft, wp);
|
||||
format_defaults(ft, NULL, s, wl, wp);
|
||||
shellcmd = format_expand(ft, args->argv[0]);
|
||||
format_free(ft);
|
||||
|
||||
if (args_has(args, 'F')) {
|
||||
cmd = NULL;
|
||||
if (*shellcmd != '0' && *shellcmd != '\0')
|
||||
cmd = args->argv[1];
|
||||
else if (args->argc == 3)
|
||||
cmd = args->argv[2];
|
||||
if (cmd == NULL)
|
||||
return (CMD_RETURN_NORMAL);
|
||||
if (cmd_string_parse(cmd, &cmdlist, NULL, 0, &cause) != 0) {
|
||||
if (cause != NULL) {
|
||||
cmdq_error(cmdq, "%s", cause);
|
||||
free(cause);
|
||||
}
|
||||
return (CMD_RETURN_ERROR);
|
||||
}
|
||||
cmdq_run(cmdq, cmdlist);
|
||||
cmd_list_free(cmdlist);
|
||||
return (CMD_RETURN_NORMAL);
|
||||
}
|
||||
|
||||
cdata = xmalloc(sizeof *cdata);
|
||||
cdata->cmd_if = xstrdup(args->argv[1]);
|
||||
if (args->argc == 3)
|
||||
@@ -148,6 +162,9 @@ cmd_if_shell_done(struct cmd_q *cmdq1)
|
||||
struct cmd_if_shell_data *cdata = cmdq1->data;
|
||||
struct cmd_q *cmdq = cdata->cmdq;
|
||||
|
||||
if (cmdq1->client_exit >= 0)
|
||||
cmdq->client_exit = cmdq1->client_exit;
|
||||
|
||||
if (!cmdq_free(cmdq) && !cdata->bflag)
|
||||
cmdq_continue(cmdq);
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $Id$ */
|
||||
/* $OpenBSD$ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2011 George Nachman <tmux@georgester.com>
|
||||
@@ -28,7 +28,6 @@
|
||||
* Join or move a pane into another (like split/swap/kill).
|
||||
*/
|
||||
|
||||
void cmd_join_pane_key_binding(struct cmd *, int);
|
||||
enum cmd_retval cmd_join_pane_exec(struct cmd *, struct cmd_q *);
|
||||
|
||||
enum cmd_retval join_pane(struct cmd *, struct cmd_q *, int);
|
||||
@@ -38,8 +37,6 @@ const struct cmd_entry cmd_join_pane_entry = {
|
||||
"bdhvp:l:s:t:", 0, 0,
|
||||
"[-bdhv] [-p percentage|-l size] [-s src-pane] [-t dst-pane]",
|
||||
0,
|
||||
cmd_join_pane_key_binding,
|
||||
NULL,
|
||||
cmd_join_pane_exec
|
||||
};
|
||||
|
||||
@@ -48,25 +45,9 @@ const struct cmd_entry cmd_move_pane_entry = {
|
||||
"bdhvp:l:s:t:", 0, 0,
|
||||
"[-bdhv] [-p percentage|-l size] [-s src-pane] [-t dst-pane]",
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
cmd_join_pane_exec
|
||||
};
|
||||
|
||||
void
|
||||
cmd_join_pane_key_binding(struct cmd *self, int key)
|
||||
{
|
||||
switch (key) {
|
||||
case '%':
|
||||
self->args = args_create(0);
|
||||
args_set(self->args, 'h', NULL);
|
||||
break;
|
||||
default:
|
||||
self->args = args_create(0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
enum cmd_retval
|
||||
cmd_join_pane_exec(struct cmd *self, struct cmd_q *cmdq)
|
||||
{
|
||||
@@ -140,11 +121,7 @@ join_pane(struct cmd *self, struct cmd_q *cmdq, int not_same_window)
|
||||
|
||||
layout_close_pane(src_wp);
|
||||
|
||||
if (src_w->active == src_wp) {
|
||||
src_w->active = TAILQ_PREV(src_wp, window_panes, entry);
|
||||
if (src_w->active == NULL)
|
||||
src_w->active = TAILQ_NEXT(src_wp, entry);
|
||||
}
|
||||
window_lost_pane(src_w, src_wp);
|
||||
TAILQ_REMOVE(&src_w->panes, src_wp, entry);
|
||||
|
||||
if (window_count_panes(src_w) == 0)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $Id$ */
|
||||
/* $OpenBSD$ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||
@@ -33,8 +33,6 @@ const struct cmd_entry cmd_kill_pane_entry = {
|
||||
"at:", 0, 0,
|
||||
"[-a] " CMD_TARGET_PANE_USAGE,
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
cmd_kill_pane_exec
|
||||
};
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $Id$ */
|
||||
/* $OpenBSD$ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||
@@ -34,15 +34,22 @@ const struct cmd_entry cmd_kill_server_entry = {
|
||||
"", 0, 0,
|
||||
"",
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
cmd_kill_server_exec
|
||||
};
|
||||
|
||||
const struct cmd_entry cmd_start_server_entry = {
|
||||
"start-server", "start",
|
||||
"", 0, 0,
|
||||
"",
|
||||
CMD_STARTSERVER,
|
||||
cmd_kill_server_exec
|
||||
};
|
||||
|
||||
enum cmd_retval
|
||||
cmd_kill_server_exec(unused struct cmd *self, unused struct cmd_q *cmdq)
|
||||
cmd_kill_server_exec(struct cmd *self, unused struct cmd_q *cmdq)
|
||||
{
|
||||
kill(getpid(), SIGTERM);
|
||||
if (self->entry == &cmd_kill_server_entry)
|
||||
kill(getpid(), SIGTERM);
|
||||
|
||||
return (CMD_RETURN_NORMAL);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $Id$ */
|
||||
/* $OpenBSD$ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||
@@ -34,8 +34,6 @@ const struct cmd_entry cmd_kill_session_entry = {
|
||||
"at:", 0, 0,
|
||||
"[-a] " CMD_TARGET_SESSION_USAGE,
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
cmd_kill_session_exec
|
||||
};
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $Id$ */
|
||||
/* $OpenBSD$ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||
@@ -31,28 +31,51 @@ const struct cmd_entry cmd_kill_window_entry = {
|
||||
"at:", 0, 0,
|
||||
"[-a] " CMD_TARGET_WINDOW_USAGE,
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
cmd_kill_window_exec
|
||||
};
|
||||
|
||||
const struct cmd_entry cmd_unlink_window_entry = {
|
||||
"unlink-window", "unlinkw",
|
||||
"kt:", 0, 0,
|
||||
"[-k] " CMD_TARGET_WINDOW_USAGE,
|
||||
0,
|
||||
cmd_kill_window_exec
|
||||
};
|
||||
|
||||
enum cmd_retval
|
||||
cmd_kill_window_exec(struct cmd *self, struct cmd_q *cmdq)
|
||||
{
|
||||
struct args *args = self->args;
|
||||
struct winlink *wl, *wl2, *wl3;
|
||||
struct session *s;
|
||||
struct args *args = self->args;
|
||||
struct winlink *wl, *wl2, *wl3;
|
||||
struct window *w;
|
||||
struct session *s;
|
||||
struct session_group *sg;
|
||||
u_int references;
|
||||
|
||||
if ((wl = cmd_find_window(cmdq, args_get(args, 't'), &s)) == NULL)
|
||||
return (CMD_RETURN_ERROR);
|
||||
w = wl->window;
|
||||
|
||||
if (args_has(args, 'a')) {
|
||||
RB_FOREACH_SAFE(wl2, winlinks, &s->windows, wl3) {
|
||||
if (wl != wl2)
|
||||
server_kill_window(wl2->window);
|
||||
if (self->entry == &cmd_unlink_window_entry) {
|
||||
sg = session_group_find(s);
|
||||
if (sg != NULL)
|
||||
references = session_group_count(sg);
|
||||
else
|
||||
references = 1;
|
||||
if (!args_has(self->args, 'k') && w->references == references) {
|
||||
cmdq_error(cmdq, "window only linked to one session");
|
||||
return (CMD_RETURN_ERROR);
|
||||
}
|
||||
} else
|
||||
server_kill_window(wl->window);
|
||||
server_unlink_window(s, wl);
|
||||
} else {
|
||||
if (args_has(args, 'a')) {
|
||||
RB_FOREACH_SAFE(wl2, winlinks, &s->windows, wl3) {
|
||||
if (wl != wl2)
|
||||
server_kill_window(wl2->window);
|
||||
}
|
||||
} else
|
||||
server_kill_window(wl->window);
|
||||
}
|
||||
|
||||
recalculate_sizes();
|
||||
return (CMD_RETURN_NORMAL);
|
||||
|
||||
@@ -1,65 +0,0 @@
|
||||
/* $Id$ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
||||
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "tmux.h"
|
||||
|
||||
/*
|
||||
* Link a window into another session.
|
||||
*/
|
||||
|
||||
enum cmd_retval cmd_link_window_exec(struct cmd *, struct cmd_q *);
|
||||
|
||||
const struct cmd_entry cmd_link_window_entry = {
|
||||
"link-window", "linkw",
|
||||
"dks:t:", 0, 0,
|
||||
"[-dk] " CMD_SRCDST_WINDOW_USAGE,
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
cmd_link_window_exec
|
||||
};
|
||||
|
||||
enum cmd_retval
|
||||
cmd_link_window_exec(struct cmd *self, struct cmd_q *cmdq)
|
||||
{
|
||||
struct args *args = self->args;
|
||||
struct session *src, *dst;
|
||||
struct winlink *wl;
|
||||
char *cause;
|
||||
int idx, kflag, dflag;
|
||||
|
||||
if ((wl = cmd_find_window(cmdq, args_get(args, 's'), &src)) == NULL)
|
||||
return (CMD_RETURN_ERROR);
|
||||
if ((idx = cmd_find_index(cmdq, args_get(args, 't'), &dst)) == -2)
|
||||
return (CMD_RETURN_ERROR);
|
||||
|
||||
kflag = args_has(self->args, 'k');
|
||||
dflag = args_has(self->args, 'd');
|
||||
if (server_link_window(src, wl, dst, idx, kflag, !dflag, &cause) != 0) {
|
||||
cmdq_error(cmdq, "can't link window: %s", cause);
|
||||
free(cause);
|
||||
return (CMD_RETURN_ERROR);
|
||||
}
|
||||
recalculate_sizes();
|
||||
|
||||
return (CMD_RETURN_NORMAL);
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $Id$ */
|
||||
/* $OpenBSD$ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||
@@ -27,6 +27,9 @@
|
||||
* List paste buffers.
|
||||
*/
|
||||
|
||||
#define LIST_BUFFERS_TEMPLATE \
|
||||
"#{buffer_name}: #{buffer_size} bytes: \"#{buffer_sample}\""
|
||||
|
||||
enum cmd_retval cmd_list_buffers_exec(struct cmd *, struct cmd_q *);
|
||||
|
||||
const struct cmd_entry cmd_list_buffers_entry = {
|
||||
@@ -34,8 +37,6 @@ const struct cmd_entry cmd_list_buffers_entry = {
|
||||
"F:", 0, 0,
|
||||
"[-F format]",
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
cmd_list_buffers_exec
|
||||
};
|
||||
|
||||
@@ -45,18 +46,16 @@ cmd_list_buffers_exec(unused struct cmd *self, struct cmd_q *cmdq)
|
||||
struct args *args = self->args;
|
||||
struct paste_buffer *pb;
|
||||
struct format_tree *ft;
|
||||
u_int idx;
|
||||
char *line;
|
||||
const char *template;
|
||||
|
||||
if ((template = args_get(args, 'F')) == NULL)
|
||||
template = LIST_BUFFERS_TEMPLATE;
|
||||
|
||||
idx = 0;
|
||||
while ((pb = paste_walk_stack(&global_buffers, &idx)) != NULL) {
|
||||
pb = NULL;
|
||||
while ((pb = paste_walk(pb)) != NULL) {
|
||||
ft = format_create();
|
||||
format_add(ft, "line", "%u", idx - 1);
|
||||
format_paste_buffer(ft, pb);
|
||||
format_defaults_paste_buffer(ft, pb, 0);
|
||||
|
||||
line = format_expand(ft, template);
|
||||
cmdq_print(cmdq, "%s", line);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $Id$ */
|
||||
/* $OpenBSD$ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||
@@ -28,6 +28,11 @@
|
||||
* List all clients.
|
||||
*/
|
||||
|
||||
#define LIST_CLIENTS_TEMPLATE \
|
||||
"#{client_tty}: #{session_name} " \
|
||||
"[#{client_width}x#{client_height} #{client_termname}]" \
|
||||
"#{?client_utf8, (utf8),} #{?client_readonly, (ro),}"
|
||||
|
||||
enum cmd_retval cmd_list_clients_exec(struct cmd *, struct cmd_q *);
|
||||
|
||||
const struct cmd_entry cmd_list_clients_entry = {
|
||||
@@ -35,8 +40,6 @@ const struct cmd_entry cmd_list_clients_entry = {
|
||||
"F:t:", 0, 0,
|
||||
"[-F format] " CMD_TARGET_SESSION_USAGE,
|
||||
CMD_READONLY,
|
||||
NULL,
|
||||
NULL,
|
||||
cmd_list_clients_exec
|
||||
};
|
||||
|
||||
@@ -71,8 +74,7 @@ cmd_list_clients_exec(struct cmd *self, struct cmd_q *cmdq)
|
||||
|
||||
ft = format_create();
|
||||
format_add(ft, "line", "%u", i);
|
||||
format_session(ft, c->session);
|
||||
format_client(ft, c);
|
||||
format_defaults(ft, c, NULL, NULL, NULL);
|
||||
|
||||
line = format_expand(ft, template);
|
||||
cmdq_print(cmdq, "%s", line);
|
||||
|
||||
@@ -1,55 +0,0 @@
|
||||
/* $Id$ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
||||
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "tmux.h"
|
||||
|
||||
/*
|
||||
* List all commands with usages.
|
||||
*/
|
||||
|
||||
enum cmd_retval cmd_list_commands_exec(struct cmd *, struct cmd_q *);
|
||||
|
||||
const struct cmd_entry cmd_list_commands_entry = {
|
||||
"list-commands", "lscm",
|
||||
"", 0, 0,
|
||||
"",
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
cmd_list_commands_exec
|
||||
};
|
||||
|
||||
enum cmd_retval
|
||||
cmd_list_commands_exec(unused struct cmd *self, struct cmd_q *cmdq)
|
||||
{
|
||||
const struct cmd_entry **entryp;
|
||||
|
||||
for (entryp = cmd_table; *entryp != NULL; entryp++) {
|
||||
if ((*entryp)->alias != NULL) {
|
||||
cmdq_print(cmdq, "%s (%s) %s", (*entryp)->name,
|
||||
(*entryp)->alias, (*entryp)->usage);
|
||||
} else {
|
||||
cmdq_print(cmdq, "%s %s", (*entryp)->name,
|
||||
(*entryp)->usage);
|
||||
}
|
||||
}
|
||||
|
||||
return (CMD_RETURN_NORMAL);
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $Id$ */
|
||||
/* $OpenBSD$ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||
@@ -27,15 +27,23 @@
|
||||
*/
|
||||
|
||||
enum cmd_retval cmd_list_keys_exec(struct cmd *, struct cmd_q *);
|
||||
|
||||
enum cmd_retval cmd_list_keys_table(struct cmd *, struct cmd_q *);
|
||||
enum cmd_retval cmd_list_keys_commands(struct cmd *, struct cmd_q *);
|
||||
|
||||
const struct cmd_entry cmd_list_keys_entry = {
|
||||
"list-keys", "lsk",
|
||||
"t:", 0, 0,
|
||||
"[-t key-table]",
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
cmd_list_keys_exec
|
||||
};
|
||||
|
||||
const struct cmd_entry cmd_list_commands_entry = {
|
||||
"list-commands", "lscm",
|
||||
"", 0, 0,
|
||||
"",
|
||||
0,
|
||||
cmd_list_keys_exec
|
||||
};
|
||||
|
||||
@@ -49,6 +57,9 @@ cmd_list_keys_exec(struct cmd *self, struct cmd_q *cmdq)
|
||||
size_t used;
|
||||
int width, keywidth;
|
||||
|
||||
if (self->entry == &cmd_list_commands_entry)
|
||||
return (cmd_list_keys_commands(self, cmdq));
|
||||
|
||||
if (args_has(args, 't'))
|
||||
return (cmd_list_keys_table(self, cmdq));
|
||||
|
||||
@@ -149,3 +160,22 @@ cmd_list_keys_table(struct cmd *self, struct cmd_q *cmdq)
|
||||
|
||||
return (CMD_RETURN_NORMAL);
|
||||
}
|
||||
|
||||
enum cmd_retval
|
||||
cmd_list_keys_commands(unused struct cmd *self, struct cmd_q *cmdq)
|
||||
{
|
||||
const struct cmd_entry **entryp;
|
||||
const struct cmd_entry *entry;
|
||||
|
||||
for (entryp = cmd_table; *entryp != NULL; entryp++) {
|
||||
entry = *entryp;
|
||||
if (entry->alias == NULL) {
|
||||
cmdq_print(cmdq, "%s %s", entry->name, entry->usage);
|
||||
continue;
|
||||
}
|
||||
cmdq_print(cmdq, "%s (%s) %s", entry->name, entry->alias,
|
||||
entry->usage);
|
||||
}
|
||||
|
||||
return (CMD_RETURN_NORMAL);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $Id$ */
|
||||
/* $OpenBSD$ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||
@@ -40,8 +40,6 @@ const struct cmd_entry cmd_list_panes_entry = {
|
||||
"asF:t:", 0, 0,
|
||||
"[-as] [-F format] " CMD_TARGET_WINDOW_USAGE,
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
cmd_list_panes_exec
|
||||
};
|
||||
|
||||
@@ -130,9 +128,7 @@ cmd_list_panes_window(struct cmd *self,
|
||||
TAILQ_FOREACH(wp, &wl->window->panes, entry) {
|
||||
ft = format_create();
|
||||
format_add(ft, "line", "%u", n);
|
||||
format_session(ft, s);
|
||||
format_winlink(ft, s, wl);
|
||||
format_window_pane(ft, wp);
|
||||
format_defaults(ft, NULL, s, wl, wp);
|
||||
|
||||
line = format_expand(ft, template);
|
||||
cmdq_print(cmdq, "%s", line);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $Id$ */
|
||||
/* $OpenBSD$ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||
@@ -28,6 +28,14 @@
|
||||
* List all sessions.
|
||||
*/
|
||||
|
||||
#define LIST_SESSIONS_TEMPLATE \
|
||||
"#{session_name}: #{session_windows} windows " \
|
||||
"(created #{session_created_string}) " \
|
||||
"[#{session_width}x#{session_height}]" \
|
||||
"#{?session_grouped, (group ,}" \
|
||||
"#{session_group}#{?session_grouped,),}" \
|
||||
"#{?session_attached, (attached),}"
|
||||
|
||||
enum cmd_retval cmd_list_sessions_exec(struct cmd *, struct cmd_q *);
|
||||
|
||||
const struct cmd_entry cmd_list_sessions_entry = {
|
||||
@@ -35,8 +43,6 @@ const struct cmd_entry cmd_list_sessions_entry = {
|
||||
"F:", 0, 0,
|
||||
"[-F format]",
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
cmd_list_sessions_exec
|
||||
};
|
||||
|
||||
@@ -57,7 +63,7 @@ cmd_list_sessions_exec(struct cmd *self, struct cmd_q *cmdq)
|
||||
RB_FOREACH(s, sessions, &sessions) {
|
||||
ft = format_create();
|
||||
format_add(ft, "line", "%u", n);
|
||||
format_session(ft, s);
|
||||
format_defaults(ft, NULL, s, NULL, NULL);
|
||||
|
||||
line = format_expand(ft, template);
|
||||
cmdq_print(cmdq, "%s", line);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $Id$ */
|
||||
/* $OpenBSD$ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||
@@ -27,19 +27,29 @@
|
||||
* List windows on given session.
|
||||
*/
|
||||
|
||||
#define LIST_WINDOWS_TEMPLATE \
|
||||
"#{window_index}: #{window_name}#{window_flags} " \
|
||||
"(#{window_panes} panes) " \
|
||||
"[#{window_width}x#{window_height}] " \
|
||||
"[layout #{window_layout}] #{window_id}" \
|
||||
"#{?window_active, (active),}";
|
||||
#define LIST_WINDOWS_WITH_SESSION_TEMPLATE \
|
||||
"#{session_name}:" \
|
||||
"#{window_index}: #{window_name}#{window_flags} " \
|
||||
"(#{window_panes} panes) " \
|
||||
"[#{window_width}x#{window_height}] "
|
||||
|
||||
enum cmd_retval cmd_list_windows_exec(struct cmd *, struct cmd_q *);
|
||||
|
||||
void cmd_list_windows_server(struct cmd *, struct cmd_q *);
|
||||
void cmd_list_windows_session(
|
||||
struct cmd *, struct session *, struct cmd_q *, int);
|
||||
void cmd_list_windows_session(struct cmd *, struct session *,
|
||||
struct cmd_q *, int);
|
||||
|
||||
const struct cmd_entry cmd_list_windows_entry = {
|
||||
"list-windows", "lsw",
|
||||
"F:at:", 0, 0,
|
||||
"[-a] [-F format] " CMD_TARGET_SESSION_USAGE,
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
cmd_list_windows_exec
|
||||
};
|
||||
|
||||
@@ -97,9 +107,7 @@ cmd_list_windows_session(
|
||||
RB_FOREACH(wl, winlinks, &s->windows) {
|
||||
ft = format_create();
|
||||
format_add(ft, "line", "%u", n);
|
||||
format_session(ft, s);
|
||||
format_winlink(ft, s, wl);
|
||||
format_window_pane(ft, wl->window->active);
|
||||
format_defaults(ft, NULL, s, wl, NULL);
|
||||
|
||||
line = format_expand(ft, template);
|
||||
cmdq_print(cmdq, "%s", line);
|
||||
|
||||
14
cmd-list.c
14
cmd-list.c
@@ -1,4 +1,4 @@
|
||||
/* $Id$ */
|
||||
/* $OpenBSD$ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||
@@ -24,7 +24,7 @@
|
||||
#include "tmux.h"
|
||||
|
||||
struct cmd_list *
|
||||
cmd_list_parse(int argc, char **argv, const char* file, u_int line,
|
||||
cmd_list_parse(int argc, char **argv, const char *file, u_int line,
|
||||
char **cause)
|
||||
{
|
||||
struct cmd_list *cmdlist;
|
||||
@@ -103,7 +103,7 @@ size_t
|
||||
cmd_list_print(struct cmd_list *cmdlist, char *buf, size_t len)
|
||||
{
|
||||
struct cmd *cmd;
|
||||
size_t off;
|
||||
size_t off, used;
|
||||
|
||||
off = 0;
|
||||
TAILQ_FOREACH(cmd, &cmdlist->list, qentry) {
|
||||
@@ -112,8 +112,12 @@ cmd_list_print(struct cmd_list *cmdlist, char *buf, size_t len)
|
||||
off += cmd_print(cmd, buf + off, len - off);
|
||||
if (off >= len)
|
||||
break;
|
||||
if (TAILQ_NEXT(cmd, qentry) != NULL)
|
||||
off += xsnprintf(buf + off, len - off, " ; ");
|
||||
if (TAILQ_NEXT(cmd, qentry) != NULL) {
|
||||
used = xsnprintf(buf + off, len - off, " ; ");
|
||||
if (used > len - off)
|
||||
used = len - off;
|
||||
off += used;
|
||||
}
|
||||
}
|
||||
return (off);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $Id$ */
|
||||
/* $OpenBSD$ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2009 Tiago Cunha <me@tiagocunha.org>
|
||||
@@ -19,6 +19,7 @@
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@@ -38,8 +39,6 @@ const struct cmd_entry cmd_load_buffer_entry = {
|
||||
"b:", 1, 1,
|
||||
CMD_BUFFER_USAGE " path",
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
cmd_load_buffer_exec
|
||||
};
|
||||
|
||||
@@ -50,30 +49,19 @@ cmd_load_buffer_exec(struct cmd *self, struct cmd_q *cmdq)
|
||||
struct client *c = cmdq->client;
|
||||
struct session *s;
|
||||
FILE *f;
|
||||
const char *path, *newpath, *wd;
|
||||
const char *path, *bufname;
|
||||
char *pdata, *new_pdata, *cause;
|
||||
size_t psize;
|
||||
u_int limit;
|
||||
int ch, error, buffer, *buffer_ptr;
|
||||
int ch, error, cwd, fd;
|
||||
|
||||
if (!args_has(args, 'b'))
|
||||
buffer = -1;
|
||||
else {
|
||||
buffer = args_strtonum(args, 'b', 0, INT_MAX, &cause);
|
||||
if (cause != NULL) {
|
||||
cmdq_error(cmdq, "buffer %s", cause);
|
||||
free(cause);
|
||||
return (CMD_RETURN_ERROR);
|
||||
}
|
||||
}
|
||||
bufname = NULL;
|
||||
if (args_has(args, 'b'))
|
||||
bufname = args_get(args, 'b');
|
||||
|
||||
path = args->argv[0];
|
||||
if (strcmp(path, "-") == 0) {
|
||||
buffer_ptr = xmalloc(sizeof *buffer_ptr);
|
||||
*buffer_ptr = buffer;
|
||||
|
||||
error = server_set_stdin_callback (c, cmd_load_buffer_callback,
|
||||
buffer_ptr, &cause);
|
||||
error = server_set_stdin_callback(c, cmd_load_buffer_callback,
|
||||
(void *)bufname, &cause);
|
||||
if (error != 0) {
|
||||
cmdq_error(cmdq, "%s: %s", path, cause);
|
||||
free(cause);
|
||||
@@ -82,20 +70,17 @@ cmd_load_buffer_exec(struct cmd *self, struct cmd_q *cmdq)
|
||||
return (CMD_RETURN_WAIT);
|
||||
}
|
||||
|
||||
if (c != NULL)
|
||||
wd = c->cwd;
|
||||
else if ((s = cmd_current_session(cmdq, 0)) != NULL) {
|
||||
wd = options_get_string(&s->options, "default-path");
|
||||
if (*wd == '\0')
|
||||
wd = s->cwd;
|
||||
} else
|
||||
wd = NULL;
|
||||
if (wd != NULL && *wd != '\0') {
|
||||
newpath = get_full_path(wd, path);
|
||||
if (newpath != NULL)
|
||||
path = newpath;
|
||||
}
|
||||
if ((f = fopen(path, "rb")) == NULL) {
|
||||
if (c != NULL && c->session == NULL)
|
||||
cwd = c->cwd;
|
||||
else if ((s = cmd_current_session(cmdq, 0)) != NULL)
|
||||
cwd = s->cwd;
|
||||
else
|
||||
cwd = AT_FDCWD;
|
||||
|
||||
if ((fd = openat(cwd, path, O_RDONLY)) == -1 ||
|
||||
(f = fdopen(fd, "rb")) == NULL) {
|
||||
if (fd != -1)
|
||||
close(fd);
|
||||
cmdq_error(cmdq, "%s: %s", path, strerror(errno));
|
||||
return (CMD_RETURN_ERROR);
|
||||
}
|
||||
@@ -120,14 +105,10 @@ cmd_load_buffer_exec(struct cmd *self, struct cmd_q *cmdq)
|
||||
|
||||
fclose(f);
|
||||
|
||||
limit = options_get_number(&global_options, "buffer-limit");
|
||||
if (buffer == -1) {
|
||||
paste_add(&global_buffers, pdata, psize, limit);
|
||||
return (CMD_RETURN_NORMAL);
|
||||
}
|
||||
if (paste_replace(&global_buffers, buffer, pdata, psize) != 0) {
|
||||
cmdq_error(cmdq, "no buffer %d", buffer);
|
||||
if (paste_set(pdata, psize, bufname, &cause) != 0) {
|
||||
cmdq_error(cmdq, "%s", cause);
|
||||
free(pdata);
|
||||
free(cause);
|
||||
return (CMD_RETURN_ERROR);
|
||||
}
|
||||
|
||||
@@ -143,10 +124,9 @@ error:
|
||||
void
|
||||
cmd_load_buffer_callback(struct client *c, int closed, void *data)
|
||||
{
|
||||
int *buffer = data;
|
||||
char *pdata;
|
||||
size_t psize;
|
||||
u_int limit;
|
||||
const char *bufname = data;
|
||||
char *pdata, *cause;
|
||||
size_t psize;
|
||||
|
||||
if (!closed)
|
||||
return;
|
||||
@@ -157,25 +137,21 @@ cmd_load_buffer_callback(struct client *c, int closed, void *data)
|
||||
return;
|
||||
|
||||
psize = EVBUFFER_LENGTH(c->stdin_data);
|
||||
if (psize == 0 || (pdata = malloc(psize + 1)) == NULL) {
|
||||
free(data);
|
||||
if (psize == 0 || (pdata = malloc(psize + 1)) == NULL)
|
||||
goto out;
|
||||
}
|
||||
|
||||
memcpy(pdata, EVBUFFER_DATA(c->stdin_data), psize);
|
||||
pdata[psize] = '\0';
|
||||
evbuffer_drain(c->stdin_data, psize);
|
||||
|
||||
limit = options_get_number(&global_options, "buffer-limit");
|
||||
if (*buffer == -1)
|
||||
paste_add(&global_buffers, pdata, psize, limit);
|
||||
else if (paste_replace(&global_buffers, *buffer, pdata, psize) != 0) {
|
||||
if (paste_set(pdata, psize, bufname, &cause) != 0) {
|
||||
/* No context so can't use server_client_msg_error. */
|
||||
evbuffer_add_printf(c->stderr_data, "no buffer %d\n", *buffer);
|
||||
evbuffer_add_printf(c->stderr_data, "%s", cause);
|
||||
server_push_stderr(c);
|
||||
free(pdata);
|
||||
free(cause);
|
||||
}
|
||||
|
||||
free(data);
|
||||
|
||||
out:
|
||||
cmdq_continue(c->cmdq);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $Id$ */
|
||||
/* $OpenBSD$ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||
@@ -18,10 +18,6 @@
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <pwd.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "tmux.h"
|
||||
|
||||
/*
|
||||
@@ -35,8 +31,6 @@ const struct cmd_entry cmd_lock_server_entry = {
|
||||
"", 0, 0,
|
||||
"",
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
cmd_lock_server_exec
|
||||
};
|
||||
|
||||
@@ -45,8 +39,6 @@ const struct cmd_entry cmd_lock_session_entry = {
|
||||
"t:", 0, 0,
|
||||
CMD_TARGET_SESSION_USAGE,
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
cmd_lock_server_exec
|
||||
};
|
||||
|
||||
@@ -55,8 +47,6 @@ const struct cmd_entry cmd_lock_client_entry = {
|
||||
"t:", 0, 0,
|
||||
CMD_TARGET_CLIENT_USAGE,
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
cmd_lock_server_exec
|
||||
};
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $Id$ */
|
||||
/* $OpenBSD$ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||
@@ -33,8 +33,14 @@ const struct cmd_entry cmd_move_window_entry = {
|
||||
"dkrs:t:", 0, 0,
|
||||
"[-dkr] " CMD_SRCDST_WINDOW_USAGE,
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
cmd_move_window_exec
|
||||
};
|
||||
|
||||
const struct cmd_entry cmd_link_window_entry = {
|
||||
"link-window", "linkw",
|
||||
"dks:t:", 0, 0,
|
||||
"[-dk] " CMD_SRCDST_WINDOW_USAGE,
|
||||
0,
|
||||
cmd_move_window_exec
|
||||
};
|
||||
|
||||
@@ -48,7 +54,8 @@ cmd_move_window_exec(struct cmd *self, struct cmd_q *cmdq)
|
||||
int idx, kflag, dflag;
|
||||
|
||||
if (args_has(args, 'r')) {
|
||||
if ((s = cmd_find_session(cmdq, args_get(args, 't'), 0)) == NULL)
|
||||
s = cmd_find_session(cmdq, args_get(args, 't'), 0);
|
||||
if (s == NULL)
|
||||
return (CMD_RETURN_ERROR);
|
||||
|
||||
session_renumber_windows(s);
|
||||
@@ -64,12 +71,14 @@ cmd_move_window_exec(struct cmd *self, struct cmd_q *cmdq)
|
||||
|
||||
kflag = args_has(self->args, 'k');
|
||||
dflag = args_has(self->args, 'd');
|
||||
if (server_link_window(src, wl, dst, idx, kflag, !dflag, &cause) != 0) {
|
||||
cmdq_error(cmdq, "can't move window: %s", cause);
|
||||
if (server_link_window(src, wl, dst, idx, kflag, !dflag,
|
||||
&cause) != 0) {
|
||||
cmdq_error(cmdq, "can't link window: %s", cause);
|
||||
free(cause);
|
||||
return (CMD_RETURN_ERROR);
|
||||
}
|
||||
server_unlink_window(src, wl);
|
||||
if (self->entry == &cmd_move_window_entry)
|
||||
server_unlink_window(src, wl);
|
||||
recalculate_sizes();
|
||||
|
||||
return (CMD_RETURN_NORMAL);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $Id$ */
|
||||
/* $OpenBSD$ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||
@@ -18,7 +18,8 @@
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <pwd.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <termios.h>
|
||||
@@ -30,45 +31,56 @@
|
||||
* Create a new session and attach to the current terminal unless -d is given.
|
||||
*/
|
||||
|
||||
enum cmd_retval cmd_new_session_check(struct args *);
|
||||
#define NEW_SESSION_TEMPLATE "#{session_name}:"
|
||||
|
||||
enum cmd_retval cmd_new_session_exec(struct cmd *, struct cmd_q *);
|
||||
|
||||
const struct cmd_entry cmd_new_session_entry = {
|
||||
"new-session", "new",
|
||||
"AdDF:n:Ps:t:x:y:", 0, 1,
|
||||
"[-AdDP] [-F format] [-n window-name] [-s session-name] "
|
||||
CMD_TARGET_SESSION_USAGE " [-x width] [-y height] [command]",
|
||||
CMD_STARTSERVER|CMD_CANTNEST|CMD_SENDENVIRON,
|
||||
NULL,
|
||||
cmd_new_session_check,
|
||||
"Ac:dDF:n:Ps:t:x:y:", 0, -1,
|
||||
"[-AdDP] [-c start-directory] [-F format] [-n window-name] "
|
||||
"[-s session-name] " CMD_TARGET_SESSION_USAGE " [-x width] "
|
||||
"[-y height] [command]",
|
||||
CMD_STARTSERVER|CMD_CANTNEST,
|
||||
cmd_new_session_exec
|
||||
};
|
||||
|
||||
enum cmd_retval
|
||||
cmd_new_session_check(struct args *args)
|
||||
{
|
||||
if (args_has(args, 't') && (args->argc != 0 || args_has(args, 'n')))
|
||||
return (CMD_RETURN_ERROR);
|
||||
return (CMD_RETURN_NORMAL);
|
||||
}
|
||||
const struct cmd_entry cmd_has_session_entry = {
|
||||
"has-session", "has",
|
||||
"t:", 0, 0,
|
||||
CMD_TARGET_SESSION_USAGE,
|
||||
0,
|
||||
cmd_new_session_exec
|
||||
};
|
||||
|
||||
enum cmd_retval
|
||||
cmd_new_session_exec(struct cmd *self, struct cmd_q *cmdq)
|
||||
{
|
||||
struct args *args = self->args;
|
||||
struct client *c = cmdq->client;
|
||||
struct client *c = cmdq->client, *c0;
|
||||
struct session *s, *groupwith;
|
||||
struct window *w;
|
||||
struct environ env;
|
||||
struct termios tio, *tiop;
|
||||
struct passwd *pw;
|
||||
const char *newname, *target, *update, *cwd, *errstr;
|
||||
const char *template;
|
||||
char *cmd, *cause, *cp;
|
||||
int detached, idx;
|
||||
const char *newname, *target, *update, *errstr, *template;
|
||||
const char *path;
|
||||
char **argv, *cmd, *cause, *cp;
|
||||
int detached, already_attached, idx, cwd, fd = -1;
|
||||
int argc;
|
||||
u_int sx, sy;
|
||||
int already_attached;
|
||||
struct format_tree *ft;
|
||||
struct environ_entry *envent;
|
||||
|
||||
if (self->entry == &cmd_has_session_entry) {
|
||||
if (cmd_find_session(cmdq, args_get(args, 't'), 0) == NULL)
|
||||
return (CMD_RETURN_ERROR);
|
||||
return (CMD_RETURN_NORMAL);
|
||||
}
|
||||
|
||||
if (args_has(args, 't') && (args->argc != 0 || args_has(args, 'n'))) {
|
||||
cmdq_error(cmdq, "command or window name given with target");
|
||||
return (CMD_RETURN_ERROR);
|
||||
}
|
||||
|
||||
newname = args_get(args, 's');
|
||||
if (newname != NULL) {
|
||||
@@ -79,7 +91,7 @@ cmd_new_session_exec(struct cmd *self, struct cmd_q *cmdq)
|
||||
if (session_find(newname) != NULL) {
|
||||
if (args_has(args, 'A')) {
|
||||
return (cmd_attach_session(cmdq, newname,
|
||||
args_has(args, 'D'), 0));
|
||||
args_has(args, 'D'), 0, NULL));
|
||||
}
|
||||
cmdq_error(cmdq, "duplicate session: %s", newname);
|
||||
return (CMD_RETURN_ERROR);
|
||||
@@ -104,6 +116,34 @@ cmd_new_session_exec(struct cmd *self, struct cmd_q *cmdq)
|
||||
if (c != NULL && c->session != NULL)
|
||||
already_attached = 1;
|
||||
|
||||
/* Get the new session working directory. */
|
||||
if (args_has(args, 'c')) {
|
||||
ft = format_create();
|
||||
format_defaults(ft, cmd_find_client(cmdq, NULL, 1), NULL, NULL,
|
||||
NULL);
|
||||
cp = format_expand(ft, args_get(args, 'c'));
|
||||
format_free(ft);
|
||||
|
||||
if (cp != NULL && *cp != '\0') {
|
||||
fd = open(cp, O_RDONLY|O_DIRECTORY);
|
||||
free(cp);
|
||||
if (fd == -1) {
|
||||
cmdq_error(cmdq, "bad working directory: %s",
|
||||
strerror(errno));
|
||||
return (CMD_RETURN_ERROR);
|
||||
}
|
||||
} else if (cp != NULL)
|
||||
free(cp);
|
||||
cwd = fd;
|
||||
} else if (c != NULL && c->session == NULL)
|
||||
cwd = c->cwd;
|
||||
else if ((c0 = cmd_current_client(cmdq)) != NULL)
|
||||
cwd = c0->session->cwd;
|
||||
else {
|
||||
fd = open(".", O_RDONLY);
|
||||
cwd = fd;
|
||||
}
|
||||
|
||||
/*
|
||||
* Save the termios settings, part of which is used for new windows in
|
||||
* this session.
|
||||
@@ -122,24 +162,13 @@ cmd_new_session_exec(struct cmd *self, struct cmd_q *cmdq)
|
||||
|
||||
/* Open the terminal if necessary. */
|
||||
if (!detached && !already_attached) {
|
||||
if (server_client_open(c, NULL, &cause) != 0) {
|
||||
if (server_client_open(c, &cause) != 0) {
|
||||
cmdq_error(cmdq, "open terminal failed: %s", cause);
|
||||
free(cause);
|
||||
return (CMD_RETURN_ERROR);
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
/* Get the new session working directory. */
|
||||
if (c != NULL && c->cwd != NULL)
|
||||
cwd = c->cwd;
|
||||
else {
|
||||
pw = getpwuid(getuid());
|
||||
if (pw->pw_dir != NULL && *pw->pw_dir != '\0')
|
||||
cwd = pw->pw_dir;
|
||||
else
|
||||
cwd = "/";
|
||||
}
|
||||
|
||||
/* Find new session size. */
|
||||
if (c != NULL) {
|
||||
sx = c->tty.sx;
|
||||
@@ -152,14 +181,14 @@ cmd_new_session_exec(struct cmd *self, struct cmd_q *cmdq)
|
||||
sx = strtonum(args_get(args, 'x'), 1, USHRT_MAX, &errstr);
|
||||
if (errstr != NULL) {
|
||||
cmdq_error(cmdq, "width %s", errstr);
|
||||
return (CMD_RETURN_ERROR);
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
if (detached && args_has(args, 'y')) {
|
||||
sy = strtonum(args_get(args, 'y'), 1, USHRT_MAX, &errstr);
|
||||
if (errstr != NULL) {
|
||||
cmdq_error(cmdq, "height %s", errstr);
|
||||
return (CMD_RETURN_ERROR);
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
if (sy > 0 && options_get_number(&global_s_options, "status"))
|
||||
@@ -170,12 +199,29 @@ cmd_new_session_exec(struct cmd *self, struct cmd_q *cmdq)
|
||||
sy = 1;
|
||||
|
||||
/* Figure out the command for the new window. */
|
||||
if (target != NULL)
|
||||
cmd = NULL;
|
||||
else if (args->argc != 0)
|
||||
cmd = args->argv[0];
|
||||
else
|
||||
argc = -1;
|
||||
argv = NULL;
|
||||
if (target == NULL && args->argc != 0) {
|
||||
argc = args->argc;
|
||||
argv = args->argv;
|
||||
} else if (target == NULL) {
|
||||
cmd = options_get_string(&global_s_options, "default-command");
|
||||
if (cmd != NULL && *cmd != '\0') {
|
||||
argc = 1;
|
||||
argv = &cmd;
|
||||
} else {
|
||||
argc = 0;
|
||||
argv = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
path = NULL;
|
||||
if (c != NULL && c->session == NULL)
|
||||
envent = environ_find(&c->environ, "PATH");
|
||||
else
|
||||
envent = environ_find(&global_environ, "PATH");
|
||||
if (envent != NULL)
|
||||
path = envent->value;
|
||||
|
||||
/* Construct the environment. */
|
||||
environ_init(&env);
|
||||
@@ -185,16 +231,17 @@ cmd_new_session_exec(struct cmd *self, struct cmd_q *cmdq)
|
||||
|
||||
/* Create the new session. */
|
||||
idx = -1 - options_get_number(&global_s_options, "base-index");
|
||||
s = session_create(newname, cmd, cwd, &env, tiop, idx, sx, sy, &cause);
|
||||
s = session_create(newname, argc, argv, path, cwd, &env, tiop, idx, sx,
|
||||
sy, &cause);
|
||||
if (s == NULL) {
|
||||
cmdq_error(cmdq, "create session failed: %s", cause);
|
||||
free(cause);
|
||||
return (CMD_RETURN_ERROR);
|
||||
goto error;
|
||||
}
|
||||
environ_free(&env);
|
||||
|
||||
/* Set the initial window name if one given. */
|
||||
if (cmd != NULL && args_has(args, 'n')) {
|
||||
if (argc >= 0 && args_has(args, 'n')) {
|
||||
w = s->curw->window;
|
||||
window_set_name(w, args_get(args, 'n'));
|
||||
options_set_number(&w->options, "automatic-rename", 0);
|
||||
@@ -240,9 +287,8 @@ cmd_new_session_exec(struct cmd *self, struct cmd_q *cmdq)
|
||||
template = NEW_SESSION_TEMPLATE;
|
||||
|
||||
ft = format_create();
|
||||
if ((c = cmd_find_client(cmdq, NULL, 1)) != NULL)
|
||||
format_client(ft, c);
|
||||
format_session(ft, s);
|
||||
format_defaults(ft, cmd_find_client(cmdq, NULL, 1), s, NULL,
|
||||
NULL);
|
||||
|
||||
cp = format_expand(ft, template);
|
||||
cmdq_print(cmdq, "%s", cp);
|
||||
@@ -253,5 +299,13 @@ cmd_new_session_exec(struct cmd *self, struct cmd_q *cmdq)
|
||||
|
||||
if (!detached)
|
||||
cmdq->client_exit = 0;
|
||||
|
||||
if (fd != -1)
|
||||
close(fd);
|
||||
return (CMD_RETURN_NORMAL);
|
||||
|
||||
error:
|
||||
if (fd != -1)
|
||||
close(fd);
|
||||
return (CMD_RETURN_ERROR);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $Id$ */
|
||||
/* $OpenBSD$ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||
@@ -18,7 +18,11 @@
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "tmux.h"
|
||||
|
||||
@@ -26,16 +30,16 @@
|
||||
* Create a new window.
|
||||
*/
|
||||
|
||||
#define NEW_WINDOW_TEMPLATE "#{session_name}:#{window_index}.#{pane_index}"
|
||||
|
||||
enum cmd_retval cmd_new_window_exec(struct cmd *, struct cmd_q *);
|
||||
|
||||
const struct cmd_entry cmd_new_window_entry = {
|
||||
"new-window", "neww",
|
||||
"ac:dF:kn:Pt:", 0, 1,
|
||||
"ac:dF:kn:Pt:", 0, -1,
|
||||
"[-adkP] [-c start-directory] [-F format] [-n window-name] "
|
||||
CMD_TARGET_WINDOW_USAGE " [command]",
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
cmd_new_window_exec
|
||||
};
|
||||
|
||||
@@ -45,11 +49,11 @@ cmd_new_window_exec(struct cmd *self, struct cmd_q *cmdq)
|
||||
struct args *args = self->args;
|
||||
struct session *s;
|
||||
struct winlink *wl;
|
||||
struct client *c;
|
||||
const char *cmd, *cwd, *template;
|
||||
char *cause, *cp;
|
||||
int idx, last, detached;
|
||||
const char *cmd, *path, *template;
|
||||
char **argv, *cause, *cp;
|
||||
int argc, idx, last, detached, cwd, fd = -1;
|
||||
struct format_tree *ft;
|
||||
struct environ_entry *envent;
|
||||
|
||||
if (args_has(args, 'a')) {
|
||||
wl = cmd_find_window(cmdq, args_get(args, 't'), &s);
|
||||
@@ -74,11 +78,57 @@ cmd_new_window_exec(struct cmd *self, struct cmd_q *cmdq)
|
||||
server_unlink_window(s, wl);
|
||||
}
|
||||
} else {
|
||||
if ((idx = cmd_find_index(cmdq, args_get(args, 't'), &s)) == -2)
|
||||
idx = cmd_find_index(cmdq, args_get(args, 't'), &s);
|
||||
if (idx == -2)
|
||||
return (CMD_RETURN_ERROR);
|
||||
}
|
||||
detached = args_has(args, 'd');
|
||||
|
||||
if (args->argc == 0) {
|
||||
cmd = options_get_string(&s->options, "default-command");
|
||||
if (cmd != NULL && *cmd != '\0') {
|
||||
argc = 1;
|
||||
argv = (char **)&cmd;
|
||||
} else {
|
||||
argc = 0;
|
||||
argv = NULL;
|
||||
}
|
||||
} else {
|
||||
argc = args->argc;
|
||||
argv = args->argv;
|
||||
}
|
||||
|
||||
path = NULL;
|
||||
if (cmdq->client != NULL && cmdq->client->session == NULL)
|
||||
envent = environ_find(&cmdq->client->environ, "PATH");
|
||||
else
|
||||
envent = environ_find(&s->environ, "PATH");
|
||||
if (envent != NULL)
|
||||
path = envent->value;
|
||||
|
||||
if (args_has(args, 'c')) {
|
||||
ft = format_create();
|
||||
format_defaults(ft, cmd_find_client(cmdq, NULL, 1), s, NULL,
|
||||
NULL);
|
||||
cp = format_expand(ft, args_get(args, 'c'));
|
||||
format_free(ft);
|
||||
|
||||
if (cp != NULL && *cp != '\0') {
|
||||
fd = open(cp, O_RDONLY|O_DIRECTORY);
|
||||
free(cp);
|
||||
if (fd == -1) {
|
||||
cmdq_error(cmdq, "bad working directory: %s",
|
||||
strerror(errno));
|
||||
return (CMD_RETURN_ERROR);
|
||||
}
|
||||
} else if (cp != NULL)
|
||||
free(cp);
|
||||
cwd = fd;
|
||||
} else if (cmdq->client != NULL && cmdq->client->session == NULL)
|
||||
cwd = cmdq->client->cwd;
|
||||
else
|
||||
cwd = s->cwd;
|
||||
|
||||
wl = NULL;
|
||||
if (idx != -1)
|
||||
wl = winlink_find_by_index(&s->windows, idx);
|
||||
@@ -99,19 +149,14 @@ cmd_new_window_exec(struct cmd *self, struct cmd_q *cmdq)
|
||||
}
|
||||
}
|
||||
|
||||
if (args->argc == 0)
|
||||
cmd = options_get_string(&s->options, "default-command");
|
||||
else
|
||||
cmd = args->argv[0];
|
||||
cwd = cmd_get_default_path(cmdq, args_get(args, 'c'));
|
||||
|
||||
if (idx == -1)
|
||||
idx = -1 - options_get_number(&s->options, "base-index");
|
||||
wl = session_new(s, args_get(args, 'n'), cmd, cwd, idx, &cause);
|
||||
wl = session_new(s, args_get(args, 'n'), argc, argv, path, cwd, idx,
|
||||
&cause);
|
||||
if (wl == NULL) {
|
||||
cmdq_error(cmdq, "create window failed: %s", cause);
|
||||
free(cause);
|
||||
return (CMD_RETURN_ERROR);
|
||||
goto error;
|
||||
}
|
||||
if (!detached) {
|
||||
session_select(s, wl->idx);
|
||||
@@ -124,11 +169,8 @@ cmd_new_window_exec(struct cmd *self, struct cmd_q *cmdq)
|
||||
template = NEW_WINDOW_TEMPLATE;
|
||||
|
||||
ft = format_create();
|
||||
if ((c = cmd_find_client(cmdq, NULL, 1)) != NULL)
|
||||
format_client(ft, c);
|
||||
format_session(ft, s);
|
||||
format_winlink(ft, s, wl);
|
||||
format_window_pane(ft, wl->window->active);
|
||||
format_defaults(ft, cmd_find_client(cmdq, NULL, 1), s, wl,
|
||||
NULL);
|
||||
|
||||
cp = format_expand(ft, template);
|
||||
cmdq_print(cmdq, "%s", cp);
|
||||
@@ -137,5 +179,12 @@ cmd_new_window_exec(struct cmd *self, struct cmd_q *cmdq)
|
||||
format_free(ft);
|
||||
}
|
||||
|
||||
if (fd != -1)
|
||||
close(fd);
|
||||
return (CMD_RETURN_NORMAL);
|
||||
|
||||
error:
|
||||
if (fd != -1)
|
||||
close(fd);
|
||||
return (CMD_RETURN_ERROR);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $Id$ */
|
||||
/* $OpenBSD$ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||
@@ -35,10 +35,8 @@ void cmd_paste_buffer_filter(struct window_pane *,
|
||||
const struct cmd_entry cmd_paste_buffer_entry = {
|
||||
"paste-buffer", "pasteb",
|
||||
"db:prs:t:", 0, 0,
|
||||
"[-dpr] [-s separator] [-b buffer-index] " CMD_TARGET_PANE_USAGE,
|
||||
"[-dpr] [-s separator] " CMD_BUFFER_USAGE " " CMD_TARGET_PANE_USAGE,
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
cmd_paste_buffer_exec
|
||||
};
|
||||
|
||||
@@ -49,31 +47,21 @@ cmd_paste_buffer_exec(struct cmd *self, struct cmd_q *cmdq)
|
||||
struct window_pane *wp;
|
||||
struct session *s;
|
||||
struct paste_buffer *pb;
|
||||
const char *sepstr;
|
||||
char *cause;
|
||||
int buffer;
|
||||
int pflag;
|
||||
const char *sepstr, *bufname;
|
||||
|
||||
if (cmd_find_pane(cmdq, args_get(args, 't'), &s, &wp) == NULL)
|
||||
return (CMD_RETURN_ERROR);
|
||||
|
||||
if (!args_has(args, 'b'))
|
||||
buffer = -1;
|
||||
else {
|
||||
buffer = args_strtonum(args, 'b', 0, INT_MAX, &cause);
|
||||
if (cause != NULL) {
|
||||
cmdq_error(cmdq, "buffer %s", cause);
|
||||
free(cause);
|
||||
return (CMD_RETURN_ERROR);
|
||||
}
|
||||
}
|
||||
bufname = NULL;
|
||||
if (args_has(args, 'b'))
|
||||
bufname = args_get(args, 'b');
|
||||
|
||||
if (buffer == -1)
|
||||
pb = paste_get_top(&global_buffers);
|
||||
if (bufname == NULL)
|
||||
pb = paste_get_top();
|
||||
else {
|
||||
pb = paste_get_index(&global_buffers, buffer);
|
||||
pb = paste_get_name(bufname);
|
||||
if (pb == NULL) {
|
||||
cmdq_error(cmdq, "no buffer %d", buffer);
|
||||
cmdq_error(cmdq, "no buffer %s", bufname);
|
||||
return (CMD_RETURN_ERROR);
|
||||
}
|
||||
}
|
||||
@@ -86,16 +74,15 @@ cmd_paste_buffer_exec(struct cmd *self, struct cmd_q *cmdq)
|
||||
else
|
||||
sepstr = "\r";
|
||||
}
|
||||
pflag = (wp->screen->mode & MODE_BRACKETPASTE);
|
||||
paste_send_pane(pb, wp, sepstr, args_has(args, 'p') && pflag);
|
||||
paste_send_pane(pb, wp, sepstr, args_has(args, 'p'));
|
||||
}
|
||||
|
||||
/* Delete the buffer if -d. */
|
||||
if (args_has(args, 'd')) {
|
||||
if (buffer == -1)
|
||||
paste_free_top(&global_buffers);
|
||||
if (bufname == NULL)
|
||||
paste_free_top();
|
||||
else
|
||||
paste_free_index(&global_buffers, buffer);
|
||||
paste_free_name(bufname);
|
||||
}
|
||||
|
||||
return (CMD_RETURN_NORMAL);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $Id$ */
|
||||
/* $OpenBSD$ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||
@@ -21,6 +21,7 @@
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
@@ -40,8 +41,6 @@ const struct cmd_entry cmd_pipe_pane_entry = {
|
||||
"ot:", 0, 1,
|
||||
"[-o] " CMD_TARGET_PANE_USAGE " [command]",
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
cmd_pipe_pane_exec
|
||||
};
|
||||
|
||||
@@ -50,11 +49,14 @@ cmd_pipe_pane_exec(struct cmd *self, struct cmd_q *cmdq)
|
||||
{
|
||||
struct args *args = self->args;
|
||||
struct client *c;
|
||||
struct session *s;
|
||||
struct winlink *wl;
|
||||
struct window_pane *wp;
|
||||
char *command;
|
||||
char *cmd;
|
||||
int old_fd, pipe_fd[2], null_fd;
|
||||
struct format_tree *ft;
|
||||
|
||||
if (cmd_find_pane(cmdq, args_get(args, 't'), NULL, &wp) == NULL)
|
||||
if ((wl = cmd_find_pane(cmdq, args_get(args, 't'), &s, &wp)) == NULL)
|
||||
return (CMD_RETURN_ERROR);
|
||||
c = cmd_find_client(cmdq, NULL, 1);
|
||||
|
||||
@@ -85,10 +87,18 @@ cmd_pipe_pane_exec(struct cmd *self, struct cmd_q *cmdq)
|
||||
return (CMD_RETURN_ERROR);
|
||||
}
|
||||
|
||||
/* Expand the command. */
|
||||
ft = format_create();
|
||||
format_defaults(ft, c, s, wl, wp);
|
||||
cmd = format_expand_time(ft, args->argv[0], time(NULL));
|
||||
format_free(ft);
|
||||
|
||||
/* Fork the child. */
|
||||
switch (fork()) {
|
||||
case -1:
|
||||
cmdq_error(cmdq, "fork error: %s", strerror(errno));
|
||||
|
||||
free(cmd);
|
||||
return (CMD_RETURN_ERROR);
|
||||
case 0:
|
||||
/* Child process. */
|
||||
@@ -110,9 +120,7 @@ cmd_pipe_pane_exec(struct cmd *self, struct cmd_q *cmdq)
|
||||
|
||||
closefrom(STDERR_FILENO + 1);
|
||||
|
||||
command = status_replace(
|
||||
c, NULL, NULL, NULL, args->argv[0], time(NULL), 0);
|
||||
execl(_PATH_BSHELL, "sh", "-c", command, (char *) NULL);
|
||||
execl(_PATH_BSHELL, "sh", "-c", cmd, (char *) NULL);
|
||||
_exit(1);
|
||||
default:
|
||||
/* Parent process. */
|
||||
@@ -126,6 +134,8 @@ cmd_pipe_pane_exec(struct cmd *self, struct cmd_q *cmdq)
|
||||
bufferevent_enable(wp->pipe_event, EV_WRITE);
|
||||
|
||||
setblocking(wp->pipe_fd, 0);
|
||||
|
||||
free(cmd);
|
||||
return (CMD_RETURN_NORMAL);
|
||||
}
|
||||
}
|
||||
|
||||
96
cmd-queue.c
96
cmd-queue.c
@@ -1,4 +1,4 @@
|
||||
/* $Id$ */
|
||||
/* $OpenBSD$ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2013 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||
@@ -35,7 +35,7 @@ cmdq_new(struct client *c)
|
||||
cmdq->dead = 0;
|
||||
|
||||
cmdq->client = c;
|
||||
cmdq->client_exit = 0;
|
||||
cmdq->client_exit = -1;
|
||||
|
||||
TAILQ_INIT(&cmdq->queue);
|
||||
cmdq->item = NULL;
|
||||
@@ -57,7 +57,7 @@ cmdq_free(struct cmd_q *cmdq)
|
||||
}
|
||||
|
||||
/* Show message from command. */
|
||||
void printflike2
|
||||
void
|
||||
cmdq_print(struct cmd_q *cmdq, const char *fmt, ...)
|
||||
{
|
||||
struct client *c = cmdq->client;
|
||||
@@ -69,9 +69,7 @@ cmdq_print(struct cmd_q *cmdq, const char *fmt, ...)
|
||||
if (c == NULL)
|
||||
/* nothing */;
|
||||
else if (c->session == NULL || (c->flags & CLIENT_CONTROL)) {
|
||||
va_start(ap, fmt);
|
||||
evbuffer_add_vprintf(c->stdout_data, fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
evbuffer_add(c->stdout_data, "\n", 1);
|
||||
server_push_stdout(c);
|
||||
@@ -88,62 +86,28 @@ cmdq_print(struct cmd_q *cmdq, const char *fmt, ...)
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
/* Show info from command. */
|
||||
void printflike2
|
||||
cmdq_info(struct cmd_q *cmdq, const char *fmt, ...)
|
||||
{
|
||||
struct client *c = cmdq->client;
|
||||
va_list ap;
|
||||
char *msg;
|
||||
|
||||
if (options_get_number(&global_options, "quiet"))
|
||||
return;
|
||||
|
||||
va_start(ap, fmt);
|
||||
|
||||
if (c == NULL)
|
||||
/* nothing */;
|
||||
else if (c->session == NULL || (c->flags & CLIENT_CONTROL)) {
|
||||
va_start(ap, fmt);
|
||||
evbuffer_add_vprintf(c->stdout_data, fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
evbuffer_add(c->stdout_data, "\n", 1);
|
||||
server_push_stdout(c);
|
||||
} else {
|
||||
xvasprintf(&msg, fmt, ap);
|
||||
*msg = toupper((u_char) *msg);
|
||||
status_message_set(c, "%s", msg);
|
||||
free(msg);
|
||||
}
|
||||
|
||||
va_end(ap);
|
||||
|
||||
}
|
||||
|
||||
/* Show error from command. */
|
||||
void printflike2
|
||||
void
|
||||
cmdq_error(struct cmd_q *cmdq, const char *fmt, ...)
|
||||
{
|
||||
struct client *c = cmdq->client;
|
||||
struct cmd *cmd = cmdq->cmd;
|
||||
va_list ap;
|
||||
char *msg, *cause;
|
||||
char *msg;
|
||||
size_t msglen;
|
||||
|
||||
va_start(ap, fmt);
|
||||
msglen = xvasprintf(&msg, fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
if (c == NULL) {
|
||||
xasprintf(&cause, "%s:%u: %s", cmd->file, cmd->line, msg);
|
||||
ARRAY_ADD(&cfg_causes, cause);
|
||||
} else if (c->session == NULL || (c->flags & CLIENT_CONTROL)) {
|
||||
if (c == NULL)
|
||||
cfg_add_cause("%s:%u: %s", cmd->file, cmd->line, msg);
|
||||
else if (c->session == NULL || (c->flags & CLIENT_CONTROL)) {
|
||||
evbuffer_add(c->stderr_data, msg, msglen);
|
||||
evbuffer_add(c->stderr_data, "\n", 1);
|
||||
|
||||
server_push_stderr(c);
|
||||
c->retcode = 1;
|
||||
c->retval = 1;
|
||||
} else {
|
||||
*msg = toupper((u_char) *msg);
|
||||
status_message_set(c, "%s", msg);
|
||||
@@ -153,20 +117,17 @@ cmdq_error(struct cmd_q *cmdq, const char *fmt, ...)
|
||||
}
|
||||
|
||||
/* Print a guard line. */
|
||||
int
|
||||
cmdq_guard(struct cmd_q *cmdq, const char *guard)
|
||||
void
|
||||
cmdq_guard(struct cmd_q *cmdq, const char *guard, int flags)
|
||||
{
|
||||
struct client *c = cmdq->client;
|
||||
|
||||
if (c == NULL || c->session == NULL)
|
||||
return 0;
|
||||
if (!(c->flags & CLIENT_CONTROL))
|
||||
return 0;
|
||||
if (c == NULL || !(c->flags & CLIENT_CONTROL))
|
||||
return;
|
||||
|
||||
evbuffer_add_printf(c->stdout_data, "%%%s %ld %u\n", guard,
|
||||
(long) cmdq->time, cmdq->number);
|
||||
evbuffer_add_printf(c->stdout_data, "%%%s %ld %u %d\n", guard,
|
||||
(long) cmdq->time, cmdq->number, flags);
|
||||
server_push_stdout(c);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Add command list to queue and begin processing if needed. */
|
||||
@@ -199,9 +160,10 @@ cmdq_continue(struct cmd_q *cmdq)
|
||||
{
|
||||
struct cmd_q_item *next;
|
||||
enum cmd_retval retval;
|
||||
int empty, guard;
|
||||
int empty, flags;
|
||||
char s[1024];
|
||||
|
||||
cmdq->references++;
|
||||
notify_disable();
|
||||
|
||||
empty = TAILQ_EMPTY(&cmdq->queue);
|
||||
@@ -215,8 +177,6 @@ cmdq_continue(struct cmd_q *cmdq)
|
||||
cmdq->cmd = TAILQ_NEXT(cmdq->cmd, qentry);
|
||||
|
||||
do {
|
||||
next = TAILQ_NEXT(cmdq->item, qentry);
|
||||
|
||||
while (cmdq->cmd != NULL) {
|
||||
cmd_print(cmdq->cmd, s, sizeof s);
|
||||
log_debug("cmdq %p: %s (client %d)", cmdq, s,
|
||||
@@ -225,14 +185,15 @@ cmdq_continue(struct cmd_q *cmdq)
|
||||
cmdq->time = time(NULL);
|
||||
cmdq->number++;
|
||||
|
||||
guard = cmdq_guard(cmdq, "begin");
|
||||
flags = !!(cmdq->cmd->flags & CMD_CONTROL);
|
||||
cmdq_guard(cmdq, "begin", flags);
|
||||
|
||||
retval = cmdq->cmd->entry->exec(cmdq->cmd, cmdq);
|
||||
if (guard) {
|
||||
if (retval == CMD_RETURN_ERROR)
|
||||
cmdq_guard(cmdq, "error");
|
||||
else
|
||||
cmdq_guard(cmdq, "end");
|
||||
}
|
||||
|
||||
if (retval == CMD_RETURN_ERROR)
|
||||
cmdq_guard(cmdq, "error", flags);
|
||||
else
|
||||
cmdq_guard(cmdq, "end", flags);
|
||||
|
||||
if (retval == CMD_RETURN_ERROR)
|
||||
break;
|
||||
@@ -245,6 +206,7 @@ cmdq_continue(struct cmd_q *cmdq)
|
||||
|
||||
cmdq->cmd = TAILQ_NEXT(cmdq->cmd, qentry);
|
||||
}
|
||||
next = TAILQ_NEXT(cmdq->item, qentry);
|
||||
|
||||
TAILQ_REMOVE(&cmdq->queue, cmdq->item, qentry);
|
||||
cmd_list_free(cmdq->item->cmdlist);
|
||||
@@ -256,14 +218,16 @@ cmdq_continue(struct cmd_q *cmdq)
|
||||
} while (cmdq->item != NULL);
|
||||
|
||||
empty:
|
||||
if (cmdq->client_exit)
|
||||
if (cmdq->client_exit > 0)
|
||||
cmdq->client->flags |= CLIENT_EXIT;
|
||||
if (cmdq->emptyfn != NULL)
|
||||
cmdq->emptyfn(cmdq); /* may free cmdq */
|
||||
cmdq->emptyfn(cmdq);
|
||||
empty = 1;
|
||||
|
||||
out:
|
||||
notify_enable();
|
||||
cmdq_free(cmdq);
|
||||
|
||||
return (empty);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $Id$ */
|
||||
/* $OpenBSD$ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||
@@ -29,10 +29,8 @@ enum cmd_retval cmd_refresh_client_exec(struct cmd *, struct cmd_q *);
|
||||
const struct cmd_entry cmd_refresh_client_entry = {
|
||||
"refresh-client", "refresh",
|
||||
"C:St:", 0, 0,
|
||||
"[-S] [-C size]" CMD_TARGET_CLIENT_USAGE,
|
||||
"[-S] [-C size] " CMD_TARGET_CLIENT_USAGE,
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
cmd_refresh_client_exec
|
||||
};
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $Id$ */
|
||||
/* $OpenBSD$ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||
@@ -33,8 +33,6 @@ const struct cmd_entry cmd_rename_session_entry = {
|
||||
"t:", 1, 1,
|
||||
CMD_TARGET_SESSION_USAGE " new-name",
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
cmd_rename_session_exec
|
||||
};
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $Id$ */
|
||||
/* $OpenBSD$ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||
@@ -33,8 +33,6 @@ const struct cmd_entry cmd_rename_window_entry = {
|
||||
"t:", 1, 1,
|
||||
CMD_TARGET_WINDOW_USAGE " new-name",
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
cmd_rename_window_exec
|
||||
};
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $Id$ */
|
||||
/* $OpenBSD$ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||
@@ -26,7 +26,6 @@
|
||||
* Increase or decrease pane size.
|
||||
*/
|
||||
|
||||
void cmd_resize_pane_key_binding(struct cmd *, int);
|
||||
enum cmd_retval cmd_resize_pane_exec(struct cmd *, struct cmd_q *);
|
||||
|
||||
const struct cmd_entry cmd_resize_pane_entry = {
|
||||
@@ -34,57 +33,9 @@ const struct cmd_entry cmd_resize_pane_entry = {
|
||||
"DLRt:Ux:y:Z", 0, 1,
|
||||
"[-DLRUZ] [-x width] [-y height] " CMD_TARGET_PANE_USAGE " [adjustment]",
|
||||
0,
|
||||
cmd_resize_pane_key_binding,
|
||||
NULL,
|
||||
cmd_resize_pane_exec
|
||||
};
|
||||
|
||||
void
|
||||
cmd_resize_pane_key_binding(struct cmd *self, int key)
|
||||
{
|
||||
switch (key) {
|
||||
case KEYC_UP | KEYC_CTRL:
|
||||
self->args = args_create(0);
|
||||
args_set(self->args, 'U', NULL);
|
||||
break;
|
||||
case KEYC_DOWN | KEYC_CTRL:
|
||||
self->args = args_create(0);
|
||||
args_set(self->args, 'D', NULL);
|
||||
break;
|
||||
case KEYC_LEFT | KEYC_CTRL:
|
||||
self->args = args_create(0);
|
||||
args_set(self->args, 'L', NULL);
|
||||
break;
|
||||
case KEYC_RIGHT | KEYC_CTRL:
|
||||
self->args = args_create(0);
|
||||
args_set(self->args, 'R', NULL);
|
||||
break;
|
||||
case KEYC_UP | KEYC_ESCAPE:
|
||||
self->args = args_create(1, "5");
|
||||
args_set(self->args, 'U', NULL);
|
||||
break;
|
||||
case KEYC_DOWN | KEYC_ESCAPE:
|
||||
self->args = args_create(1, "5");
|
||||
args_set(self->args, 'D', NULL);
|
||||
break;
|
||||
case KEYC_LEFT | KEYC_ESCAPE:
|
||||
self->args = args_create(1, "5");
|
||||
args_set(self->args, 'L', NULL);
|
||||
break;
|
||||
case KEYC_RIGHT | KEYC_ESCAPE:
|
||||
self->args = args_create(1, "5");
|
||||
args_set(self->args, 'R', NULL);
|
||||
break;
|
||||
case 'z':
|
||||
self->args = args_create(0);
|
||||
args_set(self->args, 'Z', NULL);
|
||||
break;
|
||||
default:
|
||||
self->args = args_create(0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
enum cmd_retval
|
||||
cmd_resize_pane_exec(struct cmd *self, struct cmd_q *cmdq)
|
||||
{
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $Id$ */
|
||||
/* $OpenBSD$ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||
@@ -32,11 +32,9 @@ enum cmd_retval cmd_respawn_pane_exec(struct cmd *, struct cmd_q *);
|
||||
|
||||
const struct cmd_entry cmd_respawn_pane_entry = {
|
||||
"respawn-pane", "respawnp",
|
||||
"kt:", 0, 1,
|
||||
"kt:", 0, -1,
|
||||
"[-k] " CMD_TARGET_PANE_USAGE " [command]",
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
cmd_respawn_pane_exec
|
||||
};
|
||||
|
||||
@@ -49,9 +47,10 @@ cmd_respawn_pane_exec(struct cmd *self, struct cmd_q *cmdq)
|
||||
struct window_pane *wp;
|
||||
struct session *s;
|
||||
struct environ env;
|
||||
const char *cmd;
|
||||
const char *path;
|
||||
char *cause;
|
||||
u_int idx;
|
||||
struct environ_entry *envent;
|
||||
|
||||
if ((wl = cmd_find_pane(cmdq, args_get(args, 't'), &s, &wp)) == NULL)
|
||||
return (CMD_RETURN_ERROR);
|
||||
@@ -74,11 +73,16 @@ cmd_respawn_pane_exec(struct cmd *self, struct cmd_q *cmdq)
|
||||
screen_reinit(&wp->base);
|
||||
input_init(wp);
|
||||
|
||||
if (args->argc != 0)
|
||||
cmd = args->argv[0];
|
||||
path = NULL;
|
||||
if (cmdq->client != NULL && cmdq->client->session == NULL)
|
||||
envent = environ_find(&cmdq->client->environ, "PATH");
|
||||
else
|
||||
cmd = NULL;
|
||||
if (window_pane_spawn(wp, cmd, NULL, NULL, &env, s->tio, &cause) != 0) {
|
||||
envent = environ_find(&s->environ, "PATH");
|
||||
if (envent != NULL)
|
||||
path = envent->value;
|
||||
|
||||
if (window_pane_spawn(wp, args->argc, args->argv, path, NULL, -1, &env,
|
||||
s->tio, &cause) != 0) {
|
||||
cmdq_error(cmdq, "respawn pane failed: %s", cause);
|
||||
free(cause);
|
||||
environ_free(&env);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $Id$ */
|
||||
/* $OpenBSD$ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||
@@ -31,11 +31,9 @@ enum cmd_retval cmd_respawn_window_exec(struct cmd *, struct cmd_q *);
|
||||
|
||||
const struct cmd_entry cmd_respawn_window_entry = {
|
||||
"respawn-window", "respawnw",
|
||||
"kt:", 0, 1,
|
||||
"kt:", 0, -1,
|
||||
"[-k] " CMD_TARGET_WINDOW_USAGE " [command]",
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
cmd_respawn_window_exec
|
||||
};
|
||||
|
||||
@@ -48,8 +46,9 @@ cmd_respawn_window_exec(struct cmd *self, struct cmd_q *cmdq)
|
||||
struct window_pane *wp;
|
||||
struct session *s;
|
||||
struct environ env;
|
||||
const char *cmd;
|
||||
const char *path;
|
||||
char *cause;
|
||||
struct environ_entry *envent;
|
||||
|
||||
if ((wl = cmd_find_window(cmdq, args_get(args, 't'), &s)) == NULL)
|
||||
return (CMD_RETURN_ERROR);
|
||||
@@ -76,11 +75,17 @@ cmd_respawn_window_exec(struct cmd *self, struct cmd_q *cmdq)
|
||||
window_destroy_panes(w);
|
||||
TAILQ_INSERT_HEAD(&w->panes, wp, entry);
|
||||
window_pane_resize(wp, w->sx, w->sy);
|
||||
if (args->argc != 0)
|
||||
cmd = args->argv[0];
|
||||
|
||||
path = NULL;
|
||||
if (cmdq->client != NULL && cmdq->client->session == NULL)
|
||||
envent = environ_find(&cmdq->client->environ, "PATH");
|
||||
else
|
||||
cmd = NULL;
|
||||
if (window_pane_spawn(wp, cmd, NULL, NULL, &env, s->tio, &cause) != 0) {
|
||||
envent = environ_find(&s->environ, "PATH");
|
||||
if (envent != NULL)
|
||||
path = envent->value;
|
||||
|
||||
if (window_pane_spawn(wp, args->argc, args->argv, path, NULL, -1, &env,
|
||||
s->tio, &cause) != 0) {
|
||||
cmdq_error(cmdq, "respawn window failed: %s", cause);
|
||||
free(cause);
|
||||
environ_free(&env);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $Id$ */
|
||||
/* $OpenBSD$ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||
@@ -24,7 +24,6 @@
|
||||
* Rotate the panes in a window.
|
||||
*/
|
||||
|
||||
void cmd_rotate_window_key_binding(struct cmd *, int);
|
||||
enum cmd_retval cmd_rotate_window_exec(struct cmd *, struct cmd_q *);
|
||||
|
||||
const struct cmd_entry cmd_rotate_window_entry = {
|
||||
@@ -32,19 +31,9 @@ const struct cmd_entry cmd_rotate_window_entry = {
|
||||
"Dt:U", 0, 0,
|
||||
"[-DU] " CMD_TARGET_WINDOW_USAGE,
|
||||
0,
|
||||
cmd_rotate_window_key_binding,
|
||||
NULL,
|
||||
cmd_rotate_window_exec
|
||||
};
|
||||
|
||||
void
|
||||
cmd_rotate_window_key_binding(struct cmd *self, int key)
|
||||
{
|
||||
self->args = args_create(0);
|
||||
if (key == ('o' | KEYC_ESCAPE))
|
||||
args_set(self->args, 'D', NULL);
|
||||
}
|
||||
|
||||
enum cmd_retval
|
||||
cmd_rotate_window_exec(struct cmd *self, struct cmd_q *cmdq)
|
||||
{
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $Id$ */
|
||||
/* $OpenBSD$ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2009 Tiago Cunha <me@tiagocunha.org>
|
||||
@@ -40,8 +40,6 @@ const struct cmd_entry cmd_run_shell_entry = {
|
||||
"bt:", 1, 1,
|
||||
"[-b] " CMD_TARGET_PANE_USAGE " shell-command",
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
cmd_run_shell_exec
|
||||
};
|
||||
|
||||
@@ -95,12 +93,7 @@ cmd_run_shell_exec(struct cmd *self, struct cmd_q *cmdq)
|
||||
}
|
||||
|
||||
ft = format_create();
|
||||
if (s != NULL)
|
||||
format_session(ft, s);
|
||||
if (s != NULL && wl != NULL)
|
||||
format_winlink(ft, s, wl);
|
||||
if (wp != NULL)
|
||||
format_window_pane(ft, wp);
|
||||
format_defaults(ft, NULL, s, wl, wp);
|
||||
shellcmd = format_expand(ft, args->argv[0]);
|
||||
format_free(ft);
|
||||
|
||||
@@ -162,13 +155,9 @@ cmd_run_shell_callback(struct job *job)
|
||||
retcode = WTERMSIG(job->status);
|
||||
xasprintf(&msg, "'%s' terminated by signal %d", cmd, retcode);
|
||||
}
|
||||
if (msg != NULL) {
|
||||
if (lines == 0)
|
||||
cmdq_info(cmdq, "%s", msg);
|
||||
else
|
||||
cmd_run_shell_print(job, msg);
|
||||
free(msg);
|
||||
}
|
||||
if (msg != NULL)
|
||||
cmd_run_shell_print(job, msg);
|
||||
free(msg);
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $Id$ */
|
||||
/* $OpenBSD$ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2009 Tiago Cunha <me@tiagocunha.org>
|
||||
@@ -20,8 +20,10 @@
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "tmux.h"
|
||||
|
||||
@@ -36,8 +38,6 @@ const struct cmd_entry cmd_save_buffer_entry = {
|
||||
"ab:", 1, 1,
|
||||
"[-a] " CMD_BUFFER_USAGE " path",
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
cmd_save_buffer_exec
|
||||
};
|
||||
|
||||
@@ -46,8 +46,6 @@ const struct cmd_entry cmd_show_buffer_entry = {
|
||||
"b:", 0, 0,
|
||||
CMD_BUFFER_USAGE,
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
cmd_save_buffer_exec
|
||||
};
|
||||
|
||||
@@ -55,34 +53,25 @@ enum cmd_retval
|
||||
cmd_save_buffer_exec(struct cmd *self, struct cmd_q *cmdq)
|
||||
{
|
||||
struct args *args = self->args;
|
||||
struct client *c;
|
||||
struct client *c = cmdq->client;
|
||||
struct session *s;
|
||||
struct paste_buffer *pb;
|
||||
const char *path, *newpath, *wd;
|
||||
char *cause, *start, *end;
|
||||
size_t size, used;
|
||||
int buffer;
|
||||
mode_t mask;
|
||||
const char *path, *bufname;
|
||||
char *start, *end, *msg;
|
||||
size_t size, used, msglen;
|
||||
int cwd, fd;
|
||||
FILE *f;
|
||||
char *msg;
|
||||
size_t msglen;
|
||||
|
||||
if (!args_has(args, 'b')) {
|
||||
if ((pb = paste_get_top(&global_buffers)) == NULL) {
|
||||
if ((pb = paste_get_top()) == NULL) {
|
||||
cmdq_error(cmdq, "no buffers");
|
||||
return (CMD_RETURN_ERROR);
|
||||
}
|
||||
} else {
|
||||
buffer = args_strtonum(args, 'b', 0, INT_MAX, &cause);
|
||||
if (cause != NULL) {
|
||||
cmdq_error(cmdq, "buffer %s", cause);
|
||||
free(cause);
|
||||
return (CMD_RETURN_ERROR);
|
||||
}
|
||||
|
||||
pb = paste_get_index(&global_buffers, buffer);
|
||||
bufname = args_get(args, 'b');
|
||||
pb = paste_get_name(bufname);
|
||||
if (pb == NULL) {
|
||||
cmdq_error(cmdq, "no buffer %d", buffer);
|
||||
cmdq_error(cmdq, "no buffer %s", bufname);
|
||||
return (CMD_RETURN_ERROR);
|
||||
}
|
||||
}
|
||||
@@ -92,7 +81,6 @@ cmd_save_buffer_exec(struct cmd *self, struct cmd_q *cmdq)
|
||||
else
|
||||
path = args->argv[0];
|
||||
if (strcmp(path, "-") == 0) {
|
||||
c = cmdq->client;
|
||||
if (c == NULL) {
|
||||
cmdq_error(cmdq, "can't write to stdout");
|
||||
return (CMD_RETURN_ERROR);
|
||||
@@ -102,28 +90,26 @@ cmd_save_buffer_exec(struct cmd *self, struct cmd_q *cmdq)
|
||||
goto do_print;
|
||||
}
|
||||
|
||||
c = cmdq->client;
|
||||
if (c != NULL)
|
||||
wd = c->cwd;
|
||||
else if ((s = cmd_current_session(cmdq, 0)) != NULL) {
|
||||
wd = options_get_string(&s->options, "default-path");
|
||||
if (*wd == '\0')
|
||||
wd = s->cwd;
|
||||
} else
|
||||
wd = NULL;
|
||||
if (wd != NULL && *wd != '\0') {
|
||||
newpath = get_full_path(wd, path);
|
||||
if (newpath != NULL)
|
||||
path = newpath;
|
||||
}
|
||||
|
||||
mask = umask(S_IRWXG | S_IRWXO);
|
||||
if (args_has(self->args, 'a'))
|
||||
f = fopen(path, "ab");
|
||||
if (c != NULL && c->session == NULL)
|
||||
cwd = c->cwd;
|
||||
else if ((s = cmd_current_session(cmdq, 0)) != NULL)
|
||||
cwd = s->cwd;
|
||||
else
|
||||
f = fopen(path, "wb");
|
||||
umask(mask);
|
||||
cwd = AT_FDCWD;
|
||||
|
||||
f = NULL;
|
||||
if (args_has(self->args, 'a')) {
|
||||
fd = openat(cwd, path, O_CREAT|O_RDWR|O_APPEND, 0600);
|
||||
if (fd != -1)
|
||||
f = fdopen(fd, "ab");
|
||||
} else {
|
||||
fd = openat(cwd, path, O_CREAT|O_RDWR|O_TRUNC, 0600);
|
||||
if (fd != -1)
|
||||
f = fdopen(fd, "wb");
|
||||
}
|
||||
if (f == NULL) {
|
||||
if (fd != -1)
|
||||
close(fd);
|
||||
cmdq_error(cmdq, "%s: %s", path, strerror(errno));
|
||||
return (CMD_RETURN_ERROR);
|
||||
}
|
||||
@@ -147,7 +133,6 @@ do_print:
|
||||
return (CMD_RETURN_ERROR);
|
||||
}
|
||||
msg = NULL;
|
||||
msglen = 0;
|
||||
|
||||
used = 0;
|
||||
while (used != pb->size) {
|
||||
@@ -159,7 +144,7 @@ do_print:
|
||||
size = pb->size - used;
|
||||
|
||||
msglen = size * 4 + 1;
|
||||
msg = xrealloc(msg, 1, msglen);
|
||||
msg = xrealloc(msg, msglen);
|
||||
|
||||
strvisx(msg, start, size, VIS_OCTAL|VIS_TAB);
|
||||
cmdq_print(cmdq, "%s", msg);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $Id$ */
|
||||
/* $OpenBSD$ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||
@@ -24,7 +24,6 @@
|
||||
* Switch window to selected layout.
|
||||
*/
|
||||
|
||||
void cmd_select_layout_key_binding(struct cmd *, int);
|
||||
enum cmd_retval cmd_select_layout_exec(struct cmd *, struct cmd_q *);
|
||||
|
||||
const struct cmd_entry cmd_select_layout_entry = {
|
||||
@@ -32,8 +31,6 @@ const struct cmd_entry cmd_select_layout_entry = {
|
||||
"npt:", 0, 1,
|
||||
"[-np] " CMD_TARGET_WINDOW_USAGE " [layout-name]",
|
||||
0,
|
||||
cmd_select_layout_key_binding,
|
||||
NULL,
|
||||
cmd_select_layout_exec
|
||||
};
|
||||
|
||||
@@ -42,8 +39,6 @@ const struct cmd_entry cmd_next_layout_entry = {
|
||||
"t:", 0, 0,
|
||||
CMD_TARGET_WINDOW_USAGE,
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
cmd_select_layout_exec
|
||||
};
|
||||
|
||||
@@ -52,36 +47,9 @@ const struct cmd_entry cmd_previous_layout_entry = {
|
||||
"t:", 0, 0,
|
||||
CMD_TARGET_WINDOW_USAGE,
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
cmd_select_layout_exec
|
||||
};
|
||||
|
||||
void
|
||||
cmd_select_layout_key_binding(struct cmd *self, int key)
|
||||
{
|
||||
switch (key) {
|
||||
case '1' | KEYC_ESCAPE:
|
||||
self->args = args_create(1, "even-horizontal");
|
||||
break;
|
||||
case '2' | KEYC_ESCAPE:
|
||||
self->args = args_create(1, "even-vertical");
|
||||
break;
|
||||
case '3' | KEYC_ESCAPE:
|
||||
self->args = args_create(1, "main-horizontal");
|
||||
break;
|
||||
case '4' | KEYC_ESCAPE:
|
||||
self->args = args_create(1, "main-vertical");
|
||||
break;
|
||||
case '5' | KEYC_ESCAPE:
|
||||
self->args = args_create(1, "tiled");
|
||||
break;
|
||||
default:
|
||||
self->args = args_create(0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
enum cmd_retval
|
||||
cmd_select_layout_exec(struct cmd *self, struct cmd_q *cmdq)
|
||||
{
|
||||
@@ -107,7 +75,6 @@ cmd_select_layout_exec(struct cmd *self, struct cmd_q *cmdq)
|
||||
else
|
||||
layout = layout_set_previous(wl->window);
|
||||
server_redraw_window(wl->window);
|
||||
cmdq_info(cmdq, "arranging in: %s", layout_set_name(layout));
|
||||
return (CMD_RETURN_NORMAL);
|
||||
}
|
||||
|
||||
@@ -118,7 +85,6 @@ cmd_select_layout_exec(struct cmd *self, struct cmd_q *cmdq)
|
||||
if (layout != -1) {
|
||||
layout = layout_set_select(wl->window, layout);
|
||||
server_redraw_window(wl->window);
|
||||
cmdq_info(cmdq, "arranging in: %s", layout_set_name(layout));
|
||||
return (CMD_RETURN_NORMAL);
|
||||
}
|
||||
|
||||
@@ -129,7 +95,6 @@ cmd_select_layout_exec(struct cmd *self, struct cmd_q *cmdq)
|
||||
return (CMD_RETURN_ERROR);
|
||||
}
|
||||
server_redraw_window(wl->window);
|
||||
cmdq_info(cmdq, "arranging in: %s", layoutname);
|
||||
}
|
||||
return (CMD_RETURN_NORMAL);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $Id$ */
|
||||
/* $OpenBSD$ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||
@@ -24,45 +24,24 @@
|
||||
* Select pane.
|
||||
*/
|
||||
|
||||
void cmd_select_pane_key_binding(struct cmd *, int);
|
||||
enum cmd_retval cmd_select_pane_exec(struct cmd *, struct cmd_q *);
|
||||
|
||||
const struct cmd_entry cmd_select_pane_entry = {
|
||||
"select-pane", "selectp",
|
||||
"lDLRt:U", 0, 0,
|
||||
"[-lDLRU] " CMD_TARGET_PANE_USAGE,
|
||||
"DdeLlRt:U", 0, 0,
|
||||
"[-DdeLlRU] " CMD_TARGET_PANE_USAGE,
|
||||
0,
|
||||
cmd_select_pane_key_binding,
|
||||
NULL,
|
||||
cmd_select_pane_exec
|
||||
};
|
||||
|
||||
const struct cmd_entry cmd_last_pane_entry = {
|
||||
"last-pane", "lastp",
|
||||
"t:", 0, 0,
|
||||
CMD_TARGET_WINDOW_USAGE,
|
||||
"det:", 0, 0,
|
||||
"[-de] " CMD_TARGET_WINDOW_USAGE,
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
cmd_select_pane_exec
|
||||
};
|
||||
|
||||
void
|
||||
cmd_select_pane_key_binding(struct cmd *self, int key)
|
||||
{
|
||||
self->args = args_create(0);
|
||||
if (key == KEYC_UP)
|
||||
args_set(self->args, 'U', NULL);
|
||||
if (key == KEYC_DOWN)
|
||||
args_set(self->args, 'D', NULL);
|
||||
if (key == KEYC_LEFT)
|
||||
args_set(self->args, 'L', NULL);
|
||||
if (key == KEYC_RIGHT)
|
||||
args_set(self->args, 'R', NULL);
|
||||
if (key == 'o')
|
||||
args_set(self->args, 't', ":.+");
|
||||
}
|
||||
|
||||
enum cmd_retval
|
||||
cmd_select_pane_exec(struct cmd *self, struct cmd_q *cmdq)
|
||||
{
|
||||
@@ -80,10 +59,16 @@ cmd_select_pane_exec(struct cmd *self, struct cmd_q *cmdq)
|
||||
return (CMD_RETURN_ERROR);
|
||||
}
|
||||
|
||||
server_unzoom_window(wl->window);
|
||||
window_set_active_pane(wl->window, wl->window->last);
|
||||
server_status_window(wl->window);
|
||||
server_redraw_window_borders(wl->window);
|
||||
if (args_has(self->args, 'e'))
|
||||
wl->window->last->flags &= ~PANE_INPUTOFF;
|
||||
else if (args_has(self->args, 'd'))
|
||||
wl->window->last->flags |= PANE_INPUTOFF;
|
||||
else {
|
||||
server_unzoom_window(wl->window);
|
||||
window_set_active_pane(wl->window, wl->window->last);
|
||||
server_status_window(wl->window);
|
||||
server_redraw_window_borders(wl->window);
|
||||
}
|
||||
|
||||
return (CMD_RETURN_NORMAL);
|
||||
}
|
||||
@@ -110,9 +95,14 @@ cmd_select_pane_exec(struct cmd *self, struct cmd_q *cmdq)
|
||||
return (CMD_RETURN_ERROR);
|
||||
}
|
||||
|
||||
window_set_active_pane(wl->window, wp);
|
||||
server_status_window(wl->window);
|
||||
server_redraw_window_borders(wl->window);
|
||||
if (args_has(self->args, 'e'))
|
||||
wp->flags &= ~PANE_INPUTOFF;
|
||||
else if (args_has(self->args, 'd'))
|
||||
wp->flags |= PANE_INPUTOFF;
|
||||
else if (window_set_active_pane(wl->window, wp)) {
|
||||
server_status_window(wl->window);
|
||||
server_redraw_window_borders(wl->window);
|
||||
}
|
||||
|
||||
return (CMD_RETURN_NORMAL);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $Id$ */
|
||||
/* $OpenBSD$ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||
@@ -26,7 +26,6 @@
|
||||
* Select window by index.
|
||||
*/
|
||||
|
||||
void cmd_select_window_key_binding(struct cmd *, int);
|
||||
enum cmd_retval cmd_select_window_exec(struct cmd *, struct cmd_q *);
|
||||
|
||||
const struct cmd_entry cmd_select_window_entry = {
|
||||
@@ -34,8 +33,6 @@ const struct cmd_entry cmd_select_window_entry = {
|
||||
"lnpTt:", 0, 0,
|
||||
"[-lnpT] " CMD_TARGET_WINDOW_USAGE,
|
||||
0,
|
||||
cmd_select_window_key_binding,
|
||||
NULL,
|
||||
cmd_select_window_exec
|
||||
};
|
||||
|
||||
@@ -44,8 +41,6 @@ const struct cmd_entry cmd_next_window_entry = {
|
||||
"at:", 0, 0,
|
||||
"[-a] " CMD_TARGET_SESSION_USAGE,
|
||||
0,
|
||||
cmd_select_window_key_binding,
|
||||
NULL,
|
||||
cmd_select_window_exec
|
||||
};
|
||||
|
||||
@@ -54,8 +49,6 @@ const struct cmd_entry cmd_previous_window_entry = {
|
||||
"at:", 0, 0,
|
||||
"[-a] " CMD_TARGET_SESSION_USAGE,
|
||||
0,
|
||||
cmd_select_window_key_binding,
|
||||
NULL,
|
||||
cmd_select_window_exec
|
||||
};
|
||||
|
||||
@@ -64,25 +57,9 @@ const struct cmd_entry cmd_last_window_entry = {
|
||||
"t:", 0, 0,
|
||||
CMD_TARGET_SESSION_USAGE,
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
cmd_select_window_exec
|
||||
};
|
||||
|
||||
void
|
||||
cmd_select_window_key_binding(struct cmd *self, int key)
|
||||
{
|
||||
char tmp[16];
|
||||
|
||||
self->args = args_create(0);
|
||||
if (key >= '0' && key <= '9') {
|
||||
xsnprintf(tmp, sizeof tmp, ":%d", key - '0');
|
||||
args_set(self->args, 't', tmp);
|
||||
}
|
||||
if (key == ('n' | KEYC_ESCAPE) || key == ('p' | KEYC_ESCAPE))
|
||||
args_set(self->args, 'a', NULL);
|
||||
}
|
||||
|
||||
enum cmd_retval
|
||||
cmd_select_window_exec(struct cmd *self, struct cmd_q *cmdq)
|
||||
{
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $Id$ */
|
||||
/* $OpenBSD$ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||
@@ -34,8 +34,6 @@ const struct cmd_entry cmd_send_keys_entry = {
|
||||
"lRt:", 0, -1,
|
||||
"[-lR] " CMD_TARGET_PANE_USAGE " key ...",
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
cmd_send_keys_exec
|
||||
};
|
||||
|
||||
@@ -44,8 +42,6 @@ const struct cmd_entry cmd_send_prefix_entry = {
|
||||
"2t:", 0, 0,
|
||||
"[-2] " CMD_TARGET_PANE_USAGE,
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
cmd_send_keys_exec
|
||||
};
|
||||
|
||||
@@ -56,7 +52,7 @@ cmd_send_keys_exec(struct cmd *self, struct cmd_q *cmdq)
|
||||
struct window_pane *wp;
|
||||
struct session *s;
|
||||
struct input_ctx *ictx;
|
||||
const char *str;
|
||||
const u_char *str;
|
||||
int i, key;
|
||||
|
||||
if (cmd_find_pane(cmdq, args_get(args, 't'), &s, &wp) == NULL)
|
||||
|
||||
@@ -1,174 +0,0 @@
|
||||
/* $Id$ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
||||
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/utsname.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "tmux.h"
|
||||
|
||||
/*
|
||||
* Show various information about server.
|
||||
*/
|
||||
|
||||
enum cmd_retval cmd_server_info_exec(struct cmd *, struct cmd_q *);
|
||||
|
||||
const struct cmd_entry cmd_server_info_entry = {
|
||||
"server-info", "info",
|
||||
"", 0, 0,
|
||||
"",
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
cmd_server_info_exec
|
||||
};
|
||||
|
||||
enum cmd_retval
|
||||
cmd_server_info_exec(unused struct cmd *self, struct cmd_q *cmdq)
|
||||
{
|
||||
struct tty_term *term;
|
||||
struct client *c;
|
||||
struct session *s;
|
||||
struct winlink *wl;
|
||||
struct window *w;
|
||||
struct window_pane *wp;
|
||||
struct tty_code *code;
|
||||
const struct tty_term_code_entry *ent;
|
||||
struct utsname un;
|
||||
struct job *job;
|
||||
struct grid *gd;
|
||||
struct grid_line *gl;
|
||||
u_int i, j, k, lines;
|
||||
size_t size;
|
||||
char out[80];
|
||||
char *tim;
|
||||
time_t t;
|
||||
|
||||
tim = ctime(&start_time);
|
||||
*strchr(tim, '\n') = '\0';
|
||||
cmdq_print(cmdq,
|
||||
"tmux " VERSION ", pid %ld, started %s", (long) getpid(), tim);
|
||||
cmdq_print(cmdq, "socket path %s, debug level %d", socket_path,
|
||||
debug_level);
|
||||
if (uname(&un) >= 0) {
|
||||
cmdq_print(cmdq, "system is %s %s %s %s",
|
||||
un.sysname, un.release, un.version, un.machine);
|
||||
}
|
||||
if (cfg_file != NULL)
|
||||
cmdq_print(cmdq, "configuration file is %s", cfg_file);
|
||||
else
|
||||
cmdq_print(cmdq, "configuration file not specified");
|
||||
cmdq_print(cmdq, "protocol version is %d", PROTOCOL_VERSION);
|
||||
cmdq_print(cmdq, "%s", "");
|
||||
|
||||
cmdq_print(cmdq, "Clients:");
|
||||
for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
|
||||
c = ARRAY_ITEM(&clients, i);
|
||||
if (c == NULL || c->session == NULL)
|
||||
continue;
|
||||
|
||||
cmdq_print(cmdq,"%2d: %s (%d, %d): %s [%ux%u %s bs=%hho "
|
||||
"class=%u] [flags=0x%x/0x%x, references=%u]", i,
|
||||
c->tty.path, c->ibuf.fd, c->tty.fd, c->session->name,
|
||||
c->tty.sx, c->tty.sy, c->tty.termname,
|
||||
c->tty.tio.c_cc[VERASE], c->tty.class,
|
||||
c->flags, c->tty.flags, c->references);
|
||||
}
|
||||
cmdq_print(cmdq, "%s", "");
|
||||
|
||||
cmdq_print(cmdq, "Sessions: [%zu]", sizeof (struct grid_cell));
|
||||
RB_FOREACH(s, sessions, &sessions) {
|
||||
t = s->creation_time.tv_sec;
|
||||
tim = ctime(&t);
|
||||
*strchr(tim, '\n') = '\0';
|
||||
|
||||
cmdq_print(cmdq, "%2u: %s: %u windows (created %s) [%ux%u] "
|
||||
"[flags=0x%x]", s->id, s->name,
|
||||
winlink_count(&s->windows), tim, s->sx, s->sy, s->flags);
|
||||
RB_FOREACH(wl, winlinks, &s->windows) {
|
||||
w = wl->window;
|
||||
cmdq_print(cmdq, "%4u: %s [%ux%u] [flags=0x%x, "
|
||||
"references=%u, last layout=%d]", wl->idx, w->name,
|
||||
w->sx, w->sy, w->flags, w->references,
|
||||
w->lastlayout);
|
||||
j = 0;
|
||||
TAILQ_FOREACH(wp, &w->panes, entry) {
|
||||
lines = size = 0;
|
||||
gd = wp->base.grid;
|
||||
for (k = 0; k < gd->hsize + gd->sy; k++) {
|
||||
gl = &gd->linedata[k];
|
||||
if (gl->celldata == NULL)
|
||||
continue;
|
||||
lines++;
|
||||
size += gl->cellsize *
|
||||
sizeof *gl->celldata;
|
||||
}
|
||||
cmdq_print(cmdq,
|
||||
"%6u: %s %lu %d %u/%u, %zu bytes", j,
|
||||
wp->tty, (u_long) wp->pid, wp->fd, lines,
|
||||
gd->hsize + gd->sy, size);
|
||||
j++;
|
||||
}
|
||||
}
|
||||
}
|
||||
cmdq_print(cmdq, "%s", "");
|
||||
|
||||
cmdq_print(cmdq, "Terminals:");
|
||||
LIST_FOREACH(term, &tty_terms, entry) {
|
||||
cmdq_print(cmdq, "%s [references=%u, flags=0x%x]:",
|
||||
term->name, term->references, term->flags);
|
||||
for (i = 0; i < NTTYCODE; i++) {
|
||||
ent = &tty_term_codes[i];
|
||||
code = &term->codes[ent->code];
|
||||
switch (code->type) {
|
||||
case TTYCODE_NONE:
|
||||
cmdq_print(cmdq, "%2u: %s: [missing]",
|
||||
ent->code, ent->name);
|
||||
break;
|
||||
case TTYCODE_STRING:
|
||||
strnvis(out, code->value.string, sizeof out,
|
||||
VIS_OCTAL|VIS_TAB|VIS_NL);
|
||||
cmdq_print(cmdq, "%2u: %s: (string) %s",
|
||||
ent->code, ent->name, out);
|
||||
break;
|
||||
case TTYCODE_NUMBER:
|
||||
cmdq_print(cmdq, "%2u: %s: (number) %d",
|
||||
ent->code, ent->name, code->value.number);
|
||||
break;
|
||||
case TTYCODE_FLAG:
|
||||
cmdq_print(cmdq, "%2u: %s: (flag) %s",
|
||||
ent->code, ent->name,
|
||||
code->value.flag ? "true" : "false");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
cmdq_print(cmdq, "%s", "");
|
||||
|
||||
cmdq_print(cmdq, "Jobs:");
|
||||
LIST_FOREACH(job, &all_jobs, lentry) {
|
||||
cmdq_print(cmdq, "%s [fd=%d, pid=%d, status=%d]",
|
||||
job->cmd, job->fd, job->pid, job->status);
|
||||
}
|
||||
|
||||
return (CMD_RETURN_NORMAL);
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $Id$ */
|
||||
/* $OpenBSD$ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||
@@ -24,51 +24,93 @@
|
||||
#include "tmux.h"
|
||||
|
||||
/*
|
||||
* Add or set a paste buffer.
|
||||
* Add, set, or append to a paste buffer.
|
||||
*/
|
||||
|
||||
enum cmd_retval cmd_set_buffer_exec(struct cmd *, struct cmd_q *);
|
||||
|
||||
const struct cmd_entry cmd_set_buffer_entry = {
|
||||
"set-buffer", "setb",
|
||||
"b:", 1, 1,
|
||||
CMD_BUFFER_USAGE " data",
|
||||
"ab:n:", 0, 1,
|
||||
"[-a] " CMD_BUFFER_USAGE " [-n new-buffer-name] data",
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
cmd_set_buffer_exec
|
||||
};
|
||||
|
||||
enum cmd_retval
|
||||
cmd_set_buffer_exec(struct cmd *self, struct cmd_q *cmdq)
|
||||
{
|
||||
struct args *args = self->args;
|
||||
u_int limit;
|
||||
char *pdata, *cause;
|
||||
size_t psize;
|
||||
int buffer;
|
||||
struct args *args = self->args;
|
||||
struct paste_buffer *pb;
|
||||
char *pdata, *cause;
|
||||
const char *bufname;
|
||||
size_t psize, newsize;
|
||||
|
||||
limit = options_get_number(&global_options, "buffer-limit");
|
||||
bufname = NULL;
|
||||
|
||||
pdata = xstrdup(args->argv[0]);
|
||||
psize = strlen(pdata);
|
||||
if (args_has(args, 'n')) {
|
||||
if (args->argc > 0) {
|
||||
cmdq_error(cmdq, "don't provide data with n flag");
|
||||
return (CMD_RETURN_ERROR);
|
||||
}
|
||||
|
||||
if (args_has(args, 'b'))
|
||||
bufname = args_get(args, 'b');
|
||||
|
||||
if (bufname == NULL) {
|
||||
pb = paste_get_top();
|
||||
if (pb == NULL) {
|
||||
cmdq_error(cmdq, "no buffer");
|
||||
return (CMD_RETURN_ERROR);
|
||||
}
|
||||
bufname = pb->name;
|
||||
}
|
||||
|
||||
if (paste_rename(bufname, args_get(args, 'n'), &cause) != 0) {
|
||||
cmdq_error(cmdq, "%s", cause);
|
||||
free(cause);
|
||||
return (CMD_RETURN_ERROR);
|
||||
}
|
||||
|
||||
if (!args_has(args, 'b')) {
|
||||
paste_add(&global_buffers, pdata, psize, limit);
|
||||
return (CMD_RETURN_NORMAL);
|
||||
}
|
||||
|
||||
buffer = args_strtonum(args, 'b', 0, INT_MAX, &cause);
|
||||
if (cause != NULL) {
|
||||
cmdq_error(cmdq, "buffer %s", cause);
|
||||
free(cause);
|
||||
free(pdata);
|
||||
if (args->argc != 1) {
|
||||
cmdq_error(cmdq, "no data specified");
|
||||
return (CMD_RETURN_ERROR);
|
||||
}
|
||||
|
||||
if (paste_replace(&global_buffers, buffer, pdata, psize) != 0) {
|
||||
cmdq_error(cmdq, "no buffer %d", buffer);
|
||||
psize = 0;
|
||||
pdata = NULL;
|
||||
|
||||
pb = NULL;
|
||||
|
||||
if ((newsize = strlen(args->argv[0])) == 0)
|
||||
return (CMD_RETURN_NORMAL);
|
||||
|
||||
if (args_has(args, 'b')) {
|
||||
bufname = args_get(args, 'b');
|
||||
pb = paste_get_name(bufname);
|
||||
} else if (args_has(args, 'a')) {
|
||||
pb = paste_get_top();
|
||||
if (pb != NULL)
|
||||
bufname = pb->name;
|
||||
}
|
||||
|
||||
if (args_has(args, 'a') && pb != NULL) {
|
||||
psize = pb->size;
|
||||
pdata = xmalloc(psize);
|
||||
memcpy(pdata, pb->data, psize);
|
||||
}
|
||||
|
||||
pdata = xrealloc(pdata, psize + newsize);
|
||||
memcpy(pdata + psize, args->argv[0], newsize);
|
||||
psize += newsize;
|
||||
|
||||
if (paste_set(pdata, psize, bufname, &cause) != 0) {
|
||||
cmdq_error(cmdq, "%s", cause);
|
||||
free(pdata);
|
||||
free(cause);
|
||||
return (CMD_RETURN_ERROR);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $Id$ */
|
||||
/* $OpenBSD$ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||
@@ -34,8 +34,6 @@ const struct cmd_entry cmd_set_environment_entry = {
|
||||
"grt:u", 1, 2,
|
||||
"[-gru] " CMD_TARGET_SESSION_USAGE " name [value]",
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
cmd_set_environment_exec
|
||||
};
|
||||
|
||||
|
||||
116
cmd-set-option.c
116
cmd-set-option.c
@@ -1,4 +1,4 @@
|
||||
/* $Id$ */
|
||||
/* $OpenBSD$ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||
@@ -60,14 +60,15 @@ struct options_entry *cmd_set_option_flag(struct cmd *, struct cmd_q *,
|
||||
struct options_entry *cmd_set_option_choice(struct cmd *, struct cmd_q *,
|
||||
const struct options_table_entry *, struct options *,
|
||||
const char *);
|
||||
struct options_entry *cmd_set_option_style(struct cmd *, struct cmd_q *,
|
||||
const struct options_table_entry *, struct options *,
|
||||
const char *);
|
||||
|
||||
const struct cmd_entry cmd_set_option_entry = {
|
||||
"set-option", "set",
|
||||
"agoqst:uw", 1, 2,
|
||||
"[-agosquw] [-t target-session|target-window] option [value]",
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
cmd_set_option_exec
|
||||
};
|
||||
|
||||
@@ -76,8 +77,6 @@ const struct cmd_entry cmd_set_window_option_entry = {
|
||||
"agoqt:u", 1, 2,
|
||||
"[-agoqu] " CMD_TARGET_WINDOW_USAGE " option [value]",
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
cmd_set_option_exec
|
||||
};
|
||||
|
||||
@@ -116,8 +115,11 @@ cmd_set_option_exec(struct cmd *self, struct cmd_q *cmdq)
|
||||
return (CMD_RETURN_ERROR);
|
||||
}
|
||||
if (oe == NULL) {
|
||||
cmdq_error(cmdq, "unknown option: %s", optstr);
|
||||
return (CMD_RETURN_ERROR);
|
||||
if (!args_has(args, 'q')) {
|
||||
cmdq_error(cmdq, "unknown option: %s", optstr);
|
||||
return (CMD_RETURN_ERROR);
|
||||
}
|
||||
return (CMD_RETURN_NORMAL);
|
||||
}
|
||||
|
||||
/* Work out the tree from the table. */
|
||||
@@ -128,8 +130,13 @@ cmd_set_option_exec(struct cmd *self, struct cmd_q *cmdq)
|
||||
oo = &global_w_options;
|
||||
else {
|
||||
wl = cmd_find_window(cmdq, args_get(args, 't'), NULL);
|
||||
if (wl == NULL)
|
||||
if (wl == NULL) {
|
||||
cmdq_error(cmdq,
|
||||
"couldn't set '%s'%s", optstr,
|
||||
(!args_has(args, 't') && !args_has(args,
|
||||
'g')) ? " need target window or -g" : "");
|
||||
return (CMD_RETURN_ERROR);
|
||||
}
|
||||
oo = &wl->window->options;
|
||||
}
|
||||
} else if (table == session_options_table) {
|
||||
@@ -137,8 +144,13 @@ cmd_set_option_exec(struct cmd *self, struct cmd_q *cmdq)
|
||||
oo = &global_s_options;
|
||||
else {
|
||||
s = cmd_find_session(cmdq, args_get(args, 't'), 0);
|
||||
if (s == NULL)
|
||||
if (s == NULL) {
|
||||
cmdq_error(cmdq,
|
||||
"couldn't set '%s'%s", optstr,
|
||||
(!args_has(args, 't') && !args_has(args,
|
||||
'g')) ? " need target session or -g" : "");
|
||||
return (CMD_RETURN_ERROR);
|
||||
}
|
||||
oo = &s->options;
|
||||
}
|
||||
} else {
|
||||
@@ -152,8 +164,10 @@ cmd_set_option_exec(struct cmd *self, struct cmd_q *cmdq)
|
||||
return (CMD_RETURN_ERROR);
|
||||
} else {
|
||||
if (args_has(args, 'o') && options_find1(oo, optstr) != NULL) {
|
||||
if (!args_has(args, 'q'))
|
||||
cmdq_print(cmdq, "already set: %s", optstr);
|
||||
if (!args_has(args, 'q')) {
|
||||
cmdq_error(cmdq, "already set: %s", optstr);
|
||||
return (CMD_RETURN_ERROR);
|
||||
}
|
||||
return (CMD_RETURN_NORMAL);
|
||||
}
|
||||
if (cmd_set_option_set(self, cmdq, oe, oo, valstr) != 0)
|
||||
@@ -161,7 +175,7 @@ cmd_set_option_exec(struct cmd *self, struct cmd_q *cmdq)
|
||||
}
|
||||
|
||||
/* Start or stop timers when automatic-rename changed. */
|
||||
if (strcmp (oe->name, "automatic-rename") == 0) {
|
||||
if (strcmp(oe->name, "automatic-rename") == 0) {
|
||||
for (i = 0; i < ARRAY_LENGTH(&windows); i++) {
|
||||
if ((w = ARRAY_ITEM(&windows, i)) == NULL)
|
||||
continue;
|
||||
@@ -185,7 +199,7 @@ cmd_set_option_exec(struct cmd *self, struct cmd_q *cmdq)
|
||||
|
||||
/* Set user option. */
|
||||
enum cmd_retval
|
||||
cmd_set_option_user(struct cmd *self, struct cmd_q *cmdq, const char* optstr,
|
||||
cmd_set_option_user(struct cmd *self, struct cmd_q *cmdq, const char *optstr,
|
||||
const char *valstr)
|
||||
{
|
||||
struct args *args = self->args;
|
||||
@@ -218,8 +232,11 @@ cmd_set_option_user(struct cmd *self, struct cmd_q *cmdq, const char* optstr,
|
||||
|
||||
if (args_has(args, 'u')) {
|
||||
if (options_find1(oo, optstr) == NULL) {
|
||||
cmdq_error(cmdq, "unknown option: %s", optstr);
|
||||
return (CMD_RETURN_ERROR);
|
||||
if (!args_has(args, 'q')) {
|
||||
cmdq_error(cmdq, "unknown option: %s", optstr);
|
||||
return (CMD_RETURN_ERROR);
|
||||
}
|
||||
return (CMD_RETURN_NORMAL);
|
||||
}
|
||||
if (valstr != NULL) {
|
||||
cmdq_error(cmdq, "value passed to unset option: %s",
|
||||
@@ -233,15 +250,13 @@ cmd_set_option_user(struct cmd *self, struct cmd_q *cmdq, const char* optstr,
|
||||
return (CMD_RETURN_ERROR);
|
||||
}
|
||||
if (args_has(args, 'o') && options_find1(oo, optstr) != NULL) {
|
||||
if (!args_has(args, 'q'))
|
||||
cmdq_print(cmdq, "already set: %s", optstr);
|
||||
if (!args_has(args, 'q')) {
|
||||
cmdq_error(cmdq, "already set: %s", optstr);
|
||||
return (CMD_RETURN_ERROR);
|
||||
}
|
||||
return (CMD_RETURN_NORMAL);
|
||||
}
|
||||
options_set_string(oo, optstr, "%s", valstr);
|
||||
if (!args_has(args, 'q')) {
|
||||
cmdq_info(cmdq, "set option: %s -> %s", optstr,
|
||||
valstr);
|
||||
}
|
||||
}
|
||||
return (CMD_RETURN_NORMAL);
|
||||
}
|
||||
@@ -250,7 +265,8 @@ cmd_set_option_user(struct cmd *self, struct cmd_q *cmdq, const char* optstr,
|
||||
/* Unset an option. */
|
||||
int
|
||||
cmd_set_option_unset(struct cmd *self, struct cmd_q *cmdq,
|
||||
const struct options_table_entry *oe, struct options *oo, const char *value)
|
||||
const struct options_table_entry *oe, struct options *oo,
|
||||
const char *value)
|
||||
{
|
||||
struct args *args = self->args;
|
||||
|
||||
@@ -264,19 +280,16 @@ cmd_set_option_unset(struct cmd *self, struct cmd_q *cmdq,
|
||||
}
|
||||
|
||||
options_remove(oo, oe->name);
|
||||
if (!args_has(args, 'q'))
|
||||
cmdq_info(cmdq, "unset option: %s", oe->name);
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* Set an option. */
|
||||
int
|
||||
cmd_set_option_set(struct cmd *self, struct cmd_q *cmdq,
|
||||
const struct options_table_entry *oe, struct options *oo, const char *value)
|
||||
const struct options_table_entry *oe, struct options *oo,
|
||||
const char *value)
|
||||
{
|
||||
struct args *args = self->args;
|
||||
struct options_entry *o;
|
||||
const char *s;
|
||||
|
||||
if (oe->type != OPTIONS_TABLE_FLAG && value == NULL) {
|
||||
cmdq_error(cmdq, "empty value");
|
||||
@@ -296,9 +309,13 @@ cmd_set_option_set(struct cmd *self, struct cmd_q *cmdq,
|
||||
break;
|
||||
case OPTIONS_TABLE_COLOUR:
|
||||
o = cmd_set_option_colour(self, cmdq, oe, oo, value);
|
||||
if (o != NULL)
|
||||
style_update_new(oo, o->name, oe->style);
|
||||
break;
|
||||
case OPTIONS_TABLE_ATTRIBUTES:
|
||||
o = cmd_set_option_attributes(self, cmdq, oe, oo, value);
|
||||
if (o != NULL)
|
||||
style_update_new(oo, o->name, oe->style);
|
||||
break;
|
||||
case OPTIONS_TABLE_FLAG:
|
||||
o = cmd_set_option_flag(self, cmdq, oe, oo, value);
|
||||
@@ -306,20 +323,20 @@ cmd_set_option_set(struct cmd *self, struct cmd_q *cmdq,
|
||||
case OPTIONS_TABLE_CHOICE:
|
||||
o = cmd_set_option_choice(self, cmdq, oe, oo, value);
|
||||
break;
|
||||
case OPTIONS_TABLE_STYLE:
|
||||
o = cmd_set_option_style(self, cmdq, oe, oo, value);
|
||||
break;
|
||||
}
|
||||
if (o == NULL)
|
||||
return (-1);
|
||||
|
||||
s = options_table_print_entry(oe, o, 0);
|
||||
if (!args_has(args, 'q'))
|
||||
cmdq_info(cmdq, "set option: %s -> %s", oe->name, s);
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* Set a string option. */
|
||||
struct options_entry *
|
||||
cmd_set_option_string(struct cmd *self, unused struct cmd_q *cmdq,
|
||||
const struct options_table_entry *oe, struct options *oo, const char *value)
|
||||
const struct options_table_entry *oe, struct options *oo,
|
||||
const char *value)
|
||||
{
|
||||
struct args *args = self->args;
|
||||
struct options_entry *o;
|
||||
@@ -340,7 +357,8 @@ cmd_set_option_string(struct cmd *self, unused struct cmd_q *cmdq,
|
||||
/* Set a number option. */
|
||||
struct options_entry *
|
||||
cmd_set_option_number(unused struct cmd *self, struct cmd_q *cmdq,
|
||||
const struct options_table_entry *oe, struct options *oo, const char *value)
|
||||
const struct options_table_entry *oe, struct options *oo,
|
||||
const char *value)
|
||||
{
|
||||
long long ll;
|
||||
const char *errstr;
|
||||
@@ -357,7 +375,8 @@ cmd_set_option_number(unused struct cmd *self, struct cmd_q *cmdq,
|
||||
/* Set a key option. */
|
||||
struct options_entry *
|
||||
cmd_set_option_key(unused struct cmd *self, struct cmd_q *cmdq,
|
||||
const struct options_table_entry *oe, struct options *oo, const char *value)
|
||||
const struct options_table_entry *oe, struct options *oo,
|
||||
const char *value)
|
||||
{
|
||||
int key;
|
||||
|
||||
@@ -372,7 +391,8 @@ cmd_set_option_key(unused struct cmd *self, struct cmd_q *cmdq,
|
||||
/* Set a colour option. */
|
||||
struct options_entry *
|
||||
cmd_set_option_colour(unused struct cmd *self, struct cmd_q *cmdq,
|
||||
const struct options_table_entry *oe, struct options *oo, const char *value)
|
||||
const struct options_table_entry *oe, struct options *oo,
|
||||
const char *value)
|
||||
{
|
||||
int colour;
|
||||
|
||||
@@ -387,7 +407,8 @@ cmd_set_option_colour(unused struct cmd *self, struct cmd_q *cmdq,
|
||||
/* Set an attributes option. */
|
||||
struct options_entry *
|
||||
cmd_set_option_attributes(unused struct cmd *self, struct cmd_q *cmdq,
|
||||
const struct options_table_entry *oe, struct options *oo, const char *value)
|
||||
const struct options_table_entry *oe, struct options *oo,
|
||||
const char *value)
|
||||
{
|
||||
int attr;
|
||||
|
||||
@@ -402,7 +423,8 @@ cmd_set_option_attributes(unused struct cmd *self, struct cmd_q *cmdq,
|
||||
/* Set a flag option. */
|
||||
struct options_entry *
|
||||
cmd_set_option_flag(unused struct cmd *self, struct cmd_q *cmdq,
|
||||
const struct options_table_entry *oe, struct options *oo, const char *value)
|
||||
const struct options_table_entry *oe, struct options *oo,
|
||||
const char *value)
|
||||
{
|
||||
int flag;
|
||||
|
||||
@@ -454,3 +476,23 @@ cmd_set_option_choice(unused struct cmd *self, struct cmd_q *cmdq,
|
||||
|
||||
return (options_set_number(oo, oe->name, choice));
|
||||
}
|
||||
|
||||
/* Set a style option. */
|
||||
struct options_entry *
|
||||
cmd_set_option_style(struct cmd *self, struct cmd_q *cmdq,
|
||||
const struct options_table_entry *oe, struct options *oo,
|
||||
const char *value)
|
||||
{
|
||||
struct args *args = self->args;
|
||||
struct options_entry *o;
|
||||
int append;
|
||||
|
||||
append = args_has(args, 'a');
|
||||
if ((o = options_set_style(oo, oe->name, value, append)) == NULL) {
|
||||
cmdq_error(cmdq, "bad style: %s", value);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
style_update_old(oo, oe->name, &o->style);
|
||||
return (o);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $Id$ */
|
||||
/* $OpenBSD$ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||
@@ -34,8 +34,6 @@ const struct cmd_entry cmd_show_environment_entry = {
|
||||
"gt:", 0, 1,
|
||||
"[-g] " CMD_TARGET_SESSION_USAGE " [name]",
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
cmd_show_environment_exec
|
||||
};
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $Id$ */
|
||||
/* $OpenBSD$ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||
@@ -20,6 +20,7 @@
|
||||
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "tmux.h"
|
||||
|
||||
@@ -31,14 +32,96 @@ enum cmd_retval cmd_show_messages_exec(struct cmd *, struct cmd_q *);
|
||||
|
||||
const struct cmd_entry cmd_show_messages_entry = {
|
||||
"show-messages", "showmsgs",
|
||||
"t:", 0, 0,
|
||||
CMD_TARGET_CLIENT_USAGE,
|
||||
"IJTt:", 0, 0,
|
||||
"[-IJT] " CMD_TARGET_CLIENT_USAGE,
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
cmd_show_messages_exec
|
||||
};
|
||||
|
||||
const struct cmd_entry cmd_server_info_entry = {
|
||||
"server-info", "info",
|
||||
"", 0, 0,
|
||||
"",
|
||||
0,
|
||||
cmd_show_messages_exec
|
||||
};
|
||||
|
||||
void cmd_show_messages_server(struct cmd_q *);
|
||||
void cmd_show_messages_terminals(struct cmd_q *);
|
||||
void cmd_show_messages_jobs(struct cmd_q *);
|
||||
|
||||
void
|
||||
cmd_show_messages_server(struct cmd_q *cmdq)
|
||||
{
|
||||
char *tim;
|
||||
|
||||
tim = ctime(&start_time);
|
||||
*strchr(tim, '\n') = '\0';
|
||||
|
||||
cmdq_print(cmdq, "started %s", tim);
|
||||
cmdq_print(cmdq, "socket path %s", socket_path);
|
||||
cmdq_print(cmdq, "debug level %d", debug_level);
|
||||
cmdq_print(cmdq, "protocol version %d", PROTOCOL_VERSION);
|
||||
}
|
||||
|
||||
void
|
||||
cmd_show_messages_terminals(struct cmd_q *cmdq)
|
||||
{
|
||||
struct tty_term *term;
|
||||
const struct tty_term_code_entry *ent;
|
||||
struct tty_code *code;
|
||||
u_int i, n;
|
||||
char out[80];
|
||||
|
||||
n = 0;
|
||||
LIST_FOREACH(term, &tty_terms, entry) {
|
||||
cmdq_print(cmdq,
|
||||
"Terminal %u: %s [references=%u, flags=0x%x]:",
|
||||
n, term->name, term->references, term->flags);
|
||||
n++;
|
||||
for (i = 0; i < NTTYCODE; i++) {
|
||||
ent = &tty_term_codes[i];
|
||||
code = &term->codes[ent->code];
|
||||
switch (code->type) {
|
||||
case TTYCODE_NONE:
|
||||
cmdq_print(cmdq, "%4u: %s: [missing]",
|
||||
ent->code, ent->name);
|
||||
break;
|
||||
case TTYCODE_STRING:
|
||||
strnvis(out, code->value.string, sizeof out,
|
||||
VIS_OCTAL|VIS_TAB|VIS_NL);
|
||||
cmdq_print(cmdq, "%4u: %s: (string) %s",
|
||||
ent->code, ent->name, out);
|
||||
break;
|
||||
case TTYCODE_NUMBER:
|
||||
cmdq_print(cmdq, "%4u: %s: (number) %d",
|
||||
ent->code, ent->name, code->value.number);
|
||||
break;
|
||||
case TTYCODE_FLAG:
|
||||
cmdq_print(cmdq, "%4u: %s: (flag) %s",
|
||||
ent->code, ent->name,
|
||||
code->value.flag ? "true" : "false");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
cmd_show_messages_jobs(struct cmd_q *cmdq)
|
||||
{
|
||||
struct job *job;
|
||||
u_int n;
|
||||
|
||||
n = 0;
|
||||
LIST_FOREACH(job, &all_jobs, lentry) {
|
||||
cmdq_print(cmdq,
|
||||
"Job %u: %s [fd=%d, pid=%d, status=%d]",
|
||||
n, job->cmd, job->fd, job->pid, job->status);
|
||||
n++;
|
||||
}
|
||||
}
|
||||
|
||||
enum cmd_retval
|
||||
cmd_show_messages_exec(struct cmd *self, struct cmd_q *cmdq)
|
||||
{
|
||||
@@ -47,6 +130,27 @@ cmd_show_messages_exec(struct cmd *self, struct cmd_q *cmdq)
|
||||
struct message_entry *msg;
|
||||
char *tim;
|
||||
u_int i;
|
||||
int done;
|
||||
|
||||
done = 0;
|
||||
if (args_has(args, 'I') || self->entry == &cmd_server_info_entry) {
|
||||
cmd_show_messages_server(cmdq);
|
||||
done = 1;
|
||||
}
|
||||
if (args_has(args, 'T') || self->entry == &cmd_server_info_entry) {
|
||||
if (done)
|
||||
cmdq_print(cmdq, "%s", "");
|
||||
cmd_show_messages_terminals(cmdq);
|
||||
done = 1;
|
||||
}
|
||||
if (args_has(args, 'J') || self->entry == &cmd_server_info_entry) {
|
||||
if (done)
|
||||
cmdq_print(cmdq, "%s", "");
|
||||
cmd_show_messages_jobs(cmdq);
|
||||
done = 1;
|
||||
}
|
||||
if (done)
|
||||
return (CMD_RETURN_NORMAL);
|
||||
|
||||
if ((c = cmd_find_client(cmdq, args_get(args, 't'), 0)) == NULL)
|
||||
return (CMD_RETURN_ERROR);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $Id$ */
|
||||
/* $OpenBSD$ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||
@@ -39,8 +39,6 @@ const struct cmd_entry cmd_show_options_entry = {
|
||||
"gqst:vw", 0, 1,
|
||||
"[-gqsvw] [-t target-session|target-window] [option]",
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
cmd_show_options_exec
|
||||
};
|
||||
|
||||
@@ -49,8 +47,6 @@ const struct cmd_entry cmd_show_window_options_entry = {
|
||||
"gvt:", 0, 1,
|
||||
"[-gv] " CMD_TARGET_WINDOW_USAGE " [option]",
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
cmd_show_options_exec
|
||||
};
|
||||
|
||||
@@ -102,15 +98,17 @@ cmd_show_options_one(struct cmd *self, struct cmd_q *cmdq,
|
||||
struct options *oo, int quiet)
|
||||
{
|
||||
struct args *args = self->args;
|
||||
const char *name = args->argv[0];
|
||||
const struct options_table_entry *table, *oe;
|
||||
struct options_entry *o;
|
||||
const char *optval;
|
||||
|
||||
if (*args->argv[0] == '@') {
|
||||
if ((o = options_find1(oo, args->argv[0])) == NULL) {
|
||||
retry:
|
||||
if (*name == '@') {
|
||||
if ((o = options_find1(oo, name)) == NULL) {
|
||||
if (quiet)
|
||||
return (CMD_RETURN_NORMAL);
|
||||
cmdq_error(cmdq, "unknown option: %s", args->argv[0]);
|
||||
cmdq_error(cmdq, "unknown option: %s", name);
|
||||
return (CMD_RETURN_ERROR);
|
||||
}
|
||||
if (args_has(self->args, 'v'))
|
||||
@@ -121,16 +119,20 @@ cmd_show_options_one(struct cmd *self, struct cmd_q *cmdq,
|
||||
}
|
||||
|
||||
table = oe = NULL;
|
||||
if (options_table_find(args->argv[0], &table, &oe) != 0) {
|
||||
cmdq_error(cmdq, "ambiguous option: %s", args->argv[0]);
|
||||
if (options_table_find(name, &table, &oe) != 0) {
|
||||
cmdq_error(cmdq, "ambiguous option: %s", name);
|
||||
return (CMD_RETURN_ERROR);
|
||||
}
|
||||
if (oe == NULL) {
|
||||
if (quiet)
|
||||
return (CMD_RETURN_NORMAL);
|
||||
cmdq_error(cmdq, "unknown option: %s", args->argv[0]);
|
||||
cmdq_error(cmdq, "unknown option: %s", name);
|
||||
return (CMD_RETURN_ERROR);
|
||||
}
|
||||
if (oe->style != NULL) {
|
||||
name = oe->style;
|
||||
goto retry;
|
||||
}
|
||||
if ((o = options_find1(oo, oe->name)) == NULL)
|
||||
return (CMD_RETURN_NORMAL);
|
||||
optval = options_table_print_entry(oe, o, args_has(self->args, 'v'));
|
||||
@@ -159,6 +161,8 @@ cmd_show_options_all(struct cmd *self, struct cmd_q *cmdq,
|
||||
}
|
||||
|
||||
for (oe = table; oe->name != NULL; oe++) {
|
||||
if (oe->style != NULL)
|
||||
continue;
|
||||
if ((o = options_find1(oo, oe->name)) == NULL)
|
||||
continue;
|
||||
optval = options_table_print_entry(oe, o,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $Id$ */
|
||||
/* $OpenBSD$ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2008 Tiago Cunha <me@tiagocunha.org>
|
||||
@@ -28,7 +28,6 @@
|
||||
|
||||
enum cmd_retval cmd_source_file_exec(struct cmd *, struct cmd_q *);
|
||||
|
||||
void cmd_source_file_show(struct cmd_q *);
|
||||
void cmd_source_file_done(struct cmd_q *);
|
||||
|
||||
const struct cmd_entry cmd_source_file_entry = {
|
||||
@@ -36,8 +35,6 @@ const struct cmd_entry cmd_source_file_entry = {
|
||||
"", 1, 1,
|
||||
"path",
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
cmd_source_file_exec
|
||||
};
|
||||
|
||||
@@ -49,6 +46,7 @@ cmd_source_file_exec(struct cmd *self, struct cmd_q *cmdq)
|
||||
char *cause;
|
||||
|
||||
cmdq1 = cmdq_new(NULL);
|
||||
cmdq1->client = cmdq->client;
|
||||
cmdq1->emptyfn = cmd_source_file_done;
|
||||
cmdq1->data = cmdq;
|
||||
|
||||
@@ -60,11 +58,12 @@ cmd_source_file_exec(struct cmd *self, struct cmd_q *cmdq)
|
||||
free(cause);
|
||||
return (CMD_RETURN_ERROR);
|
||||
}
|
||||
ARRAY_ADD(&cfg_causes, cause);
|
||||
cfg_add_cause("%s", cause);
|
||||
free(cause);
|
||||
/* FALLTHROUGH */
|
||||
case 0:
|
||||
if (cfg_references == 0)
|
||||
cmd_source_file_show(cmdq);
|
||||
cfg_print_causes(cmdq);
|
||||
cmdq_free(cmdq1);
|
||||
return (CMD_RETURN_NORMAL);
|
||||
}
|
||||
@@ -76,25 +75,14 @@ cmd_source_file_exec(struct cmd *self, struct cmd_q *cmdq)
|
||||
return (CMD_RETURN_WAIT);
|
||||
}
|
||||
|
||||
void
|
||||
cmd_source_file_show(struct cmd_q *cmdq)
|
||||
{
|
||||
u_int i;
|
||||
char *cause;
|
||||
|
||||
for (i = 0; i < ARRAY_LENGTH(&cfg_causes); i++) {
|
||||
cause = ARRAY_ITEM(&cfg_causes, i);
|
||||
cmdq_print(cmdq, "%s", cause);
|
||||
free(cause);
|
||||
}
|
||||
ARRAY_FREE(&cfg_causes);
|
||||
}
|
||||
|
||||
void
|
||||
cmd_source_file_done(struct cmd_q *cmdq1)
|
||||
{
|
||||
struct cmd_q *cmdq = cmdq1->data;
|
||||
|
||||
if (cmdq1->client_exit >= 0)
|
||||
cmdq->client_exit = cmdq1->client_exit;
|
||||
|
||||
cmdq_free(cmdq1);
|
||||
|
||||
cfg_references--;
|
||||
@@ -103,6 +91,6 @@ cmd_source_file_done(struct cmd_q *cmdq1)
|
||||
return;
|
||||
|
||||
if (cfg_references == 0)
|
||||
cmd_source_file_show(cmdq);
|
||||
cfg_print_causes(cmdq);
|
||||
cmdq_continue(cmdq);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $Id$ */
|
||||
/* $OpenBSD$ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||
@@ -18,7 +18,10 @@
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "tmux.h"
|
||||
@@ -27,28 +30,19 @@
|
||||
* Split a window (add a new pane).
|
||||
*/
|
||||
|
||||
void cmd_split_window_key_binding(struct cmd *, int);
|
||||
#define SPLIT_WINDOW_TEMPLATE "#{session_name}:#{window_index}.#{pane_index}"
|
||||
|
||||
enum cmd_retval cmd_split_window_exec(struct cmd *, struct cmd_q *);
|
||||
|
||||
const struct cmd_entry cmd_split_window_entry = {
|
||||
"split-window", "splitw",
|
||||
"c:dF:l:hp:Pt:v", 0, 1,
|
||||
"[-dhvP] [-c start-directory] [-F format] [-p percentage|-l size] "
|
||||
"bc:dF:l:hp:Pt:v", 0, -1,
|
||||
"[-bdhvP] [-c start-directory] [-F format] [-p percentage|-l size] "
|
||||
CMD_TARGET_PANE_USAGE " [command]",
|
||||
0,
|
||||
cmd_split_window_key_binding,
|
||||
NULL,
|
||||
cmd_split_window_exec
|
||||
};
|
||||
|
||||
void
|
||||
cmd_split_window_key_binding(struct cmd *self, int key)
|
||||
{
|
||||
self->args = args_create(0);
|
||||
if (key == '%')
|
||||
args_set(self->args, 'h', NULL);
|
||||
}
|
||||
|
||||
enum cmd_retval
|
||||
cmd_split_window_exec(struct cmd *self, struct cmd_q *cmdq)
|
||||
{
|
||||
@@ -58,16 +52,14 @@ cmd_split_window_exec(struct cmd *self, struct cmd_q *cmdq)
|
||||
struct window *w;
|
||||
struct window_pane *wp, *new_wp = NULL;
|
||||
struct environ env;
|
||||
const char *cmd, *cwd, *shell;
|
||||
char *cause, *new_cause;
|
||||
const char *cmd, *path, *shell, *template;
|
||||
char **argv, *cause, *new_cause, *cp;
|
||||
u_int hlimit;
|
||||
int size, percentage;
|
||||
int argc, size, percentage, cwd, fd = -1;
|
||||
enum layout_type type;
|
||||
struct layout_cell *lc;
|
||||
const char *template;
|
||||
struct client *c;
|
||||
struct format_tree *ft;
|
||||
char *cp;
|
||||
struct environ_entry *envent;
|
||||
|
||||
if ((wl = cmd_find_pane(cmdq, args_get(args, 't'), &s, &wp)) == NULL)
|
||||
return (CMD_RETURN_ERROR);
|
||||
@@ -79,11 +71,42 @@ cmd_split_window_exec(struct cmd *self, struct cmd_q *cmdq)
|
||||
environ_copy(&s->environ, &env);
|
||||
server_fill_environ(s, &env);
|
||||
|
||||
if (args->argc == 0)
|
||||
if (args->argc == 0) {
|
||||
cmd = options_get_string(&s->options, "default-command");
|
||||
if (cmd != NULL && *cmd != '\0') {
|
||||
argc = 1;
|
||||
argv = (char **)&cmd;
|
||||
} else {
|
||||
argc = 0;
|
||||
argv = NULL;
|
||||
}
|
||||
} else {
|
||||
argc = args->argc;
|
||||
argv = args->argv;
|
||||
}
|
||||
|
||||
if (args_has(args, 'c')) {
|
||||
ft = format_create();
|
||||
format_defaults(ft, cmd_find_client(cmdq, NULL, 1), s, NULL,
|
||||
NULL);
|
||||
cp = format_expand(ft, args_get(args, 'c'));
|
||||
format_free(ft);
|
||||
|
||||
if (cp != NULL && *cp != '\0') {
|
||||
fd = open(cp, O_RDONLY|O_DIRECTORY);
|
||||
free(cp);
|
||||
if (fd == -1) {
|
||||
cmdq_error(cmdq, "bad working directory: %s",
|
||||
strerror(errno));
|
||||
return (CMD_RETURN_ERROR);
|
||||
}
|
||||
} else if (cp != NULL)
|
||||
free(cp);
|
||||
cwd = fd;
|
||||
} else if (cmdq->client != NULL && cmdq->client->session == NULL)
|
||||
cwd = cmdq->client->cwd;
|
||||
else
|
||||
cmd = args->argv[0];
|
||||
cwd = cmd_get_default_path(cmdq, args_get(args, 'c'));
|
||||
cwd = s->cwd;
|
||||
|
||||
type = LAYOUT_TOPBOTTOM;
|
||||
if (args_has(args, 'h'))
|
||||
@@ -117,13 +140,23 @@ cmd_split_window_exec(struct cmd *self, struct cmd_q *cmdq)
|
||||
if (*shell == '\0' || areshell(shell))
|
||||
shell = _PATH_BSHELL;
|
||||
|
||||
if ((lc = layout_split_pane(wp, type, size, 0)) == NULL) {
|
||||
lc = layout_split_pane(wp, type, size, args_has(args, 'b'));
|
||||
if (lc == NULL) {
|
||||
cause = xstrdup("pane too small");
|
||||
goto error;
|
||||
}
|
||||
new_wp = window_add_pane(w, hlimit);
|
||||
if (window_pane_spawn(
|
||||
new_wp, cmd, shell, cwd, &env, s->tio, &cause) != 0)
|
||||
|
||||
path = NULL;
|
||||
if (cmdq->client != NULL && cmdq->client->session == NULL)
|
||||
envent = environ_find(&cmdq->client->environ, "PATH");
|
||||
else
|
||||
envent = environ_find(&s->environ, "PATH");
|
||||
if (envent != NULL)
|
||||
path = envent->value;
|
||||
|
||||
if (window_pane_spawn(new_wp, argc, argv, path, shell, cwd, &env,
|
||||
s->tio, &cause) != 0)
|
||||
goto error;
|
||||
layout_assign_pane(lc, new_wp);
|
||||
|
||||
@@ -143,11 +176,8 @@ cmd_split_window_exec(struct cmd *self, struct cmd_q *cmdq)
|
||||
template = SPLIT_WINDOW_TEMPLATE;
|
||||
|
||||
ft = format_create();
|
||||
if ((c = cmd_find_client(cmdq, NULL, 1)) != NULL)
|
||||
format_client(ft, c);
|
||||
format_session(ft, s);
|
||||
format_winlink(ft, s, wl);
|
||||
format_window_pane(ft, new_wp);
|
||||
format_defaults(ft, cmd_find_client(cmdq, NULL, 1), s, wl,
|
||||
new_wp);
|
||||
|
||||
cp = format_expand(ft, template);
|
||||
cmdq_print(cmdq, "%s", cp);
|
||||
@@ -156,6 +186,9 @@ cmd_split_window_exec(struct cmd *self, struct cmd_q *cmdq)
|
||||
format_free(ft);
|
||||
}
|
||||
notify_window_layout_changed(w);
|
||||
|
||||
if (fd != -1)
|
||||
close(fd);
|
||||
return (CMD_RETURN_NORMAL);
|
||||
|
||||
error:
|
||||
@@ -164,5 +197,7 @@ error:
|
||||
window_remove_pane(w, new_wp);
|
||||
cmdq_error(cmdq, "create pane failed: %s", cause);
|
||||
free(cause);
|
||||
if (fd != -1)
|
||||
close(fd);
|
||||
return (CMD_RETURN_ERROR);
|
||||
}
|
||||
|
||||
50
cmd-string.c
50
cmd-string.c
@@ -1,4 +1,4 @@
|
||||
/* $Id$ */
|
||||
/* $OpenBSD$ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||
@@ -107,10 +107,11 @@ cmd_string_parse(const char *s, struct cmd_list **cmdlist, const char *file,
|
||||
case ' ':
|
||||
case '\t':
|
||||
if (buf != NULL) {
|
||||
buf = xrealloc(buf, 1, len + 1);
|
||||
buf = xrealloc(buf, len + 1);
|
||||
buf[len] = '\0';
|
||||
|
||||
argv = xrealloc(argv, argc + 1, sizeof *argv);
|
||||
argv = xreallocarray(argv, argc + 1,
|
||||
sizeof *argv);
|
||||
argv[argc++] = buf;
|
||||
|
||||
buf = NULL;
|
||||
@@ -151,7 +152,7 @@ cmd_string_parse(const char *s, struct cmd_list **cmdlist, const char *file,
|
||||
if (len >= SIZE_MAX - 2)
|
||||
goto error;
|
||||
|
||||
buf = xrealloc(buf, 1, len + 1);
|
||||
buf = xrealloc(buf, len + 1);
|
||||
buf[len++] = ch;
|
||||
break;
|
||||
}
|
||||
@@ -179,7 +180,7 @@ cmd_string_copy(char **dst, char *src, size_t *len)
|
||||
|
||||
srclen = strlen(src);
|
||||
|
||||
*dst = xrealloc(*dst, 1, *len + srclen + 1);
|
||||
*dst = xrealloc(*dst, *len + srclen + 1);
|
||||
strlcpy(*dst + *len, src, srclen + 1);
|
||||
|
||||
*len += srclen;
|
||||
@@ -231,11 +232,11 @@ cmd_string_string(const char *s, size_t *p, char endch, int esc)
|
||||
|
||||
if (len >= SIZE_MAX - 2)
|
||||
goto error;
|
||||
buf = xrealloc(buf, 1, len + 1);
|
||||
buf = xrealloc(buf, len + 1);
|
||||
buf[len++] = ch;
|
||||
}
|
||||
|
||||
buf = xrealloc(buf, 1, len + 1);
|
||||
buf = xrealloc(buf, len + 1);
|
||||
buf[len] = '\0';
|
||||
return (buf);
|
||||
|
||||
@@ -278,7 +279,7 @@ cmd_string_variable(const char *s, size_t *p)
|
||||
return (t);
|
||||
}
|
||||
|
||||
buf = xrealloc(buf, 1, len + 1);
|
||||
buf = xrealloc(buf, len + 1);
|
||||
buf[len++] = ch;
|
||||
|
||||
for (;;) {
|
||||
@@ -288,7 +289,7 @@ cmd_string_variable(const char *s, size_t *p)
|
||||
else {
|
||||
if (len >= SIZE_MAX - 3)
|
||||
goto error;
|
||||
buf = xrealloc(buf, 1, len + 1);
|
||||
buf = xrealloc(buf, len + 1);
|
||||
buf[len++] = ch;
|
||||
}
|
||||
}
|
||||
@@ -299,7 +300,7 @@ cmd_string_variable(const char *s, size_t *p)
|
||||
if (ch != EOF && fch != '{')
|
||||
cmd_string_ungetc(p); /* ch */
|
||||
|
||||
buf = xrealloc(buf, 1, len + 1);
|
||||
buf = xrealloc(buf, len + 1);
|
||||
buf[len] = '\0';
|
||||
|
||||
envent = environ_find(&global_environ, buf);
|
||||
@@ -318,10 +319,13 @@ cmd_string_expand_tilde(const char *s, size_t *p)
|
||||
{
|
||||
struct passwd *pw;
|
||||
struct environ_entry *envent;
|
||||
char *home, *path, *username;
|
||||
char *home, *path, *user, *cp;
|
||||
int last;
|
||||
|
||||
home = NULL;
|
||||
if (cmd_string_getc(s, p) == '/') {
|
||||
|
||||
last = cmd_string_getc(s, p);
|
||||
if (last == EOF || last == '/' || last == ' '|| last == '\t') {
|
||||
envent = environ_find(&global_environ, "HOME");
|
||||
if (envent != NULL && *envent->value != '\0')
|
||||
home = envent->value;
|
||||
@@ -329,15 +333,27 @@ cmd_string_expand_tilde(const char *s, size_t *p)
|
||||
home = pw->pw_dir;
|
||||
} else {
|
||||
cmd_string_ungetc(p);
|
||||
if ((username = cmd_string_string(s, p, '/', 0)) == NULL)
|
||||
return (NULL);
|
||||
if ((pw = getpwnam(username)) != NULL)
|
||||
|
||||
cp = user = xmalloc(strlen(s));
|
||||
for (;;) {
|
||||
last = cmd_string_getc(s, p);
|
||||
if (last == EOF || last == '/' || last == ' '|| last == '\t')
|
||||
break;
|
||||
*cp++ = last;
|
||||
}
|
||||
*cp = '\0';
|
||||
|
||||
if ((pw = getpwnam(user)) != NULL)
|
||||
home = pw->pw_dir;
|
||||
free(username);
|
||||
free(user);
|
||||
}
|
||||
|
||||
if (home == NULL)
|
||||
return (NULL);
|
||||
|
||||
xasprintf(&path, "%s/", home);
|
||||
if (last != EOF)
|
||||
xasprintf(&path, "%s%c", home, last);
|
||||
else
|
||||
xasprintf(&path, "%s", home);
|
||||
return (path);
|
||||
}
|
||||
|
||||
@@ -1,56 +0,0 @@
|
||||
/* $Id$ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
||||
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "tmux.h"
|
||||
|
||||
/*
|
||||
* Suspend client with SIGTSTP.
|
||||
*/
|
||||
|
||||
enum cmd_retval cmd_suspend_client_exec(struct cmd *, struct cmd_q *);
|
||||
|
||||
const struct cmd_entry cmd_suspend_client_entry = {
|
||||
"suspend-client", "suspendc",
|
||||
"t:", 0, 0,
|
||||
CMD_TARGET_CLIENT_USAGE,
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
cmd_suspend_client_exec
|
||||
};
|
||||
|
||||
enum cmd_retval
|
||||
cmd_suspend_client_exec(struct cmd *self, struct cmd_q *cmdq)
|
||||
{
|
||||
struct args *args = self->args;
|
||||
struct client *c;
|
||||
|
||||
if ((c = cmd_find_client(cmdq, args_get(args, 't'), 0)) == NULL)
|
||||
return (CMD_RETURN_ERROR);
|
||||
|
||||
tty_stop_tty(&c->tty);
|
||||
c->flags |= CLIENT_SUSPENDED;
|
||||
server_write_client(c, MSG_SUSPEND, NULL, 0);
|
||||
|
||||
return (CMD_RETURN_NORMAL);
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $Id$ */
|
||||
/* $OpenBSD$ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||
@@ -26,7 +26,6 @@
|
||||
* Swap two panes.
|
||||
*/
|
||||
|
||||
void cmd_swap_pane_key_binding(struct cmd *, int);
|
||||
enum cmd_retval cmd_swap_pane_exec(struct cmd *, struct cmd_q *);
|
||||
|
||||
const struct cmd_entry cmd_swap_pane_entry = {
|
||||
@@ -34,21 +33,9 @@ const struct cmd_entry cmd_swap_pane_entry = {
|
||||
"dDs:t:U", 0, 0,
|
||||
"[-dDU] " CMD_SRCDST_PANE_USAGE,
|
||||
0,
|
||||
cmd_swap_pane_key_binding,
|
||||
NULL,
|
||||
cmd_swap_pane_exec
|
||||
};
|
||||
|
||||
void
|
||||
cmd_swap_pane_key_binding(struct cmd *self, int key)
|
||||
{
|
||||
self->args = args_create(0);
|
||||
if (key == '{')
|
||||
args_set(self->args, 'U', NULL);
|
||||
else if (key == '}')
|
||||
args_set(self->args, 'D', NULL);
|
||||
}
|
||||
|
||||
enum cmd_retval
|
||||
cmd_swap_pane_exec(struct cmd *self, struct cmd_q *cmdq)
|
||||
{
|
||||
@@ -75,8 +62,12 @@ cmd_swap_pane_exec(struct cmd *self, struct cmd_q *cmdq)
|
||||
src_wp = TAILQ_PREV(dst_wp, window_panes, entry);
|
||||
if (src_wp == NULL)
|
||||
src_wp = TAILQ_LAST(&dst_w->panes, window_panes);
|
||||
} else
|
||||
return (CMD_RETURN_NORMAL);
|
||||
} else {
|
||||
src_wl = cmd_find_pane(cmdq, NULL, NULL, &src_wp);
|
||||
if (src_wl == NULL)
|
||||
return (CMD_RETURN_ERROR);
|
||||
src_w = src_wl->window;
|
||||
}
|
||||
} else {
|
||||
src_wl = cmd_find_pane(cmdq, args_get(args, 's'), NULL, &src_wp);
|
||||
if (src_wl == NULL)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $Id$ */
|
||||
/* $OpenBSD$ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||
@@ -33,8 +33,6 @@ const struct cmd_entry cmd_swap_window_entry = {
|
||||
"ds:t:", 0, 0,
|
||||
"[-d] " CMD_SRCDST_WINDOW_USAGE,
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
cmd_swap_window_exec
|
||||
};
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $Id$ */
|
||||
/* $OpenBSD$ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||
@@ -27,7 +27,6 @@
|
||||
* Switch client to a different session.
|
||||
*/
|
||||
|
||||
void cmd_switch_client_key_binding(struct cmd *, int);
|
||||
enum cmd_retval cmd_switch_client_exec(struct cmd *, struct cmd_q *);
|
||||
|
||||
const struct cmd_entry cmd_switch_client_entry = {
|
||||
@@ -35,49 +34,31 @@ const struct cmd_entry cmd_switch_client_entry = {
|
||||
"lc:npt:r", 0, 0,
|
||||
"[-lnpr] [-c target-client] [-t target-session]",
|
||||
CMD_READONLY,
|
||||
cmd_switch_client_key_binding,
|
||||
NULL,
|
||||
cmd_switch_client_exec
|
||||
};
|
||||
|
||||
void
|
||||
cmd_switch_client_key_binding(struct cmd *self, int key)
|
||||
{
|
||||
self->args = args_create(0);
|
||||
switch (key) {
|
||||
case '(':
|
||||
args_set(self->args, 'p', NULL);
|
||||
break;
|
||||
case ')':
|
||||
args_set(self->args, 'n', NULL);
|
||||
break;
|
||||
case 'L':
|
||||
args_set(self->args, 'l', NULL);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
enum cmd_retval
|
||||
cmd_switch_client_exec(struct cmd *self, struct cmd_q *cmdq)
|
||||
{
|
||||
struct args *args = self->args;
|
||||
struct client *c;
|
||||
struct session *s;
|
||||
struct args *args = self->args;
|
||||
struct client *c;
|
||||
struct session *s = NULL;
|
||||
struct winlink *wl = NULL;
|
||||
struct window *w = NULL;
|
||||
struct window_pane *wp = NULL;
|
||||
const char *tflag;
|
||||
|
||||
if ((c = cmd_find_client(cmdq, args_get(args, 'c'), 0)) == NULL)
|
||||
return (CMD_RETURN_ERROR);
|
||||
|
||||
if (args_has(args, 'r')) {
|
||||
if (c->flags & CLIENT_READONLY) {
|
||||
if (c->flags & CLIENT_READONLY)
|
||||
c->flags &= ~CLIENT_READONLY;
|
||||
cmdq_info(cmdq, "made client writable");
|
||||
} else {
|
||||
else
|
||||
c->flags |= CLIENT_READONLY;
|
||||
cmdq_info(cmdq, "made client read-only");
|
||||
}
|
||||
}
|
||||
|
||||
s = NULL;
|
||||
tflag = args_get(args, 't');
|
||||
if (args_has(args, 'n')) {
|
||||
if ((s = session_next_session(c->session)) == NULL) {
|
||||
cmdq_error(cmdq, "can't find next session");
|
||||
@@ -95,10 +76,33 @@ cmd_switch_client_exec(struct cmd *self, struct cmd_q *cmdq)
|
||||
cmdq_error(cmdq, "can't find last session");
|
||||
return (CMD_RETURN_ERROR);
|
||||
}
|
||||
} else
|
||||
s = cmd_find_session(cmdq, args_get(args, 't'), 0);
|
||||
if (s == NULL)
|
||||
return (CMD_RETURN_ERROR);
|
||||
} else {
|
||||
if (tflag == NULL) {
|
||||
if ((s = cmd_find_session(cmdq, tflag, 1)) == NULL)
|
||||
return (CMD_RETURN_ERROR);
|
||||
} else if (tflag[strcspn(tflag, ":.")] != '\0') {
|
||||
if ((wl = cmd_find_pane(cmdq, tflag, &s, &wp)) == NULL)
|
||||
return (CMD_RETURN_ERROR);
|
||||
} else {
|
||||
if ((s = cmd_find_session(cmdq, tflag, 1)) == NULL)
|
||||
return (CMD_RETURN_ERROR);
|
||||
w = cmd_lookup_windowid(tflag);
|
||||
if (w == NULL &&
|
||||
(wp = cmd_lookup_paneid(tflag)) != NULL)
|
||||
w = wp->window;
|
||||
if (w != NULL)
|
||||
wl = winlink_find_by_window(&s->windows, w);
|
||||
}
|
||||
|
||||
if (cmdq->client == NULL)
|
||||
return (CMD_RETURN_NORMAL);
|
||||
|
||||
if (wl != NULL) {
|
||||
if (wp != NULL)
|
||||
window_set_active_pane(wp->window, wp);
|
||||
session_set_current(s, wl);
|
||||
}
|
||||
}
|
||||
|
||||
if (c->session != NULL)
|
||||
c->last_session = c->session;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $Id$ */
|
||||
/* $OpenBSD$ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||
@@ -26,30 +26,17 @@
|
||||
* Unbind key from command.
|
||||
*/
|
||||
|
||||
enum cmd_retval cmd_unbind_key_check(struct args *);
|
||||
enum cmd_retval cmd_unbind_key_exec(struct cmd *, struct cmd_q *);
|
||||
enum cmd_retval cmd_unbind_key_table(struct cmd *, struct cmd_q *, int);
|
||||
enum cmd_retval cmd_unbind_key_mode_table(struct cmd *, struct cmd_q *, int);
|
||||
|
||||
const struct cmd_entry cmd_unbind_key_entry = {
|
||||
"unbind-key", "unbind",
|
||||
"acnt:", 0, 1,
|
||||
"[-acn] [-t key-table] key",
|
||||
"[-acn] [-t mode-table] key",
|
||||
0,
|
||||
NULL,
|
||||
cmd_unbind_key_check,
|
||||
cmd_unbind_key_exec
|
||||
};
|
||||
|
||||
enum cmd_retval
|
||||
cmd_unbind_key_check(struct args *args)
|
||||
{
|
||||
if (args_has(args, 'a') && args->argc != 0)
|
||||
return (CMD_RETURN_ERROR);
|
||||
if (!args_has(args, 'a') && args->argc != 1)
|
||||
return (CMD_RETURN_ERROR);
|
||||
return (CMD_RETURN_NORMAL);
|
||||
}
|
||||
|
||||
enum cmd_retval
|
||||
cmd_unbind_key_exec(struct cmd *self, struct cmd_q *cmdq)
|
||||
{
|
||||
@@ -58,16 +45,25 @@ cmd_unbind_key_exec(struct cmd *self, struct cmd_q *cmdq)
|
||||
int key;
|
||||
|
||||
if (!args_has(args, 'a')) {
|
||||
if (args->argc != 1) {
|
||||
cmdq_error(cmdq, "missing key");
|
||||
return (CMD_RETURN_ERROR);
|
||||
}
|
||||
key = key_string_lookup_string(args->argv[0]);
|
||||
if (key == KEYC_NONE) {
|
||||
cmdq_error(cmdq, "unknown key: %s", args->argv[0]);
|
||||
return (CMD_RETURN_ERROR);
|
||||
}
|
||||
} else
|
||||
} else {
|
||||
if (args->argc != 0) {
|
||||
cmdq_error(cmdq, "key given with -a");
|
||||
return (CMD_RETURN_ERROR);
|
||||
}
|
||||
key = KEYC_NONE;
|
||||
}
|
||||
|
||||
if (args_has(args, 't'))
|
||||
return (cmd_unbind_key_table(self, cmdq, key));
|
||||
return (cmd_unbind_key_mode_table(self, cmdq, key));
|
||||
|
||||
if (key == KEYC_NONE) {
|
||||
while (!RB_EMPTY(&key_bindings)) {
|
||||
@@ -84,7 +80,7 @@ cmd_unbind_key_exec(struct cmd *self, struct cmd_q *cmdq)
|
||||
}
|
||||
|
||||
enum cmd_retval
|
||||
cmd_unbind_key_table(struct cmd *self, struct cmd_q *cmdq, int key)
|
||||
cmd_unbind_key_mode_table(struct cmd *self, struct cmd_q *cmdq, int key)
|
||||
{
|
||||
struct args *args = self->args;
|
||||
const char *tablename;
|
||||
|
||||
@@ -1,70 +0,0 @@
|
||||
/* $Id$ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
||||
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "tmux.h"
|
||||
|
||||
/*
|
||||
* Unlink a window, unless it would be destroyed by doing so (only one link).
|
||||
*/
|
||||
|
||||
enum cmd_retval cmd_unlink_window_exec(struct cmd *, struct cmd_q *);
|
||||
|
||||
const struct cmd_entry cmd_unlink_window_entry = {
|
||||
"unlink-window", "unlinkw",
|
||||
"kt:", 0, 0,
|
||||
"[-k] " CMD_TARGET_WINDOW_USAGE,
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
cmd_unlink_window_exec
|
||||
};
|
||||
|
||||
enum cmd_retval
|
||||
cmd_unlink_window_exec(struct cmd *self, struct cmd_q *cmdq)
|
||||
{
|
||||
struct args *args = self->args;
|
||||
struct winlink *wl;
|
||||
struct window *w;
|
||||
struct session *s, *s2;
|
||||
struct session_group *sg;
|
||||
u_int references;
|
||||
|
||||
if ((wl = cmd_find_window(cmdq, args_get(args, 't'), &s)) == NULL)
|
||||
return (CMD_RETURN_ERROR);
|
||||
w = wl->window;
|
||||
|
||||
sg = session_group_find(s);
|
||||
if (sg != NULL) {
|
||||
references = 0;
|
||||
TAILQ_FOREACH(s2, &sg->sessions, gentry)
|
||||
references++;
|
||||
} else
|
||||
references = 1;
|
||||
|
||||
if (!args_has(self->args, 'k') && w->references == references) {
|
||||
cmdq_error(cmdq, "window is only linked to one session");
|
||||
return (CMD_RETURN_ERROR);
|
||||
}
|
||||
|
||||
server_unlink_window(s, wl);
|
||||
recalculate_sizes();
|
||||
|
||||
return (CMD_RETURN_NORMAL);
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $Id$ */
|
||||
/* $OpenBSD$ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2013 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||
@@ -33,10 +33,8 @@ enum cmd_retval cmd_wait_for_exec(struct cmd *, struct cmd_q *);
|
||||
const struct cmd_entry cmd_wait_for_entry = {
|
||||
"wait-for", "wait",
|
||||
"LSU", 1, 1,
|
||||
"[-LSU] channel",
|
||||
"[-L|-S|-U] channel",
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
cmd_wait_for_exec
|
||||
};
|
||||
|
||||
@@ -109,7 +107,7 @@ cmd_wait_for_signal(struct cmd_q *cmdq, const char *name,
|
||||
|
||||
if (!wc->locked) {
|
||||
RB_REMOVE(wait_channels, &wait_channels, wc);
|
||||
free((void*) wc->name);
|
||||
free((void *)wc->name);
|
||||
free(wc);
|
||||
}
|
||||
|
||||
@@ -187,7 +185,7 @@ cmd_wait_for_unlock(struct cmd_q *cmdq, const char *name,
|
||||
wc->locked = 0;
|
||||
if (TAILQ_EMPTY(&wc->waiters)) {
|
||||
RB_REMOVE(wait_channels, &wait_channels, wc);
|
||||
free((void*) wc->name);
|
||||
free((void *)wc->name);
|
||||
free(wc);
|
||||
}
|
||||
}
|
||||
@@ -195,3 +193,25 @@ cmd_wait_for_unlock(struct cmd_q *cmdq, const char *name,
|
||||
return (CMD_RETURN_NORMAL);
|
||||
}
|
||||
|
||||
void
|
||||
cmd_wait_for_flush(void)
|
||||
{
|
||||
struct wait_channel *wc, *wc1;
|
||||
struct cmd_q *wq, *wq1;
|
||||
|
||||
RB_FOREACH_SAFE(wc, wait_channels, &wait_channels, wc1) {
|
||||
TAILQ_FOREACH_SAFE(wq, &wc->waiters, waitentry, wq1) {
|
||||
TAILQ_REMOVE(&wc->waiters, wq, waitentry);
|
||||
if (!cmdq_free(wq))
|
||||
cmdq_continue(wq);
|
||||
}
|
||||
while ((wq = TAILQ_FIRST(&wc->lockers)) != NULL) {
|
||||
TAILQ_REMOVE(&wc->lockers, wq, waitentry);
|
||||
if (!cmdq_free(wq))
|
||||
cmdq_continue(wq);
|
||||
}
|
||||
RB_REMOVE(wait_channels, &wait_channels, wc);
|
||||
free((void *)wc->name);
|
||||
free(wc);
|
||||
}
|
||||
}
|
||||
|
||||
244
cmd.c
244
cmd.c
@@ -1,4 +1,4 @@
|
||||
/* $Id$ */
|
||||
/* $OpenBSD$ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||
@@ -34,7 +34,6 @@ const struct cmd_entry *cmd_table[] = {
|
||||
&cmd_capture_pane_entry,
|
||||
&cmd_choose_buffer_entry,
|
||||
&cmd_choose_client_entry,
|
||||
&cmd_choose_list_entry,
|
||||
&cmd_choose_session_entry,
|
||||
&cmd_choose_tree_entry,
|
||||
&cmd_choose_window_entry,
|
||||
@@ -121,13 +120,11 @@ struct session *cmd_choose_session_list(struct sessionslist *);
|
||||
struct session *cmd_choose_session(int);
|
||||
struct client *cmd_choose_client(struct clients *);
|
||||
struct client *cmd_lookup_client(const char *);
|
||||
struct session *cmd_lookup_session(const char *, int *);
|
||||
struct session *cmd_lookup_session(struct cmd_q *, const char *, int *);
|
||||
struct session *cmd_lookup_session_id(const char *);
|
||||
struct winlink *cmd_lookup_window(struct session *, const char *, int *);
|
||||
int cmd_lookup_index(struct session *, const char *, int *);
|
||||
struct window_pane *cmd_lookup_paneid(const char *);
|
||||
struct winlink *cmd_lookup_winlink_windowid(struct session *, const char *);
|
||||
struct window *cmd_lookup_windowid(const char *);
|
||||
struct session *cmd_window_session(struct cmd_q *, struct window *,
|
||||
struct winlink **);
|
||||
struct winlink *cmd_find_window_offset(const char *, struct session *, int *);
|
||||
@@ -140,6 +137,9 @@ cmd_pack_argv(int argc, char **argv, char *buf, size_t len)
|
||||
size_t arglen;
|
||||
int i;
|
||||
|
||||
if (argc == 0)
|
||||
return (0);
|
||||
|
||||
*buf = '\0';
|
||||
for (i = 0; i < argc; i++) {
|
||||
if (strlcpy(buf, argv[i], len) >= len)
|
||||
@@ -179,14 +179,14 @@ cmd_unpack_argv(char *buf, size_t len, int argc, char ***argv)
|
||||
}
|
||||
|
||||
char **
|
||||
cmd_copy_argv(int argc, char *const *argv)
|
||||
cmd_copy_argv(int argc, char **argv)
|
||||
{
|
||||
char **new_argv;
|
||||
int i;
|
||||
|
||||
if (argc == 0)
|
||||
return (NULL);
|
||||
new_argv = xcalloc(argc, sizeof *new_argv);
|
||||
new_argv = xcalloc(argc + 1, sizeof *new_argv);
|
||||
for (i = 0; i < argc; i++) {
|
||||
if (argv[i] != NULL)
|
||||
new_argv[i] = xstrdup(argv[i]);
|
||||
@@ -206,6 +206,32 @@ cmd_free_argv(int argc, char **argv)
|
||||
free(argv);
|
||||
}
|
||||
|
||||
char *
|
||||
cmd_stringify_argv(int argc, char **argv)
|
||||
{
|
||||
char *buf;
|
||||
int i;
|
||||
size_t len;
|
||||
|
||||
if (argc == 0)
|
||||
return (xstrdup(""));
|
||||
|
||||
len = 0;
|
||||
buf = NULL;
|
||||
|
||||
for (i = 0; i < argc; i++) {
|
||||
len += strlen(argv[i]) + 1;
|
||||
buf = xrealloc(buf, len);
|
||||
|
||||
if (i == 0)
|
||||
*buf = '\0';
|
||||
else
|
||||
strlcat(buf, " ", len);
|
||||
strlcat(buf, argv[i], len);
|
||||
}
|
||||
return (buf);
|
||||
}
|
||||
|
||||
struct cmd *
|
||||
cmd_parse(int argc, char **argv, const char *file, u_int line, char **cause)
|
||||
{
|
||||
@@ -254,8 +280,6 @@ cmd_parse(int argc, char **argv, const char *file, u_int line, char **cause)
|
||||
goto usage;
|
||||
if (entry->args_upper != -1 && args->argc > entry->args_upper)
|
||||
goto usage;
|
||||
if (entry->check != NULL && entry->check(args) != 0)
|
||||
goto usage;
|
||||
|
||||
cmd = xcalloc(1, sizeof *cmd);
|
||||
cmd->entry = entry;
|
||||
@@ -294,8 +318,8 @@ cmd_print(struct cmd *cmd, char *buf, size_t len)
|
||||
size_t off, used;
|
||||
|
||||
off = xsnprintf(buf, len, "%s ", cmd->entry->name);
|
||||
if (off < len) {
|
||||
used = args_print(cmd->args, buf + off, len - off);
|
||||
if (off + 1 < len) {
|
||||
used = args_print(cmd->args, buf + off, len - off - 1);
|
||||
if (used == 0)
|
||||
off--;
|
||||
else
|
||||
@@ -315,7 +339,6 @@ cmd_print(struct cmd *cmd, char *buf, size_t len)
|
||||
struct session *
|
||||
cmd_current_session(struct cmd_q *cmdq, int prefer_unattached)
|
||||
{
|
||||
struct msg_command_data *data = cmdq->msgdata;
|
||||
struct client *c = cmdq->client;
|
||||
struct session *s;
|
||||
struct sessionslist ss;
|
||||
@@ -357,13 +380,6 @@ cmd_current_session(struct cmd_q *cmdq, int prefer_unattached)
|
||||
return (s);
|
||||
}
|
||||
|
||||
/* Use the session from the TMUX environment variable. */
|
||||
if (data != NULL && data->pid == getpid() && data->session_id != -1) {
|
||||
s = session_find_by_id(data->session_id);
|
||||
if (s != NULL)
|
||||
return (s);
|
||||
}
|
||||
|
||||
return (cmd_choose_session(prefer_unattached));
|
||||
}
|
||||
|
||||
@@ -568,9 +584,11 @@ cmd_lookup_session_id(const char *arg)
|
||||
|
||||
/* Lookup a session by name. If no session is found, NULL is returned. */
|
||||
struct session *
|
||||
cmd_lookup_session(const char *name, int *ambiguous)
|
||||
cmd_lookup_session(struct cmd_q *cmdq, const char *name, int *ambiguous)
|
||||
{
|
||||
struct session *s, *sfound;
|
||||
struct session *s, *sfound;
|
||||
struct window *w;
|
||||
struct window_pane *wp;
|
||||
|
||||
*ambiguous = 0;
|
||||
|
||||
@@ -578,6 +596,12 @@ cmd_lookup_session(const char *name, int *ambiguous)
|
||||
if ((s = cmd_lookup_session_id(name)) != NULL)
|
||||
return (s);
|
||||
|
||||
/* Try as pane or window id. */
|
||||
if ((wp = cmd_lookup_paneid(name)) != NULL)
|
||||
return (cmd_window_session(cmdq, wp->window, NULL));
|
||||
if ((w = cmd_lookup_windowid(name)) != NULL)
|
||||
return (cmd_window_session(cmdq, w, NULL));
|
||||
|
||||
/*
|
||||
* Look for matches. First look for exact matches - session names must
|
||||
* be unique so an exact match can't be ambigious and can just be
|
||||
@@ -613,16 +637,30 @@ cmd_lookup_session(const char *name, int *ambiguous)
|
||||
struct winlink *
|
||||
cmd_lookup_window(struct session *s, const char *name, int *ambiguous)
|
||||
{
|
||||
struct winlink *wl, *wlfound;
|
||||
const char *errstr;
|
||||
u_int idx;
|
||||
struct winlink *wl, *wlfound;
|
||||
struct window *w;
|
||||
struct window_pane *wp;
|
||||
const char *errstr;
|
||||
u_int idx;
|
||||
|
||||
*ambiguous = 0;
|
||||
|
||||
/* Try as a window id. */
|
||||
/* Try as pane or window id. */
|
||||
if ((wl = cmd_lookup_winlink_windowid(s, name)) != NULL)
|
||||
return (wl);
|
||||
|
||||
/* Lookup as pane or window id. */
|
||||
if ((wp = cmd_lookup_paneid(name)) != NULL) {
|
||||
wl = winlink_find_by_window(&s->windows, wp->window);
|
||||
if (wl != NULL)
|
||||
return (wl);
|
||||
}
|
||||
if ((w = cmd_lookup_windowid(name)) != NULL) {
|
||||
wl = winlink_find_by_window(&s->windows, w);
|
||||
if (wl != NULL)
|
||||
return (wl);
|
||||
}
|
||||
|
||||
/* First see if this is a valid window index in this session. */
|
||||
idx = strtonum(name, 0, INT_MAX, &errstr);
|
||||
if (errstr == NULL) {
|
||||
@@ -769,23 +807,18 @@ cmd_window_session(struct cmd_q *cmdq, struct window *w, struct winlink **wlp)
|
||||
struct session *
|
||||
cmd_find_session(struct cmd_q *cmdq, const char *arg, int prefer_unattached)
|
||||
{
|
||||
struct session *s;
|
||||
struct window_pane *wp;
|
||||
struct window *w;
|
||||
struct client *c;
|
||||
char *tmparg;
|
||||
size_t arglen;
|
||||
int ambiguous;
|
||||
struct session *s;
|
||||
struct client *c;
|
||||
char *tmparg;
|
||||
size_t arglen;
|
||||
int ambiguous;
|
||||
|
||||
/* A NULL argument means the current session. */
|
||||
if (arg == NULL)
|
||||
return (cmd_current_session(cmdq, prefer_unattached));
|
||||
|
||||
/* Lookup as pane id or window id. */
|
||||
if ((wp = cmd_lookup_paneid(arg)) != NULL)
|
||||
return (cmd_window_session(cmdq, wp->window, NULL));
|
||||
if ((w = cmd_lookup_windowid(arg)) != NULL)
|
||||
return (cmd_window_session(cmdq, w, NULL));
|
||||
if (arg == NULL) {
|
||||
if ((s = cmd_current_session(cmdq, prefer_unattached)) == NULL)
|
||||
cmdq_error(cmdq, "can't establish current session");
|
||||
return (s);
|
||||
}
|
||||
|
||||
/* Trim a single trailing colon if any. */
|
||||
tmparg = xstrdup(arg);
|
||||
@@ -796,11 +829,13 @@ cmd_find_session(struct cmd_q *cmdq, const char *arg, int prefer_unattached)
|
||||
/* An empty session name is the current session. */
|
||||
if (*tmparg == '\0') {
|
||||
free(tmparg);
|
||||
return (cmd_current_session(cmdq, prefer_unattached));
|
||||
if ((s = cmd_current_session(cmdq, prefer_unattached)) == NULL)
|
||||
cmdq_error(cmdq, "can't establish current session");
|
||||
return (s);
|
||||
}
|
||||
|
||||
/* Find the session, if any. */
|
||||
s = cmd_lookup_session(tmparg, &ambiguous);
|
||||
s = cmd_lookup_session(cmdq, tmparg, &ambiguous);
|
||||
|
||||
/* If it doesn't, try to match it as a client. */
|
||||
if (s == NULL && (c = cmd_lookup_client(tmparg)) != NULL)
|
||||
@@ -822,12 +857,11 @@ cmd_find_session(struct cmd_q *cmdq, const char *arg, int prefer_unattached)
|
||||
struct winlink *
|
||||
cmd_find_window(struct cmd_q *cmdq, const char *arg, struct session **sp)
|
||||
{
|
||||
struct session *s;
|
||||
struct winlink *wl;
|
||||
struct window_pane *wp;
|
||||
const char *winptr;
|
||||
char *sessptr = NULL;
|
||||
int ambiguous = 0;
|
||||
struct session *s;
|
||||
struct winlink *wl;
|
||||
const char *winptr;
|
||||
char *sessptr = NULL;
|
||||
int ambiguous = 0;
|
||||
|
||||
/*
|
||||
* Find the current session. There must always be a current session, if
|
||||
@@ -845,14 +879,6 @@ cmd_find_window(struct cmd_q *cmdq, const char *arg, struct session **sp)
|
||||
return (s->curw);
|
||||
}
|
||||
|
||||
/* Lookup as pane id. */
|
||||
if ((wp = cmd_lookup_paneid(arg)) != NULL) {
|
||||
s = cmd_window_session(cmdq, wp->window, &wl);
|
||||
if (sp != NULL)
|
||||
*sp = s;
|
||||
return (wl);
|
||||
}
|
||||
|
||||
/* Time to look at the argument. If it is empty, that is an error. */
|
||||
if (*arg == '\0')
|
||||
goto not_found;
|
||||
@@ -867,7 +893,7 @@ cmd_find_window(struct cmd_q *cmdq, const char *arg, struct session **sp)
|
||||
|
||||
/* Try to lookup the session if present. */
|
||||
if (*sessptr != '\0') {
|
||||
if ((s = cmd_lookup_session(sessptr, &ambiguous)) == NULL)
|
||||
if ((s = cmd_lookup_session(cmdq, sessptr, &ambiguous)) == NULL)
|
||||
goto no_session;
|
||||
}
|
||||
if (sp != NULL)
|
||||
@@ -918,7 +944,8 @@ no_colon:
|
||||
lookup_session:
|
||||
if (ambiguous)
|
||||
goto not_found;
|
||||
if (*arg != '\0' && (s = cmd_lookup_session(arg, &ambiguous)) == NULL)
|
||||
if (*arg != '\0' &&
|
||||
(s = cmd_lookup_session(cmdq, arg, &ambiguous)) == NULL)
|
||||
goto no_session;
|
||||
|
||||
if (sp != NULL)
|
||||
@@ -1008,7 +1035,7 @@ cmd_find_index(struct cmd_q *cmdq, const char *arg, struct session **sp)
|
||||
|
||||
/* Try to lookup the session if present. */
|
||||
if (sessptr != NULL && *sessptr != '\0') {
|
||||
if ((s = cmd_lookup_session(sessptr, &ambiguous)) == NULL)
|
||||
if ((s = cmd_lookup_session(cmdq, sessptr, &ambiguous)) == NULL)
|
||||
goto no_session;
|
||||
}
|
||||
if (sp != NULL)
|
||||
@@ -1056,7 +1083,8 @@ no_colon:
|
||||
lookup_session:
|
||||
if (ambiguous)
|
||||
goto not_found;
|
||||
if (*arg != '\0' && (s = cmd_lookup_session(arg, &ambiguous)) == NULL)
|
||||
if (*arg != '\0' &&
|
||||
(s = cmd_lookup_session(cmdq, arg, &ambiguous)) == NULL)
|
||||
goto no_session;
|
||||
|
||||
if (sp != NULL)
|
||||
@@ -1170,7 +1198,13 @@ cmd_find_pane(struct cmd_q *cmdq,
|
||||
*wpp = wl->window->active;
|
||||
else if (paneptr[0] == '+' || paneptr[0] == '-')
|
||||
*wpp = cmd_find_pane_offset(paneptr, wl);
|
||||
else {
|
||||
else if (paneptr[0] == '!' && paneptr[1] == '\0') {
|
||||
if (wl->window->last == NULL) {
|
||||
cmdq_error(cmdq, "no last pane");
|
||||
goto error;
|
||||
}
|
||||
*wpp = wl->window->last;
|
||||
} else {
|
||||
idx = strtonum(paneptr, 0, INT_MAX, &errstr);
|
||||
if (errstr != NULL)
|
||||
goto lookup_string;
|
||||
@@ -1267,98 +1301,14 @@ cmd_template_replace(const char *template, const char *s, int idx)
|
||||
ptr++;
|
||||
|
||||
len += strlen(s);
|
||||
buf = xrealloc(buf, 1, len + 1);
|
||||
buf = xrealloc(buf, len + 1);
|
||||
strlcat(buf, s, len + 1);
|
||||
continue;
|
||||
}
|
||||
buf = xrealloc(buf, 1, len + 2);
|
||||
buf = xrealloc(buf, len + 2);
|
||||
buf[len++] = ch;
|
||||
buf[len] = '\0';
|
||||
}
|
||||
|
||||
return (buf);
|
||||
}
|
||||
|
||||
/*
|
||||
* Return the default path for a new pane, using the given path or the
|
||||
* default-path option if it is NULL. Several special values are accepted: the
|
||||
* empty string or relative path for the current pane's working directory, ~
|
||||
* for the user's home, - for the session working directory, . for the tmux
|
||||
* server's working directory. The default on failure is the session's working
|
||||
* directory.
|
||||
*/
|
||||
const char *
|
||||
cmd_get_default_path(struct cmd_q *cmdq, const char *cwd)
|
||||
{
|
||||
struct client *c = cmdq->client;
|
||||
struct session *s;
|
||||
struct environ_entry *envent;
|
||||
const char *root;
|
||||
char tmp[MAXPATHLEN];
|
||||
struct passwd *pw;
|
||||
int n;
|
||||
size_t skip;
|
||||
static char path[MAXPATHLEN];
|
||||
|
||||
if ((s = cmd_current_session(cmdq, 0)) == NULL)
|
||||
return (NULL);
|
||||
|
||||
if (cwd == NULL)
|
||||
cwd = options_get_string(&s->options, "default-path");
|
||||
|
||||
skip = 1;
|
||||
if (strcmp(cwd, "$HOME") == 0 || strncmp(cwd, "$HOME/", 6) == 0) {
|
||||
/* User's home directory - $HOME. */
|
||||
skip = 5;
|
||||
goto find_home;
|
||||
} else if (cwd[0] == '~' && (cwd[1] == '\0' || cwd[1] == '/')) {
|
||||
/* User's home directory - ~. */
|
||||
goto find_home;
|
||||
} else if (cwd[0] == '-' && (cwd[1] == '\0' || cwd[1] == '/')) {
|
||||
/* Session working directory. */
|
||||
root = s->cwd;
|
||||
goto complete_path;
|
||||
} else if (cwd[0] == '.' && (cwd[1] == '\0' || cwd[1] == '/')) {
|
||||
/* Server working directory. */
|
||||
if (getcwd(tmp, sizeof tmp) != NULL) {
|
||||
root = tmp;
|
||||
goto complete_path;
|
||||
}
|
||||
return (s->cwd);
|
||||
} else if (*cwd == '/') {
|
||||
/* Absolute path. */
|
||||
return (cwd);
|
||||
} else {
|
||||
/* Empty or relative path. */
|
||||
if (c != NULL && c->session == NULL && c->cwd != NULL)
|
||||
root = c->cwd;
|
||||
else if (s->curw != NULL)
|
||||
root = osdep_get_cwd(s->curw->window->active->fd);
|
||||
else
|
||||
return (s->cwd);
|
||||
skip = 0;
|
||||
if (root != NULL)
|
||||
goto complete_path;
|
||||
}
|
||||
|
||||
return (s->cwd);
|
||||
|
||||
find_home:
|
||||
envent = environ_find(&global_environ, "HOME");
|
||||
if (envent != NULL && *envent->value != '\0')
|
||||
root = envent->value;
|
||||
else if ((pw = getpwuid(getuid())) != NULL)
|
||||
root = pw->pw_dir;
|
||||
else
|
||||
return (s->cwd);
|
||||
|
||||
complete_path:
|
||||
if (root[skip] == '\0') {
|
||||
strlcpy(path, root, sizeof path);
|
||||
return (path);
|
||||
}
|
||||
n = snprintf(path, sizeof path, "%s/%s", root, cwd + skip);
|
||||
if (n > 0 && (size_t)n < sizeof path)
|
||||
return (path);
|
||||
return (s->cwd);
|
||||
}
|
||||
|
||||
44
colour.c
44
colour.c
@@ -1,4 +1,4 @@
|
||||
/* $Id$ */
|
||||
/* $OpenBSD$ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||
@@ -236,28 +236,28 @@ colour_fromstring(const char *s)
|
||||
if (strcasecmp(s, "default") == 0 || (s[0] == '8' && s[1] == '\0'))
|
||||
return (8);
|
||||
if (strcasecmp(s, "brightblack") == 0 ||
|
||||
(s[0] == '9' && s[1] == '0' && s[1] == '\0'))
|
||||
(s[0] == '9' && s[1] == '0' && s[2] == '\0'))
|
||||
return (90);
|
||||
if (strcasecmp(s, "brightred") == 0 ||
|
||||
(s[0] == '9' && s[1] == '1' && s[1] == '\0'))
|
||||
(s[0] == '9' && s[1] == '1' && s[2] == '\0'))
|
||||
return (91);
|
||||
if (strcasecmp(s, "brightgreen") == 0 ||
|
||||
(s[0] == '9' && s[1] == '2' && s[1] == '\0'))
|
||||
(s[0] == '9' && s[1] == '2' && s[2] == '\0'))
|
||||
return (92);
|
||||
if (strcasecmp(s, "brightyellow") == 0 ||
|
||||
(s[0] == '9' && s[1] == '3' && s[1] == '\0'))
|
||||
(s[0] == '9' && s[1] == '3' && s[2] == '\0'))
|
||||
return (93);
|
||||
if (strcasecmp(s, "brightblue") == 0 ||
|
||||
(s[0] == '9' && s[1] == '4' && s[1] == '\0'))
|
||||
(s[0] == '9' && s[1] == '4' && s[2] == '\0'))
|
||||
return (94);
|
||||
if (strcasecmp(s, "brightmagenta") == 0 ||
|
||||
(s[0] == '9' && s[1] == '5' && s[1] == '\0'))
|
||||
(s[0] == '9' && s[1] == '5' && s[2] == '\0'))
|
||||
return (95);
|
||||
if (strcasecmp(s, "brightcyan") == 0 ||
|
||||
(s[0] == '9' && s[1] == '6' && s[1] == '\0'))
|
||||
(s[0] == '9' && s[1] == '6' && s[2] == '\0'))
|
||||
return (96);
|
||||
if (strcasecmp(s, "brightwhite") == 0 ||
|
||||
(s[0] == '9' && s[1] == '7' && s[1] == '\0'))
|
||||
(s[0] == '9' && s[1] == '7' && s[2] == '\0'))
|
||||
return (97);
|
||||
return (-1);
|
||||
}
|
||||
@@ -287,29 +287,3 @@ colour_256to16(u_char c)
|
||||
|
||||
return (table[c]);
|
||||
}
|
||||
|
||||
/* Convert 256 colour palette to 88. */
|
||||
u_char
|
||||
colour_256to88(u_char c)
|
||||
{
|
||||
static const u_char table[256] = {
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
|
||||
16, 17, 17, 18, 18, 19, 20, 21, 21, 22, 22, 23, 20, 21, 21, 22,
|
||||
22, 23, 24, 25, 25, 26, 26, 27, 24, 25, 25, 26, 26, 27, 28, 29,
|
||||
29, 30, 30, 31, 32, 33, 33, 34, 34, 35, 36, 37, 37, 38, 38, 39,
|
||||
36, 37, 37, 38, 38, 39, 40, 41, 41, 42, 42, 43, 40, 41, 41, 42,
|
||||
42, 43, 44, 45, 45, 46, 46, 47, 32, 33, 33, 34, 34, 35, 36, 37,
|
||||
37, 38, 38, 39, 36, 37, 37, 38, 38, 39, 40, 41, 41, 42, 42, 43,
|
||||
40, 41, 41, 42, 42, 43, 44, 45, 45, 46, 46, 47, 48, 49, 49, 50,
|
||||
50, 51, 52, 53, 53, 54, 54, 55, 52, 53, 53, 54, 54, 55, 56, 57,
|
||||
57, 58, 58, 59, 56, 57, 57, 58, 58, 59, 60, 61, 61, 62, 62, 63,
|
||||
48, 49, 49, 50, 50, 51, 52, 53, 53, 54, 54, 55, 52, 53, 53, 54,
|
||||
54, 55, 56, 57, 57, 58, 58, 59, 56, 57, 57, 58, 58, 59, 60, 61,
|
||||
61, 62, 62, 63, 64, 65, 65, 66, 66, 67, 68, 69, 69, 70, 70, 71,
|
||||
68, 69, 69, 70, 70, 71, 72, 73, 73, 74, 74, 75, 72, 73, 73, 74,
|
||||
74, 75, 76, 77, 77, 78, 78, 79, 0, 0, 80, 80, 80, 81, 81, 81,
|
||||
82, 82, 82, 83, 83, 83, 84, 84, 84, 85, 85, 85, 86, 86, 86, 87
|
||||
};
|
||||
|
||||
return (table[c]);
|
||||
}
|
||||
|
||||
47
compat.h
47
compat.h
@@ -30,6 +30,10 @@
|
||||
#define __packed __attribute__ ((__packed__))
|
||||
#endif
|
||||
|
||||
#ifndef ECHOPRT
|
||||
#define ECHOPRT 0
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_BSD_TYPES
|
||||
typedef uint8_t u_int8_t;
|
||||
typedef uint16_t u_int16_t;
|
||||
@@ -121,6 +125,10 @@ typedef uint64_t u_int64_t;
|
||||
#define CMSG_LEN(len) (CMSG_ALIGN(sizeof(struct cmsghdr)) + (len))
|
||||
#endif
|
||||
|
||||
#ifndef O_DIRECTORY
|
||||
#define O_DIRECTORY 0
|
||||
#endif
|
||||
|
||||
#ifndef INFTIM
|
||||
#define INFTIM -1
|
||||
#endif
|
||||
@@ -152,10 +160,33 @@ typedef uint64_t u_int64_t;
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
#ifndef timersub
|
||||
#define timersub(tvp, uvp, vvp) \
|
||||
do { \
|
||||
(vvp)->tv_sec = (tvp)->tv_sec - (uvp)->tv_sec; \
|
||||
(vvp)->tv_usec = (tvp)->tv_usec - (uvp)->tv_usec; \
|
||||
if ((vvp)->tv_usec < 0) { \
|
||||
(vvp)->tv_sec--; \
|
||||
(vvp)->tv_usec += 1000000; \
|
||||
} \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
#ifndef TTY_NAME_MAX
|
||||
#define TTY_NAME_MAX 32
|
||||
#endif
|
||||
|
||||
#ifndef HOST_NAME_MAX
|
||||
#define HOST_NAME_MAX 255
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_FLOCK
|
||||
#define LOCK_SH 0
|
||||
#define LOCK_EX 0
|
||||
#define LOCK_NB 0
|
||||
#define flock(fd, op) (0)
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_BZERO
|
||||
#undef bzero
|
||||
#define bzero(buf, len) memset(buf, 0, len);
|
||||
@@ -198,6 +229,7 @@ int daemon(int, int);
|
||||
|
||||
#ifndef HAVE_B64_NTOP
|
||||
/* b64_ntop.c */
|
||||
#undef b64_ntop /* for Cygwin */
|
||||
int b64_ntop(const char *, size_t, char *, size_t);
|
||||
#endif
|
||||
|
||||
@@ -218,12 +250,27 @@ int vasprintf(char **, const char *, va_list);
|
||||
char *fgetln(FILE *, size_t *);
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_FPARSELN
|
||||
char *fparseln(FILE *, size_t *, size_t *, const char *, int);
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_SETENV
|
||||
/* setenv.c */
|
||||
int setenv(const char *, const char *, int);
|
||||
int unsetenv(const char *);
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_CFMAKERAW
|
||||
/* cfmakeraw.c */
|
||||
void cfmakeraw(struct termios *);
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_OPENAT
|
||||
/* openat.c */
|
||||
#define AT_FDCWD -100
|
||||
int openat(int, const char *, int, ...);
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_GETOPT
|
||||
#include <getopt.h>
|
||||
#else
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
/* $Id$ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2006 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||
*
|
||||
@@ -56,10 +54,12 @@ vasprintf(char **ret, const char *fmt, va_list ap)
|
||||
free(*ret);
|
||||
goto error;
|
||||
}
|
||||
va_end(ap2);
|
||||
|
||||
return (n);
|
||||
|
||||
error:
|
||||
va_end(ap2);
|
||||
*ret = NULL;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
/* $Id$ */
|
||||
/* $OpenBSD: bitstring.h,v 1.5 2003/06/02 19:34:12 millert Exp $ */
|
||||
/* $NetBSD: bitstring.h,v 1.5 1997/05/14 15:49:55 pk Exp $ */
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
/* $Id$ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||
* Copyright (c) 2013 Dagobert Michelsen
|
||||
* Copyright (c) 2013 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
@@ -16,28 +15,16 @@
|
||||
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "tmux.h"
|
||||
|
||||
/*
|
||||
* Start the server and do nothing else.
|
||||
*/
|
||||
|
||||
enum cmd_retval cmd_start_server_exec(struct cmd *, struct cmd_q *);
|
||||
|
||||
const struct cmd_entry cmd_start_server_entry = {
|
||||
"start-server", "start",
|
||||
"", 0, 0,
|
||||
"",
|
||||
CMD_STARTSERVER,
|
||||
NULL,
|
||||
NULL,
|
||||
cmd_start_server_exec
|
||||
};
|
||||
|
||||
enum cmd_retval
|
||||
cmd_start_server_exec(unused struct cmd *self, unused struct cmd_q *cmdq)
|
||||
void
|
||||
cfmakeraw(struct termios *tio)
|
||||
{
|
||||
return (CMD_RETURN_NORMAL);
|
||||
tio->c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON);
|
||||
tio->c_oflag &= ~OPOST;
|
||||
tio->c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN);
|
||||
tio->c_cflag &= ~(CSIZE|PARENB);
|
||||
tio->c_cflag |= CS8;
|
||||
}
|
||||
@@ -1,5 +1,3 @@
|
||||
/* $Id$ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2004-2005 Todd C. Miller <Todd.Miller@courtesan.com>
|
||||
*
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
/* $Id$ */
|
||||
/* $OpenBSD: daemon.c,v 1.6 2005/08/08 08:05:33 espie Exp $ */
|
||||
/*-
|
||||
* Copyright (c) 1990, 1993
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
/* $Id$ */
|
||||
/* $NetBSD: fgetln.c,v 1.3 2007/08/07 02:06:58 lukem Exp $ */
|
||||
|
||||
/*-
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
/* $Id$ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||
*
|
||||
@@ -23,19 +21,23 @@
|
||||
#include <stdlib.h>
|
||||
#include <stropts.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "tmux.h"
|
||||
|
||||
pid_t
|
||||
forkpty(int *master, unused char *name, struct termios *tio, struct winsize *ws)
|
||||
{
|
||||
int slave, fd;
|
||||
char *path;
|
||||
int slave = -1, fd, pipe_fd[2];
|
||||
char *path, dummy;
|
||||
pid_t pid;
|
||||
|
||||
if ((*master = open("/dev/ptc", O_RDWR|O_NOCTTY)) == -1)
|
||||
if (pipe(pipe_fd) == -1)
|
||||
return (-1);
|
||||
|
||||
if ((*master = open("/dev/ptc", O_RDWR|O_NOCTTY)) == -1)
|
||||
goto out;
|
||||
|
||||
if ((path = ttyname(*master)) == NULL)
|
||||
goto out;
|
||||
if ((slave = open(path, O_RDWR|O_NOCTTY)) == -1)
|
||||
@@ -47,6 +49,13 @@ forkpty(int *master, unused char *name, struct termios *tio, struct winsize *ws)
|
||||
case 0:
|
||||
close(*master);
|
||||
|
||||
close(pipe_fd[1]);
|
||||
while (read(pipe_fd[0], &dummy, 1) == -1) {
|
||||
if (errno != EINTR)
|
||||
break;
|
||||
}
|
||||
close(pipe_fd[0]);
|
||||
|
||||
fd = open(_PATH_TTY, O_RDWR|O_NOCTTY);
|
||||
if (fd >= 0) {
|
||||
ioctl(fd, TIOCNOTTY, NULL);
|
||||
@@ -80,10 +89,14 @@ forkpty(int *master, unused char *name, struct termios *tio, struct winsize *ws)
|
||||
dup2(slave, 2);
|
||||
if (slave > 2)
|
||||
close(slave);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
close(slave);
|
||||
|
||||
close(pipe_fd[0]);
|
||||
close(pipe_fd[1]);
|
||||
return (pid);
|
||||
|
||||
out:
|
||||
@@ -91,5 +104,8 @@ out:
|
||||
close(*master);
|
||||
if (slave != -1)
|
||||
close(slave);
|
||||
|
||||
close(pipe_fd[0]);
|
||||
close(pipe_fd[1]);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
/* $Id$ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||
*
|
||||
@@ -29,7 +27,7 @@
|
||||
pid_t
|
||||
forkpty(int *master, char *name, struct termios *tio, struct winsize *ws)
|
||||
{
|
||||
int slave;
|
||||
int slave = -1;
|
||||
char *path;
|
||||
pid_t pid;
|
||||
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
/* $Id$ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||
*
|
||||
@@ -21,6 +19,7 @@
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <stdlib.h>
|
||||
#include <strings.h>
|
||||
#include <stropts.h>
|
||||
#include <unistd.h>
|
||||
|
||||
@@ -29,7 +28,7 @@
|
||||
pid_t
|
||||
forkpty(int *master, char *name, struct termios *tio, struct winsize *ws)
|
||||
{
|
||||
int slave;
|
||||
int slave = -1;
|
||||
char *path;
|
||||
pid_t pid;
|
||||
|
||||
|
||||
221
compat/fparseln.c
Normal file
221
compat/fparseln.c
Normal file
@@ -0,0 +1,221 @@
|
||||
/* $OpenBSD: fparseln.c,v 1.6 2005/08/02 21:46:23 espie Exp $ */
|
||||
/* $NetBSD: fparseln.c,v 1.7 1999/07/02 15:49:12 simonb Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1997 Christos Zoulas. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by Christos Zoulas.
|
||||
* 4. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/* OPENBSD ORIGINAL: lib/libutil/fparseln.c */
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "tmux.h"
|
||||
|
||||
/*
|
||||
* fparseln() specific operation flags.
|
||||
*/
|
||||
#define FPARSELN_UNESCESC 0x01
|
||||
#define FPARSELN_UNESCCONT 0x02
|
||||
#define FPARSELN_UNESCCOMM 0x04
|
||||
#define FPARSELN_UNESCREST 0x08
|
||||
#define FPARSELN_UNESCALL 0x0f
|
||||
|
||||
static int isescaped(const char *, const char *, int);
|
||||
|
||||
/* isescaped():
|
||||
* Return true if the character in *p that belongs to a string
|
||||
* that starts in *sp, is escaped by the escape character esc.
|
||||
*/
|
||||
static int
|
||||
isescaped(const char *sp, const char *p, int esc)
|
||||
{
|
||||
const char *cp;
|
||||
size_t ne;
|
||||
|
||||
/* No escape character */
|
||||
if (esc == '\0')
|
||||
return 1;
|
||||
|
||||
/* Count the number of escape characters that precede ours */
|
||||
for (ne = 0, cp = p; --cp >= sp && *cp == esc; ne++)
|
||||
continue;
|
||||
|
||||
/* Return true if odd number of escape characters */
|
||||
return (ne & 1) != 0;
|
||||
}
|
||||
|
||||
|
||||
/* fparseln():
|
||||
* Read a line from a file parsing continuations ending in \
|
||||
* and eliminating trailing newlines, or comments starting with
|
||||
* the comment char.
|
||||
*/
|
||||
char *
|
||||
fparseln(FILE *fp, size_t *size, size_t *lineno, const char str[3],
|
||||
int flags)
|
||||
{
|
||||
static const char dstr[3] = { '\\', '\\', '#' };
|
||||
char *buf = NULL, *ptr, *cp, esc, con, nl, com;
|
||||
size_t s, len = 0;
|
||||
int cnt = 1;
|
||||
|
||||
if (str == NULL)
|
||||
str = dstr;
|
||||
|
||||
esc = str[0];
|
||||
con = str[1];
|
||||
com = str[2];
|
||||
|
||||
/*
|
||||
* XXX: it would be cool to be able to specify the newline character,
|
||||
* but unfortunately, fgetln does not let us
|
||||
*/
|
||||
nl = '\n';
|
||||
|
||||
while (cnt) {
|
||||
cnt = 0;
|
||||
|
||||
if (lineno)
|
||||
(*lineno)++;
|
||||
|
||||
if ((ptr = fgetln(fp, &s)) == NULL)
|
||||
break;
|
||||
|
||||
if (s && com) { /* Check and eliminate comments */
|
||||
for (cp = ptr; cp < ptr + s; cp++)
|
||||
if (*cp == com && !isescaped(ptr, cp, esc)) {
|
||||
s = cp - ptr;
|
||||
cnt = s == 0 && buf == NULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (s && nl) { /* Check and eliminate newlines */
|
||||
cp = &ptr[s - 1];
|
||||
|
||||
if (*cp == nl)
|
||||
s--; /* forget newline */
|
||||
}
|
||||
|
||||
if (s && con) { /* Check and eliminate continuations */
|
||||
cp = &ptr[s - 1];
|
||||
|
||||
if (*cp == con && !isescaped(ptr, cp, esc)) {
|
||||
s--; /* forget escape */
|
||||
cnt = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (s == 0 && buf != NULL)
|
||||
continue;
|
||||
|
||||
if ((cp = realloc(buf, len + s + 1)) == NULL) {
|
||||
free(buf);
|
||||
return NULL;
|
||||
}
|
||||
buf = cp;
|
||||
|
||||
(void) memcpy(buf + len, ptr, s);
|
||||
len += s;
|
||||
buf[len] = '\0';
|
||||
}
|
||||
|
||||
if ((flags & FPARSELN_UNESCALL) != 0 && esc && buf != NULL &&
|
||||
strchr(buf, esc) != NULL) {
|
||||
ptr = cp = buf;
|
||||
while (cp[0] != '\0') {
|
||||
int skipesc;
|
||||
|
||||
while (cp[0] != '\0' && cp[0] != esc)
|
||||
*ptr++ = *cp++;
|
||||
if (cp[0] == '\0' || cp[1] == '\0')
|
||||
break;
|
||||
|
||||
skipesc = 0;
|
||||
if (cp[1] == com)
|
||||
skipesc += (flags & FPARSELN_UNESCCOMM);
|
||||
if (cp[1] == con)
|
||||
skipesc += (flags & FPARSELN_UNESCCONT);
|
||||
if (cp[1] == esc)
|
||||
skipesc += (flags & FPARSELN_UNESCESC);
|
||||
if (cp[1] != com && cp[1] != con && cp[1] != esc)
|
||||
skipesc = (flags & FPARSELN_UNESCREST);
|
||||
|
||||
if (skipesc)
|
||||
cp++;
|
||||
else
|
||||
*ptr++ = *cp++;
|
||||
*ptr++ = *cp++;
|
||||
}
|
||||
*ptr = '\0';
|
||||
len = strlen(buf);
|
||||
}
|
||||
|
||||
if (size)
|
||||
*size = len;
|
||||
return buf;
|
||||
}
|
||||
|
||||
#ifdef TEST
|
||||
|
||||
int main(int, char **);
|
||||
|
||||
int
|
||||
main(argc, argv)
|
||||
int argc;
|
||||
char **argv;
|
||||
{
|
||||
char *ptr;
|
||||
size_t size, line;
|
||||
|
||||
line = 0;
|
||||
while ((ptr = fparseln(stdin, &size, &line, NULL,
|
||||
FPARSELN_UNESCALL)) != NULL)
|
||||
printf("line %d (%d) |%s|\n", line, size, ptr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
# This is a test
|
||||
line 1
|
||||
line 2 \
|
||||
line 3 # Comment
|
||||
line 4 \# Not comment \\\\
|
||||
|
||||
# And a comment \
|
||||
line 5 \\\
|
||||
line 6
|
||||
|
||||
*/
|
||||
|
||||
#endif /* TEST */
|
||||
@@ -1,5 +1,3 @@
|
||||
/* $Id$ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1987, 1993, 1994
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
/* $Id$ */
|
||||
/* $OpenBSD: imsg-buffer.c,v 1.3 2010/05/26 13:56:07 nicm Exp $ */
|
||||
/* $OpenBSD: imsg-buffer.c,v 1.4 2014/06/30 00:25:17 deraadt Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
|
||||
@@ -17,16 +16,19 @@
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/queue.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/uio.h>
|
||||
|
||||
#include <limits.h>
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "tmux.h"
|
||||
#include "imsg.h"
|
||||
|
||||
int ibuf_realloc(struct ibuf *, size_t);
|
||||
void ibuf_enqueue(struct msgbuf *, struct ibuf *);
|
||||
@@ -157,22 +159,23 @@ ibuf_write(struct msgbuf *msgbuf)
|
||||
i++;
|
||||
}
|
||||
|
||||
again:
|
||||
if ((n = writev(msgbuf->fd, iov, i)) == -1) {
|
||||
if (errno == EAGAIN || errno == ENOBUFS ||
|
||||
errno == EINTR) /* try later */
|
||||
return (0);
|
||||
else
|
||||
return (-1);
|
||||
if (errno == EINTR)
|
||||
goto again;
|
||||
if (errno == ENOBUFS)
|
||||
errno = EAGAIN;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
if (n == 0) { /* connection closed */
|
||||
errno = 0;
|
||||
return (-2);
|
||||
return (0);
|
||||
}
|
||||
|
||||
msgbuf_drain(msgbuf, n);
|
||||
|
||||
return (0);
|
||||
return (1);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -256,17 +259,18 @@ msgbuf_write(struct msgbuf *msgbuf)
|
||||
*(int *)CMSG_DATA(cmsg) = buf->fd;
|
||||
}
|
||||
|
||||
again:
|
||||
if ((n = sendmsg(msgbuf->fd, &msg, 0)) == -1) {
|
||||
if (errno == EAGAIN || errno == ENOBUFS ||
|
||||
errno == EINTR) /* try later */
|
||||
return (0);
|
||||
else
|
||||
return (-1);
|
||||
if (errno == EINTR)
|
||||
goto again;
|
||||
if (errno == ENOBUFS)
|
||||
errno = EAGAIN;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
if (n == 0) { /* connection closed */
|
||||
errno = 0;
|
||||
return (-2);
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -280,7 +284,7 @@ msgbuf_write(struct msgbuf *msgbuf)
|
||||
|
||||
msgbuf_drain(msgbuf, n);
|
||||
|
||||
return (0);
|
||||
return (1);
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user