Compare commits
1774 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b6254e4a67 | ||
|
|
53431c7ba8 | ||
|
|
afa0bb4c1d | ||
|
|
9ae2579dcb | ||
|
|
37fe98fdec | ||
|
|
fe91b74ba7 | ||
|
|
0fcc446298 | ||
|
|
e228f5105e | ||
|
|
719760fd7b | ||
|
|
d3e87bcd4f | ||
|
|
be771456e1 | ||
|
|
8514782ad2 | ||
|
|
a3e9e0f010 | ||
|
|
15615a4cd1 | ||
|
|
7246fb347c | ||
|
|
f1b6fb397b | ||
|
|
49fbeb9a56 | ||
|
|
f17d71454a | ||
|
|
59ea7485e4 | ||
|
|
ff63e58f95 | ||
|
|
79ec8b60b9 | ||
|
|
846c774ac2 | ||
|
|
940e311c74 | ||
|
|
251667a30e | ||
|
|
e45697f78a | ||
|
|
ea63efa522 | ||
|
|
60839cdb47 | ||
|
|
a867b4444d | ||
|
|
072fe91518 | ||
|
|
07e6171dc5 | ||
|
|
9a80fcee37 | ||
|
|
7731a558f0 | ||
|
|
7ea4c1e47f | ||
|
|
f6b748712c | ||
|
|
93abedd93f | ||
|
|
872cd7b2d5 | ||
|
|
a7e03f9c63 | ||
|
|
f53dfb27e2 | ||
|
|
36b4e0edd2 | ||
|
|
9081947751 | ||
|
|
f58013f2c6 | ||
|
|
ae35507f80 | ||
|
|
73ff508b51 | ||
|
|
b0ccf74029 | ||
|
|
6046dc8598 | ||
|
|
9bba38bd11 | ||
|
|
59505d17d5 | ||
|
|
bcecc61b67 | ||
|
|
f9af273150 | ||
|
|
8699f90fa4 | ||
|
|
0a9ba1bc08 | ||
|
|
37741ac808 | ||
|
|
6d790237c3 | ||
|
|
70d5a5134f | ||
|
|
ee166c5555 | ||
|
|
b965fb4806 | ||
|
|
e49b20bfa7 | ||
|
|
8abfb50aed | ||
|
|
10e0077a6f | ||
|
|
278477b387 | ||
|
|
58b7fb41d9 | ||
|
|
f71e0a6ee8 | ||
|
|
b59e42c9cc | ||
|
|
57888af4ea | ||
|
|
90f2ba474c | ||
|
|
09d025d88f | ||
|
|
e18ac4f0f5 | ||
|
|
63ab35ec7c | ||
|
|
d65ed5993c | ||
|
|
6436dfaf14 | ||
|
|
0c4bd96f87 | ||
|
|
6afabf7e2a | ||
|
|
a4d4cf5819 | ||
|
|
1be7425186 | ||
|
|
8f0825bc5c | ||
|
|
6a657eec33 | ||
|
|
ae952605d3 | ||
|
|
81753706d3 | ||
|
|
4120be3e2d | ||
|
|
832f73fde9 | ||
|
|
99d06f0714 | ||
|
|
e973c45968 | ||
|
|
4dbf0c89c3 | ||
|
|
1f264ffec5 | ||
|
|
547e4a3d7e | ||
|
|
d0fa0516f5 | ||
|
|
2c13005e0f | ||
|
|
b52990cb39 | ||
|
|
0a1390a7f6 | ||
|
|
5084f843c9 | ||
|
|
42b5b1cbf7 | ||
|
|
832f7a862b | ||
|
|
0d4a62ccb5 | ||
|
|
3d98501e57 | ||
|
|
a4fff7abe3 | ||
|
|
f51779d93a | ||
|
|
121d86fb1c | ||
|
|
5956639082 | ||
|
|
7e449dec4f | ||
|
|
a938b01246 | ||
|
|
a4cd10c6fb | ||
|
|
5fd17b4b99 | ||
|
|
8ae0ae2c93 | ||
|
|
59957a913a | ||
|
|
49d284cd16 | ||
|
|
dedbd14ace | ||
|
|
2c6d888b3d | ||
|
|
9b0a5d6465 | ||
|
|
32c4f4ccaa | ||
|
|
8e435dff16 | ||
|
|
98e44a8907 | ||
|
|
060362bee2 | ||
|
|
6bfe9bfe9a | ||
|
|
b4f7cd94a1 | ||
|
|
74f21ec774 | ||
|
|
5899e06b6b | ||
|
|
5f744368dd | ||
|
|
a4a9290577 | ||
|
|
77b15bf73f | ||
|
|
f41584c83b | ||
|
|
892b8c03eb | ||
|
|
ecdf901c19 | ||
|
|
5d1f58427e | ||
|
|
02a7316342 | ||
|
|
3d59e4eac1 | ||
|
|
50ce698524 | ||
|
|
32768e7939 | ||
|
|
62dbc1129c | ||
|
|
3d0d987984 | ||
|
|
2c78a22270 | ||
|
|
4a7ae0f524 | ||
|
|
bc25e5a8a2 | ||
|
|
4af2526f54 | ||
|
|
8f688fb33b | ||
|
|
6e351cd945 | ||
|
|
2d66e37dcb | ||
|
|
2da25d9187 | ||
|
|
11badac95d | ||
|
|
b4024bf7f2 | ||
|
|
759feac95b | ||
|
|
33de23d01d | ||
|
|
3f0ecbb241 | ||
|
|
e91c008357 | ||
|
|
7a2003c371 | ||
|
|
a7eb9850b7 | ||
|
|
f01446ff25 | ||
|
|
525a32be51 | ||
|
|
73386bd67f | ||
|
|
d1cf88e942 | ||
|
|
c11da595ef | ||
|
|
2546afb7aa | ||
|
|
56edb5cdbe | ||
|
|
bca3179a6d | ||
|
|
1f3d86a434 | ||
|
|
0456399ce5 | ||
|
|
799881af2d | ||
|
|
14047588ae | ||
|
|
9d9840a6d8 | ||
|
|
b36d8d6469 | ||
|
|
254ba401d4 | ||
|
|
3035ba08c3 | ||
|
|
16201ac873 | ||
|
|
42a2493286 | ||
|
|
6f48dda8b9 | ||
|
|
b8b495ac31 | ||
|
|
bd1276d079 | ||
|
|
bfb87854df | ||
|
|
f4aba9fc41 | ||
|
|
757c7900d9 | ||
|
|
3d2877eeb9 | ||
|
|
e04919098f | ||
|
|
5d05aeaace | ||
|
|
142b6fcc00 | ||
|
|
91c0f4e2d9 | ||
|
|
89a93af1d5 | ||
|
|
ef07e2941c | ||
|
|
0c3a8dadf6 | ||
|
|
6425715daf | ||
|
|
be110fb38c | ||
|
|
d743206b8c | ||
|
|
af7a104f5b | ||
|
|
c0b73986cb | ||
|
|
c48049a3bb | ||
|
|
1cb6250f14 | ||
|
|
8ed6ee97b2 | ||
|
|
1d88371604 | ||
|
|
8685558a2a | ||
|
|
d372b27ccd | ||
|
|
88410e032f | ||
|
|
622885853d | ||
|
|
0d3c7a64e2 | ||
|
|
0c274a9a0b | ||
|
|
0e5f51f195 | ||
|
|
49369d6279 | ||
|
|
bd288bd18f | ||
|
|
cdb1138465 | ||
|
|
c8c6f8691f | ||
|
|
9441cf15c3 | ||
|
|
276ed7263c | ||
|
|
6b38ca3bd2 | ||
|
|
c7bf54807e | ||
|
|
b28811846a | ||
|
|
5561aa1d37 | ||
|
|
8c0111cb08 | ||
|
|
0dc8bd5520 | ||
|
|
acdf06bf5d | ||
|
|
5e78b1c23e | ||
|
|
088b7cde4f | ||
|
|
6a8aeb2501 | ||
|
|
9c326397d0 | ||
|
|
28d89bdd53 | ||
|
|
69ba419afd | ||
|
|
afbaa36fd3 | ||
|
|
346ea8c8a0 | ||
|
|
4448444d4b | ||
|
|
daefb926d9 | ||
|
|
0a5c73dee4 | ||
|
|
cb09ae3e84 | ||
|
|
3d76c916a5 | ||
|
|
0a5ffe9b73 | ||
|
|
325603bf41 | ||
|
|
3e3744753d | ||
|
|
5bc2fa187c | ||
|
|
0a9005f5ce | ||
|
|
5d491b8067 | ||
|
|
16b4a4fa80 | ||
|
|
f6e0eb4005 | ||
|
|
a3370a1d18 | ||
|
|
2770a853f6 | ||
|
|
bd4399b5fc | ||
|
|
432df2089c | ||
|
|
d9d922546f | ||
|
|
00167cd9ab | ||
|
|
1692516955 | ||
|
|
0bcf73f980 | ||
|
|
e68914f46b | ||
|
|
fd331480fc | ||
|
|
ccf4a0e5e5 | ||
|
|
77aa3e7e11 | ||
|
|
716d588ba9 | ||
|
|
83041b1c97 | ||
|
|
e6311edf53 | ||
|
|
617316e8d9 | ||
|
|
bd21b79959 | ||
|
|
732ff7ee58 | ||
|
|
f081d6a421 | ||
|
|
3592a94517 | ||
|
|
e5de16bb01 | ||
|
|
a62e831932 | ||
|
|
b35dd5a869 | ||
|
|
ec28bd93c3 | ||
|
|
c44b5bb03f | ||
|
|
313add715c | ||
|
|
56ea741126 | ||
|
|
9dbdd58311 | ||
|
|
2ca13e886a | ||
|
|
314efe4f68 | ||
|
|
ebd2de042d | ||
|
|
c46c551fee | ||
|
|
cecca854c0 | ||
|
|
d7df4fa5dc | ||
|
|
3651a101d0 | ||
|
|
a97a05b1ec | ||
|
|
ee2520e036 | ||
|
|
88150b2012 | ||
|
|
9161c71b51 | ||
|
|
d7f569b341 | ||
|
|
5dfa02b45f | ||
|
|
45e629c56b | ||
|
|
ee437ca2d7 | ||
|
|
0293d957b2 | ||
|
|
89069407d2 | ||
|
|
495b29bf21 | ||
|
|
ec5165d958 | ||
|
|
1da8ad3839 | ||
|
|
e97afb3433 | ||
|
|
a824a45602 | ||
|
|
20e546b496 | ||
|
|
bf8e18441a | ||
|
|
c5af9613fd | ||
|
|
9ce807069a | ||
|
|
aa4fa4cc85 | ||
|
|
727c69ffdd | ||
|
|
b7a28afe7e | ||
|
|
12bcee3b78 | ||
|
|
f3376601f2 | ||
|
|
ecea1ba241 | ||
|
|
81467c2e7e | ||
|
|
889f2fce6d | ||
|
|
ae6318cb5a | ||
|
|
19e653ef1b | ||
|
|
d6949a7a3c | ||
|
|
5050a01856 | ||
|
|
564f865a63 | ||
|
|
c1cb196365 | ||
|
|
ca0fcada42 | ||
|
|
8e87b639fa | ||
|
|
fccba24f0b | ||
|
|
62e32ea108 | ||
|
|
b17fe747fc | ||
|
|
ccc2d7d2da | ||
|
|
a528b45d60 | ||
|
|
0c84285473 | ||
|
|
1df7400ad5 | ||
|
|
1cb65438fe | ||
|
|
cd5dd131d5 | ||
|
|
f0e8ab8f31 | ||
|
|
bfdb09d29f | ||
|
|
a81e5dd8a5 | ||
|
|
ddb1fcf430 | ||
|
|
646726b385 | ||
|
|
d47a80c8e8 | ||
|
|
5f4e326985 | ||
|
|
18e747babf | ||
|
|
a3ec988d07 | ||
|
|
b992a448b1 | ||
|
|
c29f50b0d6 | ||
|
|
d30ba9654f | ||
|
|
3e3dc26e3f | ||
|
|
a78138ab61 | ||
|
|
8fd5f184b7 | ||
|
|
fe075ea795 | ||
|
|
37b6677608 | ||
|
|
b91809eaa4 | ||
|
|
ca214ffe78 | ||
|
|
715925795f | ||
|
|
17a48f6b9f | ||
|
|
5c7a1d1b05 | ||
|
|
46e51811e8 | ||
|
|
34df7f6bc8 | ||
|
|
e8331b23d9 | ||
|
|
1a92f99831 | ||
|
|
6c95828e6e | ||
|
|
14142c320a | ||
|
|
727260e69b | ||
|
|
ad804cc01e | ||
|
|
dab51d33f5 | ||
|
|
77d7a6180f | ||
|
|
185669ec72 | ||
|
|
e68debc94e | ||
|
|
18ed56b639 | ||
|
|
dc2bac0068 | ||
|
|
005ab58b15 | ||
|
|
c0ff12a7de | ||
|
|
b11b04ef67 | ||
|
|
c8aba303e8 | ||
|
|
555efa4b70 | ||
|
|
da3c6945ae | ||
|
|
12c8fe32d5 | ||
|
|
053d9df0fe | ||
|
|
595ab448be | ||
|
|
86fec106e0 | ||
|
|
b9b50bf7b4 | ||
|
|
9abd5bf743 | ||
|
|
31bf212a60 | ||
|
|
624ef272fd | ||
|
|
7c59afbca9 | ||
|
|
67a92d7dc2 | ||
|
|
369f4125e1 | ||
|
|
aebf654e15 | ||
|
|
d936ede790 | ||
|
|
cd4ded6132 | ||
|
|
1603b4b522 | ||
|
|
0eac514e52 | ||
|
|
63399fe975 | ||
|
|
bc03b4dff6 | ||
|
|
cb2a99bd0e | ||
|
|
2cc3922108 | ||
|
|
e771e1ea8a | ||
|
|
6afaec1d62 | ||
|
|
80b5f31256 | ||
|
|
c96e6822e1 | ||
|
|
e4781b8af0 | ||
|
|
f3dd2a8bfd | ||
|
|
9fe9c74021 | ||
|
|
09c6c3e804 | ||
|
|
f5023e3269 | ||
|
|
2db7f559e3 | ||
|
|
b696d3f960 | ||
|
|
bc454b4417 | ||
|
|
aa6a800d1a | ||
|
|
536d6e00d9 | ||
|
|
725a04b321 | ||
|
|
3ff8cc58e1 | ||
|
|
4fc8267264 | ||
|
|
0965fc45f2 | ||
|
|
181178b0ea | ||
|
|
95e6e80921 | ||
|
|
f36b71350d | ||
|
|
3483722475 | ||
|
|
56e63baf5a | ||
|
|
0830e66e76 | ||
|
|
74a5d3a25e | ||
|
|
4fb29e1b6b | ||
|
|
2c4f616213 | ||
|
|
75afe7cd33 | ||
|
|
80eb78033f | ||
|
|
68013e8fe7 | ||
|
|
7fe32301c4 | ||
|
|
41ddc7d33f | ||
|
|
eff5840645 | ||
|
|
ddf0242f56 | ||
|
|
eae5c65d3e | ||
|
|
c85b545f8d | ||
|
|
f24dc80c49 | ||
|
|
9a9de0038c | ||
|
|
35626d3929 | ||
|
|
c8f26dd968 | ||
|
|
7e5cb50925 | ||
|
|
ffa755c723 | ||
|
|
a060bf7223 | ||
|
|
4ab5d97e9b | ||
|
|
81babd29e7 | ||
|
|
fac76ddedd | ||
|
|
f34cc1861a | ||
|
|
bd4ed38a3c | ||
|
|
8644fed534 | ||
|
|
ca9fdadf3c | ||
|
|
228364e317 | ||
|
|
e65aee4533 | ||
|
|
a1ca607f35 | ||
|
|
efbf156f82 | ||
|
|
a2533e9a46 | ||
|
|
09742af92b | ||
|
|
880de53d59 | ||
|
|
91a24dd2eb | ||
|
|
60e91b018a | ||
|
|
9be37f7d2d | ||
|
|
be79fc1c92 | ||
|
|
502960bfeb | ||
|
|
d95a00df73 | ||
|
|
b3a9c1a100 | ||
|
|
4318d2d7d0 | ||
|
|
c3ff888981 | ||
|
|
7c85616dcf | ||
|
|
353a48d913 | ||
|
|
4e736e83a3 | ||
|
|
57583d6b00 | ||
|
|
98dcb32a0c | ||
|
|
fba5e3a46d | ||
|
|
2122304515 | ||
|
|
80dbebf0ad | ||
|
|
0c160eab7b | ||
|
|
4841502959 | ||
|
|
8218df82f2 | ||
|
|
fadc1b539b | ||
|
|
c8162324ed | ||
|
|
2c46378886 | ||
|
|
cf7e43fa26 | ||
|
|
b5e8b5a124 | ||
|
|
6fa0a21b3c | ||
|
|
c43637f6cc | ||
|
|
f48a430493 | ||
|
|
a1eb341817 | ||
|
|
cc2419911c | ||
|
|
2f5d3b073d | ||
|
|
4c0a7a9566 | ||
|
|
35514e0cc3 | ||
|
|
0f23edeec3 | ||
|
|
69e54cb9c1 | ||
|
|
60b8023928 | ||
|
|
8099ae44d7 | ||
|
|
46f88494e3 | ||
|
|
4818ac0750 | ||
|
|
d96429e6b8 | ||
|
|
9cda076c93 | ||
|
|
d30c761b3b | ||
|
|
49a0e8e242 | ||
|
|
8630c7a700 | ||
|
|
905fbeec14 | ||
|
|
e1ec8dfe4f | ||
|
|
93558f75f2 | ||
|
|
7a66c1a01c | ||
|
|
9f7b975064 | ||
|
|
8e8a0d2df6 | ||
|
|
d9f4fadf2d | ||
|
|
3f3fe6b178 | ||
|
|
2e95cd7a62 | ||
|
|
9be7345ba6 | ||
|
|
950edb1110 | ||
|
|
c4b3723372 | ||
|
|
119841a2c4 | ||
|
|
2df6f9cdda | ||
|
|
55868da9d3 | ||
|
|
460373803d | ||
|
|
abf9cce6bf | ||
|
|
d9c400ac32 | ||
|
|
377607730c | ||
|
|
6da5a8073c | ||
|
|
68ad513dd5 | ||
|
|
40ff78b1c8 | ||
|
|
477baf390b | ||
|
|
76834c0975 | ||
|
|
a3b7a88e9c | ||
|
|
ce36b09593 | ||
|
|
ebaac70b27 | ||
|
|
b4a6ed8d8f | ||
|
|
7c161f2d78 | ||
|
|
39dcfb4e5d | ||
|
|
34d87b7a72 | ||
|
|
f2d2cfec8f | ||
|
|
46625d207b | ||
|
|
f35112378f | ||
|
|
bb5ded4e65 | ||
|
|
b2f406f021 | ||
|
|
7821e2508c | ||
|
|
3e6cfe3275 | ||
|
|
588313b9ac | ||
|
|
50e4811e6d | ||
|
|
c182f95684 | ||
|
|
c241524663 | ||
|
|
9517c3500d | ||
|
|
1b8978fede | ||
|
|
5796cbc040 | ||
|
|
49726384f7 | ||
|
|
e7386735f4 | ||
|
|
ddfa653197 | ||
|
|
fffee1049f | ||
|
|
cc502163cb | ||
|
|
d53d92b890 | ||
|
|
218582ced8 | ||
|
|
bc1c19b4f7 | ||
|
|
85cea78b3c | ||
|
|
7a9027a147 | ||
|
|
66db3f9764 | ||
|
|
7e84343f16 | ||
|
|
e82e57a30c | ||
|
|
336c7ddca8 | ||
|
|
4ffcbc8274 | ||
|
|
22673ebd90 | ||
|
|
b1c0398bba | ||
|
|
6310517ff2 | ||
|
|
4ff3d6a645 | ||
|
|
23570cc5f7 | ||
|
|
dc09a5183a | ||
|
|
8458b9e7d6 | ||
|
|
51900996ea | ||
|
|
663da130ae | ||
|
|
c8b1724ecf | ||
|
|
c289af8f07 | ||
|
|
da7fa53b1a | ||
|
|
d160db1bcd | ||
|
|
a788cd9f64 | ||
|
|
6997e36670 | ||
|
|
1893b3ce0f | ||
|
|
576abecf7d | ||
|
|
b9b799533b | ||
|
|
70a01955b8 | ||
|
|
5f9409a91d | ||
|
|
32805ca968 | ||
|
|
8dfb0c6675 | ||
|
|
7428d42c16 | ||
|
|
99d9cb0b0d | ||
|
|
80ab60f1b6 | ||
|
|
a1d24028b8 | ||
|
|
d03f4dbc98 | ||
|
|
f1573654b9 | ||
|
|
e703103fa8 | ||
|
|
6241369b6c | ||
|
|
2a637e4220 | ||
|
|
816360c275 | ||
|
|
c541d7e349 | ||
|
|
df70d8661a | ||
|
|
c3daa969fa | ||
|
|
66a7c3bc4d | ||
|
|
3553b3ce3d | ||
|
|
9289c2de69 | ||
|
|
dac1612cb0 | ||
|
|
87d79c7415 | ||
|
|
86d7aaa03a | ||
|
|
cae31ab336 | ||
|
|
2aa01c58a1 | ||
|
|
ee852cf5fc | ||
|
|
5eb87b9f10 | ||
|
|
820a893d75 | ||
|
|
ce823e4b08 | ||
|
|
21830048c9 | ||
|
|
1251f9ec80 | ||
|
|
4839cbe9d0 | ||
|
|
702bfccfa2 | ||
|
|
28386cc496 | ||
|
|
0c1a7347db | ||
|
|
c06a03ab96 | ||
|
|
93dbcab10a | ||
|
|
5f12fbc2ee | ||
|
|
2443dc135c | ||
|
|
40c046f86b | ||
|
|
aee5c317f6 | ||
|
|
0fdafd8398 | ||
|
|
3ca3c67828 | ||
|
|
336bc2c0e6 | ||
|
|
d3a3f99848 | ||
|
|
d31935b8eb | ||
|
|
13928d4d35 | ||
|
|
212af78032 | ||
|
|
60472fcee3 | ||
|
|
c899eb4ee3 | ||
|
|
d090db380f | ||
|
|
a26f041964 | ||
|
|
b22bda3cba | ||
|
|
69e903a4c4 | ||
|
|
6f19fd5912 | ||
|
|
9c2f96f7eb | ||
|
|
4494ddd8ff | ||
|
|
5cb36a4632 | ||
|
|
9b7342b231 | ||
|
|
01ebc8f15a | ||
|
|
472baf7337 | ||
|
|
c381716ecf | ||
|
|
0e08c6c660 | ||
|
|
6da79ab614 | ||
|
|
a44a3195ab | ||
|
|
f78feb5abf | ||
|
|
4385acd3c6 | ||
|
|
c0927a3643 | ||
|
|
37692119e1 | ||
|
|
0f193141af | ||
|
|
24d5fc5f15 | ||
|
|
1ab8d58bf7 | ||
|
|
691bf75b35 | ||
|
|
63e23d7fe3 | ||
|
|
23d0db5458 | ||
|
|
71c62664cd | ||
|
|
c9faf5dd59 | ||
|
|
baf080f147 | ||
|
|
0e29ee9299 | ||
|
|
d52e5fab1e | ||
|
|
9f442eb7e4 | ||
|
|
0d94ca5399 | ||
|
|
13b900faf7 | ||
|
|
32ad75c5ab | ||
|
|
7a45653575 | ||
|
|
b316e97a4f | ||
|
|
6c7420f4e7 | ||
|
|
80a357623d | ||
|
|
0a4dfa8fd2 | ||
|
|
4604558d35 | ||
|
|
089ab9ee9f | ||
|
|
4fb804efc6 | ||
|
|
5b2ba448b6 | ||
|
|
899b5078eb | ||
|
|
edd423aad6 | ||
|
|
518e0f4e21 | ||
|
|
7546e53c23 | ||
|
|
0f9944190d | ||
|
|
18aca275c8 | ||
|
|
6d02ef59f8 | ||
|
|
729cea88f3 | ||
|
|
9b957a1fdb | ||
|
|
e18b0cd4c8 | ||
|
|
b51be8382f | ||
|
|
a95a1f1158 | ||
|
|
be8fc47c5f | ||
|
|
4fd76b09d9 | ||
|
|
6546c1da9b | ||
|
|
8f0b3983ee | ||
|
|
7f2ce045ab | ||
|
|
38f1fe7742 | ||
|
|
a099d2364d | ||
|
|
5f91084968 | ||
|
|
cb9321e925 | ||
|
|
716ff187f9 | ||
|
|
16365f2014 | ||
|
|
0fa03da18c | ||
|
|
a4a7d49bed | ||
|
|
0de319fc73 | ||
|
|
c06823dd47 | ||
|
|
f9944e6140 | ||
|
|
426815f7ab | ||
|
|
2a842e36a1 | ||
|
|
90dfabc644 | ||
|
|
f302c2ae39 | ||
|
|
93aee3946f | ||
|
|
4b7de5d802 | ||
|
|
78c63e6a18 | ||
|
|
dcda2bff69 | ||
|
|
372c4da8f9 | ||
|
|
a95025752a | ||
|
|
a16ffcdde2 | ||
|
|
3c2e521dd7 | ||
|
|
f28d9bcd8c | ||
|
|
c6039fc399 | ||
|
|
706494016c | ||
|
|
a653233050 | ||
|
|
ed5accd702 | ||
|
|
3a247be758 | ||
|
|
d417aedde0 | ||
|
|
967aaad482 | ||
|
|
9c4942b190 | ||
|
|
67fd07a92a | ||
|
|
533b0ed591 | ||
|
|
3f1a0baa84 | ||
|
|
8057c420d9 | ||
|
|
a3717436b6 | ||
|
|
7852e0b618 | ||
|
|
5afb16ab8d | ||
|
|
8187ec2cef | ||
|
|
d55d8ac091 | ||
|
|
e13c34c2b8 | ||
|
|
8630c8830a | ||
|
|
da3f34603a | ||
|
|
97a8ff3478 | ||
|
|
2548896656 | ||
|
|
572df007df | ||
|
|
440640bbbc | ||
|
|
563b7ad2d0 | ||
|
|
b180702c97 | ||
|
|
c3f4e734f1 | ||
|
|
61a56a0561 | ||
|
|
820fb6dda9 | ||
|
|
85db87a121 | ||
|
|
dc11b76bea | ||
|
|
2b9408c217 | ||
|
|
5e033773dd | ||
|
|
855681200f | ||
|
|
456564f377 | ||
|
|
828e16b45d | ||
|
|
9289ebf9c9 | ||
|
|
f4b6cc6628 | ||
|
|
853f7cc59a | ||
|
|
5841776c65 | ||
|
|
fbf47f75d5 | ||
|
|
1b42f69119 | ||
|
|
a1b532334e | ||
|
|
edac0e8023 | ||
|
|
498d3d5906 | ||
|
|
57152a8e29 | ||
|
|
35d4e2d4e0 | ||
|
|
fe42b15ec6 | ||
|
|
1d4a86594b | ||
|
|
072e583835 | ||
|
|
463133abbe | ||
|
|
34d6c69b2a | ||
|
|
14d36e3727 | ||
|
|
ed95f7dfa0 | ||
|
|
f93a10da48 | ||
|
|
31e623afb3 | ||
|
|
2080b3d7fa | ||
|
|
a8e06a67c2 | ||
|
|
42a79cb269 | ||
|
|
1ba9cd6138 | ||
|
|
37f3328147 | ||
|
|
df1ecad7e9 | ||
|
|
5699c3ae7d | ||
|
|
1877a02378 | ||
|
|
e9f344c53f | ||
|
|
d15763f2ad | ||
|
|
76eab44f53 | ||
|
|
3a373a200c | ||
|
|
f6e518d2f9 | ||
|
|
14f9f64bce | ||
|
|
c79a0108a1 | ||
|
|
20fcc5e31b | ||
|
|
01299421ee | ||
|
|
5729e33412 | ||
|
|
f85f39e662 | ||
|
|
0e9be57119 | ||
|
|
ffd7b5779b | ||
|
|
1d1d55e2b4 | ||
|
|
3cea8f24d4 | ||
|
|
d6a43a7729 | ||
|
|
cfeeec95fa | ||
|
|
e6cff61f99 | ||
|
|
eeb02ceef4 | ||
|
|
eaa0ec4fc3 | ||
|
|
91a719f80e | ||
|
|
06f67e4765 | ||
|
|
7530bfd1a1 | ||
|
|
abf6a3f91d | ||
|
|
21d3856e90 | ||
|
|
2304d0ec5c | ||
|
|
5cafe198bf | ||
|
|
4ce2690bd2 | ||
|
|
ea186ac48d | ||
|
|
9ab5a03f53 | ||
|
|
7650c8bca9 | ||
|
|
3728d2cfd9 | ||
|
|
3214ba4541 | ||
|
|
4232904055 | ||
|
|
baf8976c2d | ||
|
|
b3ae857f3c | ||
|
|
8be0dd0d8e | ||
|
|
166ea9deb9 | ||
|
|
7a16ef2cc4 | ||
|
|
a0cee13652 | ||
|
|
a3b434d2fe | ||
|
|
36ab05f003 | ||
|
|
35dee0c46e | ||
|
|
cb1858ecc8 | ||
|
|
10fbf36e92 | ||
|
|
3c3e97aa6e | ||
|
|
f353380e86 | ||
|
|
b1375e5ed1 | ||
|
|
44bcbc4823 | ||
|
|
a402a3ad12 | ||
|
|
343eb56cdf | ||
|
|
3efa8b6322 | ||
|
|
7cd72f344d | ||
|
|
066dfc71aa | ||
|
|
769cd9be3f | ||
|
|
0f9d6a1e4a | ||
|
|
3c742a0037 | ||
|
|
9a3d99515f | ||
|
|
f3447d187d | ||
|
|
276696414e | ||
|
|
7d41aca0e4 | ||
|
|
c71d8fe1cc | ||
|
|
cc261db606 | ||
|
|
7e17ed21ce | ||
|
|
b1f4b2d8ed | ||
|
|
9cb5f6d9d7 | ||
|
|
f3177d8878 | ||
|
|
3bc7b5bad9 | ||
|
|
b70064d1be | ||
|
|
ffca2ecf19 | ||
|
|
a32b6d5cf5 | ||
|
|
3ce087a716 | ||
|
|
15cdeef552 | ||
|
|
a038477ce0 | ||
|
|
b05e939e05 | ||
|
|
6347daf0ac | ||
|
|
327f4ca327 | ||
|
|
fe0d1034aa | ||
|
|
d982a3c94e | ||
|
|
259ca4a11e | ||
|
|
b9ae1fa429 | ||
|
|
0d32c1656a | ||
|
|
2defd311e1 | ||
|
|
d078cb264a | ||
|
|
c45a656153 | ||
|
|
1cef544cff | ||
|
|
67cef371dc | ||
|
|
2fcfa8d3eb | ||
|
|
03391b4f7a | ||
|
|
2dae95bf0b | ||
|
|
558fad1630 | ||
|
|
c2641458e7 | ||
|
|
bbdfdb978d | ||
|
|
4112061a47 | ||
|
|
25e9ddb4a4 | ||
|
|
66bf39db93 | ||
|
|
be439cb887 | ||
|
|
f3b601aa06 | ||
|
|
f6a6ead0f3 | ||
|
|
43c04df98a | ||
|
|
581a373dae | ||
|
|
ca197a915c | ||
|
|
061111d822 | ||
|
|
41003d106a | ||
|
|
c9b1e66c71 | ||
|
|
17e95cb615 | ||
|
|
b5c086aedb | ||
|
|
1036132838 | ||
|
|
1d1d82ca50 | ||
|
|
85be3e4ed1 | ||
|
|
d5d52ec8b9 | ||
|
|
ecb0d1f325 | ||
|
|
68436c93a7 | ||
|
|
2a9dff2846 | ||
|
|
bcd1837924 | ||
|
|
77508bfe0d | ||
|
|
cf517effb3 | ||
|
|
901a075a38 | ||
|
|
76d6820af9 | ||
|
|
7cf73c10ac | ||
|
|
71963aa738 | ||
|
|
dcc0dabe68 | ||
|
|
348e632dd6 | ||
|
|
067502bd66 | ||
|
|
6b576fcf5c | ||
|
|
2fc972a173 | ||
|
|
a941b1af4e | ||
|
|
fbc8a1cdcb | ||
|
|
f0fab80f5b | ||
|
|
a0740d1616 | ||
|
|
8986d15a5b | ||
|
|
9f4f22743f | ||
|
|
9eebd2c921 | ||
|
|
5ce71506c8 | ||
|
|
ad5b43f6db | ||
|
|
aa9855516f | ||
|
|
fcd4649642 | ||
|
|
e12246983b | ||
|
|
e8e7ad3b75 | ||
|
|
e9d648d37c | ||
|
|
eaeece8177 | ||
|
|
aa9a991a85 | ||
|
|
0d37431def | ||
|
|
44dfd7a803 | ||
|
|
d2809a0acb | ||
|
|
4b074d723e | ||
|
|
deb6abe50e | ||
|
|
d042ea5ab9 | ||
|
|
bc7c1e4d05 | ||
|
|
a4c5e7c2ee | ||
|
|
504d915723 | ||
|
|
039ea95390 | ||
|
|
5f32d2e56f | ||
|
|
5b716df45f | ||
|
|
66e2e60ac4 | ||
|
|
69dc09489b | ||
|
|
33a6abfc07 | ||
|
|
f277cbf3f3 | ||
|
|
0a56ab7a1e | ||
|
|
a073936997 | ||
|
|
5c1dd69963 | ||
|
|
c08dc64581 | ||
|
|
5916bbd5b3 | ||
|
|
8c104b52f9 | ||
|
|
7266cb653d | ||
|
|
2a8fd278c1 | ||
|
|
4c25ceff29 | ||
|
|
26f0b53bb2 | ||
|
|
101377d7f2 | ||
|
|
2487f55bbc | ||
|
|
f69e718151 | ||
|
|
5d516a8584 | ||
|
|
b1322fbe04 | ||
|
|
38a5e38f88 | ||
|
|
78fd05c1c6 | ||
|
|
6993c905e3 | ||
|
|
14f8ce6e15 | ||
|
|
d726eb354d | ||
|
|
1136c64d49 | ||
|
|
3f3179db0c | ||
|
|
d224a4c39f | ||
|
|
3eee442f28 | ||
|
|
7c90812e51 | ||
|
|
5c8bcf9379 | ||
|
|
d40456d6a9 | ||
|
|
8e203af344 | ||
|
|
31ead3f088 | ||
|
|
efaeb0f0b2 | ||
|
|
9db9638bc3 | ||
|
|
74c1476f6d | ||
|
|
24255be0bd | ||
|
|
0d89eb2c40 | ||
|
|
2350952d05 | ||
|
|
53e38cb1d2 | ||
|
|
f9c99a61d4 | ||
|
|
2178c8e4af | ||
|
|
8aacf30f19 | ||
|
|
745e97e0ab | ||
|
|
af5c0b3b71 | ||
|
|
d7a1f3104a | ||
|
|
8fb48d7952 | ||
|
|
1ac3de4aeb | ||
|
|
0c5ea5c3c0 | ||
|
|
78e4f1cde4 | ||
|
|
fb0b94eaa1 | ||
|
|
7291fef7cc | ||
|
|
6db46850eb | ||
|
|
7997295d4c | ||
|
|
6daee3a0b5 | ||
|
|
87f6793552 | ||
|
|
40786427b0 | ||
|
|
59b84ae1a4 | ||
|
|
aafd8a8da4 | ||
|
|
5ff66f6bfa | ||
|
|
e8873804c0 | ||
|
|
0f37521592 | ||
|
|
8ad1180321 | ||
|
|
ced03c5d99 | ||
|
|
161a54ceaa | ||
|
|
c159ac287f | ||
|
|
4ddd2bf980 | ||
|
|
1d9425ecdc | ||
|
|
495981bade | ||
|
|
672cf9fffe | ||
|
|
72e15d8b4f | ||
|
|
075b4d252a | ||
|
|
1953ecdf4d | ||
|
|
89f8151579 | ||
|
|
d9cc1d67c0 | ||
|
|
d178f4c75d | ||
|
|
0668a3bf2a | ||
|
|
d548b21be2 | ||
|
|
ebcd053bf3 | ||
|
|
b282464604 | ||
|
|
42dcecde14 | ||
|
|
aa0b344b55 | ||
|
|
fa77128026 | ||
|
|
7f1c5d8534 | ||
|
|
d2a31a6a0f | ||
|
|
fb9c911ae9 | ||
|
|
5bc569c4dd | ||
|
|
8397970bf8 | ||
|
|
6fc7b3d946 | ||
|
|
0fe7796df0 | ||
|
|
40b50332de | ||
|
|
9a50dfc4b5 | ||
|
|
09c18f474f | ||
|
|
51244c4388 | ||
|
|
898f162369 | ||
|
|
2529ef2f0b | ||
|
|
fc528941bd | ||
|
|
8e9ee90d9f | ||
|
|
b03c6f70fe | ||
|
|
42da681f2b | ||
|
|
44561e8cea | ||
|
|
37735b962e | ||
|
|
34ec3eac44 | ||
|
|
59c14d07fd | ||
|
|
86ffb744f5 | ||
|
|
fab7cfb113 | ||
|
|
2715947830 | ||
|
|
eb2f3387c5 | ||
|
|
2472cea69f | ||
|
|
2a634af2bc | ||
|
|
81654c9874 | ||
|
|
28914d4450 | ||
|
|
4000cce81c | ||
|
|
35ad366427 | ||
|
|
c257adb56a | ||
|
|
929e0c126d | ||
|
|
b293e4d516 | ||
|
|
6571cf2e89 | ||
|
|
aa739cdfd4 | ||
|
|
35c608ae77 | ||
|
|
8d8095a2d1 | ||
|
|
1740821bb4 | ||
|
|
4cd6829657 | ||
|
|
ef76c075e0 | ||
|
|
b260a61c8f | ||
|
|
780e526143 | ||
|
|
1e0269faa2 | ||
|
|
73465aa44b | ||
|
|
1f5fa03015 | ||
|
|
000e1012c6 | ||
|
|
afc5821809 | ||
|
|
e8832a86bb | ||
|
|
f61b8608de | ||
|
|
92f428b6d1 | ||
|
|
8795bf8cf9 | ||
|
|
0dee0bfada | ||
|
|
482d3bb913 | ||
|
|
48035977e3 | ||
|
|
6b23921880 | ||
|
|
c98e4eb478 | ||
|
|
7cd05ad76b | ||
|
|
fa327d618d | ||
|
|
bc202aec6e | ||
|
|
606ce4e66f | ||
|
|
a10c19456a | ||
|
|
20688661aa | ||
|
|
cbbd9f475e | ||
|
|
f4b3948168 | ||
|
|
2245d4506f | ||
|
|
7f3da135e2 | ||
|
|
23f94b6e67 | ||
|
|
0ec10b52e0 | ||
|
|
2fcd57410a | ||
|
|
a993a71857 | ||
|
|
01ce0e1d1a | ||
|
|
040a152f1f | ||
|
|
f4f2013c2b | ||
|
|
6e172bdc09 | ||
|
|
725ec57bee | ||
|
|
8a9234ba4f | ||
|
|
a00e4ebe3f | ||
|
|
2d93a011df | ||
|
|
bffe7aba8f | ||
|
|
b581408137 | ||
|
|
2263cd1355 | ||
|
|
1bb87c71aa | ||
|
|
7dec7d615a | ||
|
|
2e5308ad40 | ||
|
|
d1015de700 | ||
|
|
934318adb1 | ||
|
|
179c2b21c0 | ||
|
|
85f6d3fed8 | ||
|
|
a4925eeeb4 | ||
|
|
196200d03f | ||
|
|
f2ca0424a0 | ||
|
|
07b971ad5f | ||
|
|
51fa25e03d | ||
|
|
bd5f100f13 | ||
|
|
3b8da7e4c2 | ||
|
|
4a9a021b2c | ||
|
|
d4dd226d8f | ||
|
|
0d4237f802 | ||
|
|
46b9aca16e | ||
|
|
4931477ef4 | ||
|
|
dfdd1697c5 | ||
|
|
801f0d51a1 | ||
|
|
bdebb19648 | ||
|
|
75df0cbcf5 | ||
|
|
e23b4ce6b4 | ||
|
|
1b88a68b55 | ||
|
|
a82bc6738c | ||
|
|
868626c79c | ||
|
|
e4cc8bf828 | ||
|
|
f57fb17d2b | ||
|
|
a69170b0ba | ||
|
|
4066c2389d | ||
|
|
cd7b4fcd8e | ||
|
|
b0c963b650 | ||
|
|
f67995d5d3 | ||
|
|
f0e7344bc8 | ||
|
|
aa525c68c7 | ||
|
|
a2e25331a5 | ||
|
|
d8f09d377f | ||
|
|
cc96cb1c75 | ||
|
|
5966f04656 | ||
|
|
dbce9a8f29 | ||
|
|
4333552523 | ||
|
|
c00e945f6e | ||
|
|
56cb628ee8 | ||
|
|
827b6598b2 | ||
|
|
59bafea06d | ||
|
|
d61aca40b8 | ||
|
|
bf704d35a2 | ||
|
|
fbc8881a96 | ||
|
|
8cfb1efb01 | ||
|
|
f399b8466c | ||
|
|
437ba69049 | ||
|
|
dbc7e8e85d | ||
|
|
f3333ce941 | ||
|
|
97a9261096 | ||
|
|
5a76dab3c6 | ||
|
|
5a92d3f312 | ||
|
|
b173dd1c39 | ||
|
|
473e1a6f22 | ||
|
|
9c4a890688 | ||
|
|
a803c8bcc5 | ||
|
|
5c7ce18379 | ||
|
|
aff6fdfa84 | ||
|
|
477a652b44 | ||
|
|
15e0b42f04 | ||
|
|
b25ea9c863 | ||
|
|
c838cb03c9 | ||
|
|
ba9adc127e | ||
|
|
b7d603c4de | ||
|
|
71f1f3aa64 | ||
|
|
7d1c26202a | ||
|
|
80db2f6558 | ||
|
|
e376c79dda | ||
|
|
5a47e0d2e4 | ||
|
|
ca9143bebc | ||
|
|
a49f6799de | ||
|
|
d916ecc4f3 | ||
|
|
e1ed9aca10 | ||
|
|
0e2f1b9405 | ||
|
|
db5a2d2141 | ||
|
|
a9771dccba | ||
|
|
4849e07c26 | ||
|
|
4645e78fa7 | ||
|
|
9e2590eb15 | ||
|
|
94575a5cf6 | ||
|
|
a597a8d86b | ||
|
|
3287798efe | ||
|
|
d01ac17334 | ||
|
|
2c96727c45 | ||
|
|
ca1b2454bd | ||
|
|
064fc17ce3 | ||
|
|
43ccf9cb41 | ||
|
|
96857a197c | ||
|
|
079ff7785c | ||
|
|
d6a6cbe153 | ||
|
|
2486cfd45d | ||
|
|
30cb7286db | ||
|
|
9e7253c179 | ||
|
|
276a82d1f7 | ||
|
|
57ced9bc83 | ||
|
|
3c3662b032 | ||
|
|
f490b9a8bd | ||
|
|
c7ccedae95 | ||
|
|
03517459db | ||
|
|
96326280e5 | ||
|
|
9b7899780b | ||
|
|
e01cd057e8 | ||
|
|
ba85ca1991 | ||
|
|
92a9b71f21 | ||
|
|
e50c26d1b9 | ||
|
|
7090c24321 | ||
|
|
55319cd6d6 | ||
|
|
8a6b51441c | ||
|
|
36670b49a0 | ||
|
|
a402d848d2 | ||
|
|
37c563802c | ||
|
|
2d7032973c | ||
|
|
70b5f5bce3 | ||
|
|
be34af4555 | ||
|
|
815539a933 | ||
|
|
ab889e2945 | ||
|
|
b3231c8003 | ||
|
|
5f6cb34f77 | ||
|
|
a99a080c50 | ||
|
|
4a1ca8d582 | ||
|
|
050eb5660d | ||
|
|
13e59df1f8 | ||
|
|
c797944923 | ||
|
|
ade4e67b51 | ||
|
|
656f49f2ff | ||
|
|
0045244295 | ||
|
|
6bfb704f6f | ||
|
|
80cebdefcd | ||
|
|
68cd863fe0 | ||
|
|
65e5015d19 | ||
|
|
c26665ec4d | ||
|
|
91d82ebf4b | ||
|
|
303e4baa58 | ||
|
|
3c953d47ca | ||
|
|
5e629d5c09 | ||
|
|
c6ec2d4282 | ||
|
|
66b93a9af8 | ||
|
|
8d5479f55e | ||
|
|
96ce6c9504 | ||
|
|
0d55865545 | ||
|
|
a1fc383e6f | ||
|
|
c3807e175d | ||
|
|
6f83f76d41 | ||
|
|
9a56d619af | ||
|
|
f692d586f7 | ||
|
|
d3d3e99979 | ||
|
|
8e6a179efe | ||
|
|
17ff317d30 | ||
|
|
faef9f0049 | ||
|
|
bb0c831601 | ||
|
|
9462654738 | ||
|
|
e872169e4c | ||
|
|
a22404abe6 | ||
|
|
7c06313750 | ||
|
|
6f265f448d | ||
|
|
acdc41bd03 | ||
|
|
bcff2a7fb6 | ||
|
|
94188fddce | ||
|
|
3684e7f54a | ||
|
|
890181172f | ||
|
|
9c9d68561e | ||
|
|
1bd39ff935 | ||
|
|
17f3d2d581 | ||
|
|
55aa9e11db | ||
|
|
bc895eacc5 | ||
|
|
6c8eb4a19a | ||
|
|
887347106d | ||
|
|
419cf78984 | ||
|
|
aa339a8a9f | ||
|
|
a2f7aedd9c | ||
|
|
630379651e | ||
|
|
3d9b52fbc2 | ||
|
|
2e01c1f37e | ||
|
|
174abb352c | ||
|
|
85e028cab1 | ||
|
|
ff191c9404 | ||
|
|
31da01d4df | ||
|
|
6d45a94125 | ||
|
|
e7bfb04047 | ||
|
|
b9033d721c | ||
|
|
41c0343d33 | ||
|
|
aa8156a7fd | ||
|
|
e48adf7a07 | ||
|
|
8f214c51c0 | ||
|
|
096c4c78c7 | ||
|
|
257fce5a1b | ||
|
|
182bc7b8f9 | ||
|
|
3c35999246 | ||
|
|
340159b591 | ||
|
|
075fb2eaf2 | ||
|
|
21a2768ec3 | ||
|
|
554c840d4e | ||
|
|
9c28a1ba31 | ||
|
|
13fc921fa5 | ||
|
|
61f5d3972f | ||
|
|
5027bc743b | ||
|
|
9b8085220f | ||
|
|
54c04301cc | ||
|
|
cfd3bc823c | ||
|
|
329d95fd3a | ||
|
|
8dfef58f29 | ||
|
|
eeb4d3fe55 | ||
|
|
c6da4576b6 | ||
|
|
2417122ed3 | ||
|
|
e6c17e19d7 | ||
|
|
d98c2f89aa | ||
|
|
624991b9b7 | ||
|
|
c7ee776349 | ||
|
|
ffeacef394 | ||
|
|
f4ebec6759 | ||
|
|
93e3e4d2b1 | ||
|
|
3633049ba5 | ||
|
|
c566ed4643 | ||
|
|
af956f4d84 | ||
|
|
b70c72fc3b | ||
|
|
1f35694705 | ||
|
|
d912d96f00 | ||
|
|
94f8fb4a4b | ||
|
|
103744e2ca | ||
|
|
fe18a5de92 | ||
|
|
9b0394860d | ||
|
|
380c7628d8 | ||
|
|
f787a377c3 | ||
|
|
7c1b819728 | ||
|
|
8e5175e56b | ||
|
|
9e9d1a4e96 | ||
|
|
fd475423cf | ||
|
|
070911d458 | ||
|
|
3b585e6dbb | ||
|
|
2e893690bd | ||
|
|
d052b020fa | ||
|
|
ac6224563b | ||
|
|
a9630890fd | ||
|
|
4b889750db | ||
|
|
308bd0d81d | ||
|
|
d55a86e39b | ||
|
|
0c193c3ab7 | ||
|
|
6f513f5706 | ||
|
|
368bc91eed | ||
|
|
3a322c5c6e | ||
|
|
c5ee044343 | ||
|
|
19b918e56f | ||
|
|
cf5ed54c84 | ||
|
|
b813e1f7ab | ||
|
|
cdd8e52116 | ||
|
|
6945eb4186 | ||
|
|
1d9626d493 | ||
|
|
75b73f6821 | ||
|
|
f62f94381e | ||
|
|
cd6b3da665 | ||
|
|
25fb5d0ee6 | ||
|
|
65b2ca8f57 | ||
|
|
1ec07eb17a | ||
|
|
46fbf78da5 | ||
|
|
cea8d4a87d | ||
|
|
e07ba2c53d | ||
|
|
0af3f102aa | ||
|
|
a5b293401d | ||
|
|
05d0bda044 | ||
|
|
3dee3aba59 | ||
|
|
e732df46b8 | ||
|
|
86a8b231f4 | ||
|
|
10d359c222 | ||
|
|
1ef895e246 | ||
|
|
38ae370202 | ||
|
|
610a09817f | ||
|
|
c6938c9039 | ||
|
|
7a8fb8f430 | ||
|
|
3495591c5f | ||
|
|
050c31094b | ||
|
|
6a4668974b | ||
|
|
026d200add | ||
|
|
fe991ee767 | ||
|
|
b2a219f9d8 | ||
|
|
64810e0e0b | ||
|
|
6e5ed38b76 | ||
|
|
8d308ef2b8 | ||
|
|
ab76ae3778 | ||
|
|
222055fcff | ||
|
|
247d700c30 | ||
|
|
cf41d56c00 | ||
|
|
a8f7b1eb92 | ||
|
|
90d3ce4162 | ||
|
|
bc66b7f16e | ||
|
|
606708a96e | ||
|
|
2ec0d94c31 | ||
|
|
e6a17f78b6 | ||
|
|
d6b6d3f59f | ||
|
|
5932ddb0fe | ||
|
|
d1e5c2f86f | ||
|
|
1f2f25f7a3 | ||
|
|
b0edbf2857 | ||
|
|
91f0da9dcd | ||
|
|
3d5d60bc5b | ||
|
|
5c5599592a | ||
|
|
c60d09f3b2 | ||
|
|
5768c54c5b | ||
|
|
6d413e2492 | ||
|
|
331675d413 | ||
|
|
2105940286 | ||
|
|
90164dfee7 | ||
|
|
73f641cb66 | ||
|
|
3d51835b9b | ||
|
|
f358d76409 | ||
|
|
ce486e9244 | ||
|
|
691b7215a0 | ||
|
|
5be45d0ff2 | ||
|
|
8a4b326127 | ||
|
|
051374cd55 | ||
|
|
71cd92da29 | ||
|
|
c2d3a0c8b4 | ||
|
|
fe8b151666 | ||
|
|
9e2d67f7a1 | ||
|
|
23ea3745ca | ||
|
|
d8d5a8fada | ||
|
|
21ce0e90bf | ||
|
|
ec420b8012 | ||
|
|
bd67899943 | ||
|
|
4b7600f3a5 | ||
|
|
5eabd69659 | ||
|
|
e83be21756 | ||
|
|
13c58536be | ||
|
|
512dccdbfa | ||
|
|
bb3a8453e0 | ||
|
|
e337fcaadc | ||
|
|
890a149a5d | ||
|
|
5b3ac259ce | ||
|
|
ce50043048 | ||
|
|
ebfbf6082f | ||
|
|
b44bec2207 | ||
|
|
576ce21fc8 | ||
|
|
2ba015d0be | ||
|
|
98ae2ac96a | ||
|
|
1c25ed7666 | ||
|
|
fd4c7a4ed2 | ||
|
|
32d275c138 | ||
|
|
f8924286ce | ||
|
|
6e77345263 | ||
|
|
1438c64b9e | ||
|
|
2ff1256aef | ||
|
|
5d169854c4 | ||
|
|
e61d328cb0 | ||
|
|
0c196888fb | ||
|
|
85efed8308 | ||
|
|
857c88a951 | ||
|
|
74b0a7f6f8 | ||
|
|
5da5d00aec | ||
|
|
eb59fae9b0 | ||
|
|
b6b38d6f44 | ||
|
|
4f4d9e0ae3 | ||
|
|
43c1776594 | ||
|
|
397638998b | ||
|
|
6ddbda00df | ||
|
|
df0bf74bfe | ||
|
|
5ee0651f56 | ||
|
|
9ec1c28b35 | ||
|
|
bfdbf06731 | ||
|
|
ca58b30c47 | ||
|
|
0fb2f383ac | ||
|
|
5d0eb1d330 | ||
|
|
ee77144e2b | ||
|
|
9d3a2cc219 | ||
|
|
e964ac86d5 | ||
|
|
bb26b3d549 | ||
|
|
71c8d82c33 | ||
|
|
9fffe0d710 | ||
|
|
51f8b22dfa | ||
|
|
63a36a1054 | ||
|
|
057084a708 | ||
|
|
79b130ed23 | ||
|
|
75e8b16ea3 | ||
|
|
1b35708d89 | ||
|
|
ebff343a55 | ||
|
|
c7b91e5f19 | ||
|
|
b9d52dfaf7 | ||
|
|
2c8f66586f | ||
|
|
219bf564f7 | ||
|
|
291be6f5a6 | ||
|
|
1da2344aa3 | ||
|
|
750cf7ad20 | ||
|
|
962acd1537 | ||
|
|
7a44765860 | ||
|
|
007be8e52c | ||
|
|
5e4c98eae6 | ||
|
|
858a6dc27e | ||
|
|
ad5d14c672 | ||
|
|
199685a25b | ||
|
|
d99e243f57 | ||
|
|
64f1211cf8 | ||
|
|
9432f86e43 | ||
|
|
fc99d4d757 | ||
|
|
7fb2b21a22 | ||
|
|
260b300da9 | ||
|
|
f26d5b02cb | ||
|
|
c9ff061feb | ||
|
|
86ad318e6c | ||
|
|
df05339d2a | ||
|
|
ec1303a232 | ||
|
|
c1049734e6 | ||
|
|
99fa79caaf | ||
|
|
761062a6d7 | ||
|
|
11227b3ee1 | ||
|
|
8d63d50aea | ||
|
|
3360aa6c33 | ||
|
|
bfffd98fd4 | ||
|
|
9a86184a45 | ||
|
|
00828cb804 | ||
|
|
ec31a36fd9 | ||
|
|
9003c76261 | ||
|
|
7148f262c0 | ||
|
|
3ab417e291 | ||
|
|
4ced7b7657 | ||
|
|
ad69143573 | ||
|
|
4a71afaf96 | ||
|
|
a1b87f445b | ||
|
|
33e63f000a | ||
|
|
1c8b7955eb | ||
|
|
0bade29c25 | ||
|
|
4cff3e51cb | ||
|
|
d264c3d91e | ||
|
|
099fed07e9 | ||
|
|
091fec0867 | ||
|
|
a670268a6b | ||
|
|
caa44b3d4a | ||
|
|
f3977da8f3 | ||
|
|
7dc3184f31 | ||
|
|
d09c20aa01 | ||
|
|
81411e6b54 | ||
|
|
a8d1c73fec | ||
|
|
1b3742efbb | ||
|
|
e01bb09e8c | ||
|
|
2c9c0751a4 | ||
|
|
e10a7579e8 | ||
|
|
c52a04c7d3 | ||
|
|
79dd98b20e | ||
|
|
2e71429b03 | ||
|
|
4ab299d0af | ||
|
|
c60a941d1b | ||
|
|
e2197c586b | ||
|
|
93e9d3cb5f | ||
|
|
2e7b68bf74 | ||
|
|
6ffb198e9c | ||
|
|
604458810e | ||
|
|
af5ed093b8 | ||
|
|
8f491e7dbb | ||
|
|
c1324da3fc | ||
|
|
0bbc4462fd | ||
|
|
e0261e925e | ||
|
|
46b3f71b8f | ||
|
|
3e598a17cf | ||
|
|
c1b13f2db2 | ||
|
|
a059e49579 | ||
|
|
6d7df1c5e8 | ||
|
|
dd5715ce79 | ||
|
|
43acf3c5b1 | ||
|
|
f7db9e3527 | ||
|
|
1621a67f36 | ||
|
|
248631a1a8 | ||
|
|
b4cb6e10ca | ||
|
|
5fa73e4413 | ||
|
|
49c4b20113 | ||
|
|
43ece23b89 | ||
|
|
f976851442 | ||
|
|
5470dd74bd | ||
|
|
ddd178fa82 | ||
|
|
8d411cac5f | ||
|
|
bfbb85399e | ||
|
|
9f8a120664 | ||
|
|
e1cd6b6037 | ||
|
|
2fd4487922 | ||
|
|
27a459b0dd | ||
|
|
6c344d4ae2 | ||
|
|
d7aa9952d8 | ||
|
|
09093c8f3e | ||
|
|
222bf09df4 | ||
|
|
3041ff8d25 | ||
|
|
bfe1952705 | ||
|
|
97181a39da | ||
|
|
39b3d3de0f | ||
|
|
056d16017f | ||
|
|
5cef0aef92 | ||
|
|
f794de5b9b | ||
|
|
4a67af9b90 | ||
|
|
f178dff4e0 | ||
|
|
ba821cb02f | ||
|
|
b169831810 | ||
|
|
06b3c71304 | ||
|
|
fe94f4cbb4 | ||
|
|
a4daa49f70 | ||
|
|
3b1d534f6d | ||
|
|
c1777b1098 | ||
|
|
c827a29a7b | ||
|
|
253b219d67 | ||
|
|
b702f3daf1 | ||
|
|
76c9f46438 | ||
|
|
c6c203da43 | ||
|
|
00302b74d1 | ||
|
|
32f6f18527 | ||
|
|
4fd0446538 | ||
|
|
082ad61d14 | ||
|
|
0ca4faa25b | ||
|
|
46a0566e2e | ||
|
|
97440d45d6 | ||
|
|
c5afe4e745 | ||
|
|
bc6e819396 | ||
|
|
d650a97dda | ||
|
|
cf88eb9d60 | ||
|
|
0a742ea8d0 | ||
|
|
cb8935746f | ||
|
|
608ac953e5 | ||
|
|
4d0d0b205d | ||
|
|
07b643e24c | ||
|
|
02fb020dfd | ||
|
|
bac6ebdf95 | ||
|
|
b7072d4097 | ||
|
|
d7c7bb00b8 | ||
|
|
0485f0c7ed | ||
|
|
2ade6c0739 | ||
|
|
5eeb19871b | ||
|
|
083a0ae5fc | ||
|
|
ccc370e1c4 | ||
|
|
23b8cafc41 | ||
|
|
d7ab96856c | ||
|
|
3c77229f61 | ||
|
|
fcd206891f | ||
|
|
3bf9130b0a | ||
|
|
4125ac013f | ||
|
|
e089e9c121 | ||
|
|
81af379bbc | ||
|
|
9b07aa6894 | ||
|
|
a75140c6d7 | ||
|
|
f3364cfdc0 | ||
|
|
f64b4e0e56 | ||
|
|
a1356d3bcf | ||
|
|
4c5a1ceefa | ||
|
|
e4b4a35375 | ||
|
|
cc2afef390 | ||
|
|
7c5706ead9 | ||
|
|
bcb739fcd2 | ||
|
|
85ef3724f1 | ||
|
|
cb21422836 | ||
|
|
1c9674cec9 | ||
|
|
6dcc09a96f | ||
|
|
0260c9d3fb | ||
|
|
80c03f28f8 | ||
|
|
eeaf67079a | ||
|
|
c50863c0d5 | ||
|
|
f4ab6542fa | ||
|
|
dfbe1bd234 | ||
|
|
1e89cdc055 | ||
|
|
7a40959f13 | ||
|
|
2b4d55804c | ||
|
|
858dac5601 | ||
|
|
e944945b7a | ||
|
|
920151a460 | ||
|
|
ac2a01fb09 | ||
|
|
a7933018cb | ||
|
|
5ee889eadd | ||
|
|
e811f03011 | ||
|
|
417c81de60 | ||
|
|
212c653165 | ||
|
|
e36f11385f | ||
|
|
abb05f4883 | ||
|
|
2973f33959 | ||
|
|
053c2ed2b9 | ||
|
|
1865570390 | ||
|
|
ba1ee7e6cc | ||
|
|
f6b0fcbc0f | ||
|
|
a802058886 | ||
|
|
bbc1f68966 | ||
|
|
ca0b42c3bd | ||
|
|
9536a475ff | ||
|
|
cfd731c376 | ||
|
|
de1015f6ac | ||
|
|
6c0730fef4 | ||
|
|
c73132610e | ||
|
|
77abaaf8b8 | ||
|
|
2787e86fd7 | ||
|
|
355808b0f6 | ||
|
|
80c13fa75b | ||
|
|
9a6c2aa1ea | ||
|
|
63d76ee837 | ||
|
|
7c48db7da8 | ||
|
|
bd8d5f6288 | ||
|
|
7413b7c4f6 | ||
|
|
80e3c871ce | ||
|
|
74c1e02274 | ||
|
|
efb0f6f24a | ||
|
|
dbf8580dc3 | ||
|
|
f110a01ffe | ||
|
|
eced40a761 | ||
|
|
5ac315bc3a | ||
|
|
32df4daa63 | ||
|
|
5836e456e5 | ||
|
|
dc6ab69387 | ||
|
|
7301c56753 | ||
|
|
3b76d657bd | ||
|
|
2adb6240e4 | ||
|
|
e11af496da | ||
|
|
f6e33406d7 | ||
|
|
6eab138d68 | ||
|
|
33287115de | ||
|
|
8e36056dd8 | ||
|
|
4a34f596a8 | ||
|
|
7616a3e743 | ||
|
|
c64353c324 | ||
|
|
8eac22d37a | ||
|
|
35fab12330 | ||
|
|
a46988bc50 | ||
|
|
26e1d6fe5c | ||
|
|
ec68739585 | ||
|
|
33de0f821f | ||
|
|
86ce11134a | ||
|
|
bef4905416 | ||
|
|
baa8152248 | ||
|
|
34fe103c2b | ||
|
|
0d08014bd5 | ||
|
|
dd0130180b | ||
|
|
accdf9a6a8 | ||
|
|
c891432c9d | ||
|
|
1a4efd9d81 | ||
|
|
bf462e535a | ||
|
|
5cf228e362 | ||
|
|
4dcccc553c | ||
|
|
7e53db8aac | ||
|
|
4a83584934 | ||
|
|
c735d1f6ac | ||
|
|
7bd0fdf3da | ||
|
|
b570dfcd09 | ||
|
|
2bc35539f0 | ||
|
|
80e05319c6 | ||
|
|
49459b3774 | ||
|
|
0788032003 | ||
|
|
d4c7c205cb | ||
|
|
96ce33792d | ||
|
|
13bf8a20b0 | ||
|
|
6b9b478492 | ||
|
|
c4e8bcb876 | ||
|
|
28b4fe5cb6 | ||
|
|
58b5e645c6 | ||
|
|
3e00ee4155 | ||
|
|
d1169a0f37 | ||
|
|
c8c22d3dd2 | ||
|
|
689fd03250 | ||
|
|
56fe6480ce | ||
|
|
017d5f2991 | ||
|
|
ae43b1565e | ||
|
|
3206e1b12c | ||
|
|
93d4eca2d4 | ||
|
|
57b5e493a4 | ||
|
|
fc184984a0 | ||
|
|
2178ff1c48 | ||
|
|
ae1df38c88 | ||
|
|
162e498347 | ||
|
|
172023afca | ||
|
|
18c7ea50b4 | ||
|
|
bdddb238f8 | ||
|
|
8d46237935 | ||
|
|
3fcf83e685 | ||
|
|
d374af4341 | ||
|
|
f32ad617a2 | ||
|
|
62656b24eb | ||
|
|
12763e19d8 | ||
|
|
89fd726e07 | ||
|
|
0b428987b1 | ||
|
|
1e29fad5f0 | ||
|
|
19524a4459 | ||
|
|
7043d565c9 | ||
|
|
d6f856f2f2 | ||
|
|
24f0451c10 | ||
|
|
3c4460ca98 | ||
|
|
cbf33fa14b | ||
|
|
d782654819 | ||
|
|
3c39cbf333 | ||
|
|
bd746e5151 | ||
|
|
b32c346eed | ||
|
|
77b8e204ad | ||
|
|
93dfe19c35 | ||
|
|
6dc8df5178 | ||
|
|
237fd73702 | ||
|
|
5f2d0142d1 | ||
|
|
572d576d5b | ||
|
|
6606f51636 | ||
|
|
36da65120a | ||
|
|
b6c1e1a609 | ||
|
|
5d003ec772 | ||
|
|
b9210a2ba4 | ||
|
|
f3c559ea13 | ||
|
|
6cee6b6429 | ||
|
|
84f6aabf5b | ||
|
|
9ce947d6ea | ||
|
|
0f23ad0d7e | ||
|
|
1b760b6c53 | ||
|
|
cdf64bf016 | ||
|
|
f3726023c2 | ||
|
|
cb41683f47 | ||
|
|
629a8ad055 | ||
|
|
4ba0fa00b4 | ||
|
|
f1e73c015a | ||
|
|
926c3540ff | ||
|
|
1aebd83e45 | ||
|
|
8225351145 | ||
|
|
379add8d6f | ||
|
|
ea11ce8664 | ||
|
|
82e9e96f0c |
5
.gitattributes
vendored
@@ -7,6 +7,11 @@ kitty/rgb.py linguist-generated=true
|
||||
kitty/gl-wrapper.* linguist-generated=true
|
||||
kitty/glfw-wrapper.* linguist-generated=true
|
||||
kitty/parse-graphics-command.h linguist-generated=true
|
||||
kitty/options/types.py linguist-generated=true
|
||||
kitty/options/parse.py linguist-generated=true
|
||||
kitty/options/to-c-generated.h linguist-generated=true
|
||||
kittens/diff/options/types.py linguist-generated=true
|
||||
kittens/diff/options/parse.py linguist-generated=true
|
||||
glfw/*.c linguist-vendored=true
|
||||
glfw/*.h linguist-vendored=true
|
||||
kittens/unicode_input/names.h linguist-generated=true
|
||||
|
||||
1
.github/FUNDING.yml
vendored
@@ -1,3 +1,4 @@
|
||||
github: kovidgoyal
|
||||
patreon: kovidgoyal
|
||||
liberapay: kovidgoyal
|
||||
custom: https://sw.kovidgoyal.net/kitty/support.html
|
||||
|
||||
10
.github/ISSUE_TEMPLATE/bug_report.md
vendored
@@ -17,17 +17,15 @@ Steps to reproduce the behavior:
|
||||
3. ZZZ
|
||||
4. See error
|
||||
|
||||
**Expected behavior**
|
||||
A clear and concise description of what you expected to happen.
|
||||
|
||||
**Screenshots**
|
||||
If applicable, add screenshots to help explain your problem.
|
||||
|
||||
**Environment details**
|
||||
OS: Name and version of operating system(s)
|
||||
|
||||
```
|
||||
Output of kitty --debug-config
|
||||
Press Ctrl+Shift+F6 (cmd+option+comma on macOS) in kitty, to copy debug output about kitty and its
|
||||
configuration to the clipboard and paste it here.
|
||||
|
||||
On older versions of kitty, run kitty --debug-config instead
|
||||
```
|
||||
|
||||
**Additional context**
|
||||
|
||||
11
.github/workflows/ci.py
vendored
@@ -34,18 +34,15 @@ def install_deps():
|
||||
run('brew', 'install', *items)
|
||||
else:
|
||||
run('sudo apt-get update')
|
||||
run('sudo apt-get install -y libgl1-mesa-dev libxi-dev libxrandr-dev libxinerama-dev'
|
||||
run('sudo apt-get install -y libgl1-mesa-dev libxi-dev libxrandr-dev libxinerama-dev ca-certificates'
|
||||
' libxcursor-dev libxcb-xkb-dev libdbus-1-dev libxkbcommon-dev libharfbuzz-dev libx11-xcb-dev'
|
||||
' libpng-dev liblcms2-dev libfontconfig-dev libxkbcommon-x11-dev libcanberra-dev uuid-dev')
|
||||
' libpng-dev liblcms2-dev libfontconfig-dev libxkbcommon-x11-dev libcanberra-dev librsync-dev uuid-dev')
|
||||
if is_bundle:
|
||||
install_bundle()
|
||||
else:
|
||||
if is_macos:
|
||||
# needed for zlib for pillow, should not be needed after pillow 8.0
|
||||
os.environ['PKG_CONFIG_PATH'] = '/usr/local/opt/zlib/lib/pkgconfig'
|
||||
cmd = 'pip3 install Pillow pygments'
|
||||
cmd = 'python3 -m pip install Pillow pygments'
|
||||
if sys.version_info[:2] < (3, 7):
|
||||
cmd += ' importlib-resources'
|
||||
cmd += ' importlib-resources dataclasses'
|
||||
run(cmd)
|
||||
|
||||
|
||||
|
||||
8
.github/workflows/ci.yml
vendored
@@ -20,15 +20,15 @@ jobs:
|
||||
cc: [gcc, clang]
|
||||
include:
|
||||
- python: a
|
||||
pyver: 3.6
|
||||
pyver: 3.7
|
||||
sanitize: 0
|
||||
|
||||
- python: b
|
||||
pyver: 3.7
|
||||
pyver: 3.8
|
||||
sanitize: 1
|
||||
|
||||
- python: c
|
||||
pyver: 3.8
|
||||
pyver: 3.9
|
||||
sanitize: 1
|
||||
|
||||
|
||||
@@ -76,7 +76,7 @@ jobs:
|
||||
python-version: 3.8
|
||||
|
||||
- name: Install build-only deps
|
||||
run: pip install flake8 mypy sphinx
|
||||
run: pip install -r docs/requirements.txt flake8 mypy types-requests types-docutils
|
||||
|
||||
- name: Run pyflakes
|
||||
run: python -m flake8 --count .
|
||||
|
||||
10
.github/workflows/codeql-analysis.yml
vendored
@@ -22,17 +22,11 @@ jobs:
|
||||
# a pull request then we can checkout the head.
|
||||
fetch-depth: 2
|
||||
|
||||
# If this run was triggered by a pull request event, then checkout
|
||||
# the head of the pull request instead of the merge commit.
|
||||
- run: git checkout HEAD^2
|
||||
if: ${{ github.event_name == 'pull_request' }}
|
||||
|
||||
# Initializes the CodeQL tools for scanning.
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v1
|
||||
# Override language selection by uncommenting this and choosing your languages
|
||||
# with:
|
||||
# languages: go, javascript, csharp, python, cpp, java
|
||||
with:
|
||||
languages: python, c
|
||||
|
||||
- name: Build kitty
|
||||
run: python3 .github/workflows/ci.py build
|
||||
|
||||
1
.gitignore
vendored
@@ -19,3 +19,4 @@ __pycache__/
|
||||
/.mypy_cache
|
||||
.DS_Store
|
||||
bypy/b
|
||||
bypy/virtual-machines.conf
|
||||
|
||||
@@ -1 +1 @@
|
||||
See https://sw.kovidgoyal.net/kitty/changelog.html
|
||||
See https://sw.kovidgoyal.net/kitty/changelog/
|
||||
|
||||
@@ -10,9 +10,9 @@ config to reproduce the issue with).
|
||||
|
||||
### Contributing code
|
||||
|
||||
Install [the dependencies](https://sw.kovidgoyal.net/kitty/build.html#dependencies)
|
||||
Install [the dependencies](https://sw.kovidgoyal.net/kitty/build/#dependencies)
|
||||
using your favorite package manager. Build and run kitty [from
|
||||
source](https://sw.kovidgoyal.net/kitty/build.html#install-and-run-from-source).
|
||||
source](https://sw.kovidgoyal.net/kitty/build/#install-and-run-from-source).
|
||||
|
||||
Make a fork, submit your Pull Request. If it's a large/controversial change, open an issue
|
||||
beforehand to discuss it, so that you don't waste your time making a pull
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
To build from source: <https://sw.kovidgoyal.net/kitty/build.html>
|
||||
[To build from source](https://sw.kovidgoyal.net/kitty/build/)
|
||||
|
||||
Pre-built binaries: <https://sw.kovidgoyal.net/kitty/binary.html>
|
||||
[Pre-built binaries](https://sw.kovidgoyal.net/kitty/binary/)
|
||||
|
||||
2
LICENSE
@@ -671,4 +671,4 @@ into proprietary programs. If your program is a subroutine library, you
|
||||
may consider it more useful to permit linking proprietary applications with
|
||||
the library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License. But first, please read
|
||||
<https://www.gnu.org/philosophy/why-not-lgpl.html>.
|
||||
<https://www.gnu.org/licenses/why-not-lgpl.html>.
|
||||
|
||||
7
Makefile
@@ -40,4 +40,11 @@ html:
|
||||
linkcheck:
|
||||
$(MAKE) FAIL_WARN=$(FAIL_WARN) -C docs linkcheck
|
||||
|
||||
website:
|
||||
./publish.py --only website
|
||||
|
||||
docs: man html
|
||||
|
||||
|
||||
develop-docs:
|
||||
$(MAKE) -C docs develop-docs
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
= kitty - the fast, feature-rich, cross-platform, GPU based terminal
|
||||
|
||||
See https://sw.kovidgoyal.net/kitty/
|
||||
See https://sw.kovidgoyal.net/kitty/[the kitty website].
|
||||
|
||||
image:https://github.com/kovidgoyal/kitty/workflows/CI/badge.svg["Build status", link="https://github.com/kovidgoyal/kitty/actions?query=workflow%3ACI"]
|
||||
|
||||
To ask questions about kitty usage, use either the https://github.com/kovidgoyal/kitty/discussions/[discussions on GitHub] or the
|
||||
https://sw.kovidgoyal.net/kitty/faq/[Frequently Asked Questions]
|
||||
|
||||
To ask other questions about kitty usage, use either the https://github.com/kovidgoyal/kitty/discussions/[discussions on GitHub] or the
|
||||
https://www.reddit.com/r/KittyTerminal[Reddit community]
|
||||
|
||||
Packaging status in various repositories:
|
||||
|
||||
57
__main__.py
@@ -1,9 +1,8 @@
|
||||
#!/usr/bin/env python3
|
||||
# vim:fileencoding=utf-8
|
||||
# License: GPL v3 Copyright: 2015, Kovid Goyal <kovid at kovidgoyal.net>
|
||||
|
||||
import sys
|
||||
import os
|
||||
import sys
|
||||
from typing import List
|
||||
|
||||
|
||||
@@ -24,14 +23,16 @@ def remote_control(args: List[str]) -> None:
|
||||
|
||||
|
||||
def runpy(args: List[str]) -> None:
|
||||
if len(args) < 2:
|
||||
raise SystemExit('Usage: kitty +runpy "some python code"')
|
||||
sys.argv = ['kitty'] + args[2:]
|
||||
exec(args[1])
|
||||
|
||||
|
||||
def hold(args: List[str]) -> None:
|
||||
import subprocess
|
||||
from contextlib import suppress
|
||||
import tty
|
||||
from contextlib import suppress
|
||||
ret = subprocess.Popen(args[1:]).wait()
|
||||
with suppress(BaseException):
|
||||
print('\n\x1b[1;32mPress any key to exit', end='', flush=True)
|
||||
@@ -49,13 +50,22 @@ def complete(args: List[str]) -> None:
|
||||
def launch(args: List[str]) -> None:
|
||||
import runpy
|
||||
sys.argv = args[1:]
|
||||
exe = args[1]
|
||||
try:
|
||||
exe = args[1]
|
||||
except IndexError:
|
||||
raise SystemExit(
|
||||
'usage: kitty +launch script.py [arguments to be passed to script.py ...]\n\n'
|
||||
'script.py will be run with full access to kitty code. If script.py is '
|
||||
'prefixed with a : it will be searched for in PATH'
|
||||
)
|
||||
if exe.startswith(':'):
|
||||
import shutil
|
||||
q = shutil.which(exe[1:])
|
||||
if not q:
|
||||
raise SystemExit('{} not found in PATH'.format(args[1][1:]))
|
||||
raise SystemExit(f'{exe[1:]} not found in PATH')
|
||||
exe = q
|
||||
if not os.path.exists(exe):
|
||||
raise SystemExit(f'{exe} does not exist')
|
||||
runpy.run_path(exe, run_name='__main__')
|
||||
|
||||
|
||||
@@ -72,13 +82,22 @@ def run_kitten(args: List[str]) -> None:
|
||||
|
||||
|
||||
def edit_config_file(args: List[str]) -> None:
|
||||
from kitty.cli import create_default_opts
|
||||
from kitty.fast_data_types import set_options
|
||||
from kitty.utils import edit_config_file as f
|
||||
set_options(create_default_opts())
|
||||
f()
|
||||
|
||||
|
||||
def namespaced(args: List[str]) -> None:
|
||||
func = namespaced_entry_points[args[1]]
|
||||
func(args[1:])
|
||||
try:
|
||||
func = namespaced_entry_points[args[1]]
|
||||
except KeyError:
|
||||
pass
|
||||
else:
|
||||
func(args[1:])
|
||||
return
|
||||
raise SystemExit(f'{args[1]} is not a known entry point. Choices are: ' + ', '.join(namespaced_entry_points))
|
||||
|
||||
|
||||
entry_points = {
|
||||
@@ -99,21 +118,21 @@ namespaced_entry_points['complete'] = complete
|
||||
|
||||
|
||||
def setup_openssl_environment() -> None:
|
||||
# Workaround for Linux distros that have still failed to get their heads
|
||||
# out of their asses and implement a common location for SSL certificates.
|
||||
# It's not that hard people, there exists a wonderful tool called the symlink
|
||||
# See https://www.mobileread.com/forums/showthread.php?t=256095
|
||||
if 'SSL_CERT_FILE' not in os.environ and 'SSL_CERT_DIR' not in os.environ:
|
||||
if os.access('/etc/pki/tls/certs/ca-bundle.crt', os.R_OK):
|
||||
os.environ['SSL_CERT_FILE'] = '/etc/pki/tls/certs/ca-bundle.crt'
|
||||
setattr(sys, 'kitty_ssl_env_var', 'SSL_CERT_FILE')
|
||||
elif os.path.isdir('/etc/ssl/certs'):
|
||||
os.environ['SSL_CERT_DIR'] = '/etc/ssl/certs'
|
||||
setattr(sys, 'kitty_ssl_env_var', 'SSL_CERT_DIR')
|
||||
# Use our bundled CA certificates instead of the system ones, since
|
||||
# many systems come with no certificates in a useable form or have various
|
||||
# locations for the certificates.
|
||||
d = os.path.dirname
|
||||
ext_dir: str = getattr(sys, 'kitty_extensions_dir')
|
||||
if 'darwin' in sys.platform.lower():
|
||||
cert_file = os.path.join(d(d(d(ext_dir))), 'cacert.pem')
|
||||
else:
|
||||
cert_file = os.path.join(d(ext_dir), 'cacert.pem')
|
||||
os.environ['SSL_CERT_FILE'] = cert_file
|
||||
setattr(sys, 'kitty_ssl_env_var', 'SSL_CERT_FILE')
|
||||
|
||||
|
||||
def main() -> None:
|
||||
if getattr(sys, 'frozen', False) and 'darwin' not in sys.platform.lower():
|
||||
if getattr(sys, 'frozen', False) and getattr(sys, 'kitty_extensions_dir', ''):
|
||||
setup_openssl_environment()
|
||||
first_arg = '' if len(sys.argv) < 2 else sys.argv[1]
|
||||
func = entry_points.get(first_arg)
|
||||
|
||||
@@ -30,6 +30,7 @@ def initialize_constants():
|
||||
kitty_constants['appname'] = re.search(
|
||||
r'appname: str\s+=\s+(u{0,1})[\'"]([^\'"]+)[\'"]', src
|
||||
).group(2)
|
||||
kitty_constants['cacerts_url'] = 'https://curl.haxx.se/ca/cacert.pem'
|
||||
return kitty_constants
|
||||
|
||||
|
||||
@@ -46,9 +47,12 @@ def run(*args, **extra_env):
|
||||
return subprocess.call(list(args), env=env, cwd=cwd)
|
||||
|
||||
|
||||
SETUP_CMD = [PYTHON, 'setup.py', '--build-universal-binary']
|
||||
|
||||
|
||||
def build_frozen_launcher(extra_include_dirs):
|
||||
inc_dirs = [f'--extra-include-dirs={x}' for x in extra_include_dirs]
|
||||
cmd = [PYTHON, 'setup.py', '--prefix', build_frozen_launcher.prefix] + inc_dirs + ['build-frozen-launcher']
|
||||
cmd = SETUP_CMD + ['--prefix', build_frozen_launcher.prefix] + inc_dirs + ['build-frozen-launcher']
|
||||
if run(*cmd, cwd=build_frozen_launcher.writeable_src_dir) != 0:
|
||||
print('Building of frozen kitty launcher failed', file=sys.stderr)
|
||||
os.chdir(KITTY_DIR)
|
||||
@@ -89,7 +93,7 @@ def build_c_extensions(ext_dir, args):
|
||||
with suppress(FileNotFoundError):
|
||||
os.unlink(os.path.join(writeable_src_dir, 'kitty', 'launcher', 'kitty'))
|
||||
|
||||
cmd = [PYTHON, 'setup.py', 'macos-freeze' if ismacos else 'linux-freeze']
|
||||
cmd = SETUP_CMD + ['macos-freeze' if ismacos else 'linux-freeze']
|
||||
if args.dont_strip:
|
||||
cmd.append('--debug')
|
||||
dest = kitty_constants['appname'] + ('.app' if ismacos else '')
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
image 'https://partner-images.canonical.com/core/xenial/current/ubuntu-xenial-core-cloudimg-{}-root.tar.gz'
|
||||
image 'https://cloud-images.ubuntu.com/releases/bionic/release/ubuntu-18.04-server-cloudimg-{}.img'
|
||||
|
||||
deps 'bison flex libxcursor-dev libxrandr-dev libxi-dev libxinerama-dev libgl1-mesa-dev libxcb-xkb-dev libfontconfig1-dev libdbus-1-dev'
|
||||
|
||||
@@ -19,7 +19,11 @@ from bypy.freeze import (
|
||||
from bypy.utils import get_dll_path, mkdtemp, py_compile, walk
|
||||
|
||||
j = os.path.join
|
||||
arch = 'x86_64' if is64bit else 'i686'
|
||||
machine = (os.uname()[4] or '').lower()
|
||||
if machine.startswith('arm64') or machine.startswith('aarch64'):
|
||||
arch = 'arm64'
|
||||
else:
|
||||
arch = 'x86_64' if is64bit else 'i686'
|
||||
self_dir = os.path.dirname(os.path.abspath(__file__))
|
||||
py_ver = '.'.join(map(str, python_major_minor_version()))
|
||||
iv = globals()['init_env']
|
||||
@@ -29,9 +33,9 @@ kitty_constants = iv['kitty_constants']
|
||||
def binary_includes():
|
||||
return tuple(map(get_dll_path, (
|
||||
'expat', 'sqlite3', 'ffi', 'z', 'lzma', 'png16', 'lcms2', 'crypt',
|
||||
'iconv', 'pcre', 'graphite2', 'glib-2.0', 'freetype',
|
||||
'iconv', 'pcre', 'graphite2', 'glib-2.0', 'freetype', 'rsync',
|
||||
'harfbuzz', 'xkbcommon', 'xkbcommon-x11',
|
||||
'ncursesw', 'readline',
|
||||
'ncursesw', 'readline', 'brotlicommon', 'brotlienc', 'brotlidec'
|
||||
))) + (
|
||||
get_dll_path('bz2', 2), get_dll_path('ssl', 2), get_dll_path('crypto', 2),
|
||||
get_dll_path('python' + py_ver, 2),
|
||||
@@ -88,6 +92,17 @@ def copy_libs(env):
|
||||
for x in binary_includes():
|
||||
dest = env.bin_dir if '/bin/' in x else env.lib_dir
|
||||
shutil.copy2(x, dest)
|
||||
dest = os.path.join(dest, os.path.basename(x))
|
||||
subprocess.check_call(['chrpath', '-d', dest])
|
||||
|
||||
|
||||
def add_ca_certs(env):
|
||||
print('Downloading CA certs...')
|
||||
from urllib.request import urlopen
|
||||
cdata = urlopen(kitty_constants['cacerts_url']).read()
|
||||
dest = os.path.join(env.lib_dir, 'cacert.pem')
|
||||
with open(dest, 'wb') as f:
|
||||
f.write(cdata)
|
||||
|
||||
|
||||
def copy_python(env):
|
||||
@@ -104,8 +119,7 @@ def copy_python(env):
|
||||
shutil.copy2(y, env.py_dir)
|
||||
|
||||
srcdir = j(srcdir, 'site-packages')
|
||||
site_packages_dir = j(env.py_dir, 'site-packages')
|
||||
import_site_packages(srcdir, site_packages_dir)
|
||||
import_site_packages(srcdir, env.py_dir)
|
||||
|
||||
pdir = os.path.join(env.lib_dir, 'kitty-extensions')
|
||||
os.makedirs(pdir, exist_ok=True)
|
||||
@@ -124,7 +138,7 @@ def copy_python(env):
|
||||
for x in bases:
|
||||
iv['sanitize_source_folder'](os.path.join(env.py_dir, x))
|
||||
py_compile(env.py_dir)
|
||||
freeze_python(env.py_dir, pdir, env.obj_dir, ext_map, develop_mode_env_var='KITTY_DEVELOP_FROM')
|
||||
freeze_python(env.py_dir, pdir, env.obj_dir, ext_map, develop_mode_env_var='KITTY_DEVELOP_FROM', remove_pyc_files=True)
|
||||
|
||||
|
||||
def build_launcher(env):
|
||||
@@ -218,6 +232,7 @@ def main():
|
||||
build_launcher(env)
|
||||
files = find_binaries(env)
|
||||
fix_permissions(files)
|
||||
add_ca_certs(env)
|
||||
if not args.dont_strip:
|
||||
strip_binaries(files)
|
||||
if not args.skip_tests:
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
# Requires installation of XCode 10.3 and Python 3 and
|
||||
# python3 -m pip install certifi
|
||||
|
||||
vm_name 'macos-kitty-build'
|
||||
vm_name 'macos-kitty'
|
||||
root '/Users/Shared/kitty-build'
|
||||
python '/usr/local/bin/python3'
|
||||
universal 'true'
|
||||
deploy_target '10.14'
|
||||
|
||||
@@ -170,6 +170,7 @@ class Freeze(object):
|
||||
self.add_stdlib()
|
||||
self.add_misc_libraries()
|
||||
self.freeze_python()
|
||||
self.add_ca_certs()
|
||||
if not self.dont_strip:
|
||||
self.strip_files()
|
||||
if not self.skip_tests:
|
||||
@@ -180,6 +181,15 @@ class Freeze(object):
|
||||
|
||||
return ret
|
||||
|
||||
@flush
|
||||
def add_ca_certs(self):
|
||||
print('\nDownloading CA certs...')
|
||||
from urllib.request import urlopen
|
||||
cdata = urlopen(kitty_constants['cacerts_url']).read()
|
||||
dest = os.path.join(self.contents_dir, 'Resources', 'cacert.pem')
|
||||
with open(dest, 'wb') as f:
|
||||
f.write(cdata)
|
||||
|
||||
@flush
|
||||
def strip_files(self):
|
||||
print('\nStripping files...')
|
||||
@@ -212,7 +222,7 @@ class Freeze(object):
|
||||
@flush
|
||||
def get_local_dependencies(self, path_to_lib):
|
||||
for x, is_id in self.get_dependencies(path_to_lib):
|
||||
for y in (PREFIX + '/lib/', PREFIX + '/python/Python.framework/'):
|
||||
for y in (PREFIX + '/lib/', PREFIX + '/python/Python.framework/', '@rpath/'):
|
||||
if x.startswith(y):
|
||||
if y == PREFIX + '/python/Python.framework/':
|
||||
y = PREFIX + '/python/'
|
||||
@@ -278,7 +288,7 @@ class Freeze(object):
|
||||
'lcms2.2',
|
||||
'crypto.1.1',
|
||||
'ssl.1.1',
|
||||
'ffi.7',
|
||||
'rsync.2',
|
||||
):
|
||||
print('\nAdding', x)
|
||||
x = 'lib%s.dylib' % x
|
||||
@@ -349,7 +359,7 @@ class Freeze(object):
|
||||
for x in bases:
|
||||
iv['sanitize_source_folder'](os.path.join(self.python_stdlib, x))
|
||||
self.compile_py_modules()
|
||||
freeze_python(self.python_stdlib, pdir, self.obj_dir, ext_map, develop_mode_env_var='KITTY_DEVELOP_FROM')
|
||||
freeze_python(self.python_stdlib, pdir, self.obj_dir, ext_map, develop_mode_env_var='KITTY_DEVELOP_FROM', remove_pyc_files=True)
|
||||
iv['build_frozen_launcher']([path_to_freeze_dir(), self.obj_dir])
|
||||
os.rename(join(dirname(self.contents_dir), 'bin', 'kitty'), join(self.contents_dir, 'MacOS', 'kitty'))
|
||||
shutil.rmtree(join(dirname(self.contents_dir), 'bin'))
|
||||
@@ -420,7 +430,7 @@ class Freeze(object):
|
||||
py_compile(join(self.resources_dir, 'Python'))
|
||||
|
||||
@flush
|
||||
def makedmg(self, d, volname, internet_enable=True, format='ULFO'):
|
||||
def makedmg(self, d, volname, format='ULFO'):
|
||||
''' Copy a directory d into a dmg named volname '''
|
||||
print('\nMaking dmg...')
|
||||
sys.stdout.flush()
|
||||
@@ -456,9 +466,6 @@ class Freeze(object):
|
||||
print('\nCreating dmg...')
|
||||
with timeit() as times:
|
||||
subprocess.check_call(cmd + [dmg])
|
||||
if internet_enable:
|
||||
subprocess.check_call(
|
||||
['/usr/bin/hdiutil', 'internet-enable', '-yes', dmg])
|
||||
print('dmg created in %d minutes and %d seconds' % tuple(times))
|
||||
shutil.rmtree(tdir)
|
||||
size = os.stat(dmg).st_size / (1024 * 1024.)
|
||||
|
||||
@@ -28,6 +28,25 @@
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"name": "openssl",
|
||||
"unix": {
|
||||
"filename": "openssl-1.1.1i.tar.gz",
|
||||
"hash": "sha256:e8be6a35fe41d10603c3cc635e93289ed00bf34b79671a3a4de64fcee00d5242",
|
||||
"urls": ["https://www.openssl.org/source/{filename}"]
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"name": "cmake",
|
||||
"os": "macos",
|
||||
"unix": {
|
||||
"filename": "cmake-3.19.4.tar.gz",
|
||||
"hash": "sha256:7d0232b9f1c57e8de81f38071ef8203e6820fe7eec8ae46a1df125d88dbcc2e1",
|
||||
"urls": ["https://cmake.org/files/v3.19/{filename}"]
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
{
|
||||
"name": "expat",
|
||||
@@ -38,25 +57,22 @@
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
{
|
||||
"name": "libxml2",
|
||||
"os": "linux",
|
||||
"unix": {
|
||||
"filename": "libxml2-2.9.10.tar.gz",
|
||||
"hash": "sha256:aafee193ffb8fe0c82d4afef6ef91972cbaf5feea100edc2f262750611b4be1f",
|
||||
"filename": "libxml2-2.9.12.tar.gz",
|
||||
"hash": "sha256:c8d6681e38c56f172892c85ddc0852e1fd4b53b4209e7f4ebf17f7e2eae71d92",
|
||||
"urls": ["ftp://xmlsoft.org/libxml2/{filename}"]
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
{
|
||||
"name": "xkbcommon",
|
||||
"os": "linux",
|
||||
"unix": {
|
||||
"filename": "libxkbcommon-1.0.3.tar.xz",
|
||||
"hash": "sha256:a2202f851e072b84e64a395212cbd976ee18a8ee602008b0bad02a13247dbc52",
|
||||
"urls": ["http://xkbcommon.org/download/{filename}"]
|
||||
"urls": ["https://xkbcommon.org/download/{filename}"]
|
||||
}
|
||||
},
|
||||
|
||||
@@ -72,6 +88,7 @@
|
||||
|
||||
{
|
||||
"name": "libffi",
|
||||
"os": "linux",
|
||||
"unix": {
|
||||
"filename": "libffi-3.3.0.tar.gz",
|
||||
"hash": "sha256:72fba7922703ddfa7a028d513ac15a85c8d54c8d67f55fa5a4802885dc652056",
|
||||
@@ -79,15 +96,6 @@
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"name": "openssl",
|
||||
"unix": {
|
||||
"filename": "openssl-1.1.1i.tar.gz",
|
||||
"hash": "sha256:e8be6a35fe41d10603c3cc635e93289ed00bf34b79671a3a4de64fcee00d5242",
|
||||
"urls": ["https://www.openssl.org/source/{filename}"]
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"name": "ncurses",
|
||||
"os": "linux",
|
||||
@@ -104,7 +112,7 @@
|
||||
"unix": {
|
||||
"filename": "readline-8.1.tar.gz",
|
||||
"hash": "sha256:f8ceb4ee131e3232226a17f51b164afc46cd0b9e6cef344be87c65962cb82b02",
|
||||
"urls": ["http://ftp.gnu.org/gnu/readline/{filename}"]
|
||||
"urls": ["https://ftp.gnu.org/gnu/readline/{filename}"]
|
||||
}
|
||||
},
|
||||
|
||||
@@ -117,6 +125,16 @@
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"name": "librsync",
|
||||
"unix": {
|
||||
"filename": "librsync-2.3.2.tar.gz",
|
||||
"hash": "sha256:ef8ce23df38d5076d25510baa2cabedffbe0af460d887d86c2413a1c2b0c676f",
|
||||
"urls": ["https://github.com/librsync/librsync/releases/download/v2.3.2/{filename}"]
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
{
|
||||
"name": "xcrypt",
|
||||
"os": "linux",
|
||||
@@ -130,9 +148,9 @@
|
||||
{
|
||||
"name": "python",
|
||||
"unix": {
|
||||
"filename": "Python-3.9.1.tar.xz",
|
||||
"hash": "sha256:991c3f8ac97992f3d308fefeb03a64db462574eadbff34ce8bc5bb583d9903ff",
|
||||
"urls": ["https://www.python.org/ftp/python/3.9.1/{filename}"]
|
||||
"filename": "Python-3.9.4.tar.xz",
|
||||
"hash": "sha256:4b0e6644a76f8df864ae24ac500a51bbf68bd098f6a173e27d3b61cdca9aa134",
|
||||
"urls": ["https://www.python.org/ftp/python/3.9.4/{filename}"]
|
||||
}
|
||||
},
|
||||
|
||||
@@ -154,22 +172,12 @@
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"name": "cmake",
|
||||
"os": "macos",
|
||||
"unix": {
|
||||
"filename": "cmake-3.19.4.tar.gz",
|
||||
"hash": "sha256:7d0232b9f1c57e8de81f38071ef8203e6820fe7eec8ae46a1df125d88dbcc2e1",
|
||||
"urls": ["https://cmake.org/files/v3.19/{filename}"]
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"name": "libpng",
|
||||
"unix": {
|
||||
"filename": "libpng-1.6.37.tar.xz",
|
||||
"hash": "sha256:505e70834d35383537b6491e7ae8641f1a4bed1876dbfe361201fc80868d88ca",
|
||||
"urls": ["http://downloads.sourceforge.net/sourceforge/libpng/{filename}"]
|
||||
"urls": ["https://downloads.sourceforge.net/sourceforge/libpng/{filename}"]
|
||||
}
|
||||
},
|
||||
|
||||
@@ -188,7 +196,7 @@
|
||||
"unix": {
|
||||
"filename": "graphite2-1.3.14.tgz",
|
||||
"hash": "sha256:f99d1c13aa5fa296898a181dff9b82fb25f6cc0933dbaa7a475d8109bd54209d",
|
||||
"urls": ["http://downloads.sourceforge.net/silgraphite/{filename}"]
|
||||
"urls": ["https://downloads.sourceforge.net/silgraphite/{filename}"]
|
||||
}
|
||||
},
|
||||
|
||||
@@ -222,6 +230,16 @@
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"name": "brotli",
|
||||
"os": "linux",
|
||||
"unix": {
|
||||
"filename": "brotli-1.0.9.tar.gz",
|
||||
"hash": "sha256:f9e8d81d0405ba66d181529af42a3354f838c939095ff99930da6aa9cdf6fe46",
|
||||
"urls": ["https://github.com/google/brotli/archive/v1.0.9/{filename}"]
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"name": "freetype",
|
||||
"os": "linux",
|
||||
@@ -238,7 +256,7 @@
|
||||
"unix": {
|
||||
"filename": "fontconfig-2.13.1.tar.bz2",
|
||||
"hash": "sha256:f655dd2a986d7aa97e052261b36aa67b0a64989496361eca8d604e6414006741",
|
||||
"urls": ["http://www.fontconfig.org/release/{filename}"]
|
||||
"urls": ["https://www.fontconfig.org/release/{filename}"]
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
@@ -16,6 +16,11 @@ kitty/glfw-wrapper.c
|
||||
kitty/emoji.h
|
||||
kittens/unicode_input/names.h
|
||||
kitty/parse-graphics-command.h
|
||||
kitty/options/types.py
|
||||
kitty/options/parse.py
|
||||
kitty/options/to-c-generated.h
|
||||
kittens/diff/options/types.py
|
||||
kittens/diff/options/parse.py
|
||||
'''
|
||||
|
||||
p = subprocess.Popen([
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
#
|
||||
|
||||
# You can set these variables from the command line.
|
||||
SPHINXOPTS = -j auto -T $(FAIL_WARN)
|
||||
SPHINXOPTS = -n -q -j auto -T $(FAIL_WARN) $(OPTS)
|
||||
SPHINXBUILD = sphinx-build
|
||||
SPHINXPROJ = kitty
|
||||
SOURCEDIR = .
|
||||
@@ -18,3 +18,7 @@ help:
|
||||
# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
|
||||
%: Makefile
|
||||
$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
|
||||
|
||||
|
||||
develop-docs:
|
||||
sphinx-autobuild --ignore "$(abspath $(SOURCEDIR))/generated/*" --watch ../kitty --watch ../kittens -b dirhtml "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS)
|
||||
|
||||
128
docs/_static/custom.css
vendored
@@ -5,122 +5,26 @@
|
||||
* Distributed under terms of the MIT license.
|
||||
*/
|
||||
|
||||
.float-left-img {
|
||||
float: left;
|
||||
margin-right: 1em;
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
|
||||
.float-right-img { float: right; margin-left: 1em; margin-bottom: 1em }
|
||||
|
||||
.half-with-img { max-width: 50% }
|
||||
|
||||
.fit-img { max-width: 95% }
|
||||
|
||||
div.body p, div.body dd, div.body li, div.body blockquote {
|
||||
text-align: justify;
|
||||
}
|
||||
|
||||
div.body {
|
||||
min-width: 200px;
|
||||
}
|
||||
|
||||
pre {
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
|
||||
pre.pre {
|
||||
white-space: pre;
|
||||
}
|
||||
|
||||
a[href], input[type="submit"] { cursor: pointer; }
|
||||
|
||||
img[style] {
|
||||
/* Used for :scale: images to have them render properly but still popup when clicked */
|
||||
width: auto !important;
|
||||
height: auto !important;
|
||||
}
|
||||
|
||||
a {
|
||||
text-decoration: none !important;
|
||||
border-bottom: none !important;
|
||||
}
|
||||
|
||||
body div.document {
|
||||
margin-top: 1ex;
|
||||
}
|
||||
|
||||
.major-features li {
|
||||
margin-top: 0.75ex;
|
||||
margin-bottom: 0.75ex;
|
||||
}
|
||||
|
||||
.support-form input[type=submit] {
|
||||
border-radius: 6px;
|
||||
box-shadow: rgb(255, 246, 175) 0px 1px 0px 0px;
|
||||
background: linear-gradient(rgb(255, 236, 100) 5%, rgb(255, 171, 35) 100%) rgb(255, 236, 100);
|
||||
border: 1px solid rgb(255, 170, 34);
|
||||
display: inline-block;
|
||||
color: rgb(51, 51, 51);
|
||||
font-family: Arial;
|
||||
font-size: 15px;
|
||||
font-weight: bold;
|
||||
padding: 6px 24px;
|
||||
text-decoration: none;
|
||||
text-shadow: rgb(255, 238, 102) 0px 1px 0px;
|
||||
}
|
||||
|
||||
.support-form input[type=submit]:hover {
|
||||
background: linear-gradient(rgb(255, 171, 35) 5%, rgb(255, 236, 100) 100%) rgb(255, 171, 35);
|
||||
}
|
||||
|
||||
.support-form input[type=submit]:focus {
|
||||
outline: 0;
|
||||
}
|
||||
|
||||
|
||||
div.sphinxsidebar {
|
||||
font-size: inherit;
|
||||
line-height: inherit;
|
||||
max-height: 100%;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
#sidebartoc li {
|
||||
margin-top: 0.75ex;
|
||||
margin-bottom: 0.75ex;
|
||||
}
|
||||
|
||||
#sidebartoc ul {
|
||||
list-style: none !important;
|
||||
}
|
||||
|
||||
#sidebartoc a[href]:hover {
|
||||
color: red;
|
||||
}
|
||||
|
||||
|
||||
.green {
|
||||
color: green;
|
||||
}
|
||||
|
||||
.cyan {
|
||||
color: blue;
|
||||
}
|
||||
|
||||
.env {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.italic {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.bold {
|
||||
font-weight: bold;
|
||||
.sidebar-logo {
|
||||
max-height: 128px;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: larger;
|
||||
font-weight: bold
|
||||
.major-features li {
|
||||
margin-bottom: 0.75ex;
|
||||
margin-top: 0.75ex;
|
||||
}
|
||||
|
||||
.sidebar-tree a.current {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
details > summary {
|
||||
color: var(--color-link);
|
||||
cursor: pointer;
|
||||
text-decoration-color: var(--color-link-underline);
|
||||
text-decoration-line: underline;
|
||||
}
|
||||
|
||||
57
docs/_static/custom.js
vendored
Normal file
@@ -0,0 +1,57 @@
|
||||
/* vim:fileencoding=utf-8
|
||||
*
|
||||
* Copyright (C) 2021 Kovid Goyal <kovid at kovidgoyal.net>
|
||||
*
|
||||
* Distributed under terms of the GPLv3 license
|
||||
*/
|
||||
|
||||
(function() {
|
||||
"use strict";
|
||||
|
||||
function get_sidebar_tree() {
|
||||
return document.querySelector('.sidebar-tree');
|
||||
}
|
||||
|
||||
function scroll_sidebar_node_into_view(a) {
|
||||
var ss = get_sidebar_tree().closest('.sidebar-scroll');
|
||||
if (!ss || !a) return;
|
||||
ss.style.position = 'relative';
|
||||
var pos = 0;
|
||||
while (true) {
|
||||
pos += a.offsetTop;
|
||||
a = a.offsetParent;
|
||||
if (!a || a == ss) break;
|
||||
}
|
||||
ss.scrollTo({top: pos, behavior: 'instant'});
|
||||
}
|
||||
|
||||
function mark_current_link(sidebar_tree, a, onload) {
|
||||
var li = a.closest('li.has-children');
|
||||
while (li) {
|
||||
li.querySelector('input[type=checkbox]').setAttribute('checked', 'checked');
|
||||
li = li.parentNode.closest('li.has-children');
|
||||
}
|
||||
sidebar_tree.querySelectorAll('.current').forEach(function (elem) {
|
||||
elem.classList.remove('current');
|
||||
});
|
||||
if (onload) scroll_sidebar_node_into_view(a);
|
||||
a.classList.add('current');
|
||||
}
|
||||
|
||||
function show_hash_in_sidebar(onload) {
|
||||
var sidebar_tree = document.querySelector('.sidebar-tree');
|
||||
if (document.location.hash.length > 1) {
|
||||
var a = sidebar_tree.querySelector('a[href="' + document.location.hash + '"]');
|
||||
if (a) mark_current_link(sidebar_tree, a, onload);
|
||||
} else {
|
||||
if (onload) scroll_sidebar_node_into_view(sidebar_tree.querySelector('.current-page a'));
|
||||
}
|
||||
}
|
||||
|
||||
document.addEventListener("DOMContentLoaded", function() {
|
||||
show_hash_in_sidebar(true);
|
||||
window.addEventListener('hashchange', show_hash_in_sidebar.bind(null, false));
|
||||
});
|
||||
|
||||
}());
|
||||
|
||||
22
docs/_templates/base.html
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
{% extends "!base.html" %}
|
||||
{% block extrahead %}
|
||||
|
||||
{{ super() }}
|
||||
|
||||
{%- if analytics_id %}
|
||||
<script type="text/javascript">
|
||||
var _gaq = _gaq || [];
|
||||
_gaq.push(['_setAccount', '{{ analytics_id }}']);
|
||||
_gaq.push(['_setDomainName', 'none']);
|
||||
_gaq.push(['_setAllowLinker', true]);
|
||||
_gaq.push(['_trackPageview']);
|
||||
|
||||
(function() {
|
||||
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
|
||||
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
|
||||
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
|
||||
})();
|
||||
</script>
|
||||
{% endif -%}
|
||||
|
||||
{% endblock %}
|
||||
6
docs/_templates/layout.html
vendored
@@ -1,6 +0,0 @@
|
||||
{% extends "!layout.html" %}
|
||||
|
||||
{%- block extrahead %}
|
||||
<!-- kitty analytics placeholder -->
|
||||
{{ super() }}
|
||||
{% endblock %}
|
||||
6
docs/_templates/localtoc.html
vendored
@@ -1,6 +0,0 @@
|
||||
{%- if display_toc %}
|
||||
<div> </div>
|
||||
<div id="sidebartoc">
|
||||
{{ toc }}
|
||||
</div>
|
||||
{%- endif %}
|
||||
22
docs/_templates/searchbox.html
vendored
@@ -1,22 +0,0 @@
|
||||
{#
|
||||
basic/searchbox.html
|
||||
~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Sphinx sidebar template: quick search box.
|
||||
|
||||
:copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS.
|
||||
:license: BSD, see LICENSE for details.
|
||||
#}
|
||||
{%- if pagename != "search" and builder != "singlehtml" %}
|
||||
<div id="searchbox" style="display: none" role="search">
|
||||
<div class="searchformwrapper">
|
||||
<form class="search" action="{{ pathto('search') }}" method="get">
|
||||
<input type="text" name="q" placeholder="{{ _('Search') }}" />
|
||||
<input type="submit" value="{{ _('Go') }}" style="cursor: pointer" />
|
||||
<input type="hidden" name="check_keywords" value="yes" />
|
||||
<input type="hidden" name="area" value="default" />
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<script type="text/javascript">$('#searchbox').show(0);</script>
|
||||
{%- endif %}
|
||||
7
docs/_templates/support.html
vendored
@@ -1,7 +0,0 @@
|
||||
{% if pagename != "support" %}
|
||||
<div id="support" style="text-align: center">
|
||||
<form class="support-form" action="{{ pathto('support') }}" title="{{ _('Donate to support kitty development') }}">
|
||||
<input type="submit" value="{{ _('Support kitty') }}">
|
||||
</form>
|
||||
</div>
|
||||
{% endif %}
|
||||
10
docs/actions.rst
Normal file
@@ -0,0 +1,10 @@
|
||||
Mappable actions
|
||||
-----------------------
|
||||
|
||||
.. highlight:: conf
|
||||
|
||||
The actions described below can be mapped to any key press or mouse action
|
||||
using the ``map`` and ``mouse_map`` directives in :file:`kitty.conf`. For
|
||||
configuration examples, see the default shortcut links for each action.
|
||||
|
||||
.. include:: /generated/actions.rst
|
||||
141
docs/basic.rst
Normal file
@@ -0,0 +1,141 @@
|
||||
Tabs and Windows
|
||||
-------------------
|
||||
|
||||
|kitty| is capable of running multiple programs organized into tabs and
|
||||
windows. The top level of organization is the *Tab*. Each tab consists
|
||||
of one or more *windows*. The windows can be arranged in multiple
|
||||
different layouts, like windows are organized in a tiling window
|
||||
manager. The keyboard controls (which are all customizable) for tabs and
|
||||
windows are:
|
||||
|
||||
Scrolling
|
||||
~~~~~~~~~~~~~~
|
||||
|
||||
========================= =======================
|
||||
Action Shortcut
|
||||
========================= =======================
|
||||
Line up :sc:`scroll_line_up` (also :kbd:`⌥+⌘+⇞` and :kbd:`⌘+↑` on macOS)
|
||||
Line down :sc:`scroll_line_down` (also :kbd:`⌥+⌘+⇟` and :kbd:`⌘+↓` on macOS)
|
||||
Page up :sc:`scroll_page_up` (also :kbd:`⌘+⇞` on macOS)
|
||||
Page down :sc:`scroll_page_down` (also :kbd:`⌘+⇟` on macOS)
|
||||
Top :sc:`scroll_home` (also :kbd:`⌘+↖` on macOS)
|
||||
Bottom :sc:`scroll_end` (also :kbd:`⌘+↘` on macOS)
|
||||
Previous shell prompt :sc:`scroll_to_previous_prompt` (see :ref:`shell_integration`)
|
||||
Next shell prompt :sc:`scroll_to_next_prompt` (see :ref:`shell_integration`)
|
||||
Browse scrollback in less :sc:`show_scrollback`
|
||||
Browse last cmd output :sc:`show_last_command_output` (see :ref:`shell_integration`)
|
||||
========================= =======================
|
||||
|
||||
Tabs
|
||||
~~~~~~~~~~~
|
||||
|
||||
======================== =======================
|
||||
Action Shortcut
|
||||
======================== =======================
|
||||
New tab :sc:`new_tab` (also :kbd:`⌘+t` on macOS)
|
||||
Close tab :sc:`close_tab` (also :kbd:`⌘+w` on macOS)
|
||||
Next tab :sc:`next_tab` (also :kbd:`⌃+⇥` and :kbd:`⇧+⌘+]` on macOS)
|
||||
Previous tab :sc:`previous_tab` (also :kbd:`⇧+⌃+⇥` and :kbd:`⇧+⌘+[` on macOS)
|
||||
Next layout :sc:`next_layout`
|
||||
Move tab forward :sc:`move_tab_forward`
|
||||
Move tab backward :sc:`move_tab_backward`
|
||||
Set tab title :sc:`set_tab_title` (also :kbd:`⇧+⌘+i` on macOS)
|
||||
======================== =======================
|
||||
|
||||
|
||||
Windows
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
|
||||
======================== =======================
|
||||
Action Shortcut
|
||||
======================== =======================
|
||||
New window :sc:`new_window` (also :kbd:`⌘+↩` on macOS)
|
||||
New OS window :sc:`new_os_window` (also :kbd:`⌘+n` on macOS)
|
||||
Close window :sc:`close_window` (also :kbd:`⇧+⌘+d` on macOS)
|
||||
Next window :sc:`next_window`
|
||||
Previous window :sc:`previous_window`
|
||||
Move window forward :sc:`move_window_forward`
|
||||
Move window backward :sc:`move_window_backward`
|
||||
Move window to top :sc:`move_window_to_top`
|
||||
Visually focus window :sc:`focus_visible_window`
|
||||
Visually swap window :sc:`swap_with_window`
|
||||
Focus specific window :sc:`first_window`, :sc:`second_window` ... :sc:`tenth_window`
|
||||
(also :kbd:`⌘+1`, :kbd:`⌘+2` ... :kbd:`⌘+9` on macOS)
|
||||
(clockwise from the top-left)
|
||||
======================== =======================
|
||||
|
||||
Additionally, you can define shortcuts in :file:`kitty.conf` to focus neighboring
|
||||
windows and move windows around (similar to window movement in vim)::
|
||||
|
||||
map ctrl+left neighboring_window left
|
||||
map shift+left move_window right
|
||||
map ctrl+down neighboring_window down
|
||||
map shift+down move_window up
|
||||
...
|
||||
|
||||
You can also define a shortcut to switch to the previously active window::
|
||||
|
||||
map ctrl+p nth_window -1
|
||||
|
||||
``nth_window`` will focus the nth window for positive numbers and the
|
||||
previously active windows for negative numbers.
|
||||
|
||||
.. _detach_window:
|
||||
|
||||
You can define shortcuts to detach the current window and
|
||||
move it to another tab or another OS window::
|
||||
|
||||
# moves the window into a new OS window
|
||||
map ctrl+f2 detach_window
|
||||
# moves the window into a new Tab
|
||||
map ctrl+f3 detach_window new-tab
|
||||
# moves the window into the previously active tab
|
||||
map ctrl+f3 detach_window tab-prev
|
||||
# moves the window into the tab at the left of the active tab
|
||||
map ctrl+f3 detach_window tab-left
|
||||
# asks which tab to move the window into
|
||||
map ctrl+f4 detach_window ask
|
||||
|
||||
Similarly, you can detach the current tab, with::
|
||||
|
||||
# moves the tab into a new OS window
|
||||
map ctrl+f2 detach_tab
|
||||
# asks which OS Window to move the tab into
|
||||
map ctrl+f4 detach_tab ask
|
||||
|
||||
Finally, you can define a shortcut to close all windows in a tab other than
|
||||
the currently active window::
|
||||
|
||||
map f9 close_other_windows_in_tab
|
||||
|
||||
|
||||
Other keyboard shortcuts
|
||||
----------------------------------
|
||||
|
||||
The full list of actions that can be mapped to key presses is available
|
||||
:doc:`here </actions>`.
|
||||
|
||||
================================== =======================
|
||||
Action Shortcut
|
||||
================================== =======================
|
||||
Copy to clipboard :sc:`copy_to_clipboard` (also :kbd:`⌘+c` on macOS)
|
||||
Paste from clipboard :sc:`paste_from_clipboard` (also :kbd:`⌘+v` on macOS)
|
||||
Paste from selection :sc:`paste_from_selection`
|
||||
Increase font size :sc:`increase_font_size` (also :kbd:`⌘++` on macOS)
|
||||
Decrease font size :sc:`decrease_font_size` (also :kbd:`⌘+-` on macOS)
|
||||
Restore font size :sc:`reset_font_size` (also :kbd:`⌘+0` on macOS)
|
||||
Toggle fullscreen :sc:`toggle_fullscreen` (also :kbd:`⌃+⌘+f` on macOS)
|
||||
Toggle maximized :sc:`toggle_maximized`
|
||||
Input unicode character :sc:`input_unicode_character` (also :kbd:`⌃+⌘+space` on macOS)
|
||||
Click URL using the keyboard :sc:`open_url`
|
||||
Reset the terminal :sc:`reset_terminal`
|
||||
Reload :file:`kitty.conf` :sc:`reload_config_file` (also :kbd:`⌃+⌘+,` on macOS)
|
||||
Debug :file:`kitty.conf` :sc:`debug_config` (also :kbd:`⌘+⌥+f6` on macOS)
|
||||
Pass current selection to program :sc:`pass_selection_to_program`
|
||||
Edit |kitty| config file :sc:`edit_config_file`
|
||||
Open a |kitty| shell :sc:`kitty_shell`
|
||||
Increase background opacity :sc:`increase_background_opacity`
|
||||
Decrease background opacity :sc:`decrease_background_opacity`
|
||||
Full background opacity :sc:`full_background_opacity`
|
||||
Reset background opacity :sc:`reset_background_opacity`
|
||||
================================== =======================
|
||||
@@ -1,6 +1,9 @@
|
||||
kitty - Binary install
|
||||
Install kitty
|
||||
========================
|
||||
|
||||
Binary install
|
||||
----------------
|
||||
|
||||
.. |ins| replace:: curl -L :literal:`https://sw.kovidgoyal.net/kitty/installer.sh` | sh /dev/stdin
|
||||
|
||||
.. highlight:: sh
|
||||
@@ -19,6 +22,11 @@ The binaries will be installed in the standard location for your OS,
|
||||
Linux. The installer only touches files in that directory. To update kitty,
|
||||
simply re-run the command.
|
||||
|
||||
.. warning::
|
||||
**Do not** copy the kitty binary out of the installation folder. If you want
|
||||
to add it to your ``PATH`` create a symlink in :file:`~/.local/bin` or
|
||||
:file:`/usr/bin` or wherever.
|
||||
|
||||
|
||||
Manually installing
|
||||
---------------------
|
||||
@@ -48,11 +56,37 @@ particular desktop, but it should work for most major desktop environments.
|
||||
# Update the path to the kitty icon in the kitty.desktop file
|
||||
sed -i "s|Icon=kitty|Icon=/home/$USER/.local/kitty.app/share/icons/hicolor/256x256/apps/kitty.png|g" ~/.local/share/applications/kitty.desktop
|
||||
|
||||
.. note::
|
||||
If you use the venerable `stow <https://www.gnu.org/software/stow/>`_
|
||||
command to manage your manual installations, the following takes care of the
|
||||
above for you (use with :file:`dest=~/.local/stow`)::
|
||||
|
||||
cd ~/.local/stow
|
||||
stow -v kitty.app
|
||||
|
||||
|
||||
Customizing the installation
|
||||
--------------------------------
|
||||
|
||||
.. _nightly:
|
||||
|
||||
* You can install the latest nightly kitty build with ``installer``:
|
||||
|
||||
.. parsed-literal::
|
||||
:class: pre
|
||||
|
||||
|ins| \\
|
||||
installer=nightly
|
||||
|
||||
If you want to install it in parallel to the released kitty specify a
|
||||
different install locations with ``dest``:
|
||||
|
||||
.. parsed-literal::
|
||||
:class: pre
|
||||
|
||||
|ins| \\
|
||||
installer=nightly dest=/some/other/location
|
||||
|
||||
* You can specify a different install location, with ``dest``:
|
||||
|
||||
.. parsed-literal::
|
||||
@@ -78,6 +112,7 @@ Customizing the installation
|
||||
|ins| \\
|
||||
installer=/path/to/dmg or tarball
|
||||
|
||||
|
||||
Uninstalling
|
||||
----------------
|
||||
|
||||
|
||||
143
docs/build.rst
@@ -1,37 +1,66 @@
|
||||
Building kitty from source
|
||||
==============================
|
||||
Build from source
|
||||
==================
|
||||
|
||||
.. image:: https://github.com/kovidgoyal/kitty/workflows/CI/badge.svg
|
||||
:alt: Build status
|
||||
:target: https://github.com/kovidgoyal/kitty/actions?query=workflow%3ACI
|
||||
|
||||
.. highlight:: sh
|
||||
|
||||
|kitty| is designed to run from source, for easy hackability. Make sure
|
||||
|kitty| is designed to run from source, for easy hack-ability. Make sure
|
||||
the following dependencies are installed first.
|
||||
|
||||
.. note::
|
||||
If you just want to test the latest changes to kitty you dont need to build
|
||||
from source. Instead install the :ref:`latest nightly build <nightly>`.
|
||||
|
||||
.. note::
|
||||
If you are making small changes only to the python parts of kitty, there is no need to
|
||||
build kitty at all, instead, assuming you have installed the official kitty
|
||||
binaries, you can simply set the KITTY_DEVELOP_FROM enviroment variable to
|
||||
point to the directory into which you have checked out the kitty source
|
||||
code. kitty will then load its python code from there. You should use a
|
||||
version of the source that matches the binary version as closely as
|
||||
possible, since the two are tightly coupled.
|
||||
|
||||
|
||||
Dependencies
|
||||
----------------
|
||||
|
||||
Run-time dependencies:
|
||||
|
||||
* python >= 3.5
|
||||
* harfbuzz >= 1.5.0
|
||||
* zlib
|
||||
* libpng
|
||||
* liblcms2
|
||||
* freetype (not needed on macOS)
|
||||
* fontconfig (not needed on macOS)
|
||||
* libcanberra (not needed on macOS)
|
||||
* ImageMagick (optional, needed to use the ``kitty icat`` tool to display images in the terminal)
|
||||
* pygments (optional, need for syntax highlighting in ``kitty +kitten diff``)
|
||||
* ``python`` >= 3.6
|
||||
* ``harfbuzz`` >= 2.2.0
|
||||
* ``zlib``
|
||||
* ``libpng``
|
||||
* ``liblcms2``
|
||||
* ``librsync``
|
||||
* ``freetype`` (not needed on macOS)
|
||||
* ``fontconfig`` (not needed on macOS)
|
||||
* ``libcanberra`` (not needed on macOS)
|
||||
* ``ImageMagick`` (optional, needed to use the ``kitty +kitten icat`` tool to display images in the terminal)
|
||||
* ``pygments`` (optional, needed for syntax highlighting in ``kitty +kitten diff``)
|
||||
|
||||
|
||||
Build-time dependencies:
|
||||
|
||||
* gcc or clang
|
||||
* pkg-config
|
||||
* For building on Linux in addition to the above dependencies you might also need to install the ``-dev`` packages for:
|
||||
``libdbus-1-dev``, ``libxcursor-dev``, ``libxrandr-dev``, ``libxi-dev``, ``libxinerama-dev``, ``libgl1-mesa-dev``, ``libxkbcommon-x11-dev``, ``libfontconfig-dev``, ``libx11-xcb-dev``, ``liblcms2-dev``, and ``libpython3-dev``,
|
||||
if they are not already installed by your distro.
|
||||
* ``gcc`` or ``clang``
|
||||
* ``pkg-config``
|
||||
* For building on Linux in addition to the above dependencies you might also need to install the following packages, if they are not already installed by your distro:
|
||||
|
||||
- ``libdbus-1-dev``
|
||||
- ``libxcursor-dev``
|
||||
- ``libxrandr-dev``
|
||||
- ``libxi-dev``
|
||||
- ``libxinerama-dev``
|
||||
- ``libgl1-mesa-dev``
|
||||
- ``libxkbcommon-x11-dev``
|
||||
- ``libfontconfig-dev``
|
||||
- ``libx11-xcb-dev``
|
||||
- ``liblcms2-dev``
|
||||
- ``libpython3-dev``
|
||||
- ``librsync-dev``
|
||||
|
||||
|
||||
Install and run from source
|
||||
------------------------------
|
||||
@@ -67,10 +96,8 @@ you might have to rebuild the app.
|
||||
.. note::
|
||||
The released :file:`kitty.dmg` includes all dependencies, unlike the
|
||||
:file:`kitty.app` built above and is built automatically by using the
|
||||
:file:`kitty` branch of `build-calibre
|
||||
<https://github.com/kovidgoyal/build-calibre>`_ however, that is designed to
|
||||
run on Linux and is not for the faint of heart.
|
||||
|
||||
`bypy framework <https://github.com/kovidgoyal/bypy>`_ however, that is
|
||||
designed to run on Linux and is not for the faint of heart.
|
||||
|
||||
.. note::
|
||||
Apple disallows certain functionality, such as notifications for unsigned applications.
|
||||
@@ -78,6 +105,12 @@ you might have to rebuild the app.
|
||||
a self signed certificate, see for example, `here
|
||||
<https://stackoverflow.com/questions/27474751/how-can-i-codesign-an-app-without-being-in-the-mac-developer-program/27474942>`_.
|
||||
|
||||
.. note::
|
||||
If you are facing issues with ``linker`` while building,
|
||||
try with a ``brew`` installed python instead, see :iss:`289`
|
||||
for more discussion.
|
||||
|
||||
|
||||
Build and run from source with Nix
|
||||
-------------------------------------------
|
||||
|
||||
@@ -92,7 +125,9 @@ make them available in the newly spawned shell.
|
||||
Then proceed with ``make`` or ``make app`` according to the platform specific instructions above.
|
||||
|
||||
|
||||
Note for Linux/macOS packagers
|
||||
.. _packagers:
|
||||
|
||||
Notes for Linux/macOS packagers
|
||||
----------------------------------
|
||||
|
||||
The released |kitty| source code is available as a `tarball`_ from
|
||||
@@ -112,24 +147,58 @@ with :file:`linux-package/bin/kitty`. All the files needed to run kitty will be
|
||||
installed. You can choose a different staging area, by passing the ``--prefix``
|
||||
argument to :file:`setup.py`.
|
||||
|
||||
You should probably split |kitty| into two packages, :file:`kitty-terminfo` that
|
||||
installs the terminfo file and :file:`kitty` that installs the main program.
|
||||
This allows users to install the terminfo file on servers into which they ssh,
|
||||
without needing to install all of |kitty|.
|
||||
You should probably split |kitty| into three packages:
|
||||
|
||||
:code:`kitty-terminfo`
|
||||
installs the terminfo file
|
||||
|
||||
:code:`kitty-shell-integration`
|
||||
installs the shell integration scripts (the contents of the
|
||||
shell-integration directory in the kitty source code, probably to
|
||||
:file:`/usr/share/kitty/shell-integration`
|
||||
|
||||
:code:`kitty`
|
||||
installs the main program
|
||||
|
||||
This allows users to install the terminfo and shell integration files on
|
||||
servers into which they ssh, without needing to install all of |kitty|.
|
||||
|
||||
.. note::
|
||||
You need a couple of extra dependencies to build linux-package.
|
||||
:file:`tic` to compile terminfo files, usually found in the
|
||||
development package of :file:`ncurses`. Also, if you are building from
|
||||
a git checkout instead of the released source code tarball, you will
|
||||
need :file:`sphinx-build` from the `Sphinx documentation generator
|
||||
<https://www.sphinx-doc.org/>`_.
|
||||
You need a couple of extra dependencies to build linux-package.
|
||||
:file:`tic` to compile terminfo files, usually found in the
|
||||
development package of :file:`ncurses`. Also, if you are building from
|
||||
a git checkout instead of the released source code tarball, you will
|
||||
need to install the dependencies from ``docs/requirements.txt`` to
|
||||
build the kitty documentation. They can be installed most easily with
|
||||
``python -m pip -r docs/requirements.txt``.
|
||||
|
||||
This applies to creating packages for |kitty| for macOS package managers such as
|
||||
brew or MacPorts as well.
|
||||
|
||||
|
||||
.. note::
|
||||
|kitty| has its own update check mechanism, if you would like to turn
|
||||
it off for your package, use
|
||||
``python3 setup.py linux-package --update-check-interval=0``
|
||||
Changing defaults for packages
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
|kitty| has its defaults chosen to be suitable for a standalone distributable.
|
||||
If you are packaging it a few of these might need to be changed.
|
||||
|
||||
update-checking
|
||||
|kitty| has its own update check mechanism, if you would like to turn
|
||||
it off for your package, use::
|
||||
|
||||
./setup.py linux-package --update-check-interval=0
|
||||
|
||||
shell-integration
|
||||
|kitty| by default injects its :ref:`shell_integration` code into the user's
|
||||
shell using environment variables or (for bash only) modifying
|
||||
the user's :file:`~/.bashrc` file.
|
||||
For a package, it might make more sense to distribute the shell
|
||||
integration scripts into the system-wide shell vendor locations. The
|
||||
shell integration files are found in the :file:`shell-integration`
|
||||
directory. Copy them to the system wide shell vendor locations for each
|
||||
shell, and use::
|
||||
|
||||
./setup.py linux-package --shell-integration=enabled\ no-rc
|
||||
|
||||
This will prevent kitty from modifying the user's shell environment to load
|
||||
the integration scripts.
|
||||
|
||||
26
docs/color-stack.rst
Normal file
@@ -0,0 +1,26 @@
|
||||
Saving and restoring colors
|
||||
==============================
|
||||
|
||||
It is often useful for a full screen application with its own color themes to
|
||||
set the default foreground, background, selection and cursor colors and the
|
||||
ANSI color table. This allows for various performance optimizations when
|
||||
drawing the screen. The problem is that if the user previously used the escape
|
||||
codes to change these colors herself, then running the full screen application
|
||||
will lose her changes even after it exits. To avoid this, kitty introduces a
|
||||
new pair of *OSC* escape codes to push and pop the current color values from a
|
||||
stack::
|
||||
|
||||
<ESC>]30001<ESC>\ # push onto stack
|
||||
<ESC>]30101<ESC>\ # pop from stack
|
||||
|
||||
These escape codes save/restore the colors, default
|
||||
background, default foreground, selection background, selection foreground and
|
||||
cursor color and the 256 colors of the ANSI color table.
|
||||
|
||||
.. note:: In July 2020, after several years, XTerm copied this protocol
|
||||
extension, without acknowledgement, and using incompatible escape codes
|
||||
(XTPUSHCOLORS, XTPOPCOLORS, XTREPORTCOLORS). And they decided to save not
|
||||
just the dynamic colors but the entire ANSI color table. In the interests of
|
||||
promoting interoperability, kitty added support for XTerm's escape codes as
|
||||
well, and changed this extension to also save/restore the entire ANSI color
|
||||
table.
|
||||
262
docs/conf.py
@@ -13,10 +13,7 @@ import subprocess
|
||||
import sys
|
||||
import time
|
||||
from functools import partial
|
||||
from typing import (
|
||||
Any, Callable, Dict, Iterable, List, Match, Optional, Sequence, Tuple,
|
||||
Union
|
||||
)
|
||||
from typing import Any, Callable, Dict, Iterable, List, Match, Optional, Tuple
|
||||
|
||||
from docutils import nodes
|
||||
from docutils.parsers.rst.roles import set_classes
|
||||
@@ -24,17 +21,18 @@ from pygments.lexer import RegexLexer, bygroups # type: ignore
|
||||
from pygments.token import ( # type: ignore
|
||||
Comment, Keyword, Literal, Name, Number, String, Whitespace
|
||||
)
|
||||
from sphinx import addnodes, version_info # type: ignore
|
||||
from sphinx.environment.adapters.toctree import TocTree # type: ignore
|
||||
from sphinx.util.logging import getLogger # type: ignore
|
||||
from sphinx import addnodes, version_info
|
||||
from sphinx.builders.html.transforms import KeyboardTransform
|
||||
from sphinx.util.logging import getLogger
|
||||
|
||||
KeyboardTransform.builders = ('html', 'dirhtml') # type: ignore
|
||||
|
||||
kitty_src = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
||||
if kitty_src not in sys.path:
|
||||
sys.path.insert(0, kitty_src)
|
||||
|
||||
from kitty.conf.definition import Option, Shortcut # noqa
|
||||
from kitty.constants import str_version # noqa
|
||||
|
||||
from kitty.conf.types import Definition # noqa
|
||||
from kitty.constants import str_version, website_url # noqa
|
||||
|
||||
# config {{{
|
||||
# -- Project information -----------------------------------------------------
|
||||
@@ -64,8 +62,14 @@ extensions = [
|
||||
'sphinx.ext.ifconfig',
|
||||
'sphinx.ext.viewcode',
|
||||
'sphinx.ext.githubpages',
|
||||
'sphinx_copybutton',
|
||||
'sphinx_inline_tabs',
|
||||
"sphinxext.opengraph",
|
||||
]
|
||||
|
||||
# URL for OpenGraph tags
|
||||
ogp_site_url = website_url()
|
||||
|
||||
# Add any paths that contain templates here, relative to this directory.
|
||||
templates_path = ['_templates']
|
||||
|
||||
@@ -89,25 +93,18 @@ language: Optional[str] = None
|
||||
# directories to ignore when looking for source files.
|
||||
# This pattern also affects html_static_path and html_extra_path .
|
||||
exclude_patterns = [
|
||||
'_build', 'Thumbs.db', '.DS_Store',
|
||||
'generated/cli-*.rst', 'generated/conf-*.rst'
|
||||
'_build', 'Thumbs.db', '.DS_Store', 'basic.rst',
|
||||
'generated/cli-*.rst', 'generated/conf-*.rst', 'generated/actions.rst'
|
||||
]
|
||||
|
||||
# The name of the Pygments (syntax highlighting) style to use.
|
||||
pygments_style = 'sphinx'
|
||||
|
||||
rst_prolog = '''
|
||||
.. |kitty| replace:: *kitty*
|
||||
.. |version| replace:: VERSION
|
||||
.. _tarball: https://github.com/kovidgoyal/kitty/releases/download/vVERSION/kitty-VERSION.tar.xz
|
||||
.. role:: green
|
||||
.. role:: italic
|
||||
.. role:: bold
|
||||
.. role:: cyan
|
||||
.. role:: title
|
||||
.. role:: env
|
||||
|
||||
'''.replace('VERSION', str_version)
|
||||
smartquotes_action = 'qe' # educate quotes and ellipses but not dashes
|
||||
|
||||
|
||||
# -- Options for HTML output -------------------------------------------------
|
||||
@@ -115,32 +112,26 @@ rst_prolog = '''
|
||||
# The theme to use for HTML and HTML Help pages. See the documentation for
|
||||
# a list of builtin themes.
|
||||
#
|
||||
html_theme = 'alabaster'
|
||||
html_theme = 'furo'
|
||||
html_title = 'kitty'
|
||||
|
||||
# Theme options are theme-specific and customize the look and feel of a theme
|
||||
# further. For a list of options available for each theme, see the
|
||||
# documentation.
|
||||
#
|
||||
html_theme_options = {
|
||||
'logo': 'kitty.png',
|
||||
'show_powered_by': False,
|
||||
'fixed_sidebar': True,
|
||||
'sidebar_collapse': True,
|
||||
'github_button': False,
|
||||
'github_banner': True,
|
||||
'github_user': 'kovidgoyal',
|
||||
'github_repo': 'kitty',
|
||||
# increase contrast of link color with text color
|
||||
'link': '#00587d',
|
||||
'link_hover': 'green',
|
||||
html_theme_options: Dict[str, Any] = {
|
||||
'sidebar_hide_name': True,
|
||||
'navigation_with_keys': True,
|
||||
}
|
||||
|
||||
|
||||
# Add any paths that contain custom static files (such as style sheets) here,
|
||||
# relative to this directory. They are copied after the builtin static files,
|
||||
# so a file named "default.css" will overwrite the builtin "default.css".
|
||||
html_static_path = ['_static', '../logo/kitty.png']
|
||||
html_favicon = '../logo/kitty.png'
|
||||
html_static_path = ['_static']
|
||||
html_favicon = html_logo = '../logo/kitty.svg'
|
||||
html_css_files = ['custom.css']
|
||||
html_js_files = ['custom.js']
|
||||
|
||||
# Custom sidebar templates, must be a dictionary that maps document names
|
||||
# to template names.
|
||||
@@ -150,25 +141,17 @@ html_favicon = '../logo/kitty.png'
|
||||
# default: ``['localtoc.html', 'relations.html', 'sourcelink.html',
|
||||
# 'searchbox.html']``.
|
||||
#
|
||||
html_sidebars = {
|
||||
'**': [
|
||||
'about.html',
|
||||
'support.html',
|
||||
'searchbox.html',
|
||||
'localtoc.html',
|
||||
'relations.html',
|
||||
]
|
||||
}
|
||||
html_show_sourcelink = False
|
||||
|
||||
html_show_sphinx = False
|
||||
manpages_url = 'https://man7.org/linux/man-pages/man{section}/{page}.{section}.html'
|
||||
|
||||
# -- Options for manual page output ------------------------------------------
|
||||
|
||||
# One entry per manual page. List of tuples
|
||||
# (source start file, name, description, authors, manual section).
|
||||
man_pages = [
|
||||
('invocation', 'kitty', 'kitty Documentation',
|
||||
[author], 1)
|
||||
('invocation', 'kitty', 'kitty Documentation', [author], 1),
|
||||
('conf', 'kitty.conf', 'kitty.conf Documentation', [author], 5)
|
||||
]
|
||||
|
||||
|
||||
@@ -187,7 +170,9 @@ texinfo_documents = [
|
||||
|
||||
# GitHub linking inline roles {{{
|
||||
|
||||
def num_role(which: str, name: str, rawtext: str, text: str, lineno: int, inliner: Any, options: Any = {}, content: Any = []) -> Tuple[List, List]:
|
||||
def num_role(
|
||||
which: str, name: str, rawtext: str, text: str, lineno: int, inliner: Any, options: Any = {}, content: Any = []
|
||||
) -> Tuple[List[nodes.reference], List[nodes.problematic]]:
|
||||
' Link to a github issue '
|
||||
try:
|
||||
issue_num = int(text)
|
||||
@@ -205,7 +190,9 @@ def num_role(which: str, name: str, rawtext: str, text: str, lineno: int, inline
|
||||
return [node], []
|
||||
|
||||
|
||||
def commit_role(name: str, rawtext: str, text: str, lineno: int, inliner: Any, options: Any = {}, content: Any = []) -> Tuple[List, List]:
|
||||
def commit_role(
|
||||
name: str, rawtext: str, text: str, lineno: int, inliner: Any, options: Any = {}, content: Any = []
|
||||
) -> Tuple[List[nodes.reference], List[nodes.problematic]]:
|
||||
' Link to a github commit '
|
||||
try:
|
||||
commit_id = subprocess.check_output(
|
||||
@@ -224,32 +211,10 @@ def commit_role(name: str, rawtext: str, text: str, lineno: int, inliner: Any, o
|
||||
# }}}
|
||||
|
||||
|
||||
# Sidebar ToC {{{
|
||||
def create_toc(app: Any, pagename: str) -> Optional[Any]:
|
||||
tt = TocTree(app.env)
|
||||
toctree = tt.get_toc_for(pagename, app.builder)
|
||||
if toctree is not None:
|
||||
subtree = toctree[toctree.first_child_matching_class(nodes.list_item)]
|
||||
bl = subtree.first_child_matching_class(nodes.bullet_list)
|
||||
if bl is None:
|
||||
return None # Empty ToC
|
||||
subtree = subtree[bl]
|
||||
# for li in subtree.traverse(nodes.list_item):
|
||||
# modify_li(li)
|
||||
# subtree['ids'] = [ID]
|
||||
return app.builder.render_partial(subtree)['fragment']
|
||||
|
||||
|
||||
def add_html_context(app: Any, pagename: str, templatename: str, context: Any, *args: Any) -> None:
|
||||
if 'toc' in context:
|
||||
context['toc'] = create_toc(app, pagename) or context['toc']
|
||||
# }}}
|
||||
|
||||
|
||||
# CLI docs {{{
|
||||
def write_cli_docs(all_kitten_names: Iterable[str]) -> None:
|
||||
from kitty.launch import options_spec as launch_options_spec
|
||||
from kitty.cli import option_spec_as_rst
|
||||
from kitty.launch import options_spec as launch_options_spec
|
||||
with open('generated/launch.rst', 'w') as f:
|
||||
f.write(option_spec_as_rst(
|
||||
appname='launch', ospec=launch_options_spec, heading_char='_',
|
||||
@@ -264,7 +229,7 @@ if you specify a program-to-run you can use the special placeholder
|
||||
'kitty --to', 'kitty @ --to'))
|
||||
as_rst = partial(option_spec_as_rst, heading_char='_')
|
||||
from kitty.rc.base import all_command_names, command_for_name
|
||||
from kitty.remote_control import global_options_spec, cli_msg
|
||||
from kitty.remote_control import cli_msg, global_options_spec
|
||||
with open('generated/cli-kitty-at.rst', 'w') as f:
|
||||
p = partial(print, file=f)
|
||||
p('kitty @\n' + '-' * 80)
|
||||
@@ -285,6 +250,11 @@ if you specify a program-to-run you can use the special placeholder
|
||||
with open(f'generated/cli-kitten-{kitten}.rst', 'w') as f:
|
||||
p = partial(print, file=f)
|
||||
p('.. program::', f'kitty +kitten {kitten}')
|
||||
p(f'\nSource code for {kitten}')
|
||||
p('-' * 72)
|
||||
p(f'\nThe source code for this kitten is `available on GitHub <https://github.com/kovidgoyal/kitty/tree/master/kittens/{kitten}>`_.')
|
||||
p('\nCommand Line Interface')
|
||||
p('-' * 72, file=f)
|
||||
p('\n\n' + option_spec_as_rst(
|
||||
data['options'], message=data['help_text'], usage=data['usage'], appname=f'kitty +kitten {kitten}',
|
||||
heading_char='^'))
|
||||
@@ -293,10 +263,12 @@ if you specify a program-to-run you can use the special placeholder
|
||||
|
||||
|
||||
def write_remote_control_protocol_docs() -> None: # {{{
|
||||
from kitty.rc.base import all_command_names, command_for_name, RemoteCommand
|
||||
from kitty.rc.base import (
|
||||
RemoteCommand, all_command_names, command_for_name
|
||||
)
|
||||
field_pat = re.compile(r'\s*([a-zA-Z0-9_+]+)\s*:\s*(.+)')
|
||||
|
||||
def format_cmd(p: Callable, name: str, cmd: RemoteCommand) -> None:
|
||||
def format_cmd(p: Callable[..., None], name: str, cmd: RemoteCommand) -> None:
|
||||
p(name)
|
||||
p('-' * 80)
|
||||
lines = (cmd.__doc__ or '').strip().splitlines()
|
||||
@@ -336,7 +308,7 @@ def write_remote_control_protocol_docs() -> None: # {{{
|
||||
|
||||
# config file docs {{{
|
||||
|
||||
class ConfLexer(RegexLexer):
|
||||
class ConfLexer(RegexLexer): # type: ignore
|
||||
name = 'Conf'
|
||||
aliases = ['conf']
|
||||
filenames = ['*.conf']
|
||||
@@ -349,6 +321,8 @@ class ConfLexer(RegexLexer):
|
||||
(r'(include)(\s+)(.+?)$', bygroups(Comment.Preproc, Whitespace, Name.Namespace)),
|
||||
(r'(map)(\s+)(\S+)(\s+)', bygroups(
|
||||
Keyword.Declaration, Whitespace, String, Whitespace), 'action'),
|
||||
(r'(mouse_map)(\s+)(\S+)(\s+)(\S+)(\s+)(\S+)(\s+)', bygroups(
|
||||
Keyword.Declaration, Whitespace, String, Whitespace, Name.Variable, Whitespace, String, Whitespace), 'action'),
|
||||
(r'(symbol_map)(\s+)(\S+)(\s+)(.+?)$', bygroups(
|
||||
Keyword.Declaration, Whitespace, String, Whitespace, Literal)),
|
||||
(r'([a-zA-Z_0-9]+)(\s+)', bygroups(
|
||||
@@ -373,7 +347,7 @@ class ConfLexer(RegexLexer):
|
||||
}
|
||||
|
||||
|
||||
class SessionLexer(RegexLexer):
|
||||
class SessionLexer(RegexLexer): # type: ignore
|
||||
name = 'Session'
|
||||
aliases = ['session']
|
||||
filenames = ['*.session']
|
||||
@@ -389,13 +363,17 @@ class SessionLexer(RegexLexer):
|
||||
}
|
||||
|
||||
|
||||
def link_role(name: str, rawtext: str, text: str, lineno: int, inliner: Any, options: Any = {}, content: Any = []) -> Tuple[List, List]:
|
||||
def link_role(
|
||||
name: str, rawtext: str, text: str, lineno: int, inliner: Any, options: Any = {}, content: Any = []
|
||||
) -> Tuple[List[nodes.reference], List[nodes.problematic]]:
|
||||
text = text.replace('\n', ' ')
|
||||
m = re.match(r'(.+)\s+<(.+?)>', text)
|
||||
if m is None:
|
||||
msg = inliner.reporter.error(f'link "{text}" not recognized', line=lineno)
|
||||
prb = inliner.problematic(rawtext, rawtext, msg)
|
||||
return [prb], [msg]
|
||||
text, url = m.group(1, 2)
|
||||
url = url.replace(' ', '')
|
||||
set_classes(options)
|
||||
node = nodes.reference(rawtext, text, refuri=url, **options)
|
||||
return [node], []
|
||||
@@ -404,7 +382,7 @@ def link_role(name: str, rawtext: str, text: str, lineno: int, inliner: Any, opt
|
||||
def expand_opt_references(conf_name: str, text: str) -> str:
|
||||
conf_name += '.'
|
||||
|
||||
def expand(m: Match) -> str:
|
||||
def expand(m: Match[str]) -> str:
|
||||
ref = m.group(1)
|
||||
if '<' not in ref and '.' not in ref:
|
||||
full_ref = conf_name + ref
|
||||
@@ -447,87 +425,6 @@ def parse_shortcut_node(env: Any, sig: str, signode: Any) -> str:
|
||||
return sig
|
||||
|
||||
|
||||
def render_conf(conf_name: str, all_options: Iterable[Union['Option', Sequence['Shortcut']]]) -> str:
|
||||
from kitty.conf.definition import merged_opts, Option, Group
|
||||
ans = ['.. default-domain:: conf', '']
|
||||
a = ans.append
|
||||
current_group: Optional[Group] = None
|
||||
all_options_ = list(all_options)
|
||||
kitty_mod = 'kitty_mod'
|
||||
|
||||
def render_group(group: Group) -> None:
|
||||
a('')
|
||||
a(f'.. _conf-{conf_name}-{group.name}:')
|
||||
a('')
|
||||
a(group.short_text)
|
||||
heading_level = '+' if '.' in group.name else '^'
|
||||
a(heading_level * (len(group.short_text) + 20))
|
||||
a('')
|
||||
if group.start_text:
|
||||
a(group.start_text)
|
||||
a('')
|
||||
|
||||
def handle_group_end(group: Group) -> None:
|
||||
if group.end_text:
|
||||
assert current_group is not None
|
||||
a(''), a(current_group.end_text)
|
||||
|
||||
def handle_group(new_group: Group, new_group_is_shortcut: bool = False) -> None:
|
||||
nonlocal current_group
|
||||
if new_group is not current_group:
|
||||
if current_group:
|
||||
handle_group_end(current_group)
|
||||
current_group = new_group
|
||||
render_group(current_group)
|
||||
|
||||
def handle_option(i: int, opt: Option) -> None:
|
||||
nonlocal kitty_mod
|
||||
if not opt.long_text or not opt.add_to_docs:
|
||||
return
|
||||
handle_group(opt.group)
|
||||
if opt.name == 'kitty_mod':
|
||||
kitty_mod = opt.defval_as_string
|
||||
mopts = list(merged_opts(all_options_, opt, i))
|
||||
a('.. opt:: ' + ', '.join(conf_name + '.' + mo.name for mo in mopts))
|
||||
a('.. code-block:: conf')
|
||||
a('')
|
||||
sz = max(len(x.name) for x in mopts)
|
||||
for mo in mopts:
|
||||
a((' {:%ds} {}' % sz).format(mo.name, mo.defval_as_string))
|
||||
a('')
|
||||
if opt.long_text:
|
||||
a(expand_opt_references(conf_name, opt.long_text))
|
||||
a('')
|
||||
|
||||
def handle_shortcuts(shortcuts: Sequence[Shortcut]) -> None:
|
||||
sc = shortcuts[0]
|
||||
handle_group(sc.group, True)
|
||||
sc_text = f'{conf_name}.{sc.short_text}'
|
||||
a('.. shortcut:: ' + sc_text)
|
||||
shortcuts = [s for s in shortcuts if s.add_to_default]
|
||||
shortcut_slugs[f'{conf_name}.{sc.name}'] = (sc_text, sc.key.replace('kitty_mod', kitty_mod))
|
||||
if shortcuts:
|
||||
a('.. code-block:: conf')
|
||||
a('')
|
||||
for x in shortcuts:
|
||||
if x.add_to_default:
|
||||
a(' map {} {}'.format(x.key.replace('kitty_mod', kitty_mod), x.action_def))
|
||||
a('')
|
||||
if sc.long_text:
|
||||
a(expand_opt_references(conf_name, sc.long_text))
|
||||
a('')
|
||||
|
||||
for i, opt in enumerate(all_options_):
|
||||
if isinstance(opt, Option):
|
||||
handle_option(i, opt)
|
||||
else:
|
||||
handle_shortcuts(opt)
|
||||
|
||||
if current_group:
|
||||
handle_group_end(current_group)
|
||||
return '\n'.join(ans)
|
||||
|
||||
|
||||
def process_opt_link(env: Any, refnode: Any, has_explicit_title: bool, title: str, target: str) -> Tuple[str, str]:
|
||||
conf_name, opt = target.partition('.')[::2]
|
||||
if not opt:
|
||||
@@ -571,29 +468,47 @@ def write_conf_docs(app: Any, all_kitten_names: Iterable[str]) -> None:
|
||||
sc_role = app.registry.domain_roles['std']['sc']
|
||||
sc_role.warn_dangling = True
|
||||
sc_role.process_link = process_shortcut_link
|
||||
shortcut_slugs.clear()
|
||||
|
||||
def generate_default_config(all_options: Dict[str, Union[Option, Sequence[Shortcut]]], name: str) -> None:
|
||||
from kitty.conf.definition import as_conf_file
|
||||
def generate_default_config(definition: Definition, name: str) -> None:
|
||||
with open(f'generated/conf-{name}.rst', 'w', encoding='utf-8') as f:
|
||||
print('.. highlight:: conf\n', file=f)
|
||||
f.write(render_conf(name, all_options.values()))
|
||||
f.write('\n'.join(definition.as_rst(name, shortcut_slugs)))
|
||||
|
||||
conf_name = re.sub(r'^kitten-', '', name) + '.conf'
|
||||
with open(f'generated/conf/{conf_name}', 'w', encoding='utf-8') as f:
|
||||
text = '\n'.join(as_conf_file(all_options.values()))
|
||||
text = '\n'.join(definition.as_conf())
|
||||
print(text, file=f)
|
||||
|
||||
from kitty.config_data import all_options
|
||||
generate_default_config(all_options, 'kitty')
|
||||
from kitty.options.definition import definition
|
||||
generate_default_config(definition, 'kitty')
|
||||
|
||||
from kittens.runner import get_kitten_conf_docs
|
||||
for kitten in all_kitten_names:
|
||||
all_options = get_kitten_conf_docs(kitten)
|
||||
if all_options:
|
||||
generate_default_config(all_options, f'kitten-{kitten}')
|
||||
definition = get_kitten_conf_docs(kitten)
|
||||
if definition:
|
||||
generate_default_config(definition, f'kitten-{kitten}')
|
||||
|
||||
from kitty.actions import as_rst
|
||||
with open('generated/actions.rst', 'w', encoding='utf-8') as f:
|
||||
f.write(as_rst())
|
||||
# }}}
|
||||
|
||||
|
||||
def add_html_context(app: Any, pagename: str, templatename: str, context: Any, doctree: Any, *args: Any) -> None:
|
||||
context['analytics_id'] = app.config.analytics_id
|
||||
if 'toctree' in context:
|
||||
# this is needed with furo to use all titles from pages
|
||||
# in the sidebar (global) toc
|
||||
original_toctee_function = context['toctree']
|
||||
|
||||
def include_sub_headings(**kwargs: Any) -> Any:
|
||||
kwargs['titles_only'] = False
|
||||
return original_toctee_function(**kwargs)
|
||||
|
||||
context['toctree'] = include_sub_headings
|
||||
|
||||
|
||||
def setup(app: Any) -> None:
|
||||
os.makedirs('generated/conf', exist_ok=True)
|
||||
from kittens.runner import all_kitten_names
|
||||
@@ -601,10 +516,15 @@ def setup(app: Any) -> None:
|
||||
write_cli_docs(kn)
|
||||
write_remote_control_protocol_docs()
|
||||
write_conf_docs(app, kn)
|
||||
app.add_css_file('custom.css')
|
||||
app.add_config_value('analytics_id', '', 'env')
|
||||
app.connect('html-page-context', add_html_context)
|
||||
app.add_lexer('session', SessionLexer() if version_info[0] < 3 else SessionLexer)
|
||||
app.add_role('link', link_role)
|
||||
app.add_role('iss', partial(num_role, 'issues'))
|
||||
app.add_role('pull', partial(num_role, 'pull'))
|
||||
app.add_role('disc', partial(num_role, 'discussions'))
|
||||
app.add_role('commit', commit_role)
|
||||
app.connect('html-page-context', add_html_context)
|
||||
# monkey patch sphinx_inline_tabs to avoid a warning about parallel reads
|
||||
# see https://github.com/pradyunsg/sphinx-inline-tabs/issues/26
|
||||
inline_tabs = app.extensions['sphinx_inline_tabs']
|
||||
inline_tabs.parallel_read_safe = inline_tabs.parallel_write_safe = True
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
:tocdepth: 2
|
||||
|
||||
Configuring kitty
|
||||
===============================
|
||||
kitty.conf
|
||||
-----------------------
|
||||
|
||||
.. highlight:: conf
|
||||
|
||||
|kitty| is highly customizable, everything from keyboard shortcuts, to painting
|
||||
frames-per-second. See below for an overview of all customization
|
||||
|kitty| is highly customizable, everything from keyboard shortcuts, to
|
||||
rendering frames-per-second. See below for an overview of all customization
|
||||
possibilities.
|
||||
|
||||
You can open the config file within kitty by pressing :sc:`edit_config_file`.
|
||||
You can also display the current configuration by running ``kitty
|
||||
--debug-config``.
|
||||
You can reload the config file within kitty by pressing
|
||||
:sc:`reload_config_file` (:kbd:`⌃+⌘+,` on macOS) or sending kitty the ``SIGUSR1`` signal.
|
||||
You can also display the current configuration by pressing the :sc:`debug_config`
|
||||
(:kbd:`⌘+⌥+f6` on macOS) key.
|
||||
|
||||
.. _confloc:
|
||||
|
||||
@@ -33,12 +33,37 @@ expanded, so :code:`${USER}.conf` becomes :file:`name.conf` if
|
||||
include other.conf
|
||||
|
||||
|
||||
.. note:: Syntax highlighting for :file:`kitty.conf` in vim is available via
|
||||
`vim-kitty <https://github.com/fladson/vim-kitty>`_.
|
||||
|
||||
|
||||
.. include:: /generated/conf-kitty.rst
|
||||
|
||||
|
||||
Sample kitty.conf
|
||||
^^^^^^^^^^^^^^^^^^^^^
|
||||
--------------------
|
||||
|
||||
You can download a sample :file:`kitty.conf` file with all default settings and
|
||||
comments describing each setting by clicking: :download:`sample kitty.conf
|
||||
</generated/conf/kitty.conf>`.
|
||||
.. only:: html
|
||||
|
||||
You can download a sample :file:`kitty.conf` file with all default settings and
|
||||
comments describing each setting by clicking: :download:`sample kitty.conf
|
||||
</generated/conf/kitty.conf>`.
|
||||
|
||||
.. only:: man
|
||||
|
||||
You can edit a fully commented sample kitty.conf by pressing the
|
||||
:sc:`edit_config_file` shortcut in kitty. This will generate a config
|
||||
file with full documentation and all settings commented out. If you
|
||||
have a pre-existing kitty.conf, then that will be used instead, delete
|
||||
it to see the sample file.
|
||||
|
||||
|
||||
All mappable actions
|
||||
------------------------
|
||||
|
||||
See the :doc:`list of all the things you can make kitty can do </actions>`.
|
||||
|
||||
.. toctree::
|
||||
:hidden:
|
||||
|
||||
actions
|
||||
|
||||
21
docs/deccara.rst
Normal file
@@ -0,0 +1,21 @@
|
||||
Setting text styles/colors in arbitrary regions of the screen
|
||||
------------------------------------------------------------------
|
||||
|
||||
There already exists an escape code to set *some* text attributes in arbitrary
|
||||
regions of the screen, `DECCARA
|
||||
<https://vt100.net/docs/vt510-rm/DECCARA.html>`_. However, it is limited to
|
||||
only a few attributes. |kitty| extends this to work with *all* SGR attributes.
|
||||
So, for example, this can be used to set the background color in an arbitrary
|
||||
region of the screen.
|
||||
|
||||
The motivation for this extension is the various problems with the existing
|
||||
solution for erasing to background color, namely the *background color erase
|
||||
(bce)* capability. See
|
||||
`this discussion <https://github.com/kovidgoyal/kitty/issues/160#issuecomment-346470545>`_
|
||||
and `this FAQ <https://invisible-island.net/ncurses/ncurses.faq.html#bce_mismatches>`_
|
||||
for a summary of problems with *bce*.
|
||||
|
||||
For example, to set the background color to blue in a
|
||||
rectangular region of the screen from (3, 4) to (10, 11), you use::
|
||||
|
||||
<ESC>[2*x<ESC>[4;3;11;10;44$r<ESC>[*x
|
||||
122
docs/desktop-notifications.rst
Normal file
@@ -0,0 +1,122 @@
|
||||
.. _desktop_notifications:
|
||||
|
||||
|
||||
Desktop notifications
|
||||
=======================
|
||||
|
||||
|kitty| implements an extensible escape code (OSC 99) to show desktop
|
||||
notifications. It is easy to use from shell scripts and fully extensible to
|
||||
show title and body. Clicking on the notification can optionally focus the
|
||||
window it came from, and/or send an escape code back to the application running
|
||||
in that window.
|
||||
|
||||
The design of the escape code is partially based on the discussion in
|
||||
the defunct
|
||||
`terminal-wg <https://gitlab.freedesktop.org/terminal-wg/specifications/-/issues/13>`_
|
||||
|
||||
The escape code has the form::
|
||||
|
||||
<OSC> 99 ; metadata ; payload <terminator>
|
||||
|
||||
Here ``<OSC>`` is :code:`<ESC>]` and ``<terminator>`` is
|
||||
:code:`<ESC><backslash>`. The metadata is a section of colon separated
|
||||
:code:`key=value` pairs. Every key must be a single character from the set
|
||||
:code:`a-zA-Z` and every value must be a word consisting of characters from
|
||||
the set :code:`a-zA-Z0-9-_/\+.,(){}[]*&^%$#@!`~`. The payload must be
|
||||
interpreted based on the metadata section. The two semi-colons *must* always be
|
||||
present even when no metadata is present.
|
||||
|
||||
Before going into details, lets see how one can display a simple, single line
|
||||
notification from a shell script::
|
||||
|
||||
printf '\x1b]99;;Hello world\x1b\\'
|
||||
|
||||
To show a message with a title and a body::
|
||||
|
||||
printf '\x1b]99;i=1:d=0;Hello world\x1b\\'
|
||||
printf '\x1b]99;i=1:d=1:p=body;This is cool\x1b\\'
|
||||
|
||||
The most important key in the metadata is the ``p`` key, it controls how the
|
||||
payload is interpreted. A value of ``title`` means the payload is setting the
|
||||
title for the notification. A value of ``body`` means it is setting the body,
|
||||
and so on, see the table below for full details.
|
||||
|
||||
The design of the escape code is fundamentally chunked, this is because
|
||||
different terminal emulators have different limits on how large a single escape
|
||||
code can be. Chunking is accomplished by the ``i`` and ``d`` keys. The ``i``
|
||||
key is the *notification id* which can be any string containing the characters
|
||||
``[a-zA-Z0-9_-+.]``. The ``d`` key stands for *done* and
|
||||
can only take the values ``0`` and ``1``. A value of ``0`` means the
|
||||
notification is not yet done and the terminal emulator should hold off
|
||||
displaying it. A value of ``1`` means the notification is done, and should be
|
||||
displayed. You can specify the title or body multiple times and the terminal
|
||||
emulator will concatenate them, thereby allowing arbitrarily long text
|
||||
(terminal emulators are free to impose a sensible limit to avoid
|
||||
Denial-of-Service attacks).
|
||||
|
||||
Both the ``title`` and ``body`` payloads must be either UTF-8 encoded plain
|
||||
text with no embedded escape codes, or UTF-8 text that is base64 encoded, in
|
||||
which case there must be an ``e=1`` key in the metadata to indicate the payload
|
||||
is base64 encoded.
|
||||
|
||||
When the user clicks the notification, a couple of things can happen, the
|
||||
terminal emulator can focus the window from which the notification came, and/or
|
||||
it can send back an escape code to the application indicating the notification
|
||||
was activated. This is controlled by the ``a`` key which takes a comma
|
||||
separated set of values, ``report`` and ``focus``. The value ``focus`` means
|
||||
focus the window from which the notification was issued and is the default.
|
||||
``report`` means send an escape code back to the application. The format of the
|
||||
returned escape code is::
|
||||
|
||||
<OSC> 99 ; i=identifier ; <terminator>
|
||||
|
||||
The value of ``identifier`` comes from the ``i`` key in the escape code sent by
|
||||
the application. If the application sends no identifier, then the terminal
|
||||
*must* use ``i=0``. Actions can be preceded by a negative sign to turn them
|
||||
off, so for example if you do not want any action, turn off the default
|
||||
``focus`` action with::
|
||||
|
||||
a=-focus
|
||||
|
||||
Complete specification of all the metadata keys is in the table below. If a
|
||||
terminal emulator encounters a key in the metadata it does not understand,
|
||||
the key *must* be ignored, to allow for future extensibility of this escape
|
||||
code. Similarly if values for known keys are unknown, the terminal emulator
|
||||
*should* either ignore the entire escape code or perform a best guess effort
|
||||
to display it based on what it does understand.
|
||||
|
||||
.. note::
|
||||
It is possible to extend this escape code to allow specifying an icon for
|
||||
the notification, however, given that some platforms, such as macOS, dont
|
||||
allow displaying custom icons on a notification, at all, it was decided to
|
||||
leave it out of the spec for the time being.
|
||||
|
||||
Similarly, features such as scheduled notifications could be added in future
|
||||
revisions.
|
||||
|
||||
|
||||
======= ==================== ========= =================
|
||||
Key Value Default Description
|
||||
======= ==================== ========= =================
|
||||
``a`` Comma separated list ``focus`` What action to perform when the
|
||||
of ``report``, notification is clicked
|
||||
``focus``, with
|
||||
optional leading
|
||||
``-``
|
||||
|
||||
``d`` ``0`` or ``1`` ``1`` Indicates if the notification is
|
||||
complete or not.
|
||||
|
||||
``e`` ``0`` or ``1`` ``0`` If set to ``1`` means the payload is base64 encoded UTF-8,
|
||||
otherwise it is plain UTF-8 text with no C0 control codes in it
|
||||
|
||||
``i`` ``[a-zA-Z0-9-_+.]`` ``0`` Identifier for the notification
|
||||
|
||||
``p`` One of ``title`` or ``title`` Whether the payload is the notification title or body. If a
|
||||
``body``. notification has no title, the body will be used as title.
|
||||
======= ==================== ========= =================
|
||||
|
||||
|
||||
.. note::
|
||||
|kitty| also supports the legacy OSC 9 protocol developed by iTerm2 for
|
||||
desktop notifications.
|
||||
145
docs/faq.rst
@@ -3,8 +3,6 @@ Frequently Asked Questions
|
||||
|
||||
.. highlight:: sh
|
||||
|
||||
.. contents::
|
||||
|
||||
Some special symbols are rendered small/truncated in kitty?
|
||||
-----------------------------------------------------------
|
||||
|
||||
@@ -35,7 +33,7 @@ it by adding the following to your vimrc::
|
||||
|
||||
let &t_ut=''
|
||||
|
||||
See :ref:`here <ext_styles>` for why |kitty| does not support background color erase.
|
||||
See :doc:`here <deccara>` for why |kitty| does not support background color erase.
|
||||
|
||||
|
||||
I get errors about the terminal being unknown or opening the terminal failing when SSHing into a different computer?
|
||||
@@ -53,8 +51,12 @@ type it each time::
|
||||
|
||||
alias ssh="kitty +kitten ssh"
|
||||
|
||||
Remember to also setup :ref:`shell_integration` for completion and other
|
||||
niceties.
|
||||
|
||||
If for some reason that does not work (typically because the server is using a
|
||||
non POSIX compliant shell), you can try using it with python instead::
|
||||
non POSIX compliant shell as ``/bin/sh``), you can try using it with ``python``
|
||||
instead::
|
||||
|
||||
kitty +kitten ssh use-python myserver
|
||||
|
||||
@@ -63,7 +65,7 @@ server, use the following one-liner instead (it
|
||||
is slower as it needs to ssh into the server twice, but will work with most
|
||||
servers)::
|
||||
|
||||
infocmp xterm-kitty | ssh myserver tic -x -o \~/.terminfo /dev/stdin
|
||||
infocmp -a xterm-kitty | ssh myserver tic -x -o \~/.terminfo /dev/stdin
|
||||
|
||||
If you are behind a proxy (like Balabit) that prevents this, you must redirect the
|
||||
1st command to a file, copy that to the server and run ``tic`` manually. If you
|
||||
@@ -118,9 +120,14 @@ explicitly set a UTF-8 locale, like::
|
||||
How do I change the colors in a running kitty instance?
|
||||
------------------------------------------------------------
|
||||
|
||||
You can either use the
|
||||
`OSC terminal escape codes <https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h2-Operating-System-Commands>`_
|
||||
to set colors or you can define keyboard shortcuts to set colors, for example::
|
||||
The easiest way to do it is to use the :doc:`themes kitten </kittens/themes>`,
|
||||
to choose a new color theme. Simply run::
|
||||
|
||||
kitty +kitten themes
|
||||
|
||||
And choose your theme from the list.
|
||||
|
||||
You can also define keyboard shortcuts to set colors, for example::
|
||||
|
||||
map f1 set_colors --configured /path/to/some/config/file/colors.conf
|
||||
|
||||
@@ -128,10 +135,9 @@ Or you can enable :doc:`remote control <remote-control>` for |kitty| and use :re
|
||||
The shortcut mapping technique has the same syntax as the remote control
|
||||
command, for details, see :ref:`at_set-colors`.
|
||||
|
||||
A list of pre-made color themes for kitty is available at:
|
||||
`kitty-themes <https://github.com/dexpota/kitty-themes>`_
|
||||
|
||||
Examples of using OSC escape codes to set colors::
|
||||
Additionally, You can use the
|
||||
`OSC terminal escape codes <https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h3-Operating-System-Commands>`_
|
||||
to set colors. Examples of using OSC escape codes to set colors::
|
||||
|
||||
Change the default foreground color:
|
||||
printf '\x1b]10;#ff0000\x1b\\'
|
||||
@@ -169,17 +175,39 @@ You can, of course, also run |kitty| from a terminal with command line options,
|
||||
And within |kitty| itself, you can always run |kitty| using just `kitty` as it
|
||||
cleverly adds itself to the ``PATH``.
|
||||
|
||||
I catted a binary file and now kitty is hung?
|
||||
-----------------------------------------------
|
||||
|
||||
**Never** output unknown binary data directly into a terminal.
|
||||
|
||||
Terminals have a single channel for both data and control. Certain bytes
|
||||
are control codes. Some of these control codes are of arbitrary length, so
|
||||
if the binary data you output into the terminal happens to contain the starting
|
||||
sequence for one of these control codes, the terminal will hang waiting for
|
||||
the closing sequence. Press :kbd:`ctrl+shift+delete` to reset the terminal.
|
||||
|
||||
If you do want to cat unknown data, use ``cat -v``.
|
||||
|
||||
|
||||
kitty is not able to use my favorite font?
|
||||
---------------------------------------------
|
||||
|
||||
|kitty| achieves its stellar performance by caching alpha masks of each rendered
|
||||
character on the GPU, so that every character needs to be rendered only once.
|
||||
This means it is a strictly character cell based display. As such it can use
|
||||
only monospace fonts, since every cell in the grid has to be the same size.
|
||||
|kitty| achieves its stellar performance by caching alpha masks of each
|
||||
rendered character on the GPU, and rendering them all in parallel. This means
|
||||
it is a strictly character cell based display. As such it can use only
|
||||
monospace fonts, since every cell in the grid has to be the same size.
|
||||
Furthermore, it needs fonts to be freely resizable, so it does not support
|
||||
bitmapped fonts.
|
||||
|
||||
.. note::
|
||||
If you are trying to use a font patched with NERD font symbols, dont do that
|
||||
as patching destroys fonts. There is no need, simply install the standalone
|
||||
NERD font, kitty should pick up symbols from it automatically, and you can
|
||||
tell it to do so explicitly in case it doesnt with the :opt:`symbol_map`
|
||||
directive::
|
||||
|
||||
symbol_map U+23FB-U+23FE,U+2B58,U+E200-U+E2A9,U+E0A0-U+E0A3,U+E0B0-U+E0BF,U+E0C0-U+E0C8,U+E0CC-U+E0CF,U+E0D0-U+E0D2,U+E0D4,U+E700-U+E7C5,U+F000-U+F2E0,U+2665,U+26A1,U+F400-U+F4A8,U+F67C,U+E000-U+E00A,U+F300-U+F313,U+E5FA-U+E62B Symbols Nerd Font
|
||||
|
||||
If your font is not listed in ``kitty list-fonts`` it means that it is not
|
||||
monospace or is a bitmapped font. On Linux you can list all monospace fonts with::
|
||||
|
||||
@@ -220,32 +248,51 @@ terminal) in different environments,
|
||||
see `here <https://github.com/kovidgoyal/kitty/issues/45>`_.
|
||||
|
||||
|
||||
I do not like the kitty icon!
|
||||
-------------------------------
|
||||
|
||||
There are many alternate icons available, click on an icon to visit its
|
||||
homepage:
|
||||
|
||||
.. image:: https://github.com/k0nserv/kitty-icon/raw/main/icon_512x512.png
|
||||
:target: https://github.com/k0nserv/kitty-icon
|
||||
:width: 256
|
||||
|
||||
.. image:: https://github.com/DinkDonk/kitty-icon/raw/main/kitty-dark.png
|
||||
:target: https://github.com/DinkDonk/kitty-icon
|
||||
:width: 256
|
||||
|
||||
.. image:: https://github.com/DinkDonk/kitty-icon/raw/main/kitty-light.png
|
||||
:target: https://github.com/DinkDonk/kitty-icon
|
||||
:width: 256
|
||||
|
||||
.. image:: https://github.com/hristost/kitty-alternative-icon/raw/main/kitty_icon.png
|
||||
:target: https://github.com/hristost/kitty-alternative-icon
|
||||
:width: 256
|
||||
|
||||
On macOS you can change the icon by following the steps:
|
||||
|
||||
#. Find :file:`kitty.app` in the Applications folder, select it and press :kbd:`⌘+i`
|
||||
#. Drag :file:`kitty.icns` onto the application icon in the kitty info pane
|
||||
#. Delete the icon cache and restart Dock::
|
||||
|
||||
$ rm /var/folders/*/*/*/com.apple.dock.iconcache; killall Dock
|
||||
|
||||
|
||||
How do I map key presses in kitty to different keys in the terminal program?
|
||||
--------------------------------------------------------------------------------------
|
||||
|
||||
This is accomplished by using ``map`` with :sc:`send_text <send_text>` in :file:`kitty.conf`.
|
||||
For example::
|
||||
|
||||
map alt+s send_text all \x13
|
||||
map alt+s send_text normal,application \x13
|
||||
|
||||
This maps :kbd:`alt+s` to :kbd:`ctrl+s`. To figure out what bytes to use for
|
||||
the :sc:`send_text <send_text>` you can use the ``showkey`` utility. Run::
|
||||
the :sc:`send_text <send_text>` you can use the ``show_key`` kitten. Run::
|
||||
|
||||
showkey -a
|
||||
kitty +kitten show_key
|
||||
|
||||
Then press the key you want to emulate. On macOS, this utility is currently not
|
||||
available. The manual way to figure it out is:
|
||||
|
||||
1. Look up your key's decimal value in the table at the bottom of `this
|
||||
page <http://ascii-table.com/ansi-escape-sequences.php>`_ or any
|
||||
ANSI escape sequence table. There are different modifiers for :kbd:`ctrl`,
|
||||
:kbd:`alt`, etc. For e.g., for :kbd:`ctrl+s`, find the ``S`` row and look at
|
||||
the third column value, ``19``.
|
||||
|
||||
2. Convert the decimal value to hex with ``kitty +runpy "print(hex(19))"``.
|
||||
This shows the hex value, ``13`` in this case.
|
||||
|
||||
3. Use ``\x(hexval)`` in your ``send_text`` command in kitty. So in this example, ``\x13``
|
||||
Then press the key you want to emulate.
|
||||
|
||||
How do I open a new window or tab with the same working directory as the current window?
|
||||
--------------------------------------------------------------------------------------------
|
||||
@@ -253,7 +300,7 @@ How do I open a new window or tab with the same working directory as the current
|
||||
In :file:`kitty.conf` add the following::
|
||||
|
||||
map f1 launch --cwd=current
|
||||
map f2 launch --cwd=current --type=tab
|
||||
map f2 launch --cwd=current --type=tab
|
||||
|
||||
Pressing :kbd:`F1` will open a new kitty window with the same working directory
|
||||
as the current window. The :doc:`launch command <launch>` is very powerful,
|
||||
@@ -299,15 +346,14 @@ If you still want to use tmux, read on.
|
||||
Image display will not work, see `tmux issue
|
||||
<https://github.com/tmux/tmux/issues/1391>`_.
|
||||
|
||||
Using ancient versions of tmux such as 1.8 will
|
||||
cause gibberish on screen when pressing keys (:iss:`3541`).
|
||||
|
||||
If you are using tmux with multiple terminals or you start it under one
|
||||
terminal and then switch to another and these terminals have different TERM
|
||||
variables, tmux will break. You will need to restart it as tmux does not
|
||||
support multiple terminfo definitions.
|
||||
|
||||
Copying to clipboard via OSC 52 will not work, because tmux does not support
|
||||
the extended version of that protocol, you will need to add ``no-append`` to
|
||||
:opt:`clipboard_control` in kitty.conf.
|
||||
|
||||
If you use any of the advanced features that kitty has innovated, such as
|
||||
styled underlines, desktop notifications, extended keyboard support, etc.
|
||||
they may or may not work, depending on the whims of tmux's maintainer, your
|
||||
@@ -349,3 +395,28 @@ remaining used memory can be investigated using valgrind again, and it will
|
||||
come from arenas in the GPU drivers and the per thread arenas glibc's malloc
|
||||
maintains. These too allocate memory in large blocks and dont release it back
|
||||
to the OS immediately.
|
||||
|
||||
Why does kitty sometimes start slowly on my Linux system?
|
||||
-------------------------------------------------------------------------------------------
|
||||
|
||||
|kitty| takes no longer (within 100ms) to start than other similar GPU terminal
|
||||
emulators, (and may be faster than some). If |kitty| occasionally takes a long
|
||||
time to start, it could be a power management issue with the graphics card. On
|
||||
a multi-GPU system (which many modern laptops are, having a power efficient GPU
|
||||
that's built into the processor and a power hungry dedicated one that's usually
|
||||
off), even if the answer of the GPU will only be "don't use me".
|
||||
|
||||
For example, if you have a system with an AMD CPU and an NVIDIA GPU, and you
|
||||
know that you want to use the lower powered card to save battery life and
|
||||
because kitty does not require a powerful GPU to function, you can choose not
|
||||
to wake up the dedicated card, which has been reported on at least one system
|
||||
(:iss:`4292`) to take ≈2 seconds, by running |kitty| as::
|
||||
|
||||
MESA_LOADER_DRIVER_OVERRIDE=radeonsi __EGL_VENDOR_LIBRARY_FILENAMES=/usr/share/glvnd/egl_vendor.d/50_mesa.json kitty
|
||||
|
||||
The correct command will depend on your situation and hardware.
|
||||
``__EGL_VENDOR_LIBRARY_FILENAMES`` instructs the GL dispatch library to use
|
||||
:file:`libEGL_mesa.so` and ignore :file:`libEGL_nvidia.so` also available on the
|
||||
system, which will wake the NVIDIA card during device enumeration.
|
||||
``MESA_LOADER_DRIVER_OVERRIDE`` also assures that Mesa won't offer any NVIDIA
|
||||
card during enumeration, and will instead just use `/lib/dri/radeonsi_dri.so`.
|
||||
|
||||
535
docs/file-transfer-protocol.rst
Normal file
@@ -0,0 +1,535 @@
|
||||
File transfer over the TTY
|
||||
===============================
|
||||
|
||||
There are sometimes situations where the TTY is the only convenient pipe
|
||||
between two connected systems, for example, nested SSH sessions, a serial
|
||||
line, etc. In such scenarios, it is useful to be able to transfer files
|
||||
over the TTY.
|
||||
|
||||
This protocol provides the ability to transfer regular files, directories and
|
||||
links (both symbolic and hard) preserving most of their metadata. It can
|
||||
optionally use compression and transmit only binary diffs to speed up
|
||||
transfers. However, since all data is base64 encoded for transmission over the
|
||||
TTY, this protocol will never be competitive with more direct file transfer
|
||||
mechanisms.
|
||||
|
||||
Overall design
|
||||
----------------
|
||||
|
||||
The basic design of this protocol is around transfer "sessions". Since
|
||||
untrusted software should not be able to read/write to another machines
|
||||
filesystem, a session must be approved by the user in the terminal emulator
|
||||
before any actual data is transmitted, unless a :ref:`pre-shared password is
|
||||
provided <bypass_auth>`.
|
||||
|
||||
There can be either send or receive sessions. In send sessions files are sent
|
||||
from remote client to the terminal emulator and vice versa for receive sessions.
|
||||
Every session basically consists of sending metadata for the files first and
|
||||
then sending the actual data. The session is a series of commands, every command
|
||||
carrying the session id (which should be a random unique-ish identifier, to
|
||||
avoid conflicts). The session is bi-directional with commands going both to and
|
||||
from the terminal emulator. Every command in a session also carries an
|
||||
``action`` field that specifies what the command does. The remaining fields in
|
||||
the command are dependent on the nature of the command.
|
||||
|
||||
Let's look at some simple examples of sessions to get a feel for the protocol.
|
||||
|
||||
|
||||
Sending files to the computer running the terminal emulator
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
The client starts by sending a start send command::
|
||||
|
||||
→ action=send id=someid
|
||||
|
||||
It then waits for a status message from the terminal either
|
||||
allowing the transfer or refusing it. Until this message is received
|
||||
the client is not allowed to send any more commands for the session.
|
||||
The terminal emulator should drop a session if it receives any commands
|
||||
before sending an ``OK`` response. If the user accepts the transfer,
|
||||
the terminal will send::
|
||||
|
||||
← action=status id=someid status=OK
|
||||
|
||||
Or if the transfer is refused::
|
||||
|
||||
← action=status id=someid status=EPERM:User refused the transfer
|
||||
|
||||
The client then sends one or more ``file`` commands with the metadata of the file it wants
|
||||
to transfer::
|
||||
|
||||
→ action=file id=someid file_id=f1 name=/path/to/destination
|
||||
→ action=file id=someid file_id=f2 name=/path/to/destination2 ftype=directory
|
||||
|
||||
The terminal responds with either ``OK`` for directories or ``STARTED`` for
|
||||
files::
|
||||
|
||||
← action=status id=someid file_id=f1 status=STARTED
|
||||
← action=status id=someid file_id=f2 status=OK
|
||||
|
||||
If there was an error with the file, for example, if the terminal does not have
|
||||
permission to write to the specified location, it will instead respond with an
|
||||
error, such as::
|
||||
|
||||
← action=status id=someid file_id=f1 status=EPERM:No permission
|
||||
|
||||
The client sends data for files using ``data`` commands. It does not need to
|
||||
wait for the ``STARTED`` from the terminal for this, the terminal must discard data
|
||||
for files that are not ``STARTED``. Data for a file is sent in individual
|
||||
chunks of no larger than ``4096`` bytes. For example::
|
||||
|
||||
|
||||
→ action=data id=someid file_id=f1 data=chunk of bytes
|
||||
→ action=data id=someid file_id=f1 data=chunk of bytes
|
||||
...
|
||||
→ action=end_data id=someid file_id=f1 data=chunk of bytes
|
||||
|
||||
The sequence of data transmission for a file is ended with an ``end_data``
|
||||
command. After each data packet is received the terminal replies with
|
||||
an acknowledgement of the form::
|
||||
|
||||
← action=status id=someid file_id=f1 status=PROGRESS size=bytes written
|
||||
|
||||
After ``end_data`` the terminal replies with::
|
||||
|
||||
← action=status id=someid file_id=f1 status=OK size=bytes written
|
||||
|
||||
If an error occurs while writing the data, the terminal replies with an error
|
||||
code and ignores further commands about that file, for example::
|
||||
|
||||
← action=status id=someid file_id=f1 status=EIO:Failed to write to file
|
||||
|
||||
Once the client has finished sending as many files as it wants to, it ends
|
||||
the session with::
|
||||
|
||||
→ action=finish id=someid
|
||||
|
||||
At this point the terminal commits the session, applying file metadata,
|
||||
creating links, etc. If any errors occur it responds with an error message,
|
||||
such as::
|
||||
|
||||
← action=status id=someid status=Some error occurred
|
||||
|
||||
|
||||
Receiving files from the computer running terminal emulator
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
The client starts by sending a start receive command::
|
||||
|
||||
→ action=receive id=someid size=num_of_paths
|
||||
|
||||
It then sends a list of ``num_of_paths`` paths it is interested in
|
||||
receiving::
|
||||
|
||||
→ action=file id=someid file_id=f1 name=/some/path
|
||||
→ action=file id=someid file_id=f2 name=/some/path2
|
||||
...
|
||||
|
||||
The client must then wait for responses from the terminal emulator. It
|
||||
is an error to send anymore commands to to the terminal until an ``OK``
|
||||
response is received from the terminal. The terminal wait for the user to accept
|
||||
the request. If accepted, it sends::
|
||||
|
||||
← action=status id=someid status=OK
|
||||
|
||||
If permission is denied it sends::
|
||||
|
||||
← action=status id=someid status=EPERM:User refused the transfer
|
||||
|
||||
The terminal then sends the metadata for all requested files. If any of them
|
||||
are directories, it traverses the directories recursively, listing all files.
|
||||
Note that symlinks must not be followed, but sent as symlinks::
|
||||
|
||||
← action=file id=someid file_id=f1 mtime=XXX permissions=XXX name=/absolute/path status=file_id1 size=size_in_bytes file_type=type parent=file_id of parent
|
||||
← action=file id=someid file_id=f1 mtime=XXX permissions=XXX name=/absolute/path2 status=file_id2 size=size_in_bytes file_type=type parent=file_id of parent
|
||||
...
|
||||
|
||||
Here the ``file_id`` field is set to the ``file_id`` value sent from the client
|
||||
and the ``status`` field is set to the actual file id for each file. This is
|
||||
because a file query sent from the client can result in multiple actual files if
|
||||
it is a directory. The ``parent`` field is the actual ``file_id`` of the directory
|
||||
containing this file and is set for entries that are generated from client
|
||||
requests that match directories. This allows the client to build an unambiguous picture
|
||||
of the file tree.
|
||||
|
||||
Once all the files are listed, the terminal sends an ``OK`` response that also
|
||||
specifies the absolute path to the home directory for the user account running
|
||||
the terminal::
|
||||
|
||||
← action=status id=someid status=OK name=/path/to/home
|
||||
|
||||
If an error occurs while listing any of the files asked for by the client,
|
||||
the terminal will send an error response like::
|
||||
|
||||
← action=status id=someid file_id=f1 status=ENOENT: Does not exist
|
||||
|
||||
Here, ``file_id`` is the same as was sent by the client in its initial query.
|
||||
|
||||
Now, the client can send requests for file data using the paths sent by the
|
||||
terminal emulator::
|
||||
|
||||
→ action=file id=someid file_id=f1 name=/some/path
|
||||
...
|
||||
|
||||
The terminal emulator replies with the data for the files, as a sequence of
|
||||
``data`` commands each with a chunk of data no larger than ``4096`` bytes,
|
||||
for each file (the terminal emulator should send the data for
|
||||
one file at a time)::
|
||||
|
||||
|
||||
← action=data id=someid file_id=f1 data=chunk of bytes
|
||||
...
|
||||
← action=end_data id=someid file_id=f1 data=chunk of bytes
|
||||
|
||||
If any errors occur reading file data, the terminal emulator sends an error
|
||||
message for the file, for example::
|
||||
|
||||
← action=status id=someid file_id=f1 status=EIO:Could not read
|
||||
|
||||
Once the client is done reading data for all the files it expects, it
|
||||
terminates the session with::
|
||||
|
||||
→ action=finished id=someid
|
||||
|
||||
Canceling a session
|
||||
----------------------
|
||||
|
||||
A client can decide to cancel a session at any time (for example if the user
|
||||
presses :kbd:`ctrl+c`). To cancel a session it sends a ``cancel`` action to the
|
||||
terminal emulator::
|
||||
|
||||
→ action=cancel id=someid
|
||||
|
||||
The terminal emulator drops the session and sends a cancel acknowledgement::
|
||||
|
||||
← action=status id=someid status=CANCELED
|
||||
|
||||
The client **must** wait for the canceled response from the emulator discarding
|
||||
any other responses till the cancel is received. If it does not wait, after
|
||||
it quits the responses might end up being printed to screen.
|
||||
|
||||
Quieting responses from the terminal
|
||||
-------------------------------------
|
||||
|
||||
The above protocol includes lots of messages from the terminal acknowledging
|
||||
receipt of data, granting permission etc., acknowledging cancel requests, etc.
|
||||
For extremely simple clients like shell scripts, it might be useful to suppress
|
||||
these responses, which can be done by adding the ``quiet`` key to the start
|
||||
session command::
|
||||
|
||||
→ action=send id=someid quiet=1
|
||||
|
||||
The key can take the values ``1`` - meaning suppress acknowledgement responses
|
||||
or ``2`` - meaning suppress all responses including errors. Only actual data
|
||||
responses are sent. Note that in particular this means acknowledgement of
|
||||
permission for the transfer to go ahead is suppressed, so this is typically
|
||||
useful only with :ref:`bypass_auth`.
|
||||
|
||||
.. _file_metadata:
|
||||
|
||||
File metadata
|
||||
-----------------
|
||||
|
||||
File metadata includes file paths, permissions and modification times. They are
|
||||
somewhat tricky as different operating systems support different kinds of
|
||||
metadata. This specification defines a common minimum set which should work
|
||||
across most operating systems.
|
||||
|
||||
File paths
|
||||
File paths must be valid UTF-8 encoded POSIX paths (i.e. using the forward slash
|
||||
``/`` as a separator). Linux systems allow non UTF-8 file paths, these
|
||||
are not supported. A leading ``~/`` means a path is relative to the
|
||||
``HOME`` directory. All path must be either absolute (i.e. with a leading
|
||||
``/``) or relative to the HOME directory. Individual components of the
|
||||
path must be no longer than 255 UTF-8 bytes. Total path length must be no
|
||||
more than 4096 bytes. Paths from Windows systems must use the forward slash
|
||||
as the separator, the first path component must be the drive letter with a
|
||||
colon. For example: :file:`C:\some\file.txt` is represented as
|
||||
:file:`/C:/some/file.txt`. For maximum portability, the following
|
||||
characters *should* be omitted from paths (however implementations are free
|
||||
to try to support them returning errors for non-representable paths)::
|
||||
|
||||
\ * : < > ? | /
|
||||
|
||||
File modification times
|
||||
Must be represented as the number of nanoseconds since the UNIX epoch. An
|
||||
individual file system may not store file metadata with this level of
|
||||
accuracy in which case it should use the closest possible approximation.
|
||||
|
||||
File permissions
|
||||
Represented as a number with the usual UNIX read, write and execute bits.
|
||||
In addition, the sticky, set-group-id and set-user-id bits may be present.
|
||||
Implementations should make a best effort to preserve as many bits as
|
||||
possible. On Windows, there is only a read-only bit. When reading file
|
||||
metadata all the ``WRITE`` bits should be set if the read only bit is clear
|
||||
and cleared if it is set. When writing files, the read-only bit should be
|
||||
set if the bit indicating write permission for the user is clear. The other
|
||||
UNIX bits must be ignored when writing. When reading, all the ``READ`` bits
|
||||
should always be set and all the ``EXECUTE`` bits should be set if the file is
|
||||
directly executable by the Windows Operating system. There is no attempt to
|
||||
map Window's ACLs to permission bits.
|
||||
|
||||
|
||||
Symbolic and hard links
|
||||
---------------------------
|
||||
|
||||
Symbolic and hard links can be preserved by this protocol.
|
||||
|
||||
.. note::
|
||||
In the following when target paths of symlinks are sent as actual paths, they must be
|
||||
encoded in the same way as discussed in :ref:`file_metadata`. It is up to
|
||||
the receiving side to translate them into appropriate paths for the local
|
||||
operating system. This may not always be possible, in which case either the
|
||||
symlink should not be created or a broken symlink should be created.
|
||||
|
||||
|
||||
Sending links to the terminal emulator
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
When sending files to the terminal emulator, the file command has the form::
|
||||
|
||||
→ action=file id=someid file_id=f1 name=/path/to/link file_type=link
|
||||
→ action=file id=someid file_id=f2 name=/path/to/symlink file_type=symlink
|
||||
|
||||
Then, when the client is sending data for the files, for hardlinks, the data
|
||||
will be the ``file_id`` of the target file (assuming the target file is also
|
||||
being transmitted, otherwise the hard link should be transmitted as a plain
|
||||
file)::
|
||||
|
||||
→ action=end_data id=someid file_id=f1 data=target_file_id_encoded_as_utf8
|
||||
|
||||
For symbolic links, the data is a little more complex. If the symbolic link is
|
||||
to a destination being transmitted, the data has the form::
|
||||
|
||||
→ action=end_data id=someid file_id=f1 data=fid:target_file_id_encoded_as_utf8
|
||||
→ action=end_data id=someid file_id=f1 data=fid_abs:target_file_id_encoded_as_utf8
|
||||
|
||||
The ``fid_abs`` form is used if the symlink uses an absolute path, ``fid`` if
|
||||
it uses a relative path. If the symlink is to a destination that is not being
|
||||
transmitted, then the prefix ``path:`` and the actual path in the symlink is
|
||||
transmitted.
|
||||
|
||||
Receiving links from the terminal emulator
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
When receiving files from the terminal emulator, link data is transmitted in
|
||||
two parts. First when the emulator sends the initial file listing to the
|
||||
client, the ``file_type`` is set to the link type and the ``data`` field is set
|
||||
to file_id of the target file if the target file is included in the listing.
|
||||
For example::
|
||||
|
||||
← action=file id=someid file_id=f1 status=file_id1 ...
|
||||
← action=file id=someid file_id=f1 status=file_id2 file_type=symlink data=file_id1 ...
|
||||
|
||||
Here the rest of the metadata has been left out for clarity. Notice that the
|
||||
second file is symlink whose ``data`` field is set to the file id of the first
|
||||
file (the value of the ``status`` field of the first file). The same technique
|
||||
is used for hard links.
|
||||
|
||||
The client should not request data for hard links, instead creating them
|
||||
directly after transmission is complete. For symbolic links the terminal
|
||||
must send the actual symbolic link target as a UTF-8 encoded path in the
|
||||
data field. The client can use this path either as-is (when the target is not
|
||||
a transmitted file) or to decide whether to create the symlink with a relative
|
||||
or absolute path when the target is a transmitted file.
|
||||
|
||||
|
||||
Transmitting binary deltas
|
||||
-----------------------------
|
||||
|
||||
Repeated transfer of large files that have only changed a little between
|
||||
the receiving and sending side can be sped up significantly by transmitting
|
||||
binary deltas of only the changed portions. This protocol has built-in support
|
||||
for doing that. This support uses the `rsync algorithm
|
||||
<https://github.com/librsync/librsync>`__. In this algorithm first the
|
||||
receiving side sends a file signature that contains hashes of blocks
|
||||
in the file. Then the sending side sends only those blocks that have changed.
|
||||
The receiving side applies these deltas to the file to update it till it matches
|
||||
the file on the sending side.
|
||||
|
||||
The modification to the basic protocol consists of setting the
|
||||
``transmission_type`` key to ``rsync`` when requesting a file. This triggers
|
||||
transmission of signatures and deltas instead of file data. The details are
|
||||
different for sending and receiving.
|
||||
|
||||
Sending to the terminal emulator
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
When sending the metadata of the file it wants to transfer, the client adds the
|
||||
``transmission_type`` key::
|
||||
|
||||
→ action=file id=someid file_id=f1 name=/path/to/destination transmission_type=rsync
|
||||
|
||||
The ``STARTED`` response from the terminal will have ``transmission_type`` set
|
||||
to ``rsync`` if the file exists and the terminal is able to send signature data::
|
||||
|
||||
← action=status id=someid file_id=f1 status=STARTED transmission_type=rsync
|
||||
|
||||
The terminal then transmits the signature using ``data`` commands::
|
||||
|
||||
← action=data id=someid file_id=f1 data=...
|
||||
...
|
||||
← action=end_data id=someid file_id=f1 data=...
|
||||
|
||||
Once the client receives and processes the full signature, it transmits the
|
||||
file delta to the terminal as ``data`` commands::
|
||||
|
||||
→ action=data id=someid file_id=f1 data=...
|
||||
→ action=data id=someid file_id=f1 data=...
|
||||
...
|
||||
→ action=end_data id=someid file_id=f1 data=...
|
||||
|
||||
The terminal then uses this delta to update the file.
|
||||
|
||||
Receiving from the terminal emulator
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
When the client requests file data from the terminal emulator, it can
|
||||
add the ``transmission_type=rsync`` key to indicate it will be sending
|
||||
a signature for that file::
|
||||
|
||||
→ action=file id=someid file_id=f1 name=/some/path transmission_type=rsync
|
||||
|
||||
The client then sends the signature using ``data`` commands::
|
||||
|
||||
→ action=data id=someid file_id=f1 data=...
|
||||
...
|
||||
→ action=end_data id=someid file_id=f1 data=...
|
||||
|
||||
After receiving the signature the terminal replies with the delta as a series
|
||||
of ``data`` commands::
|
||||
|
||||
← action=data id=someid file_id=f1 data=...
|
||||
...
|
||||
← action=end_data id=someid file_id=f1 data=...
|
||||
|
||||
The client then uses this delta to update the file.
|
||||
|
||||
The format of signatures and deltas
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
These come from `librsync <https://github.com/librsync/librsync>`__. If this
|
||||
specification gains wider adoption, these formats should be documented here.
|
||||
|
||||
Compression
|
||||
--------------
|
||||
|
||||
Individual files can be transmitted compressed if needed.
|
||||
Currently, only :rfc:`1950` ZLIB based deflate compression is
|
||||
supported, which is specified using the ``compression=zlib`` key when
|
||||
requesting a file. For example when sending files to the terminal emulator,
|
||||
when sending the file metadata the ``compression`` key can also be
|
||||
specified::
|
||||
|
||||
→ action=file id=someid file_id=f1 name=/path/to/destination compression=zlib
|
||||
|
||||
Similarly when receiving files from the terminal emulator, the final file
|
||||
command that the client sends to the terminal requesting the start of the
|
||||
transfer of data for the file can include the ``compression`` key::
|
||||
|
||||
→ action=file id=someid file_id=f1 name=/some/path compression=zlib
|
||||
|
||||
.. _bypass_auth:
|
||||
|
||||
Bypassing explicit user authorization
|
||||
------------------------------------------
|
||||
|
||||
In order to bypass the requirement of interactive user authentication,
|
||||
this protocol has the ability to use a pre-shared secret (password).
|
||||
When initiating a transfer session the client sends a hash of the password and
|
||||
the session id::
|
||||
|
||||
→ action=send id=someid bypass=sha256:hash_value
|
||||
|
||||
For example, suppose that the session id is ``mysession`` and the
|
||||
shared secret is ``mypassword``. Then the value of the ``bypass``
|
||||
key above is ``sha256:SHA256("mysession" + ";" + "mypassword")``, which
|
||||
is::
|
||||
|
||||
→ action=send id=mysession bypass=sha256:192bd215915eeaa8c2b2a4c0f8f851826497d12b30036d8b5b1b4fc4411caf2c
|
||||
|
||||
The value of ``bypass`` is of the form ``hash_function_name : hash_value``
|
||||
(without spaces). Currently, only the SHA256 hash function is supported.
|
||||
|
||||
.. warning::
|
||||
Hashing does not effectively hide the value of the password. So this
|
||||
functionality should only be used in secure/trusted contexts. While there
|
||||
exist hash functions harder to compute than SHA256, they are unsuitable as
|
||||
they will introduce a lot of latency to starting a session and in any case
|
||||
there is no mathematical proof that **any** hash function is not brute-forceable.
|
||||
|
||||
Encoding of transfer commands as escape codes
|
||||
------------------------------------------------
|
||||
|
||||
Transfer commands are encoded as ``OSC`` escape codes of the form::
|
||||
|
||||
<OSC> 5113 ; key=value ; key=value ... <ST>
|
||||
|
||||
Here ``OSC`` is the bytes ``0x1b 0x5d`` and ``ST`` is the bytes
|
||||
``0x1b 0x5c``. Keys are words containing only the characters ``[a-zA-Z0-9_]``
|
||||
and ``value`` is arbitrary data, whose encoding is dependent on the value of
|
||||
``key``. Unknown keys **must** be ignored when decoding a command.
|
||||
The number ``5113`` is a constant and is unused by any known OSC codes. It is
|
||||
the numeralization of the word ``file``.
|
||||
|
||||
|
||||
.. table:: The keys and value types for this protocol
|
||||
:align: left
|
||||
|
||||
================= ======== ============== =======================================================================
|
||||
Key Key name Value type Notes
|
||||
================= ======== ============== =======================================================================
|
||||
action ac enum send, file, data, end_data, receive, cancel, status, finish
|
||||
compression zip enum none, zlib
|
||||
file_type ft enum regular, directory, symlink, link
|
||||
transmission_type tt enum simple, rsync
|
||||
id id safe_string A unique-ish value, to avoid collisions
|
||||
file_id fid safe_string Must be unique per file in a session
|
||||
bypass pw safe_string hash of the bypass password and the session id
|
||||
quiet q integer 0 - verbose, 1 - only errors, 2 - totally silent
|
||||
mtime mod integer the modification time of file in nanoseconds since the UNIX epoch
|
||||
permissions prm integer the UNIX file permissions bits
|
||||
size sz integer size in bytes
|
||||
name n base64_string The path to a file
|
||||
status st base64_string Status messages
|
||||
parent pr safe_string The file id of the parent directory
|
||||
data d base64_bytes Binary data
|
||||
================= ======== ============== =======================================================================
|
||||
|
||||
The ``Key name`` is the actual serialized name of the key sent in the escape
|
||||
code. So for example, ``permissions=123`` is serialized as ``prm=123``. This
|
||||
is done to reduce overhead.
|
||||
|
||||
The value types are:
|
||||
|
||||
enum
|
||||
One from a permitted set of values, for example::
|
||||
|
||||
ac=file
|
||||
|
||||
safe_string
|
||||
A string consisting only of characters from the set ``[0-9a-zA-Z_:.,/!@#$%^&*()[]{}~`?"'\\|=+-]``
|
||||
Note that the semi-colon is missing from this set.
|
||||
|
||||
integer
|
||||
A base-10 number composed of the characters ``[0-9]`` with a possible
|
||||
leading ``-`` sign
|
||||
|
||||
base64_string
|
||||
A base64 encoded UTF-8 string using the standard base64 encoding
|
||||
|
||||
base64_bytes
|
||||
Binary data encoded using the standard base64 encoding
|
||||
|
||||
|
||||
An example of serializing an escape code is shown below::
|
||||
|
||||
action=send id=test name=somefile size=3 data=01 02 03
|
||||
|
||||
becomes::
|
||||
|
||||
<OSC> 5113 ; ac=send ; id=test ; n=c29tZWZpbGU= ; sz=3 ; d=AQID <ST>
|
||||
|
||||
Here ``c29tZWZpbGU`` is the base64 encoded form of somefile and ``AQID`` is the
|
||||
base64 encoded form of the bytes ``0x01 0x02 0x03``. The spaces in the encoded
|
||||
form are present for clarity and should be ignored.
|
||||
161
docs/glossary.rst
Normal file
@@ -0,0 +1,161 @@
|
||||
:orphan:
|
||||
|
||||
Glossary
|
||||
=========
|
||||
|
||||
.. glossary::
|
||||
|
||||
os_window
|
||||
kitty has two kinds of windows. Operating System windows, refered to as :term:`OS
|
||||
Window <os_window>`, and *kitty windows*. An OS Window consists of one or more kitty
|
||||
:term:`tabs <tab>`. Each tab in turn consists of one or more *kitty
|
||||
windows* organized in a :term:`layout`.
|
||||
|
||||
tab
|
||||
A *tab* refers to a group of :term:`kitty windows <window>`, organized in
|
||||
a :term:`layout`. Every :term:`OS Window <os_window>` contains one or more tabs.
|
||||
|
||||
layout
|
||||
A *layout* is a system of organizing :term:`kitty windows <window>` in
|
||||
groups inside a tab. The layout automatically maintains the size and
|
||||
position of the windows, think of a layout as a tiling window manager for
|
||||
the terminal. See :doc:`layouts` for details.
|
||||
|
||||
window
|
||||
kitty has two kinds of windows. Operating System windows, refered to as :term:`OS
|
||||
Window <os_window>`, and *kitty windows*. An OS Window consists of one or more kitty
|
||||
:term:`tabs <tab>`. Each tab in turn consists of one or more *kitty
|
||||
windows* organized in a :term:`layout`.
|
||||
|
||||
overlay
|
||||
An *overlay window* is a :term:`kitty window <window>` that is placed on
|
||||
top of an existing kitty window, entirely covering it. Overlays are used
|
||||
throught kitty, for example, to display the :ref:`the scrollback buffer <scrollback>`,
|
||||
to display :doc:`hints </kittens/hints>`, for :doc:`unicode input
|
||||
</kittens/unicode_input>` etc.
|
||||
|
||||
hyperlinks
|
||||
Terminals can have hyperlinks, just like the internet. In kitty you can
|
||||
:doc:`control exactly what happens <open_actions>` when clicking on a
|
||||
hyperlink, based on the type of link and its URL.
|
||||
|
||||
.. _env_vars:
|
||||
|
||||
Environment variables
|
||||
------------------------
|
||||
|
||||
Variables that influence kitty behavior
|
||||
|
||||
.. envvar:: KITTY_CONFIG_DIRECTORY
|
||||
|
||||
Controls where kitty looks for :file:`kitty.conf` and other configuration
|
||||
files. Defaults to :file:`~/.config/kitty`. For full details of the config
|
||||
directory lookup mechanism see, :option:`kitty --config`.
|
||||
|
||||
.. envvar:: KITTY_CACHE_DIRECTORY
|
||||
|
||||
Controls where kitty stores cache files. Defaults to :file:`~/.cache/kitty`
|
||||
or :file:`~/Library/Caches/kitty` on macOS.
|
||||
|
||||
.. envvar:: VISUAL
|
||||
|
||||
The terminal editor (such as ``vi`` or ``nano``) kitty uses, when, for
|
||||
instance, opening :file:`kitty.conf` in response to :sc:`edit_config_file`.
|
||||
|
||||
|
||||
.. envvar:: EDITOR
|
||||
|
||||
Same as :envvar:`VISUAL`. Used if :envvar:`VISUAL` is not set.
|
||||
|
||||
.. envvar:: GLFW_IM_MODULE
|
||||
|
||||
Set this to ``ibus`` to enable support for IME under X11.
|
||||
|
||||
.. envvar:: KITTY_WAYLAND_DETECT_MODIFIERS
|
||||
|
||||
When set to a non-empty value, kitty attempts to autodiscover XKB modifiers
|
||||
under Wayland. This is useful if using non-standard modifers like hyper. It
|
||||
is possible for the autodiscovery to fail; the default Wayland XKB mappings
|
||||
are used in this case. See :pull:`3943` for details.
|
||||
|
||||
|
||||
Variables that kitty sets when running child programs
|
||||
|
||||
.. envvar:: LANG
|
||||
|
||||
This is set only on macOS, and only if the country and language from the
|
||||
macOS user settings form a valid locale.
|
||||
|
||||
|
||||
.. envvar:: KITTY_WINDOW_ID
|
||||
|
||||
An integer that is the id for the kitty :term:`window` the program is running in.
|
||||
Can be used with the :doc:`kitty remote control facility <remote-control>`.
|
||||
|
||||
|
||||
.. envvar:: KITTY_PID
|
||||
|
||||
An integer that is the process id for the kitty process in which the program
|
||||
is running. Allows programs to tell kitty to reload its config by sending it
|
||||
the SIGUSR1 signal.
|
||||
|
||||
|
||||
.. envvar:: WINDOWID
|
||||
|
||||
The id for the :term:`OS Window <os_window>` the program is running in. Only available
|
||||
on platforms that have ids for their windows, such as X11 and macOS.
|
||||
|
||||
|
||||
.. envvar:: TERM
|
||||
|
||||
The name of the terminal, defaults to ``xterm-kitty``. See :opt:`term`.
|
||||
|
||||
|
||||
.. envvar:: TERMINFO
|
||||
|
||||
Path to a directory containing the kitty terminfo database.
|
||||
|
||||
|
||||
.. envvar:: KITTY_INSTALLATION_DIR
|
||||
|
||||
Path to the kitty installation directory.
|
||||
|
||||
|
||||
.. envvar:: COLORTERM
|
||||
|
||||
Set to the value ``truecolor`` to indicate that kitty supports 16 million
|
||||
colors.
|
||||
|
||||
|
||||
.. envvar:: KITTY_LISTEN_ON
|
||||
|
||||
Set when the :doc:`remote control <remote-control>` facility is enabled and
|
||||
the a socket is used for control via :option:`kitty --listen-on` or :opt:`listen_on`.
|
||||
Contains the path to the socket. Avoids needs to use :option:`kitty @ --to` when
|
||||
issuing remote control commands.
|
||||
|
||||
|
||||
.. envvar:: KITTY_PIPE_DATA
|
||||
|
||||
Set to data describing the layout of the screen when running child
|
||||
programs using :option:`launch --stdin-source` with the contents of the
|
||||
screen/scrollback piped to them.
|
||||
|
||||
|
||||
.. envvar:: KITTY_CHILD_CMDLINE
|
||||
|
||||
Set to the command line of the child process running in the kitty
|
||||
window when calling the notification callback program on terminal bell, see
|
||||
:opt:`command_on_bell`.
|
||||
|
||||
|
||||
.. envvar:: KITTY_COMMON_OPTS
|
||||
|
||||
Set with the values of some common kitty options when running
|
||||
kittens, so kittens can use them without needing to load kitty.conf.
|
||||
|
||||
|
||||
.. envvar:: KITTY_SHELL_INTEGRATION
|
||||
|
||||
Set when enabling :ref:`shell_integration`. It is automatically removed by
|
||||
the shell integration scripts.
|
||||
@@ -1,18 +1,16 @@
|
||||
:tocdepth: 3
|
||||
|
||||
The terminal graphics protocol
|
||||
==================================
|
||||
Terminal graphics protocol
|
||||
=================================
|
||||
|
||||
The goal of this specification is to create a flexible and performant protocol
|
||||
that allows the program running in the terminal, hereafter called the *client*,
|
||||
to render arbitrary pixel (raster) graphics to the screen of the terminal
|
||||
emulator. The major design goals are
|
||||
emulator. The major design goals are:
|
||||
|
||||
* Should not require terminal emulators to understand image formats.
|
||||
* Should allow specifying graphics to be drawn at individual pixel positions.
|
||||
* The graphics should integrate with the text, in particular it should be possible to draw graphics
|
||||
below as well as above the text, with alpha blending. The graphics should also scroll with the text, automatically.
|
||||
* Should use optimizations when the client is running on the same computer as the terminal emulator.
|
||||
* Should not require terminal emulators to understand image formats.
|
||||
* Should allow specifying graphics to be drawn at individual pixel positions.
|
||||
* The graphics should integrate with the text, in particular it should be possible to draw graphics
|
||||
below as well as above the text, with alpha blending. The graphics should also scroll with the text, automatically.
|
||||
* Should use optimizations when the client is running on the same computer as the terminal emulator.
|
||||
|
||||
For some discussion regarding the design choices, see `#33
|
||||
<https://github.com/kovidgoyal/kitty/issues/33>`_.
|
||||
@@ -30,22 +28,25 @@ alpha-blending and text over graphics.
|
||||
|
||||
Some programs and libraries that use the kitty graphics protocol:
|
||||
|
||||
* `termpdf.py <https://github.com/dsanson/termpdf.py>`_ - a terminal PDF/DJVU/CBR viewer
|
||||
* `ranger <https://github.com/ranger/ranger>`_ - a terminal file manager, with
|
||||
image previews, see this `PR <https://github.com/ranger/ranger/pull/1077>`_
|
||||
* :doc:`kitty-diff <kittens/diff>` - a side-by-side terminal diff program with support for images
|
||||
* `pixcat <https://github.com/mirukana/pixcat>`_ - a third party CLI and python library that wraps the graphics protocol
|
||||
* `neofetch <https://github.com/dylanaraps/neofetch>`_ - A command line system
|
||||
information tool
|
||||
* `viu <https://github.com/atanunq/viu>`_ - a terminal image viewer
|
||||
* `glkitty <https://github.com/michaeljclark/glkitty>`_ - C library to draw OpenGL shaders in the terminal with a glgears demo
|
||||
* `ctx.graphics <https://ctx.graphics/>`_ - Library for drawing graphics
|
||||
* `timg <https://github.com/hzeller/timg>`_ - a terminal image and video viewer
|
||||
* `notcurses <https://github.com/dankamongmen/notcurses>`_ - C library for terminal graphics with bindings for C++, Rust and Python
|
||||
* `rasterm <https://github.com/BourgeoisBear/rasterm>`_ - Go library to display images in the the terminal
|
||||
* `termpdf.py <https://github.com/dsanson/termpdf.py>`_ - a terminal PDF/DJVU/CBR viewer
|
||||
* `ranger <https://github.com/ranger/ranger>`_ - a terminal file manager, with
|
||||
image previews, see this `PR <https://github.com/ranger/ranger/pull/1077>`_
|
||||
* :doc:`kitty-diff <kittens/diff>` - a side-by-side terminal diff program with support for images
|
||||
* `pixcat <https://github.com/mirukana/pixcat>`_ - a third party CLI and python library that wraps the graphics protocol
|
||||
* `neofetch <https://github.com/dylanaraps/neofetch>`_ - A command line system
|
||||
information tool
|
||||
* `viu <https://github.com/atanunq/viu>`_ - a terminal image viewer
|
||||
* `glkitty <https://github.com/michaeljclark/glkitty>`_ - C library to draw OpenGL shaders in the terminal with a glgears demo
|
||||
* `ctx.graphics <https://ctx.graphics/>`_ - Library for drawing graphics
|
||||
* `timg <https://github.com/hzeller/timg>`_ - a terminal image and video viewer
|
||||
* `notcurses <https://github.com/dankamongmen/notcurses>`_ - C library for terminal graphics with bindings for C++, Rust and Python
|
||||
* `rasterm <https://github.com/BourgeoisBear/rasterm>`_ - Go library to display images in the terminal
|
||||
* `chafa <https://github.com/hpjansson/chafa>`_ - a terminal image viewer
|
||||
* `hologram.nvim <https://github.com/edluffy/hologram.nvim>`_ - view images inside nvim
|
||||
|
||||
Other terminals that have implemented the graphics protocol:
|
||||
|
||||
.. contents::
|
||||
* `WezTerm <https://github.com/wez/wezterm/issues/986>`_
|
||||
|
||||
|
||||
Getting the window size
|
||||
@@ -56,28 +57,33 @@ client must be able to get the window size in pixels and the number of cells
|
||||
per row and column. This can be done by using the ``TIOCGWINSZ`` ioctl. Some
|
||||
code to demonstrate its use
|
||||
|
||||
In C:
|
||||
.. tab:: C
|
||||
|
||||
.. code-block:: c
|
||||
.. code-block:: c
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/ioctl.h>
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
struct winsize sz;
|
||||
ioctl(0, TIOCGWINSZ, &sz);
|
||||
printf("number of rows: %i, number of columns: %i, screen width: %i, screen height: %i\n", sz.ws_row, sz.ws_col, sz.ws_xpixel, sz.ws_ypixel);
|
||||
return 0;
|
||||
}
|
||||
int main(int argc, char **argv) {
|
||||
struct winsize sz;
|
||||
ioctl(0, TIOCGWINSZ, &sz);
|
||||
printf(
|
||||
"number of rows: %i, number of columns: %i, screen width: %i, screen height: %i\n",
|
||||
sz.ws_row, sz.ws_col, sz.ws_xpixel, sz.ws_ypixel);
|
||||
return 0;
|
||||
}
|
||||
|
||||
In Python:
|
||||
|
||||
.. code-block:: python
|
||||
.. tab:: Python
|
||||
|
||||
import array, fcntl, sys, termios
|
||||
buf = array.array('H', [0, 0, 0, 0])
|
||||
fcntl.ioctl(sys.stdout, termios.TIOCGWINSZ, buf)
|
||||
print('number of rows: {}, number of columns: {}, screen width: {}, screen height: {}'.format(*buf))
|
||||
.. code-block:: python
|
||||
|
||||
import array, fcntl, sys, termios
|
||||
buf = array.array('H', [0, 0, 0, 0])
|
||||
fcntl.ioctl(sys.stdout, termios.TIOCGWINSZ, buf)
|
||||
print((
|
||||
'number of rows: {} number of columns: {}'
|
||||
'screen width: {} screen height: {}').format(*buf))
|
||||
|
||||
Note that some terminals return ``0`` for the width and height values. Such
|
||||
terminals should be modified to return the correct values. Examples of
|
||||
@@ -97,32 +103,36 @@ features of the graphics protocol:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
import sys
|
||||
from base64 import standard_b64encode
|
||||
import sys
|
||||
from base64 import standard_b64encode
|
||||
|
||||
def serialize_gr_command(cmd, payload=None):
|
||||
cmd = ','.join('{}={}'.format(k, v) for k, v in cmd.items())
|
||||
ans = []
|
||||
w = ans.append
|
||||
w(b'\033_G'), w(cmd.encode('ascii'))
|
||||
if payload:
|
||||
w(b';')
|
||||
w(payload)
|
||||
w(b'\033\\')
|
||||
return b''.join(ans)
|
||||
|
||||
def write_chunked(cmd, data):
|
||||
data = standard_b64encode(data)
|
||||
while data:
|
||||
chunk, data = data[:4096], data[4096:]
|
||||
m = 1 if data else 0
|
||||
cmd['m'] = m
|
||||
sys.stdout.buffer.write(serialize_gr_command(cmd, chunk))
|
||||
sys.stdout.flush()
|
||||
cmd.clear()
|
||||
def serialize_gr_command(**cmd):
|
||||
payload = cmd.pop('payload', None)
|
||||
cmd = ','.join('{}={}'.format(k, v) for k, v in cmd.items())
|
||||
ans = []
|
||||
w = ans.append
|
||||
w(b'\033_G'), w(cmd.encode('ascii'))
|
||||
if payload:
|
||||
w(b';')
|
||||
w(payload)
|
||||
w(b'\033\\')
|
||||
return b''.join(ans)
|
||||
|
||||
with open(sys.argv[-1], 'rb') as f:
|
||||
write_chunked({'a': 'T', 'f': 100}, f.read())
|
||||
|
||||
def write_chunked(**cmd):
|
||||
data = standard_b64encode(cmd.pop('data'))
|
||||
while data:
|
||||
chunk, data = data[:4096], data[4096:]
|
||||
m = 1 if data else 0
|
||||
sys.stdout.buffer.write(serialize_gr_command(payload=chunk, m=m,
|
||||
**cmd))
|
||||
sys.stdout.flush()
|
||||
cmd.clear()
|
||||
|
||||
|
||||
with open(sys.argv[-1], 'rb') as f:
|
||||
write_chunked(a='T', f=100, data=f.read())
|
||||
|
||||
|
||||
Save this script as :file:`png.py`, then you can use it to display any PNG
|
||||
@@ -219,16 +229,25 @@ and can take the values:
|
||||
Value of `t` Meaning
|
||||
================== ============
|
||||
``d`` Direct (the data is transmitted within the escape code itself)
|
||||
``f`` A simple file
|
||||
``f`` A simple file (regular files only, not named pipes or similar)
|
||||
``t`` A temporary file, the terminal emulator will delete the file after reading the pixel data. For security reasons
|
||||
the terminal emulator should only delete the file if it
|
||||
is in a known temporary directory, such as :file:`/tmp`,
|
||||
:file:`/dev/shm`, :file:`TMPDIR env var if present` and any platform
|
||||
specific temporary directories.
|
||||
``s`` A `POSIX shared memory object <http://man7.org/linux/man-pages/man7/shm_overview.7.html>`_.
|
||||
The terminal emulator will delete it after reading the pixel data
|
||||
``s`` A *shared memory object*, which on POSIX systems is a
|
||||
`POSIX shared memory object <https://pubs.opengroup.org/onlinepubs/9699919799/functions/shm_open.html>`_
|
||||
and on Windows is a
|
||||
`Named shared memory object <https://docs.microsoft.com/en-us/windows/win32/memory/creating-named-shared-memory>`_.
|
||||
The terminal emulator must read the data from the memory
|
||||
object and then unlink and close it on POSIX and just
|
||||
close it on Windows.
|
||||
================== ============
|
||||
|
||||
When opening files, the terminal emulator must follow symlinks. In case of
|
||||
symlink loops or too many symlinks, it should fail and respond with an error,
|
||||
similar to reporting any other kind of I/O error.
|
||||
|
||||
Local client
|
||||
^^^^^^^^^^^^^^
|
||||
|
||||
@@ -307,11 +326,11 @@ use the *query action*, set ``a=q``. Then the terminal emulator will try to load
|
||||
the image and respond with either OK or an error, as above, but it will not
|
||||
replace an existing image with the same id, nor will it store the image.
|
||||
|
||||
While as of May 2020, kitty is the only terminal emulator to support this
|
||||
graphics protocol, we intend that any terminal emulator that wishes to support
|
||||
it can. To check if a terminal emulator supports the graphics protocol the best way
|
||||
As of September 2021, kitty and WezTerm are the only terminal emulators to support this
|
||||
graphics protocol. We intend that any terminal emulator that wishes to support
|
||||
it can do so. To check if a terminal emulator supports the graphics protocol the best way
|
||||
is to send the above *query action* followed by a request for the
|
||||
`primary device attributes <https://vt100.net/docs/vt510-rm/DA1.html>`. If you
|
||||
`primary device attributes <https://vt100.net/docs/vt510-rm/DA1.html>`_. If you
|
||||
get back an answer for the device attributes without getting back an answer for
|
||||
the *query action* the terminal emulator does not support the graphics
|
||||
protocol.
|
||||
@@ -471,7 +490,7 @@ Requesting image ids from the terminal
|
||||
If you are writing a program that is going to share the screen with other
|
||||
programs and you still want to use image ids, it is not possible to know
|
||||
what image ids are free to use. In this case, instead of using the ``i``
|
||||
key to specify and image id use the ``I`` key to specify and image number
|
||||
key to specify an image id use the ``I`` key to specify an image number
|
||||
instead. These numbers are not unique.
|
||||
When creating a new image, even if an existing image has the same number a new
|
||||
one is created. And the terminal will reply with the id of the newly created
|
||||
@@ -585,7 +604,7 @@ Clients can control animations by using the ``a=a`` key in the escape code sent
|
||||
to the terminal.
|
||||
|
||||
The simplest is client driven animations, where the client transmits the frame
|
||||
data and the also instructs the terminal to make a particular frame the current
|
||||
data and then also instructs the terminal to make a particular frame the current
|
||||
frame. To change the current frame, use the ``c`` key::
|
||||
|
||||
<ESC>_Ga=a,i=3,c=7<ESC>\
|
||||
@@ -627,6 +646,45 @@ static background.
|
||||
In particular, the first frame or *root frame* is created with the base image
|
||||
data and has no gap, so its gap must be set using this control code.
|
||||
|
||||
Composing animation frames
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. versionadded:: 0.22.0
|
||||
Support for frame composition
|
||||
|
||||
Clients can *compose* animation frames, this means that they can compose pixels
|
||||
in rectangular regions from one frame onto another frame. This allows for fast
|
||||
and low band-width modification of frames.
|
||||
|
||||
To achieve this use the ``a=c`` key. The source frame is specified with
|
||||
``r=frame number`` and the destination frame as ``c=frame number``. The size of
|
||||
the rectangle is specified as ``w=width,h=height`` pixels. If unspecified, the
|
||||
full image width and height are used. The offset of the rectangle from the
|
||||
top-left corner for the source frame is specified by the ``x,y`` keys and the
|
||||
destination frame by the ``X,Y`` keys. The composition operation is specified
|
||||
by the ``C`` key with the default being to alpha blend the source rectangle
|
||||
onto the destination rectangle. With ``C=1`` it will be a simple replacement
|
||||
of pixels. For example::
|
||||
|
||||
<ESC>_Gi=1,r=7,c=9,w=23,h=27,X=4,Y=8,x=1,y=3<ESC>\
|
||||
|
||||
Will compose a ``23x27`` rectangle located at ``(4, 8)`` in the ``7th frame``
|
||||
onto the rectangle located at ``(1, 3)`` in the ``9th frame``. These will be
|
||||
in the image with ``id=1``.
|
||||
|
||||
If the frames or the image are not found the terminal emulator must
|
||||
respond with `ENOENT`. If the rectangles go out of bounds of the image
|
||||
the terminal must respond with `EINVAL`. If the source and destination frames are
|
||||
the same and the rectangles overlap, the terminal must respond with `EINVAL`.
|
||||
|
||||
|
||||
.. note::
|
||||
In kitty, doing a composition will cause a frame to be *fully rendered*
|
||||
potentially increasing its storage requirements, when the frame was previously
|
||||
stored as a set of operations on other frames. If this happens and there
|
||||
is not enough storage space, kitty will respond with ENOSPC.
|
||||
|
||||
|
||||
Image persistence and storage quotas
|
||||
-----------------------------------------
|
||||
|
||||
@@ -649,10 +707,10 @@ take, and the default value they take when missing. All integers are 32-bit.
|
||||
Key Value Default Description
|
||||
======= ==================== ========= =================
|
||||
``a`` Single character. ``t`` The overall action this graphics command is performing.
|
||||
``(t, T, q, p, d)`` ``t`` - transmit data, ``T`` - transmit data and display image,
|
||||
``q`` - query terminal, ``p`` - put (display) previous transmitted image,
|
||||
``(a, c, d, f, `` ``t`` - transmit data, ``T`` - transmit data and display image,
|
||||
``p, q, t, T)`` ``q`` - query terminal, ``p`` - put (display) previous transmitted image,
|
||||
``d`` - delete image, ``f`` - transmit data for animation frames,
|
||||
``a`` - control animation
|
||||
``a`` - control animation, ``c`` - compose animation frames
|
||||
|
||||
``q`` ``0, 1, 2`` ``0`` Suppress responses from the terminal to this graphics command.
|
||||
|
||||
@@ -706,6 +764,20 @@ Key Value Default Description
|
||||
``Y`` Positive integer ``0`` The background color for pixels not
|
||||
specified in the frame data. Must be in 32-bit RGBA format
|
||||
|
||||
**Keys for animation frame composition**
|
||||
-----------------------------------------------------------
|
||||
|
||||
``c`` Positive integer ``0`` The 1-based frame number of the frame whose image data serves as the overlaid data
|
||||
``r`` Positive integer ``0`` The 1-based frame number of the frame that is being edited.
|
||||
``x`` Positive integer ``0`` The left edge (in pixels) of the destination rectangle
|
||||
``y`` Positive integer ``0`` The top edge (in pixels) of the destination rectangle
|
||||
``w`` Positive integer ``0`` The width (in pixels) of the source and destination rectangles. By default, the entire width is used
|
||||
``h`` Positive integer ``0`` The height (in pixels) of the source and destination rectangles. By default, the entire height is used
|
||||
``X`` Positive integer ``0`` The left edge (in pixels) of the source rectangle
|
||||
``Y`` Positive integer ``0`` The top edge (in pixels) of the source rectangle
|
||||
``C`` Positive integer ``0`` The composition mode for blending
|
||||
pixels. Default is full alpha blending. ``1`` means a simple overwrite.
|
||||
|
||||
|
||||
**Keys for animation control**
|
||||
-----------------------------------------------------------
|
||||
|
||||
604
docs/index.rst
@@ -1,542 +1,74 @@
|
||||
:tocdepth: 2
|
||||
|
||||
==========================================================
|
||||
kitty - the fast, featureful, GPU based terminal emulator
|
||||
kitty
|
||||
==========================================================
|
||||
|
||||
.. container:: major-features
|
||||
|
||||
* Offloads rendering to the GPU for :doc:`lower system load <performance>` and
|
||||
buttery smooth scrolling. Uses threaded rendering to minimize input latency.
|
||||
|
||||
* Supports all modern terminal features: :doc:`graphics (images)
|
||||
<graphics-protocol>`, unicode, `true-color
|
||||
<https://gist.github.com/XVilka/8346728>`_,
|
||||
OpenType ligatures, mouse protocol, :doc:`hyperlinks <open_actions>`,
|
||||
focus tracking, `bracketed paste <https://cirw.in/blog/bracketed-paste>`_
|
||||
and several :doc:`new terminal protocol extensions
|
||||
<protocol-extensions>`.
|
||||
|
||||
* Supports tiling multiple terminal windows side by side in different
|
||||
:ref:`layouts <layouts>` without needing to use an extra program like tmux
|
||||
|
||||
* Can be :doc:`controlled from scripts or the shell prompt <remote-control>`,
|
||||
even over SSH.
|
||||
|
||||
* Has a framework for :ref:`kittens`, small terminal programs that can be used to
|
||||
extend |kitty|'s functionality. For example, they are used for
|
||||
:doc:`Unicode input <kittens/unicode-input>`, :doc:`Hints <kittens/hints>` and
|
||||
:doc:`Side-by-side diff <kittens/diff>`.
|
||||
|
||||
* Supports :ref:`startup sessions <sessions>` which allow you to specify
|
||||
the window/tab layout, working directories and programs to run on startup.
|
||||
|
||||
* Cross-platform: |kitty| works on Linux and macOS, but because it uses only
|
||||
OpenGL for rendering, it should be trivial to port to other Unix-like platforms.
|
||||
|
||||
* Allows you to open :ref:`the scrollback buffer <scrollback>` in a
|
||||
separate window using arbitrary programs of your choice. This is useful for
|
||||
browsing the history comfortably in a pager or editor.
|
||||
|
||||
* Has :ref:`multiple copy/paste buffers <cpbuf>`, like vim.
|
||||
|
||||
|
||||
.. figure:: screenshots/screenshot.png
|
||||
:alt: Screenshot, showing three programs in the 'Tall' layout
|
||||
:align: center
|
||||
:scale: 100%
|
||||
|
||||
Screenshot, showing vim, tig and git running in |kitty| with the 'Tall' layout
|
||||
|
||||
|
||||
.. _quickstart:
|
||||
|
||||
Quickstart
|
||||
--------------
|
||||
|
||||
Pre-built binaries of |kitty| are available for both macOS and Linux.
|
||||
See the :doc:`binary install instructions </binary>`. You can
|
||||
:doc:`build from source </build>`.
|
||||
|
||||
You can also use your favorite package manager to install the |kitty| package.
|
||||
|kitty| packages are available for:
|
||||
`macOS with Homebrew (Cask) <https://formulae.brew.sh/cask/kitty>`_,
|
||||
`macOS and Linux with Nix <https://search.nixos.org/packages?channel=unstable&show=kitty&sort=relevance&query=kitty>`_,
|
||||
`Ubuntu <https://launchpad.net/ubuntu/+source/kitty>`_,
|
||||
`Debian <https://packages.debian.org/buster/kitty>`_,
|
||||
`openSUSE <https://build.opensuse.org/package/show/X11:terminals/kitty>`_,
|
||||
`Arch Linux <https://www.archlinux.org/packages/community/x86_64/kitty/>`_,
|
||||
`Gentoo <https://packages.gentoo.org/packages/x11-terms/kitty>`_,
|
||||
`Fedora <https://src.fedoraproject.org/rpms/kitty>`_,
|
||||
`Void Linux <https://github.com/void-linux/void-packages/blob/master/srcpkgs/kitty/template>`_,
|
||||
and `Solus <https://dev.getsol.us/source/kitty/>`_.
|
||||
|
||||
See :doc:`Configuring kitty <conf>` for help on configuring |kitty| and
|
||||
:doc:`Invocation <invocation>` for the command line arguments |kitty| supports.
|
||||
|
||||
|
||||
.. contents::
|
||||
|
||||
|
||||
Design philosophy
|
||||
-------------------
|
||||
|
||||
|kitty| is designed for power keyboard users. To that end all its controls
|
||||
work with the keyboard (although it fully supports mouse interactions as
|
||||
well). Its configuration is a simple, human editable, single file for
|
||||
easy reproducibility (I like to store configuration in source control).
|
||||
|
||||
The code in |kitty| is designed to be simple, modular and hackable. It is
|
||||
written in a mix of C (for performance sensitive parts) and Python (for
|
||||
easy hackability of the UI). It does not depend on any large and complex
|
||||
UI toolkit, using only OpenGL for rendering everything.
|
||||
|
||||
Finally, |kitty| is designed from the ground up to support all modern
|
||||
terminal features, such as unicode, true color, bold/italic fonts, text
|
||||
formatting, etc. It even extends existing text formatting escape codes,
|
||||
to add support for features not available elsewhere, such as colored and
|
||||
styled (curly) underlines. One of the design goals of |kitty| is to be
|
||||
easily extensible so that new features can be added in the future with
|
||||
relatively little effort.
|
||||
|
||||
Tabs and Windows
|
||||
-------------------
|
||||
|
||||
|kitty| is capable of running multiple programs organized into tabs and
|
||||
windows. The top level of organization is the *Tab*. Each tab consists
|
||||
of one or more *windows*. The windows can be arranged in multiple
|
||||
different layouts, like windows are organized in a tiling window
|
||||
manager. The keyboard controls (which are all customizable) for tabs and
|
||||
windows are:
|
||||
|
||||
Scrolling
|
||||
~~~~~~~~~~~~~~
|
||||
|
||||
======================== =======================
|
||||
Action Shortcut
|
||||
======================== =======================
|
||||
Scroll line up :sc:`scroll_line_up` (also :kbd:`⌥+⌘+⇞` and :kbd:`⌘+↑` on macOS)
|
||||
Scroll line down :sc:`scroll_line_down` (also :kbd:`⌥+⌘+⇟` and :kbd:`⌘+↓` on macOS)
|
||||
Scroll page up :sc:`scroll_page_up` (also :kbd:`⌘+⇞` on macOS)
|
||||
Scroll page down :sc:`scroll_page_down` (also :kbd:`⌘+⇟` on macOS)
|
||||
Scroll to top :sc:`scroll_home` (also :kbd:`⌘+↖` on macOS)
|
||||
Scroll to bottom :sc:`scroll_end` (also :kbd:`⌘+↘` on macOS)
|
||||
======================== =======================
|
||||
|
||||
Tabs
|
||||
~~~~~~~~~~~
|
||||
|
||||
======================== =======================
|
||||
Action Shortcut
|
||||
======================== =======================
|
||||
New tab :sc:`new_tab` (also :kbd:`⌘+t` on macOS)
|
||||
Close tab :sc:`close_tab` (also :kbd:`⌘+w` on macOS)
|
||||
Next tab :sc:`next_tab` (also :kbd:`^+⇥` and :kbd:`⇧+⌘+]` on macOS)
|
||||
Previous tab :sc:`previous_tab` (also :kbd:`⇧+^+⇥` and :kbd:`⇧+⌘+[` on macOS)
|
||||
Next layout :sc:`next_layout`
|
||||
Move tab forward :sc:`move_tab_forward`
|
||||
Move tab backward :sc:`move_tab_backward`
|
||||
Set tab title :sc:`set_tab_title` (also :kbd:`⇧+⌘+i` on macOS)
|
||||
======================== =======================
|
||||
|
||||
|
||||
Windows
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
|
||||
======================== =======================
|
||||
Action Shortcut
|
||||
======================== =======================
|
||||
New window :sc:`new_window` (also :kbd:`⌘+↩` on macOS)
|
||||
New OS window :sc:`new_os_window` (also :kbd:`⌘+n` on macOS)
|
||||
Close window :sc:`close_window` (also :kbd:`⇧+⌘+d` on macOS)
|
||||
Next window :sc:`next_window`
|
||||
Previous window :sc:`previous_window`
|
||||
Move window forward :sc:`move_window_forward`
|
||||
Move window backward :sc:`move_window_backward`
|
||||
Move window to top :sc:`move_window_to_top`
|
||||
Focus specific window :sc:`first_window`, :sc:`second_window` ... :sc:`tenth_window`
|
||||
(also :kbd:`⌘+1`, :kbd:`⌘+2` ... :kbd:`⌘+9` on macOS)
|
||||
(clockwise from the top-left)
|
||||
======================== =======================
|
||||
|
||||
Additionally, you can define shortcuts in :file:`kitty.conf` to focus neighboring
|
||||
windows and move windows around (similar to window movement in vim)::
|
||||
|
||||
map ctrl+left neighboring_window left
|
||||
map shift+left move_window right
|
||||
map ctrl+down neighboring_window down
|
||||
map shift+down move_window up
|
||||
...
|
||||
|
||||
You can also define a shortcut to switch to the previously active window::
|
||||
|
||||
map ctrl+p nth_window -1
|
||||
|
||||
``nth_window`` will focus the nth window for positive numbers and the
|
||||
previously active windows for negative numbers.
|
||||
|
||||
.. _detach_window:
|
||||
|
||||
You can define shortcuts to detach the current window and
|
||||
move it to another tab or another OS window::
|
||||
|
||||
# moves the window into a new OS window
|
||||
map ctrl+f2 detach_window
|
||||
# moves the window into a new Tab
|
||||
map ctrl+f3 detach_window new-tab
|
||||
# asks which tab to move the window into
|
||||
map ctrl+f4 detach_window ask
|
||||
|
||||
Similarly, you can detach the current tab, with::
|
||||
|
||||
# moves the tab into a new OS window
|
||||
map ctrl+f2 detach_tab
|
||||
# asks which OS Window to move the tab into
|
||||
map ctrl+f4 detach_tab ask
|
||||
|
||||
Finally, you can define a shortcut to close all windows in a tab other than
|
||||
the currently active window::
|
||||
|
||||
map f9 close_other_windows_in_tab
|
||||
|
||||
|
||||
Other keyboard shortcuts
|
||||
----------------------------------
|
||||
|
||||
================================== =======================
|
||||
Action Shortcut
|
||||
================================== =======================
|
||||
Copy to clipboard :sc:`copy_to_clipboard` (also :kbd:`⌘+c` on macOS)
|
||||
Paste from clipboard :sc:`paste_from_clipboard` (also :kbd:`⌘+v` on macOS)
|
||||
Paste from selection :sc:`paste_from_selection`
|
||||
Increase font size :sc:`increase_font_size` (also :kbd:`⌘++` on macOS)
|
||||
Decrease font size :sc:`decrease_font_size` (also :kbd:`⌘+-` on macOS)
|
||||
Restore font size :sc:`reset_font_size` (also :kbd:`⌘+0` on macOS)
|
||||
Toggle fullscreen :sc:`toggle_fullscreen` (also :kbd:`^+⌘+f` on macOS)
|
||||
Toggle maximized :sc:`toggle_maximized`
|
||||
Input unicode character :sc:`input_unicode_character` (also :kbd:`^+⌘+space` on macOS)
|
||||
Click URL using the keyboard :sc:`open_url`
|
||||
Reset the terminal :sc:`reset_terminal`
|
||||
Pass current selection to program :sc:`pass_selection_to_program`
|
||||
Edit |kitty| config file :sc:`edit_config_file`
|
||||
Open a |kitty| shell :sc:`kitty_shell`
|
||||
Increase background opacity :sc:`increase_background_opacity`
|
||||
Decrease background opacity :sc:`decrease_background_opacity`
|
||||
Full background opacity :sc:`full_background_opacity`
|
||||
Reset background opacity :sc:`reset_background_opacity`
|
||||
================================== =======================
|
||||
|
||||
|
||||
.. _layouts:
|
||||
|
||||
Layouts
|
||||
----------
|
||||
|
||||
A layout is an arrangement of multiple kitty *windows* inside a top-level OS window. You can create a new window
|
||||
using the :sc:`new_window` key combination.
|
||||
|
||||
Currently, there are six layouts available:
|
||||
|
||||
* **Fat** -- One (or optionally more) windows are shown full width on the top, the rest of the windows are shown side-by-side on the bottom
|
||||
* **Grid** -- All windows are shown in a grid
|
||||
* **Horizontal** -- All windows are shown side-by-side
|
||||
* **Splits** -- Windows arranged in arbitrary patterns created using horizontal and vertical splits
|
||||
* **Stack** -- Only a single maximized window is shown at a time
|
||||
* **Tall** -- One (or optionally more) windows are shown full height on the left, the rest of the windows are shown one below the other on the right
|
||||
* **Vertical** -- All windows are shown one below the other
|
||||
|
||||
By default, all layouts are enabled and you can switch between layouts using
|
||||
the :sc:`next_layout` key combination. You can also create shortcuts to select
|
||||
particular layouts, and choose which layouts you want to enable/disable, see
|
||||
:ref:`conf-kitty-shortcuts.layout` for examples. The first layout listed in
|
||||
:opt:`enabled_layouts` becomes the default layout.
|
||||
|
||||
For more details on the layouts and how to use them see :doc:`layouts`.
|
||||
|
||||
.. _kittens:
|
||||
|
||||
Kittens
|
||||
------------------
|
||||
|
||||
|kitty| has a framework for easily creating terminal programs that make use of
|
||||
its advanced features. These programs are called kittens. They are used both
|
||||
to add features to |kitty| itself and to create useful standalone programs.
|
||||
Some prominent kittens:
|
||||
|
||||
:doc:`icat <kittens/icat>`
|
||||
Display images in the terminal
|
||||
|
||||
|
||||
:doc:`diff <kittens/diff>`
|
||||
A fast, side-by-side diff for the terminal with syntax highlighting and
|
||||
images
|
||||
|
||||
|
||||
:doc:`Unicode Input <kittens/unicode-input>`
|
||||
Easily input arbitrary unicode characters in |kitty| by name or hex code.
|
||||
|
||||
|
||||
:doc:`Hints <kittens/hints>`
|
||||
Select and open/paste/insert arbitrary text snippets such as URLs,
|
||||
filenames, words, lines, etc. from the terminal screen.
|
||||
|
||||
|
||||
:doc:`Remote file <kittens/remote_file>`
|
||||
Edit, open, or download remote files over SSH easily, by simply clicking on
|
||||
the filename.
|
||||
|
||||
|
||||
:doc:`Hyperlinked grep <kittens/hyperlinked_grep>`
|
||||
Search your files using `ripgrep <https://github.com/BurntSushi/ripgrep>`_
|
||||
and open the results directly in your favorite editor in the terminal,
|
||||
at the line containing the search result, simply by clicking on the result you want.
|
||||
|
||||
|
||||
:doc:`Broadcast <kittens/broadcast>`
|
||||
Type in one kitty window and have it broadcast to all (or a subset) of
|
||||
other kitty windows.
|
||||
|
||||
|
||||
:doc:`Panel <kittens/panel>`
|
||||
Draw a GPU accelerated dock panel on your desktop showing the output
|
||||
from an arbitrary terminal program.
|
||||
|
||||
|
||||
:doc:`Clipboard <kittens/clipboard>`
|
||||
Copy/paste to the clipboard from shell scripts, even over SSH.
|
||||
|
||||
You can also :doc:`Learn to create your own kittens <kittens/custom>`.
|
||||
|
||||
|
||||
Configuring kitty
|
||||
-------------------
|
||||
|
||||
|kitty| is highly configurable, everything from keyboard shortcuts to
|
||||
painting frames-per-second. For details and a sample :file:`kitty.conf`,
|
||||
see the :doc:`configuration docs <conf>`.
|
||||
|
||||
|
||||
Remote control
|
||||
------------------
|
||||
|
||||
|kitty| has a very powerful system that allows you to control it from the
|
||||
:doc:`shell prompt, even over SSH <remote-control>`. You can change colors,
|
||||
fonts, open new windows, tabs, set their titles, change window layout, get text
|
||||
from one window and send text to another, etc, etc. The possibilities are
|
||||
endless. See the :doc:`tutorial <remote-control>` to get started.
|
||||
|
||||
.. _sessions:
|
||||
|
||||
Startup Sessions
|
||||
------------------
|
||||
|
||||
You can control the tabs, window layout, working directory, startup programs,
|
||||
etc. by creating a "session" file and using the :option:`kitty --session`
|
||||
command line flag or the :opt:`startup_session` option in :file:`kitty.conf`.
|
||||
For example:
|
||||
|
||||
.. code-block:: session
|
||||
|
||||
# Set the window layout for the current tab
|
||||
layout tall
|
||||
# Set the working directory for windows in the current tab
|
||||
cd ~
|
||||
# Create a window and run the specified command in it
|
||||
launch zsh
|
||||
# Create a window with some environment variables set and run
|
||||
# vim in it
|
||||
launch --env FOO=BAR vim
|
||||
# Set the title for the next window
|
||||
title Chat with x
|
||||
launch irssi --profile x
|
||||
|
||||
# Create a new tab (the part after new_tab is the optional tab
|
||||
# name which will be displayed in the tab bar, if omitted, the
|
||||
# title of the active window will be used instead)
|
||||
new_tab my tab
|
||||
cd ~/somewhere
|
||||
# Set the layouts allowed in this tab
|
||||
enabled_layouts tall, stack
|
||||
# Set the current layout
|
||||
layout stack
|
||||
launch zsh
|
||||
|
||||
# Create a new OS window
|
||||
new_os_window
|
||||
# set new window size to 80x25 cells
|
||||
os_window_size 80c 25c
|
||||
# set the --class for the new OS window
|
||||
os_window_class mywindow
|
||||
launch sh
|
||||
# Make the current window the active (focused) window
|
||||
focus
|
||||
launch emacs
|
||||
|
||||
.. note::
|
||||
The :doc:`launch <launch>` command when used in a session file
|
||||
cannot create new OS windows, or tabs.
|
||||
|
||||
|
||||
Mouse features
|
||||
-------------------
|
||||
|
||||
* You can hold down :kbd:`ctrl+shift` and click on a URL to open it in a browser.
|
||||
* You can double click to select a word and then drag to select more words.
|
||||
* You can triple click to select a line and then drag to select more lines.
|
||||
* You can right click to extend a previous selection.
|
||||
* You can hold down :kbd:`ctrl+alt` and drag with the mouse to select in
|
||||
columns (see also :opt:`rectangle_select_modifiers`).
|
||||
* Selecting text automatically copies it to the primary clipboard (on
|
||||
platforms with a primary clipboard).
|
||||
* You can select text with kitty even when a terminal program has grabbed
|
||||
the mouse by holding down the :kbd:`shift` key (see also
|
||||
:opt:`terminal_select_modifiers`).
|
||||
|
||||
|
||||
Font control
|
||||
-----------------
|
||||
|
||||
|kitty| has extremely flexible and powerful font selection features. You can
|
||||
specify individual families for the regular, bold, italic and bold+italic
|
||||
fonts. You can even specify specific font families for specific ranges of
|
||||
unicode characters. This allows precise control over text rendering. It can
|
||||
come in handy for applications like powerline, without the need to use patched
|
||||
fonts. See the various font related configuration directives in
|
||||
:ref:`conf-kitty-fonts`.
|
||||
|
||||
|
||||
.. _scrollback:
|
||||
|
||||
The scrollback buffer
|
||||
-----------------------
|
||||
|
||||
|kitty| supports scrolling back to view history, just like most terminals. You
|
||||
can use either keyboard shortcuts or the mouse scroll wheel to do so. However,
|
||||
|kitty| has an extra, neat feature. Sometimes you need to explore the
|
||||
scrollback buffer in more detail, maybe search for some text or refer to it
|
||||
side-by-side while typing in a follow-up command. |kitty| allows you to do this
|
||||
by pressing the :sc:`show_scrollback` key-combination, which will open the
|
||||
scrollback buffer in your favorite pager program (which is ``less`` by default).
|
||||
Colors and text formatting are preserved. You can explore the scrollback buffer
|
||||
comfortably within the pager.
|
||||
|
||||
Additionally, you can pipe the contents of the scrollback buffer to an
|
||||
arbitrary, command running in a new window, tab or overlay, for example::
|
||||
|
||||
map f1 launch --stdin-source=@screen_scrollback --stdin-add-formatting less +G -R
|
||||
|
||||
Would open the scrollback buffer in a new window when you press the :kbd:`F1`
|
||||
key. See :sc:`show_scrollback` for details.
|
||||
|
||||
If you want to use it with an editor such as vim to get more powerful features,
|
||||
you can see tips for doing so, in
|
||||
`this thread <https://github.com/kovidgoyal/kitty/issues/719>`_.
|
||||
|
||||
If you wish to store very large amounts of scrollback to view using the piping or
|
||||
:sc:`show_scrollback` features, you can use the :opt:`scrollback_pager_history_size`
|
||||
option.
|
||||
|
||||
.. _cpbuf:
|
||||
|
||||
Multiple copy/paste buffers
|
||||
-----------------------------
|
||||
|
||||
In addition to being able to copy/paste from the system clipboard, in |kitty| you
|
||||
can also setup an arbitrary number of copy paste buffers. To do so, simply add
|
||||
something like the following to your :file:`kitty.conf`::
|
||||
|
||||
map f1 copy_to_buffer a
|
||||
map f2 paste_from_buffer a
|
||||
|
||||
This will allow you to press :kbd:`F1` to copy the current selection to an
|
||||
internal buffer named ``a`` and :kbd:`F2` to paste from that buffer. The buffer
|
||||
names are arbitrary strings, so you can define as many such buffers as you
|
||||
need.
|
||||
|
||||
Marks
|
||||
-------------
|
||||
|
||||
kitty has the ability to mark text on the screen based on regular expressions.
|
||||
This can be useful to highlight words or phrases when browsing output from long
|
||||
running programs or similar. To learn how this feature works, see :doc:`marks`.
|
||||
|
||||
|
||||
Frequently Asked Questions
|
||||
---------------------------------
|
||||
|
||||
The list of Frequently Asked Questions (*FAQ*) is :doc:`available here <faq>`.
|
||||
|
||||
.. _completion:
|
||||
|
||||
|
||||
Cool integrations for kitty with other CLI tools
|
||||
--------------------------------------------------
|
||||
|
||||
kitty provides extremely powerful interfaces such as :doc:`remote-control` and
|
||||
:doc:`kittens/custom` and :doc:`kittens/icat`
|
||||
that allow it to be integrated with other tools seamlessly. For a list of such
|
||||
user created integrations, see: :doc:`integrations`.
|
||||
|
||||
Completion for kitty
|
||||
---------------------------------
|
||||
|
||||
|kitty| comes with completion for the ``kitty`` command for popular shells.
|
||||
|
||||
|
||||
bash
|
||||
~~~~~~~~
|
||||
|
||||
Add the following to your :file:`~/.bashrc`
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
source <(kitty + complete setup bash)
|
||||
|
||||
Older versions of bash (for example, v3.2) do not support
|
||||
process substitution with the source command, in which
|
||||
case you can try an alternative:
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
source /dev/stdin <<<"$(kitty + complete setup bash)"
|
||||
|
||||
|
||||
zsh
|
||||
~~~~~~~~~
|
||||
|
||||
Add the following to your :file:`~/.zshrc`
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
autoload -Uz compinit
|
||||
compinit
|
||||
# Completion for kitty
|
||||
kitty + complete setup zsh | source /dev/stdin
|
||||
|
||||
The important thing above is to make sure the call to |kitty| to load the zsh
|
||||
completions happens after the call to :file:`compinit`.
|
||||
|
||||
|
||||
fish
|
||||
~~~~~~~~
|
||||
|
||||
For versions of fish earlier than 3.0.0, add the following to your
|
||||
:file:`~/.config/fish/config.fish`. Later versions source completions by default.
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
kitty + complete setup fish | source
|
||||
|
||||
|
||||
Changelog
|
||||
------------------
|
||||
|
||||
See :doc:`changelog`.
|
||||
*The fast, feature-rich, GPU based terminal emulator*
|
||||
|
||||
.. toctree::
|
||||
:hidden:
|
||||
:glob:
|
||||
|
||||
*
|
||||
kittens/*
|
||||
generated/rc
|
||||
quickstart
|
||||
overview
|
||||
faq
|
||||
support
|
||||
performance
|
||||
changelog
|
||||
integrations
|
||||
protocol-extensions
|
||||
|
||||
|
||||
.. tab:: Fast
|
||||
|
||||
* Offloads rendering to the GPU for :doc:`lower system load <performance>`
|
||||
* Uses threaded rendering for
|
||||
`absolutely minimal latency <https://github.com/kovidgoyal/kitty/issues/2701#issuecomment-636497270>`_
|
||||
* Performance tradeoffs can be :ref:`tuned <conf-kitty-performance>`
|
||||
|
||||
.. tab:: Capable
|
||||
|
||||
* Graphics, with :doc:`images and animations <graphics-protocol>`
|
||||
* Ligatures and emoji, with :opt:`per glyph font substitution <symbol_map>`
|
||||
* :term:`Hyperlinks<hyperlinks>`, with :doc:`configurable actions <open_actions>`
|
||||
|
||||
.. tab:: Scriptable
|
||||
|
||||
* Control from :doc:`scripts or the shell <remote-control>`
|
||||
* Extend with :ref:`kittens <kittens>` using the Python language
|
||||
* Use :ref:`startup sessions <sessions>` to specify working environments
|
||||
|
||||
.. tab:: Composable
|
||||
|
||||
* Programmable tabs, :ref:`splits <splits_layout>` and multiple :doc:`layouts <layouts>` to manage windows
|
||||
* Browse the :ref:`entire history <scrollback>` or the :sc:`output from the last command <show_last_command_output>`
|
||||
comfortably in pagers and editors
|
||||
* Edit or download :doc:`remote files <kittens/remote_file>` in an existing SSH session
|
||||
|
||||
.. tab:: Cross-platform
|
||||
|
||||
* Linux
|
||||
* macOS
|
||||
* Various BSDs
|
||||
|
||||
.. tab:: Innovative
|
||||
|
||||
Pioneered various extensions to move the entire terminal ecosystem forward
|
||||
|
||||
* :doc:`graphics-protocol`
|
||||
* :doc:`keyboard-protocol`
|
||||
* Lots more in :doc:`protocol-extensions`
|
||||
|
||||
|
||||
.. only:: dirhtml
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<video controls width="640" height="360">
|
||||
<source src="https://download.calibre-ebook.com/videos/kitty.mp4" type="video/mp4">
|
||||
<source src="https://download.calibre-ebook.com/videos/kitty.webm" type="video/webm">
|
||||
</video>
|
||||
|
||||
.. rst-class:: caption caption-text
|
||||
|
||||
Watch kitty in action!
|
||||
|
||||
|
||||
To get started see :doc:`quickstart`.
|
||||
|
||||
@@ -20,10 +20,16 @@ import tempfile
|
||||
py3 = sys.version_info[0] > 2
|
||||
is64bit = platform.architecture()[0] == '64bit'
|
||||
is_macos = 'darwin' in sys.platform.lower()
|
||||
is_linux_arm = is_linux_arm64 = False
|
||||
if is_macos:
|
||||
mac_ver = tuple(map(int, platform.mac_ver()[0].split('.')))
|
||||
if mac_ver[:2] < (10, 12):
|
||||
raise SystemExit('Your version of macOS is too old, at least 10.12 is required')
|
||||
else:
|
||||
machine = (os.uname()[4] or '').lower()
|
||||
if machine.startswith('arm') or machine.startswith('aarch64'):
|
||||
is_linux_arm = True
|
||||
is_linux_arm64 = machine.startswith('arm64') or machine.startswith('aarch64')
|
||||
|
||||
try:
|
||||
__file__
|
||||
@@ -73,9 +79,11 @@ class Reporter: # {{{
|
||||
# }}}
|
||||
|
||||
|
||||
def get_latest_release_data():
|
||||
def get_release_data(relname='latest'):
|
||||
print('Checking for latest release on GitHub...')
|
||||
req = urllib.Request('https://api.github.com/repos/kovidgoyal/kitty/releases/latest', headers={'Accept': 'application/vnd.github.v3+json'})
|
||||
req = urllib.Request(
|
||||
'https://api.github.com/repos/kovidgoyal/kitty/releases/' + relname,
|
||||
headers={'Accept': 'application/vnd.github.v3+json'})
|
||||
try:
|
||||
res = urllib.urlopen(req).read().decode('utf-8')
|
||||
except Exception as err:
|
||||
@@ -90,7 +98,8 @@ def get_latest_release_data():
|
||||
else:
|
||||
if name.endswith('.txz'):
|
||||
if is64bit:
|
||||
if name.endswith('-x86_64.txz'):
|
||||
q = '-arm64.txz' if is_linux_arm64 else '-x86_64.txz'
|
||||
if name.endswith(q):
|
||||
return html_url + '/' + name, asset['size']
|
||||
else:
|
||||
if name.endswith('-i686.txz'):
|
||||
@@ -184,19 +193,22 @@ def main(dest=None, launch=True, installer=None):
|
||||
dest = '/Applications'
|
||||
else:
|
||||
dest = os.path.expanduser('~/.local')
|
||||
machine = os.uname()[4]
|
||||
if machine and machine.lower().startswith('arm'):
|
||||
if is_linux_arm and not is_linux_arm64:
|
||||
raise SystemExit(
|
||||
'You are running on an ARM system. The kitty binaries are only'
|
||||
' available for x86 systems. You will have to build from'
|
||||
'You are running on a 32-bit ARM system. The kitty binaries are only'
|
||||
' available for 64 bit ARM systems. You will have to build from'
|
||||
' source.')
|
||||
if not installer:
|
||||
url, size = get_latest_release_data()
|
||||
url, size = get_release_data()
|
||||
installer = download_installer(url, size)
|
||||
else:
|
||||
installer = os.path.abspath(installer)
|
||||
if not os.access(installer, os.R_OK):
|
||||
raise SystemExit('Could not read from: {}'.format(installer))
|
||||
if installer == 'nightly':
|
||||
url, size = get_release_data('tags/nightly')
|
||||
installer = download_installer(url, size)
|
||||
else:
|
||||
installer = os.path.abspath(installer)
|
||||
if not os.access(installer, os.R_OK):
|
||||
raise SystemExit('Could not read from: {}'.format(installer))
|
||||
if is_macos:
|
||||
macos_install(installer, dest=dest, launch=launch)
|
||||
else:
|
||||
@@ -227,7 +239,7 @@ def script_launch():
|
||||
main(**kwargs)
|
||||
|
||||
|
||||
def update_intaller_wrapper():
|
||||
def update_installer_wrapper():
|
||||
# To run: python3 -c "import runpy; runpy.run_path('installer.py', run_name='update_wrapper')" installer.sh
|
||||
with open(__file__, 'rb') as f:
|
||||
src = f.read().decode('utf-8')
|
||||
@@ -244,6 +256,6 @@ def update_intaller_wrapper():
|
||||
if __name__ == '__main__' and from_file:
|
||||
main()
|
||||
elif __name__ == 'update_wrapper':
|
||||
update_intaller_wrapper()
|
||||
update_installer_wrapper()
|
||||
elif __name__ == 'script_launch':
|
||||
script_launch()
|
||||
|
||||
@@ -25,6 +25,268 @@ echo Using python executable: $python
|
||||
$python -c "import sys; script_launch=lambda:sys.exit('Download of installer failed!'); exec(sys.stdin.read()); script_launch()" "$@" <<'INSTALLER_HEREDOC'
|
||||
# {{{
|
||||
# HEREDOC_START
|
||||
#!/usr/bin/env python3
|
||||
# vim:fileencoding=utf-8
|
||||
# License: GPL v3 Copyright: 2018, Kovid Goyal <kovid at kovidgoyal.net>
|
||||
|
||||
from __future__ import (
|
||||
absolute_import, division, print_function, unicode_literals
|
||||
)
|
||||
|
||||
import atexit
|
||||
import json
|
||||
import os
|
||||
import platform
|
||||
import re
|
||||
import shlex
|
||||
import shutil
|
||||
import subprocess
|
||||
import sys
|
||||
import tempfile
|
||||
|
||||
py3 = sys.version_info[0] > 2
|
||||
is64bit = platform.architecture()[0] == '64bit'
|
||||
is_macos = 'darwin' in sys.platform.lower()
|
||||
is_linux_arm = is_linux_arm64 = False
|
||||
if is_macos:
|
||||
mac_ver = tuple(map(int, platform.mac_ver()[0].split('.')))
|
||||
if mac_ver[:2] < (10, 12):
|
||||
raise SystemExit('Your version of macOS is too old, at least 10.12 is required')
|
||||
else:
|
||||
machine = (os.uname()[4] or '').lower()
|
||||
if machine.startswith('arm') or machine.startswith('aarch64'):
|
||||
is_linux_arm = True
|
||||
is_linux_arm64 = machine.startswith('arm64') or machine.startswith('aarch64')
|
||||
|
||||
try:
|
||||
__file__
|
||||
from_file = True
|
||||
except NameError:
|
||||
from_file = False
|
||||
|
||||
if py3:
|
||||
unicode = str
|
||||
raw_input = input
|
||||
import urllib.request as urllib
|
||||
|
||||
def encode_for_subprocess(x):
|
||||
return x
|
||||
else:
|
||||
from future_builtins import map
|
||||
import urllib2 as urllib
|
||||
|
||||
def encode_for_subprocess(x):
|
||||
if isinstance(x, unicode):
|
||||
x = x.encode('utf-8')
|
||||
return x
|
||||
|
||||
|
||||
def run(*args):
|
||||
if len(args) == 1:
|
||||
args = shlex.split(args[0])
|
||||
args = list(map(encode_for_subprocess, args))
|
||||
ret = subprocess.Popen(args).wait()
|
||||
if ret != 0:
|
||||
raise SystemExit(ret)
|
||||
|
||||
|
||||
class Reporter: # {{{
|
||||
|
||||
def __init__(self, fname):
|
||||
self.fname = fname
|
||||
self.last_percent = 0
|
||||
|
||||
def __call__(self, blocks, block_size, total_size):
|
||||
percent = (blocks*block_size)/float(total_size)
|
||||
report = '\rDownloaded {:.1%} '.format(percent)
|
||||
if percent - self.last_percent > 0.05:
|
||||
self.last_percent = percent
|
||||
print(report, end='')
|
||||
sys.stdout.flush()
|
||||
# }}}
|
||||
|
||||
|
||||
def get_release_data(relname='latest'):
|
||||
print('Checking for latest release on GitHub...')
|
||||
req = urllib.Request(
|
||||
'https://api.github.com/repos/kovidgoyal/kitty/releases/' + relname,
|
||||
headers={'Accept': 'application/vnd.github.v3+json'})
|
||||
try:
|
||||
res = urllib.urlopen(req).read().decode('utf-8')
|
||||
except Exception as err:
|
||||
raise SystemExit('Failed to contact {} with error: {}'.format(req.get_full_url(), err))
|
||||
data = json.loads(res)
|
||||
html_url = data['html_url'].replace('/tag/', '/download/').rstrip('/')
|
||||
for asset in data.get('assets', ()):
|
||||
name = asset['name']
|
||||
if is_macos:
|
||||
if name.endswith('.dmg'):
|
||||
return html_url + '/' + name, asset['size']
|
||||
else:
|
||||
if name.endswith('.txz'):
|
||||
if is64bit:
|
||||
q = '-arm64.txz' if is_linux_arm64 else '-x86_64.txz'
|
||||
if name.endswith(q):
|
||||
return html_url + '/' + name, asset['size']
|
||||
else:
|
||||
if name.endswith('-i686.txz'):
|
||||
return html_url + '/' + name, asset['size']
|
||||
raise SystemExit('Failed to find the installer package on github')
|
||||
|
||||
|
||||
def do_download(url, size, dest):
|
||||
print('Will download and install', os.path.basename(dest))
|
||||
reporter = Reporter(os.path.basename(dest))
|
||||
|
||||
# Get content length and check if range is supported
|
||||
rq = urllib.urlopen(url)
|
||||
headers = rq.info()
|
||||
sent_size = int(headers['content-length'])
|
||||
if sent_size != size:
|
||||
raise SystemExit('Failed to download from {} Content-Length ({}) != {}'.format(url, sent_size, size))
|
||||
with open(dest, 'wb') as f:
|
||||
while f.tell() < size:
|
||||
raw = rq.read(8192)
|
||||
if not raw:
|
||||
break
|
||||
f.write(raw)
|
||||
reporter(f.tell(), 1, size)
|
||||
rq.close()
|
||||
if os.path.getsize(dest) < size:
|
||||
raise SystemExit('Download failed, try again later')
|
||||
print('\rDownloaded {} bytes'.format(os.path.getsize(dest)))
|
||||
|
||||
|
||||
def clean_cache(cache, fname):
|
||||
for x in os.listdir(cache):
|
||||
if fname not in x:
|
||||
os.remove(os.path.join(cache, x))
|
||||
|
||||
|
||||
def download_installer(url, size):
|
||||
fname = url.rpartition('/')[-1]
|
||||
tdir = tempfile.gettempdir()
|
||||
cache = os.path.join(tdir, 'kitty-installer-cache')
|
||||
if not os.path.exists(cache):
|
||||
os.makedirs(cache)
|
||||
clean_cache(cache, fname)
|
||||
dest = os.path.join(cache, fname)
|
||||
if os.path.exists(dest) and os.path.getsize(dest) == size:
|
||||
print('Using previously downloaded', fname)
|
||||
return dest
|
||||
if os.path.exists(dest):
|
||||
os.remove(dest)
|
||||
do_download(url, size, dest)
|
||||
return dest
|
||||
|
||||
|
||||
def macos_install(dmg, dest='/Applications', launch=True):
|
||||
mp = tempfile.mkdtemp()
|
||||
atexit.register(shutil.rmtree, mp)
|
||||
run('hdiutil', 'attach', dmg, '-mountpoint', mp)
|
||||
try:
|
||||
os.chdir(mp)
|
||||
app = 'kitty.app'
|
||||
d = os.path.join(dest, app)
|
||||
if os.path.exists(d):
|
||||
shutil.rmtree(d)
|
||||
dest = os.path.join(dest, app)
|
||||
run('ditto', '-v', app, dest)
|
||||
print('Successfully installed kitty into', dest)
|
||||
if launch:
|
||||
run('open', dest)
|
||||
finally:
|
||||
os.chdir('/')
|
||||
run('hdiutil', 'detach', mp)
|
||||
|
||||
|
||||
def linux_install(installer, dest=os.path.expanduser('~/.local'), launch=True):
|
||||
dest = os.path.join(dest, 'kitty.app')
|
||||
if os.path.exists(dest):
|
||||
shutil.rmtree(dest)
|
||||
os.makedirs(dest)
|
||||
print('Extracting tarball...')
|
||||
run('tar', '-C', dest, '-xJof', installer)
|
||||
print('kitty successfully installed to', dest)
|
||||
kitty = os.path.join(dest, 'bin', 'kitty')
|
||||
print('Use', kitty, 'to run kitty')
|
||||
if launch:
|
||||
run(kitty, '--detach')
|
||||
|
||||
|
||||
def main(dest=None, launch=True, installer=None):
|
||||
if not dest:
|
||||
if is_macos:
|
||||
dest = '/Applications'
|
||||
else:
|
||||
dest = os.path.expanduser('~/.local')
|
||||
if is_linux_arm and not is_linux_arm64:
|
||||
raise SystemExit(
|
||||
'You are running on a 32-bit ARM system. The kitty binaries are only'
|
||||
' available for 64 bit ARM systems. You will have to build from'
|
||||
' source.')
|
||||
if not installer:
|
||||
url, size = get_release_data()
|
||||
installer = download_installer(url, size)
|
||||
else:
|
||||
if installer == 'nightly':
|
||||
url, size = get_release_data('tags/nightly')
|
||||
installer = download_installer(url, size)
|
||||
else:
|
||||
installer = os.path.abspath(installer)
|
||||
if not os.access(installer, os.R_OK):
|
||||
raise SystemExit('Could not read from: {}'.format(installer))
|
||||
if is_macos:
|
||||
macos_install(installer, dest=dest, launch=launch)
|
||||
else:
|
||||
linux_install(installer, dest=dest, launch=launch)
|
||||
|
||||
|
||||
def script_launch():
|
||||
# To test: python3 -c "import runpy; runpy.run_path('installer.py', run_name='script_launch')"
|
||||
def path(x):
|
||||
return os.path.expandvars(os.path.expanduser(x))
|
||||
|
||||
def to_bool(x):
|
||||
return x.lower() in {'y', 'yes', '1', 'true'}
|
||||
|
||||
type_map = {x: path for x in 'dest installer'.split()}
|
||||
type_map['launch'] = to_bool
|
||||
kwargs = {}
|
||||
|
||||
for arg in sys.argv[1:]:
|
||||
if arg:
|
||||
m = re.match('([a-z_]+)=(.+)', arg)
|
||||
if m is None:
|
||||
raise SystemExit('Unrecognized command line argument: ' + arg)
|
||||
k = m.group(1)
|
||||
if k not in type_map:
|
||||
raise SystemExit('Unrecognized command line argument: ' + arg)
|
||||
kwargs[k] = type_map[k](m.group(2))
|
||||
main(**kwargs)
|
||||
|
||||
|
||||
def update_installer_wrapper():
|
||||
# To run: python3 -c "import runpy; runpy.run_path('installer.py', run_name='update_wrapper')" installer.sh
|
||||
with open(__file__, 'rb') as f:
|
||||
src = f.read().decode('utf-8')
|
||||
wrapper = sys.argv[-1]
|
||||
with open(wrapper, 'r+b') as f:
|
||||
raw = f.read().decode('utf-8')
|
||||
nraw = re.sub(r'^# HEREDOC_START.+^# HEREDOC_END', lambda m: '# HEREDOC_START\n{}\n# HEREDOC_END'.format(src), raw, flags=re.MULTILINE | re.DOTALL)
|
||||
if 'update_intaller_wrapper()' not in nraw:
|
||||
raise SystemExit('regex substitute of HEREDOC failed')
|
||||
f.seek(0), f.truncate()
|
||||
f.write(nraw.encode('utf-8'))
|
||||
|
||||
|
||||
if __name__ == '__main__' and from_file:
|
||||
main()
|
||||
elif __name__ == 'update_wrapper':
|
||||
update_installer_wrapper()
|
||||
elif __name__ == 'script_launch':
|
||||
script_launch()
|
||||
|
||||
# HEREDOC_END
|
||||
# }}}
|
||||
INSTALLER_HEREDOC
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
:tocdepth: 2
|
||||
|
||||
Integrations with other tools
|
||||
================================
|
||||
|
||||
@@ -12,138 +14,245 @@ Image and document viewers
|
||||
Powered by kitty's :doc:`graphics-protocol` there exist many tools for viewing
|
||||
images and other types of documents directly in your terminal, even over SSH.
|
||||
|
||||
.. _tool_termpdf:
|
||||
|
||||
`termpdf.py <https://github.com/dsanson/termpdf.py>`_
|
||||
a terminal PDF/DJVU/CBR viewer
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
A terminal PDF/DJVU/CBR viewer
|
||||
|
||||
.. _tool_mdcat:
|
||||
|
||||
`mdcat <https://github.com/lunaryorn/mdcat>`_
|
||||
Display markdown files nicely formatted with images in the terminal
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
Display markdown files nicely formatted with images in the terminal
|
||||
|
||||
.. _tool_ranger:
|
||||
|
||||
`ranger <https://github.com/ranger/ranger>`_
|
||||
a terminal file manager, with previews of file contents powered by kitty's graphics protocol.
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
A terminal file manager, with previews of file contents powered by kitty's graphics protocol.
|
||||
|
||||
.. _tool_nnn:
|
||||
|
||||
`nnn <https://github.com/jarun/nnn/>`_
|
||||
another terminal file manager, with previews of file contents powered by kitty's graphics protocol.
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
Another terminal file manager, with previews of file contents powered by kitty's graphics protocol.
|
||||
|
||||
.. _tool_hunter:
|
||||
|
||||
`hunter <https://github.com/rabite0/hunter>`_
|
||||
another terminal file manager, with previews of file contents powered by kitty's graphics protocol.
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
Another terminal file manager, with previews of file contents powered by kitty's graphics protocol.
|
||||
|
||||
.. _tool_koneko:
|
||||
|
||||
`koneko <https://github.com/twenty5151/koneko>`_
|
||||
browse images from the pixiv artist community directly in kitty.
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
Browse images from the pixiv artist community directly in kitty.
|
||||
|
||||
.. _tool_viu:
|
||||
|
||||
`viu <https://github.com/atanunq/viu>`_
|
||||
view images in the terminal, similar to kitty's icat.
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
View images in the terminal, similar to kitty's icat.
|
||||
|
||||
.. _tool_nb:
|
||||
|
||||
|
||||
`nb <https://github.com/xwmx/nb>`_
|
||||
command line and local web note-taking, bookmarking, archiving, and
|
||||
knowledge base application that uses kitty's graphics protocol for images.
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
command line and local web note-taking, bookmarking, archiving, and
|
||||
knowledge base application that uses kitty's graphics protocol for images.
|
||||
|
||||
.. _tool_w3m:
|
||||
|
||||
`w3m <https://github.com/tats/w3m>`_
|
||||
A text mode WWW browser that supports kitty's graphics protocol to display
|
||||
images.
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
A text mode WWW browser that supports kitty's graphics protocol to display
|
||||
images.
|
||||
|
||||
.. _tool_timg:
|
||||
|
||||
`timg <https://github.com/hzeller/timg>`_
|
||||
A terminal image and video viewer, that displays static and animated
|
||||
images or plays videos. Fast multi-threaded loading, JPEG exif rotation,
|
||||
grid view and connecting to the webcam make it a versatile terminal utility.
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
A terminal image and video viewer, that displays static and animated
|
||||
images or plays videos. Fast multi-threaded loading, JPEG exif rotation,
|
||||
grid view and connecting to the webcam make it a versatile terminal utility.
|
||||
|
||||
|
||||
System and data visualisation tools
|
||||
---------------------------------------
|
||||
|
||||
.. _tool_neofetch:
|
||||
|
||||
`neofetch <https://github.com/dylanaraps/neofetch>`_
|
||||
A command line system information tool that shows images using kitty's graphics protocol
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
A command line system information tool that shows images using kitty's graphics protocol
|
||||
|
||||
.. _tool_matplotlib:
|
||||
|
||||
`matplotlib <https://github.com/jktr/matplotlib-backend-kitty>`_
|
||||
show matplotlib plots directly in kitty
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
Show matplotlib plots directly in kitty
|
||||
|
||||
.. _tool_KittyTerminalImage:
|
||||
|
||||
`KittyTerminalImages.jl <https://github.com/simonschoelly/KittyTerminalImages.jl>`_
|
||||
show images from Julia directly in kitty
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
Show images from Julia directly in kitty
|
||||
|
||||
.. _tool_euporie:
|
||||
|
||||
`euporie <https://github.com/joouha/euporie>`_
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
A text-based user interface for running and editing Jupyter notebooks,
|
||||
powered by kitty's graphics protocol for displaying plots
|
||||
|
||||
.. _tool_gnuplot:
|
||||
|
||||
`gnuplot <http://www.gnuplot.info/>`_
|
||||
a graphing and data visualization tool that can be made to display its
|
||||
output in kitty with the following bash snippet::
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
function iplot {
|
||||
cat <<EOF | gnuplot
|
||||
set terminal pngcairo enhanced font 'Fira Sans,10'
|
||||
set autoscale
|
||||
set samples 1000
|
||||
set output '|kitty +kitten icat --stdin yes'
|
||||
set object 1 rectangle from screen 0,0 to screen 1,1 fillcolor rgb"#fdf6e3" behind
|
||||
plot $@
|
||||
set output '/dev/null'
|
||||
EOF
|
||||
}
|
||||
A graphing and data visualization tool that can be made to display its
|
||||
output in kitty with the following bash snippet:
|
||||
|
||||
Add this to bashrc and then to plot a function, simply do::
|
||||
.. code-block:: sh
|
||||
|
||||
iplot 'sin(x*3)*exp(x*.2)'
|
||||
function iplot {
|
||||
cat <<EOF | gnuplot
|
||||
set terminal pngcairo enhanced font 'Fira Sans,10'
|
||||
set autoscale
|
||||
set samples 1000
|
||||
set output '|kitty +kitten icat --stdin yes'
|
||||
set object 1 rectangle from screen 0,0 to screen 1,1 fillcolor rgb"#fdf6e3" behind
|
||||
plot $@
|
||||
set output '/dev/null'
|
||||
EOF
|
||||
}
|
||||
|
||||
Add this to bashrc and then to plot a function, simply do:
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
iplot 'sin(x*3)*exp(x*.2)'
|
||||
|
||||
.. tool_onefetch:
|
||||
|
||||
`onefetch <https://github.com/o2sh/onefetch>`_
|
||||
a tool to fetch information about your git repositories
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
A tool to fetch information about your git repositories
|
||||
|
||||
.. tool_patat:
|
||||
|
||||
`patat <https://github.com/jaspervdj/patat>`_
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
Terminal based presentations using pandoc and kitty's image protocol for
|
||||
images
|
||||
|
||||
.. tool_wttr:
|
||||
|
||||
`wttr.in <https://github.com/chubin/wttr.in>`_
|
||||
a tool to display weather information in your terminal with curl
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
A tool to display weather information in your terminal with curl
|
||||
|
||||
.. tool_wl_clipboard:
|
||||
|
||||
`wl-clipboard-manager <https://github.com/maximbaz/wl-clipboard-manager>`_
|
||||
view and manage the system clipboard under Wayland in your kitty terminal
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
View and manage the system clipboard under Wayland in your kitty terminal
|
||||
|
||||
.. tool_dmenu_term:
|
||||
|
||||
`dmenu-term <https://github.com/maximbaz/dmenu-term>`_
|
||||
run applications on your system with fuzzy find inside a kitty window
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
Run applications on your system with fuzzy find inside a kitty window
|
||||
|
||||
|
||||
Editor integration
|
||||
-----------------------
|
||||
|
||||
kitty can be integrated into many different terminal editors to add features
|
||||
|kitty| can be integrated into many different terminal editors to add features
|
||||
such a split windows, previews, REPLs etc.
|
||||
|
||||
.. tool_kakoune:
|
||||
|
||||
`kakoune <https://kakoune.org/>`_
|
||||
integrates with kitty to use native kitty windows for its windows/panels and REPLs.
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
integrates with kitty to use native kitty windows for its windows/panels and REPLs.
|
||||
|
||||
.. tool_vim_slime:
|
||||
|
||||
`vim-slime <https://github.com/jpalardy/vim-slime#kitty>`_
|
||||
uses kitty remote control for a Lisp REPL.
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
uses kitty remote control for a Lisp REPL.
|
||||
|
||||
.. tool_vim_kitty_navigator:
|
||||
|
||||
`vim-kitty-navigator <https://github.com/knubie/vim-kitty-navigator>`_
|
||||
allows you to navigate seamlessly between vim and kitty splits using a consistent set of hotkeys.
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
allows you to navigate seamlessly between vim and kitty splits using a consistent set of hotkeys.
|
||||
|
||||
.. tool_vim_test:
|
||||
|
||||
`vim-test <https://github.com/vim-test/vim-test>`_
|
||||
allows easily running tests in a terminal window
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
Allows easily running tests in a terminal window
|
||||
|
||||
.. tool_hologram:
|
||||
|
||||
`hologram.nvim <https://github.com/edluffy/hologram.nvim>`_
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
Terminal image viewer for nvim
|
||||
|
||||
|
||||
Scrollback manipulation
|
||||
-------------------------
|
||||
|
||||
.. tool_kitty_search:
|
||||
|
||||
`kitty-search <https://github.com/trygveaa/kitty-kitten-search>`_
|
||||
Live incremental search of the scrollback buffer.
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
Live incremental search of the scrollback buffer.
|
||||
|
||||
.. tool_kitty_grab:
|
||||
|
||||
`kitty-grab <https://github.com/yurikhan/kitty_grab>`_
|
||||
keyboard based text selection for the kitty scrollback buffer.
|
||||
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
Keyboard based text selection for the kitty scrollback buffer.
|
||||
|
||||
|
||||
Miscellaneous
|
||||
------------------
|
||||
|
||||
.. tool_kitty_smart_tab:
|
||||
|
||||
`kitty-smart-tab <https://github.com/yurikhan/kitty-smart-tab>`_
|
||||
use keys to either control tabs or pass them onto running applications if
|
||||
no tabs are present
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
use keys to either control tabs or pass them onto running applications if
|
||||
no tabs are present
|
||||
|
||||
.. tool_kitty_smart_scroll:
|
||||
|
||||
`kitty-smart-scroll <https://github.com/yurikhan/kitty-smart-scroll>`_
|
||||
use keys to either scroll or pass them onto running applications if
|
||||
no scrollback buffer is present
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
use keys to either scroll or pass them onto running applications if
|
||||
no scrollback buffer is present
|
||||
|
||||
`reload keybindings <https://github.com/kovidgoyal/kitty/issues/1292#issuecomment-582388769>`_
|
||||
reload key bindings from :file:`kitty.conf` without needing to restart
|
||||
kitty
|
||||
.. tool_kitti3:
|
||||
|
||||
`kitti3 <https://github.com/LandingEllipse/kitti3>`_
|
||||
allow using kitty as a drop-down terminal under the i3 window manager
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
allow using kitty as a drop-down terminal under the i3 window manager
|
||||
|
||||
.. tool_weechat_hints:
|
||||
|
||||
`weechat-hints <https://github.com/GermainZ/kitty-weechat-hints>`_
|
||||
URL hints kitten for WeeChat that works without having to use WeeChat's
|
||||
raw-mode.
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
URL hints kitten for WeeChat that works without having to use WeeChat's
|
||||
raw-mode.
|
||||
|
||||
.. tool_glkitty:
|
||||
|
||||
`glkitty <https://github.com/michaeljclark/glkitty>`_
|
||||
C library to draw OpenGL shaders in the terminal with a glgears demo
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
C library to draw OpenGL shaders in the terminal with a glgears demo
|
||||
|
||||
@@ -1,6 +1,15 @@
|
||||
:orphan:
|
||||
|
||||
The kitty command line interface
|
||||
====================================
|
||||
|
||||
.. program:: kitty
|
||||
|
||||
.. include:: generated/cli-kitty.rst
|
||||
|
||||
.. include:: basic.rst
|
||||
|
||||
See also
|
||||
-----------
|
||||
|
||||
See kitty.conf(5)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
A protocol for comprehensive keyboard handling in terminals
|
||||
=================================================================
|
||||
Comprehensive keyboard handling in terminals
|
||||
==============================================
|
||||
|
||||
There are various problems with the current state of keyboard handling in
|
||||
terminals. They include:
|
||||
@@ -28,10 +28,17 @@ issues in that proposal, listed at the :ref:`bottom of this document
|
||||
|
||||
You can see this protocol with all enhancements in action by running::
|
||||
|
||||
kitty +kitten key_demo
|
||||
kitty +kitten show_key -m kitty
|
||||
|
||||
inside the kitty terminal to report key events.
|
||||
|
||||
In addition to kitty, this protocol is also implemented in:
|
||||
|
||||
* The `foot terminal <https://codeberg.org/dnkl/foot/issues/319>`__
|
||||
* The `notcurses library
|
||||
<https://github.com/dankamongmen/notcurses/issues/2131>`__
|
||||
* The `kakoune text editor <https://github.com/mawww/kakoune/issues/4103>`__
|
||||
|
||||
.. versionadded:: 0.20.0
|
||||
|
||||
Quickstart
|
||||
@@ -41,12 +48,14 @@ If you are an application or library developer just interested in using this
|
||||
protocol to make keyboard handling simpler and more robust in your application,
|
||||
without too many changes, do the following:
|
||||
|
||||
#. Emit the escape code ``CSI > 1 u`` at application startup or when entering
|
||||
alternate screen mode
|
||||
#. Emit the escape code ``CSI > 1 u`` at application startup if using the main
|
||||
screen or when entering alternate screen mode, if using the alternate
|
||||
screen.
|
||||
#. All key events will now be sent in only a few forms to your application,
|
||||
that are easy to parse unambiguously.
|
||||
#. Emit the escape sequence ``CSI < u`` at application exit or just before
|
||||
leaving alternate screen mode to restore the previously used keyboard mode.
|
||||
#. Emit the escape sequence ``CSI < u`` at application exit if using the main
|
||||
screen or just before leaving alternate screen mode if using the alternate screen,
|
||||
to restore the previously used keyboard mode.
|
||||
|
||||
Key events will all be delivered to your application either as plain UTF-8
|
||||
text, or using the following escape codes, for those keys that do not produce
|
||||
@@ -64,10 +73,11 @@ key, such as ``97`` for the :kbd:`a` key, or one of the numbers from the
|
||||
modifiers pressed for the key event. The encoding is described in the
|
||||
:ref:`modifiers` section.
|
||||
|
||||
The second form is used for a few functional keys, such as the :kbd:`Home, End,
|
||||
Arrow keys and F1-F4`, they are enumerated in the :ref:`functional` table below.
|
||||
Note that if no modifiers are present the parameters are omitted entirely
|
||||
giving an escape code of the form ``CSI [ABCDEFHPQRS]``.
|
||||
The second form is used for a few functional keys, such as the :kbd:`Home`,
|
||||
:kbd:`End`, :kbd:`Arrow` keys and :kbd:`F1` ... :kbd:`F4`, they are enumerated in
|
||||
the :ref:`functional` table below. Note that if no modifiers are present the
|
||||
parameters are omitted entirely giving an escape code of the form ``CSI
|
||||
[ABCDEFHPQRS]``.
|
||||
|
||||
If you want support for more advanced features such as repeat and release
|
||||
events, alternate keys for shortcut matching et cetera, these can be turned on
|
||||
@@ -110,7 +120,7 @@ decimal number. For example, the :kbd:`A` key is represented as ``97`` which is
|
||||
the unicode code for lowercase ``a``. Note that the codepoint used is *always*
|
||||
the lower-case (or more technically, un-shifted) version of the key. If the
|
||||
user presses, for example, :kbd:`ctrl+shift+a` the escape code would be ``CSI
|
||||
97;modifiers u``. It *must not* by ``CSI 65; modifiers u``.
|
||||
97;modifiers u``. It *must not* be ``CSI 65; modifiers u``.
|
||||
|
||||
If *alternate key reporting* is requested by the program running in the
|
||||
terminal, the terminal can send two additional Unicode codepoints, the
|
||||
@@ -140,11 +150,13 @@ sub-field for the shifted key, like this::
|
||||
Modifiers
|
||||
~~~~~~~~~~~~~~
|
||||
|
||||
This protocol supports six modifier keys, :kbd:`shift, alt, ctrl, super, hyper
|
||||
and meta` as well as :kbd:`num_lock and caps_lock`. Here :kbd:`super` is either
|
||||
the *Windows/Linux* key or the *Cmd* key on mac keyboards. :kbd:`hyper` and
|
||||
:kbd:`meta` are typically present only on X11 based systems with special XKB
|
||||
rules. Modifiers are encoded as a bit field with::
|
||||
This protocol supports six modifier keys, :kbd:`shift`, :kbd:`alt`,
|
||||
:kbd:`ctrl`, :kbd:`super`, :kbd:`hyper`, :kbd:`meta`, :kbd:`num_lock` and
|
||||
:kbd:`caps_lock`. Here :kbd:`super` is either the *Windows/Linux* key or the
|
||||
:kbd:`command` key on mac keyboards. The :kbd:`alt` key is the :kbd:`option`
|
||||
key on mac keyboards. :kbd:`hyper` and :kbd:`meta` are typically present only
|
||||
on X11/Wayland based systems with special XKB rules. Modifiers are encoded as a
|
||||
bit field with::
|
||||
|
||||
shift 0b1 (1)
|
||||
alt 0b10 (2)
|
||||
@@ -207,9 +219,9 @@ Non-Unicode keys
|
||||
|
||||
There are many keys that don't correspond to letters from human languages, and
|
||||
thus aren't represented in Unicode. Think of functional keys, such as
|
||||
:kbd:`Escape, Play, Pause, F1, Home, etc`. These are encoded using Unicode code
|
||||
points from the Private Use Area (``57344 - 63743``). The mapping of key
|
||||
names to code points for these keys is in the
|
||||
:kbd:`Escape`, :kbd:`Play`, :kbd:`Pause`, :kbd:`F1`, :kbd:`Home`, etc. These
|
||||
are encoded using Unicode code points from the Private Use Area (``57344 -
|
||||
63743``). The mapping of key names to code points for these keys is in the
|
||||
:ref:`Functional key definition table below <functional>`.
|
||||
|
||||
|
||||
@@ -266,10 +278,14 @@ and alternate screens. If a pop request is received that empties the stack,
|
||||
all flags are reset. If a push request is received and the stack is full, the
|
||||
oldest entry from the stack must be evicted.
|
||||
|
||||
.. note:: In the interests of interoperation, the XTerm specific sequences
|
||||
`CSI > 4; 1 m` and `CSI > 4; 0 m` are treated as `CSI > 1 u` and `CSI < 1 u`.
|
||||
These codes cause XTerm to use the CSI u encoding for more keys and are therefore
|
||||
treated as similar to the disambiguate progressive enhancement.
|
||||
.. note:: The main and alternate screens in the terminal emulator must maintain
|
||||
their own, independent, keyboard mode stacks. This is so that a program that
|
||||
uses the alternate screen such as an editor, can change the keyboard mode
|
||||
in the alternate screen only, without affecting the mode in the main screen
|
||||
or even knowing what that mode is. Without this, and if no stack is
|
||||
implemented for keyboard modes (such as in some legacy terminal emulators)
|
||||
the editor would have to somehow know what the keyboard mode of the main
|
||||
screen is and restore to that mode on exit.
|
||||
|
||||
.. _disambiguate:
|
||||
|
||||
@@ -282,8 +298,8 @@ encodings overlapping with other control codes. For instance, pressing the
|
||||
start of an escape code. Similarly pressing the key :kbd:`alt+[` will generate
|
||||
the bytes used for CSI control codes.
|
||||
|
||||
Turning on this flag will cause the terminal to report the :kbd:`Esc, alt+key,
|
||||
ctrl+key, ctrl+alt+key, shift+alt+key` keys using ``CSI u`` sequences instead
|
||||
Turning on this flag will cause the terminal to report the :kbd:`Esc`, :kbd:`alt+key`,
|
||||
:kbd:`ctrl+key`, :kbd:`ctrl+alt+key`, :kbd:`shift+alt+key` keys using ``CSI u`` sequences instead
|
||||
of legacy ones. Here key is any ASCII key as described in :ref:`legacy_text`.
|
||||
Additionally, all keypad keys will be reported as separate keys with ``CSI u``
|
||||
encoding, using dedicated numbers from the :ref:`table below <functional>`.
|
||||
@@ -296,9 +312,9 @@ represented in one of the following two forms::
|
||||
|
||||
This makes it very easy to parse key events in an application. In particular,
|
||||
:kbd:`ctrl+c` will no longer generate the ``SIGINT`` signal, but instead be
|
||||
delivers as a ``CSI u`` escape code. This has the nice side effect of making it
|
||||
delivered as a ``CSI u`` escape code. This has the nice side effect of making it
|
||||
much easier to integrate into the application event loop. The only exceptions
|
||||
are the :kbd:`Enter, Tab and Backspace` keys which still generate the same
|
||||
are the :kbd:`Enter`, :kbd:`Tab` and :kbd:`Backspace` keys which still generate the same
|
||||
bytes as in legacy mode this is to allow the user to type and execute commands
|
||||
in the shell such as ``reset`` after a program that sets this mode crashes
|
||||
without clearing it.
|
||||
@@ -338,8 +354,8 @@ only key events are sent. If the text is needed as well, combine with the
|
||||
Report associated text enhancement below.
|
||||
|
||||
Additionally, with this mode, events for pressing modifier keys are reported.
|
||||
Note that *all* keys are reported as escape codes, including :kbd:`Enter, Tab,
|
||||
Backspace` etc.
|
||||
Note that *all* keys are reported as escape codes, including :kbd:`Enter`,
|
||||
:kbd:`Tab`, :kbd:`Backspace` etc.
|
||||
|
||||
.. _report_text:
|
||||
|
||||
@@ -451,10 +467,11 @@ distinguish these, use the :ref:`disambiguate <disambiguate>` flag.
|
||||
Legacy text keys
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
For legacy compatibility, the keys
|
||||
:kbd:`a-z 0-9 \` - = [ ] \ ; ' , . /` with the modifiers
|
||||
:kbd:`shift, alt, ctrl, shift+alt, ctrl+alt` are output using the
|
||||
following algorithm:
|
||||
For legacy compatibility, the keys :kbd:`a`-:kbd:`z` :kbd:`0`-:kbd:`9`
|
||||
:kbd:`\`` :kbd:`-` :kbd:`=` :kbd:`[` :kbd:`]` :kbd:`\\` :kbd:`;` :kbd:`'`
|
||||
:kbd:`,` :kbd:`.` :kbd:`/` with the modifiers :kbd:`shift`, :kbd:`alt`,
|
||||
:kbd:`ctrl`, :kbd:`shift+alt`, :kbd:`ctrl+alt` are output using the following
|
||||
algorithm:
|
||||
|
||||
#. If the :kbd:`alt` key is pressed output the byte for ``ESC (0x1b)``
|
||||
#. If the :kbd:`ctrl` modifier is pressed map the key using the table
|
||||
@@ -626,8 +643,8 @@ specification.
|
||||
* Incorrectly encoding shifted keys when shift modifier is used, for instance,
|
||||
for :kbd:`ctrl+shift+i` is encoded as :kbd:`ctrl+I`.
|
||||
|
||||
* No way to have non-conflicting escape codes for :kbd:`alt+letter,
|
||||
ctrl+letter, ctrl+alt+letter` key presses
|
||||
* No way to have non-conflicting escape codes for :kbd:`alt+letter`,
|
||||
:kbd:`ctrl+letter`, :kbd:`ctrl+alt+letter` key presses
|
||||
|
||||
* No way to specify both shifted and unshifted keys for robust shortcut
|
||||
matching (think matching :kbd:`ctrl+shift+equal` and :kbd:`ctrl+plus`)
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
broadcast - type text in all kitty windows
|
||||
broadcast
|
||||
==================================================
|
||||
|
||||
*Type text in all kitty windows simultaneously*
|
||||
|
||||
The ``broadcast`` kitten can be used to type text simultaneously in
|
||||
all kitty windows (or a subset as desired).
|
||||
|
||||
@@ -17,7 +19,4 @@ are selected.
|
||||
.. program:: kitty +kitten broadcast
|
||||
|
||||
|
||||
Command Line Interface
|
||||
--------------------------
|
||||
|
||||
.. include:: /generated/cli-kitten-broadcast.rst
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
clipboard - copy/paste to the system clipboard
|
||||
clipboard
|
||||
==================================================
|
||||
|
||||
*Copy/paste to the system clipboard from shell scripts*
|
||||
|
||||
.. highlight:: sh
|
||||
|
||||
|
||||
@@ -21,7 +23,4 @@ use::
|
||||
.. program:: kitty +kitten clipboard
|
||||
|
||||
|
||||
Command Line Interface
|
||||
--------------------------
|
||||
|
||||
.. include:: /generated/cli-kitten-clipboard.rst
|
||||
|
||||
@@ -88,11 +88,41 @@ function, telling kitty what kind of input your kitten would like. For example:
|
||||
|
||||
|
||||
This will send the plain text of the active window to the kitten's
|
||||
:file:`STDIN`. For text with formatting escape codes, use ``ansi``
|
||||
instead. If you want line wrap markers as well, use ``screen-ansi``
|
||||
or just ``screen``. For the scrollback buffer as well, use
|
||||
``history``, ``ansi-history`` or ``screen-history``. To get
|
||||
the currently selected text, use ``selection``.
|
||||
:file:`STDIN`. There are many other types of input you can ask for,
|
||||
described in the table below:
|
||||
|
||||
.. table:: Types of input to kittens
|
||||
:align: left
|
||||
|
||||
=========================== =======================================================================================================
|
||||
Keyword Type of :file:`STDIN` input
|
||||
=========================== =======================================================================================================
|
||||
``text`` Plain text of active window
|
||||
``ansi`` Formatted text of active window
|
||||
``screen`` Plain text of active window with line wrap markers
|
||||
``screen-ansi`` Formatted text of active window with line wrap markers
|
||||
|
||||
``history`` Plain text of active window and its scrollback
|
||||
``ansi-history`` Formatted text of active window and its scrollback
|
||||
``screen-history`` Plain text of active window and its scrollback with line wrap markers
|
||||
``screen-ansi-history`` Formatted text of active window and its scrollback with line wrap markers
|
||||
|
||||
``output`` Plain text of the output from the last run command
|
||||
``output-screen`` Plain text of the output from the last run command with wrap markers
|
||||
``output-ansi`` Formatted text of the output from the last run command
|
||||
``output-screen-ansi`` Formatted text of the output from the last run command with wrap markers
|
||||
|
||||
``selection`` The text currently selected with the mouse
|
||||
=========================== =======================================================================================================
|
||||
|
||||
In addition to ``output``, that gets the output of the last run command,
|
||||
``last_visited_output`` gives the output of the command last jumped to
|
||||
and ``first_output`` gives the output of the first command currently on screen.
|
||||
These can also be combined with ``screen`` and ``ansi`` for formatting.
|
||||
|
||||
.. note::
|
||||
For the types based on the output of a command,
|
||||
:ref:`shell_integration` is required.
|
||||
|
||||
|
||||
Using kittens to script kitty, without any terminal UI
|
||||
@@ -103,7 +133,8 @@ terminal program, you can tell the kittens system to run the
|
||||
``handle_result()`` function without first running the ``main()`` function.
|
||||
|
||||
For example, here is a kitten that "zooms/unzooms" the current terminal window
|
||||
by switching to the stack layout or back to the previous layout.
|
||||
by switching to the stack layout or back to the previous layout. This is
|
||||
equivalent to the builtin :ref:`action-toggle_layout` action.
|
||||
|
||||
Create a file in the kitty config folder, :file:`~/.config/kitty/zoom_toggle.py`
|
||||
|
||||
@@ -185,6 +216,104 @@ The output of print statements will go to the ``STDOUT`` of the kitty process.
|
||||
So if you run kitty from another kitty instance, the output will be visible
|
||||
in the first kitty instance.
|
||||
|
||||
Adding options to kittens
|
||||
----------------------------
|
||||
|
||||
If you would like to use kitty's config framework to make your kittens
|
||||
configurable, you will need some boilerplate. In the directory
|
||||
of your kitten make the following files.
|
||||
|
||||
:file:`kitten_options_definition.py`
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from kitty.conf.types import Action, Definition
|
||||
|
||||
definition = Definition(
|
||||
'!kitten_options_utils',
|
||||
Action(
|
||||
'map', 'parse_map',
|
||||
{'key_definitions': 'kitty.conf.utils.KittensKeyMap'},
|
||||
['kitty.types.ParsedShortcut', 'kitty.conf.utils.KeyAction']
|
||||
),
|
||||
)
|
||||
|
||||
agr = definition.add_group
|
||||
egr = definition.end_group
|
||||
opt = definition.add_option
|
||||
map = definition.add_map
|
||||
|
||||
# main options {{{
|
||||
agr('main', 'Main')
|
||||
|
||||
opt('some_option', '33',
|
||||
option_type='some_option_parser',
|
||||
long_text='''
|
||||
Help text for this option
|
||||
'''
|
||||
)
|
||||
egr() # }}}
|
||||
|
||||
# shortcuts {{{
|
||||
agr('shortcuts', 'Keyboard shortcuts')
|
||||
|
||||
map('Quit', 'quit q quit')
|
||||
egr() # }}}
|
||||
|
||||
|
||||
:file:`kitten_options_utils.py`
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from kitty.conf.utils import KittensKeyDefinition, key_func, parse_kittens_key
|
||||
|
||||
func_with_args, args_funcs = key_func()
|
||||
FuncArgsType = Tuple[str, Sequence[Any]]
|
||||
|
||||
def some_option_parser(val: str) -> int:
|
||||
return int(val) + 3000
|
||||
|
||||
def parse_map(val: str) -> Iterable[KittensKeyDefinition]:
|
||||
x = parse_kittens_key(val, args_funcs)
|
||||
if x is not None:
|
||||
yield x
|
||||
|
||||
Then run::
|
||||
|
||||
kitty +runpy 'from kitty.conf.generate import main; main()' /path/to/kitten_options_definition.py
|
||||
|
||||
You can parse and read the options in your kitten using the following code:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from .kitten_options_types import Options, defaults
|
||||
from kitty.conf.utils import load_config as _load_config, parse_config_base
|
||||
from typing import Optional, Iterable, Dict, Any
|
||||
|
||||
def load_config(*paths: str, overrides: Optional[Iterable[str]] = None) -> Options:
|
||||
from .kitten_options_parse import (
|
||||
create_result_dict, merge_result_dicts, parse_conf_item
|
||||
)
|
||||
|
||||
def parse_config(lines: Iterable[str]) -> Dict[str, Any]:
|
||||
ans: Dict[str, Any] = create_result_dict()
|
||||
parse_config_base(
|
||||
lines,
|
||||
parse_conf_item,
|
||||
ans,
|
||||
)
|
||||
return ans
|
||||
|
||||
overrides = tuple(overrides) if overrides is not None else ()
|
||||
opts_dict, paths = _load_config(defaults, parse_config, merge_result_dicts, *paths, overrides=overrides)
|
||||
opts = Options(opts_dict)
|
||||
opts.config_paths = paths
|
||||
opts.config_overrides = overrides
|
||||
return opts
|
||||
|
||||
See the code for the builtin diff kitten for examples of creating more options
|
||||
and keyboard shortcuts.
|
||||
|
||||
.. _external_kittens:
|
||||
|
||||
Kittens created by kitty users
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
kitty-diff - A fast side-by-side diff tool with syntax highlighting and images
|
||||
kitty-diff
|
||||
================================================================================
|
||||
|
||||
*A fast side-by-side diff tool with syntax highlighting and images*
|
||||
|
||||
.. highlight:: sh
|
||||
|
||||
Major Features
|
||||
@@ -21,12 +23,10 @@ Major Features
|
||||
.. figure:: ../screenshots/diff.png
|
||||
:alt: Screenshot, showing a sample diff
|
||||
:align: center
|
||||
:scale: 100%
|
||||
:width: 100%
|
||||
|
||||
Screenshot, showing a sample diff
|
||||
|
||||
.. contents::
|
||||
|
||||
|
||||
Installation
|
||||
---------------
|
||||
@@ -34,8 +34,8 @@ Installation
|
||||
Simply :ref:`install kitty <quickstart>`. You also need
|
||||
to have either the `git <https://git-scm.com/>`_ program or the ``diff`` program
|
||||
installed. Additionally, for syntax highlighting to work,
|
||||
`pygments <http://pygments.org/>`_ must be installed (note that pygments is
|
||||
included in the macOS kitty app).
|
||||
`pygments <https://pygments.org/>`_ must be installed (note that pygments is
|
||||
included in the official kitty binary builds).
|
||||
|
||||
|
||||
Usage
|
||||
@@ -67,14 +67,14 @@ Keyboard controls
|
||||
========================= ===========================
|
||||
Action Shortcut
|
||||
========================= ===========================
|
||||
Quit :kbd:`q, Ctrl+c, Esc`
|
||||
Scroll line up :kbd:`k, up`
|
||||
Scroll line down :kbd:`j, down`
|
||||
Quit :kbd:`q`, :kbd:`ctrl+c`, :kbd:`Esc`
|
||||
Scroll line up :kbd:`k`, :kbd:`Up`
|
||||
Scroll line down :kbd:`j`, :kbd:`Down`
|
||||
Scroll page up :kbd:`PgUp`
|
||||
Scroll page down :kbd:`PgDn`
|
||||
Scroll to top :kbd:`Home`
|
||||
Scroll to bottom :kbd:`End`
|
||||
Scroll to next page :kbd:`Space, PgDn`
|
||||
Scroll to next page :kbd:`Space`, :kbd:`PgDn`
|
||||
Scroll to previous page :kbd:`PgUp`
|
||||
Scroll to next change :kbd:`n`
|
||||
Scroll to previous change :kbd:`p`
|
||||
@@ -85,8 +85,8 @@ Restore default context :kbd:`=`
|
||||
Search forwards :kbd:`/`
|
||||
Search backwards :kbd:`?`
|
||||
Clear search :kbd:`Esc`
|
||||
Scroll to next match :kbd:`>, .`
|
||||
Scroll to previous match :kbd:`<, ,`
|
||||
Scroll to next match :kbd:`>`, :kbd:`.`
|
||||
Scroll to previous match :kbd:`<`, :kbd:`,`
|
||||
========================= ===========================
|
||||
|
||||
|
||||
@@ -120,8 +120,8 @@ Why does this work only in kitty?
|
||||
|
||||
The diff kitten makes use of various features that are :doc:`kitty only
|
||||
</protocol-extensions>`, such as the :doc:`kitty graphics protocol
|
||||
</graphics-protocol>`, the :ref:`extended keyboard protocol
|
||||
<extended-key-protocol>`, etc. It also leverages terminal program
|
||||
</graphics-protocol>`, the :doc:`extended keyboard protocol
|
||||
</keyboard-protocol>`, etc. It also leverages terminal program
|
||||
infrastructure I created for all of kitty's other kittens to reduce the amount
|
||||
of code needed (the entire implementation is under 2000 lines of code).
|
||||
|
||||
@@ -142,9 +142,6 @@ configuration directives.
|
||||
.. include:: /generated/conf-kitten-diff.rst
|
||||
|
||||
|
||||
Command Line Interface
|
||||
-------------------------
|
||||
|
||||
.. include:: /generated/cli-kitten-diff.rst
|
||||
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ browser.
|
||||
.. figure:: ../screenshots/hints_mode.png
|
||||
:alt: URL hints mode
|
||||
:align: center
|
||||
:scale: 100%
|
||||
:width: 100%
|
||||
|
||||
URL hints mode
|
||||
|
||||
@@ -36,7 +36,7 @@ taken for different types of URLs <../open_actions>`.
|
||||
The hints kitten is very powerful to see more detailed help on its various
|
||||
options and modes of operation, see below. You can use these options to
|
||||
create mappings in :file:`kitty.conf` to select various different text
|
||||
snippets. See :sc:`insert_selected_path` for examples.
|
||||
snippets. See :sc:`insert_selected_path <insert_selected_path>` for examples.
|
||||
|
||||
|
||||
Completely customizing the matching and actions of the kitten
|
||||
@@ -88,8 +88,13 @@ Now run kitty with::
|
||||
When you press the :kbd:`F1` key you will be able to select a word to
|
||||
look it up in the Google dictionary.
|
||||
|
||||
|
||||
Command Line Interface
|
||||
-------------------------
|
||||
|
||||
.. include:: ../generated/cli-kitten-hints.rst
|
||||
|
||||
.. note::
|
||||
|
||||
To avoid having to specify the same command line options on every invocation,
|
||||
you can use the :opt:`action_alias` option in :file:`kitty.conf`, creating aliases
|
||||
that have common sets of options. For example::
|
||||
|
||||
action_alias myhints kitten hints --alphabet qfjdkslaureitywovmcxzpq1234567890
|
||||
map f1 myhints --customize-processing custom-hints.py
|
||||
|
||||
@@ -3,7 +3,7 @@ Hyperlinked grep
|
||||
|
||||
|
||||
This kitten allows you to search your files using `ripgrep
|
||||
<https://www.google.com/search?q=ripgrep>`_ and open the results
|
||||
<https://github.com/BurntSushi/ripgrep>`_ and open the results
|
||||
directly in your favorite editor in the terminal, at the line containing
|
||||
the search result, simply by clicking on the result you want.
|
||||
|
||||
@@ -58,7 +58,7 @@ Then, for example, for ZSH, add the following to :file:`.zshrc`::
|
||||
compdef _rg hg
|
||||
|
||||
To learn more about kitty's powerful framework for customizing URL click
|
||||
actions, :doc:`see here <../open_actions>`.
|
||||
actions, :doc:`see here </open_actions>`.
|
||||
|
||||
Hopefully, someday this functionality will make it into some `upstream grep
|
||||
<https://github.com/BurntSushi/ripgrep/issues/665>`_
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
icat - Display images in the terminal
|
||||
icat
|
||||
========================================
|
||||
|
||||
*Display images in the terminal*
|
||||
|
||||
The ``icat`` kitten can be used to display arbitrary images in the |kitty|
|
||||
terminal. Using it is as simple as::
|
||||
|
||||
@@ -35,7 +37,4 @@ The ``icat`` kitten has various command line arguments to allow it to be used
|
||||
from inside other programs to display images. In particular, :option:`--place`,
|
||||
:option:`--detect-support` and :option:`--print-window-size`.
|
||||
|
||||
Command Line Interface
|
||||
--------------------------
|
||||
|
||||
.. include:: /generated/cli-kitten-icat.rst
|
||||
|
||||
@@ -14,7 +14,7 @@ using terminal programs instead of GUI toolkits.
|
||||
.. figure:: ../screenshots/panel.png
|
||||
:alt: Screenshot, showing a sample panel
|
||||
:align: center
|
||||
:scale: 100%
|
||||
:width: 100%
|
||||
|
||||
Screenshot, showing a sample panel
|
||||
|
||||
@@ -37,7 +37,4 @@ print out ``Hello, world!``. You can make the terminal program as complex as
|
||||
you like, as demonstrated in the screenshot above.
|
||||
|
||||
|
||||
Command Line Interface
|
||||
-------------------------
|
||||
|
||||
.. include:: ../generated/cli-kitten-panel.rst
|
||||
|
||||
@@ -15,7 +15,4 @@ for *XTGETTCAP* to see the syntax for the escape code and read the source
|
||||
of this kitten to find the values of the keys for the various queries.
|
||||
|
||||
|
||||
Command Line Interface
|
||||
-------------------------
|
||||
|
||||
.. include:: ../generated/cli-kitten-query_terminal.rst
|
||||
|
||||
@@ -11,22 +11,26 @@ Then hold down :kbd:`ctrl+shift` and click the name of the file.
|
||||
.. figure:: ../screenshots/remote_file.png
|
||||
:alt: Remote file actions
|
||||
:align: center
|
||||
:scale: 100%
|
||||
:width: 100%
|
||||
|
||||
Remote file actions
|
||||
|
||||
|kitty| will ask you what you want to do with the remote file. You can choose
|
||||
to *Edit* it in which case kitty will download it and open it locally in your
|
||||
``EDITOR``. As you make changes to the file, they are automatically transferred
|
||||
to the remote computer. Note that this happens without needing to install *any*
|
||||
special software on the server, beyond ``ls`` that supports hyperlinks.
|
||||
:envvar:`EDITOR`. As you make changes to the file, they are automatically
|
||||
transferred to the remote computer. Note that this happens without needing
|
||||
to install *any* special software on the server, beyond ``ls`` that supports
|
||||
hyperlinks.
|
||||
|
||||
.. seealso:: See the :doc:`transfer` kitten
|
||||
|
||||
.. versionadded:: 0.19.0
|
||||
|
||||
.. note::
|
||||
Nested SSH sessions are not supported. The kitten will always try to copy
|
||||
remote files from the first SSH host. This is because there is no way for
|
||||
|kitty| to detect and follow a nested SSH session robustly.
|
||||
|kitty| to detect and follow a nested SSH session robustly. Use the
|
||||
:doc:`transfer` kitten for such situations.
|
||||
|
||||
.. note::
|
||||
If you have not setup automatic password-less SSH access, then, when
|
||||
|
||||
78
docs/kittens/themes.rst
Normal file
@@ -0,0 +1,78 @@
|
||||
Changing kitty colors
|
||||
========================
|
||||
|
||||
The themes kitten allows you to easily change color themes, from a collection
|
||||
of almost two hundred pre-built themes available at `kitty-themes
|
||||
<https://github.com/kovidgoyal/kitty-themes>`_. To use it, simply run::
|
||||
|
||||
kitty +kitten themes
|
||||
|
||||
|
||||
.. image:: ../screenshots/themes.png
|
||||
:alt: The themes kitten in action
|
||||
:width: 600
|
||||
|
||||
The kitten allows you to pick a theme, with live previews of the colors. You
|
||||
can choose between light and dark themes and search by theme name by just
|
||||
typing a few characters from the name.
|
||||
|
||||
The kitten maintains a list of recently used themes to allow quick switching.
|
||||
|
||||
If you want to restore the colors to default, you can do so by choosing the
|
||||
``Default`` theme.
|
||||
|
||||
.. versionadded:: 0.23.0
|
||||
The themes kitten
|
||||
|
||||
How it works
|
||||
----------------
|
||||
|
||||
A theme in kitty is just a :file:`.conf` file containing kitty settings.
|
||||
When you select a theme, the kitten simply copies the :file:`.conf` file
|
||||
to :file:`~/.config/kitty/current-theme.conf` and adds an include for
|
||||
:file:`current-theme.conf` to :file:`kitty.conf`. It also comments out
|
||||
any existing color settings in :file:`kitty.conf` so they do not interfere.
|
||||
|
||||
Once that's done, the kitten sends kitty a signal to make it reload its config.
|
||||
|
||||
Using your own themes
|
||||
-----------------------
|
||||
|
||||
You can also create your own themes as :file:`.conf` files. Put them in the
|
||||
:file:`themes` sub-directory of the kitty config directory, usually,
|
||||
:file:`~/.config/kitty/themes` and the kitten will automatically add them to
|
||||
the list of themes. You can use this to modify the builtin themes, by giving
|
||||
the conf file the name :file:`Some theme name.conf` to override the builtin
|
||||
theme of that name. Note that after doing so you have to run the kitten and
|
||||
choose that theme once for your changes to be applied.
|
||||
|
||||
|
||||
Contributing new themes
|
||||
-------------------------
|
||||
|
||||
If you wish to contribute a new theme to the kitty theme repository, start by
|
||||
going to the `kitty-themes <https://github.com/kovidgoyal/kitty-themes>`__
|
||||
repository. `Fork it
|
||||
<https://docs.github.com/en/get-started/quickstart/fork-a-repo>`_, and use the
|
||||
file :download:`template.conf
|
||||
<https://github.com/kovidgoyal/kitty-themes/raw/master/template.conf>` as a
|
||||
template when creating your theme. Once you are satisfied with how it looks,
|
||||
`submit a pull request
|
||||
<https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request>`_
|
||||
to have your theme merged into the `kitty-themes
|
||||
<https://github.com/kovidgoyal/kitty-themes>`__ repository, which will make it
|
||||
available in this kitten automatically.
|
||||
|
||||
|
||||
Changing the theme non-interactively
|
||||
---------------------------------------
|
||||
|
||||
You can specify the theme name as an argument when invoking the kitten
|
||||
to have it change to that theme instantly. For example::
|
||||
|
||||
kitty +kitten themes --reload-in=all Dimmed Monokai
|
||||
|
||||
Will change the theme to ``Dimmed Monokai`` in all running kitty
|
||||
instances. See below for more details on non-interactive operation.
|
||||
|
||||
.. include:: ../generated/cli-kitten-themes.rst
|
||||
97
docs/kittens/transfer.rst
Normal file
@@ -0,0 +1,97 @@
|
||||
Transfer files
|
||||
================
|
||||
|
||||
.. _rsync: https://en.wikipedia.org/wiki/Rsync
|
||||
|
||||
.. warning::
|
||||
This kitten is currently experimental, use with care.
|
||||
|
||||
Transfer files to and from remote computers over the ``TTY`` device itself.
|
||||
This means that file transfer works over nested SSH sessions, serial links,
|
||||
etc. Anywhere you have a terminal device, you can transfer files.
|
||||
|
||||
.. image:: ../screenshots/transfer.png
|
||||
:alt: The transfer kitten at work
|
||||
|
||||
This kitten supports transferring entire directory trees, preserving soft and
|
||||
hard links, file permissions, times, etc. It even supports the rsync_
|
||||
protocol to transfer only changes to large files.
|
||||
|
||||
.. seealso:: See the :doc:`remote_file` kitten
|
||||
|
||||
.. note::
|
||||
This kitten (which practically means kitty) must be installed on the other
|
||||
machine as well. If that is not possible you can use the :doc:`remote_file`
|
||||
kitten instead. Or write your own script to use the underlying :doc:`file transfer
|
||||
protocol </file-transfer-protocol>`.
|
||||
|
||||
.. versionadded:: 0.24.0
|
||||
|
||||
|
||||
Basic usage
|
||||
---------------
|
||||
|
||||
In what follows, the *local computer* is the computer running this kitten and
|
||||
the *remote computer* is the computer connected to the other end of the TTY pipe.
|
||||
|
||||
To send a file from the local computer to the remote computer, simply run::
|
||||
|
||||
kitty +kitten transfer /path/to/local/file /path/to/destination/on/remote/computer
|
||||
|
||||
You will be prompted by kitty for confirmation on allowing the transfer, and if
|
||||
you grant permission, the file will be copied.
|
||||
|
||||
Similarly, to get a file from the remote computer to the local computer, use
|
||||
the :option:`kitty +kitten transfer --direction` option::
|
||||
|
||||
kitty +kitten transfer --direction=receive /path/to/remote/file /path/to/destination/on/local/computer
|
||||
|
||||
Multiple files and even directories can be transferred::
|
||||
|
||||
kitty +kitten transfer file1 dir1 destination/
|
||||
|
||||
Here :file:`file1` will be copied inside :file:`destination` and :file:`dir1`
|
||||
will be recursively copied into :file:`destination`. Note the trailing slash on
|
||||
:file:`destination`. This tells kitty the destination is a directory. While not
|
||||
strictly necessary (kitty will infer the need for a destination directory from
|
||||
the fact that you are copying multiple things) it is good practice to always
|
||||
use a trailing slash when the destination is supposed to be a directory.
|
||||
|
||||
Also, when transferring multiple files/directories it is a good idea to
|
||||
use the :option:`kitty +kitten transfer --confirm-paths` option which will give
|
||||
you an opportunity to review and confirm the files that will be touched.
|
||||
|
||||
|
||||
Avoiding the confirmation prompt
|
||||
------------------------------------
|
||||
|
||||
Normally, when you start a file transfer kitty will prompt you for
|
||||
confirmation. This is to ensure that hostile programs running on a remote
|
||||
machine cannot read/write files on your computer without your permission.
|
||||
If the remote machine is trusted and the connection between your computer
|
||||
and the remote machine is secure, then you can disable the confirmation prompt
|
||||
by:
|
||||
|
||||
#. Setting the :opt:`file_transfer_confirmation_bypass` option to some
|
||||
password.
|
||||
|
||||
#. When invoking the kitten use the :option:`kitty +kitten transfer --permissions-bypass`
|
||||
to supply the password you set in step one.
|
||||
|
||||
.. warning:: Using a password to bypass confirmation means any software running
|
||||
on the remote machine could potentially learn that password and use it to
|
||||
gain full access to your computer. Also anyone that can intercept the data
|
||||
stream between your computer and the remote machine can also learn this
|
||||
password. So use it only with secure connections to trusted computers.
|
||||
|
||||
|
||||
Delta transfers
|
||||
-----------------------------------
|
||||
|
||||
This kitten has the ability to use the rsync_ protocol to only transfer the
|
||||
differences between files. To turn it on use the :option:`kitty +kitten
|
||||
transfer --transmit-deltas` option. Note that this will actually be slower when
|
||||
transferring small files because of round trip overhead, so use with care.
|
||||
|
||||
|
||||
.. include:: ../generated/cli-kitten-transfer.rst
|
||||
@@ -7,7 +7,7 @@ Press :sc:`input_unicode_character` to start the unicode input widget, shown bel
|
||||
.. figure:: ../screenshots/unicode.png
|
||||
:alt: A screenshot of the unicode input widget
|
||||
:align: center
|
||||
:scale: 100%
|
||||
:width: 100%
|
||||
|
||||
A screenshot of the unicode input widget
|
||||
|
||||
@@ -23,11 +23,9 @@ the arrow keys/tab to select the character from the displayed matches. You can
|
||||
also type a space followed by a period and the index for the match if you don't
|
||||
like to use arrow keys.
|
||||
|
||||
You can switch between modes using either the function keys or by pressing
|
||||
:kbd:`Ctrl+[` and :kbd:`Ctrl+]`.
|
||||
You can switch between modes using either the keys :kbd:`F1` ... :kbd:`F4` or
|
||||
:kbd:`Ctrl+1` ... :kbd:`Ctrl+4` or by pressing :kbd:`Ctrl+[` and :kbd:`Ctrl+]`
|
||||
or by pressing :kbd:`Ctrl+Tab` and :kbd:`Ctrl+Shift+Tab`.
|
||||
|
||||
|
||||
Command Line Interface
|
||||
-------------------------
|
||||
|
||||
.. include:: ../generated/cli-kitten-unicode_input.rst
|
||||
73
docs/kittens_intro.rst
Normal file
@@ -0,0 +1,73 @@
|
||||
.. _kittens:
|
||||
|
||||
Extend with kittens
|
||||
-----------------------
|
||||
|
||||
.. toctree::
|
||||
:hidden:
|
||||
:glob:
|
||||
|
||||
kittens/icat
|
||||
kittens/diff
|
||||
kittens/unicode_input
|
||||
kittens/themes
|
||||
kittens/hints
|
||||
kittens/remote_file
|
||||
kittens/hyperlinked_grep
|
||||
kittens/transfer
|
||||
kittens/custom
|
||||
kittens/*
|
||||
|
||||
|kitty| has a framework for easily creating terminal programs that make use of
|
||||
its advanced features. These programs are called kittens. They are used both
|
||||
to add features to |kitty| itself and to create useful standalone programs.
|
||||
Some prominent kittens:
|
||||
|
||||
:doc:`icat <kittens/icat>`
|
||||
Display images in the terminal
|
||||
|
||||
|
||||
:doc:`diff <kittens/diff>`
|
||||
A fast, side-by-side diff for the terminal with syntax highlighting and
|
||||
images
|
||||
|
||||
|
||||
:doc:`Unicode Input <kittens/unicode_input>`
|
||||
Easily input arbitrary unicode characters in |kitty| by name or hex code.
|
||||
|
||||
|
||||
:doc:`Hints <kittens/hints>`
|
||||
Select and open/paste/insert arbitrary text snippets such as URLs,
|
||||
filenames, words, lines, etc. from the terminal screen.
|
||||
|
||||
|
||||
:doc:`Remote file <kittens/remote_file>`
|
||||
Edit, open, or download remote files over SSH easily, by simply clicking on
|
||||
the filename.
|
||||
|
||||
|
||||
:doc:`Transfer files <kittens/transfer>`
|
||||
Transfer files and directories seamlessly and easily from remote machines over your existing
|
||||
SSH sessions with a simple command.
|
||||
|
||||
|
||||
:doc:`Hyperlinked grep <kittens/hyperlinked_grep>`
|
||||
Search your files using `ripgrep <https://github.com/BurntSushi/ripgrep>`_
|
||||
and open the results directly in your favorite editor in the terminal,
|
||||
at the line containing the search result, simply by clicking on the result you want.
|
||||
|
||||
|
||||
:doc:`Broadcast <kittens/broadcast>`
|
||||
Type in one :term:`kitty window <window>` and have it broadcast to all (or a subset) of
|
||||
other :term:`kitty windows <window>`.
|
||||
|
||||
|
||||
:doc:`Panel <kittens/panel>`
|
||||
Draw a GPU accelerated dock panel on your desktop showing the output
|
||||
from an arbitrary terminal program.
|
||||
|
||||
|
||||
:doc:`Clipboard <kittens/clipboard>`
|
||||
Copy/paste to the clipboard from shell scripts, even over SSH.
|
||||
|
||||
You can also :doc:`Learn to create your own kittens <kittens/custom>`.
|
||||
@@ -1,5 +1,5 @@
|
||||
Launching programs in new windows/tabs
|
||||
========================================
|
||||
The :command:`launch` command
|
||||
--------------------------------
|
||||
|
||||
.. program:: launch
|
||||
|
||||
@@ -19,7 +19,6 @@ launch::
|
||||
|
||||
map f1 launch vim path/to/some/file
|
||||
|
||||
|
||||
To open a new window with the same working directory as the currently
|
||||
active window::
|
||||
|
||||
@@ -29,17 +28,33 @@ To open the new window in a new tab::
|
||||
|
||||
map f1 launch --type=tab
|
||||
|
||||
To run multiple commands in a shell, use::
|
||||
|
||||
map f1 launch sh -c "ls && zsh"
|
||||
|
||||
To pass the contents of the current screen and scrollback to the started process::
|
||||
|
||||
map f1 launch --stdin-source=@screen_scrollback less
|
||||
|
||||
There are many more powerful options, refer to the complete list below.
|
||||
|
||||
.. note::
|
||||
To avoid duplicating launch actions with frequently used parameters, you can
|
||||
use :opt:`action_alias` to define launch action aliases. For example::
|
||||
|
||||
action_alias launch_tab launch --cwd=current --type=tab
|
||||
map f1 launch_tab vim
|
||||
map f2 launch_tab emacs
|
||||
|
||||
The :kbd:`F1` key will now open vim in a new tab with the current windows
|
||||
working directory
|
||||
|
||||
|
||||
The piping environment
|
||||
--------------------------
|
||||
|
||||
When using :option:`launch --stdin-source`, the program to which the data is
|
||||
piped has a special environment variable declared, ``KITTY_PIPE_DATA`` whose
|
||||
piped has a special environment variable declared, :envvar:`KITTY_PIPE_DATA` whose
|
||||
contents are::
|
||||
|
||||
KITTY_PIPE_DATA={scrolled_by}:{cursor_x},{cursor_y}:{lines},{columns}
|
||||
@@ -54,13 +69,40 @@ Special arguments
|
||||
-------------------
|
||||
|
||||
There are a few special placeholder arguments that can be specified as part of
|
||||
the command line. Namely ``@selection`` which is replaced by the current
|
||||
selection and ``@active-kitty-window-id`` which is replaced by the id of the
|
||||
currently active kitty window. For example::
|
||||
the command line:
|
||||
|
||||
|
||||
``@selection``
|
||||
replaced by the currently selected text
|
||||
|
||||
``@active-kitty-window-id``
|
||||
replaced by the id of the currently active kitty window
|
||||
|
||||
``@line-count``
|
||||
replaced by the number of lines in STDIN. Only present when passing some
|
||||
data to STDIN
|
||||
|
||||
``@input-line-number``
|
||||
replaced the number of lines a pager should scroll to match the current
|
||||
scroll position in kitty. See :opt:`scrollback_pager` for details
|
||||
|
||||
``@scrolled-by``
|
||||
replaced by the number of lines kitty is currently scrolled by
|
||||
|
||||
``@cursor-x``
|
||||
replaced by the current cursor x position with 1 being the leftmost cell
|
||||
|
||||
``@cursor-y``
|
||||
replaced by the current cursor y position with 1 being the topmost cell
|
||||
|
||||
|
||||
For example::
|
||||
|
||||
map f1 launch my-program @active-kitty-window-id
|
||||
|
||||
|
||||
.. _watchers:
|
||||
|
||||
Watching launched windows
|
||||
---------------------------
|
||||
|
||||
@@ -75,7 +117,7 @@ functions for the events you are interested in, for example:
|
||||
# Here data will contain old_geometry and new_geometry
|
||||
|
||||
def on_focus_change(boss, window, data):
|
||||
# Here data kill contain focused
|
||||
# Here data will contain focused
|
||||
|
||||
def on_close(boss, window, data):
|
||||
# called when window is closed, typically when the program running in
|
||||
@@ -84,7 +126,7 @@ functions for the events you are interested in, for example:
|
||||
|
||||
Every callback is passed a reference to the global ``Boss`` object as well as
|
||||
the ``Window`` object the action is occurring on. The ``data`` object is
|
||||
mapping that contains event dependent data. Some useful methods and attributes
|
||||
a dict that contains event dependent data. Some useful methods and attributes
|
||||
for the ``Window`` object are: ``as_text(as_ans=False, add_history=False,
|
||||
add_wrap_markers=False, alternate_screen=False)`` with which you can get the
|
||||
contents of the window and its scrollback buffer. Similarly,
|
||||
@@ -102,6 +144,7 @@ this **may not** be the value of ``PATH`` inside a shell, as shell startup scrip
|
||||
often change the value of this variable. If it is not found there, then a
|
||||
system specific list of default paths is searched. If it is still not found,
|
||||
then your shell is run and the value of ``PATH`` inside the shell is used.
|
||||
See :opt:`exe_search_path` for details and how to control this.
|
||||
|
||||
Syntax reference
|
||||
------------------
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
Layouts
|
||||
============
|
||||
Arrange windows
|
||||
-------------------
|
||||
|
||||
kitty has the ability to define its own windows that can be tiled next to each
|
||||
other in arbitrary arrangements, based on *Layouts*, see below for examples:
|
||||
@@ -8,7 +8,7 @@ other in arbitrary arrangements, based on *Layouts*, see below for examples:
|
||||
.. figure:: screenshots/screenshot.png
|
||||
:alt: Screenshot, showing three programs in the 'Tall' layout
|
||||
:align: center
|
||||
:scale: 100%
|
||||
:width: 100%
|
||||
|
||||
Screenshot, showing vim, tig and git running in |kitty| with the 'Tall' layout
|
||||
|
||||
@@ -16,7 +16,7 @@ other in arbitrary arrangements, based on *Layouts*, see below for examples:
|
||||
.. figure:: screenshots/splits.png
|
||||
:alt: Screenshot, showing windows in the 'Splits' layout
|
||||
:align: center
|
||||
:scale: 100%
|
||||
:width: 100%
|
||||
|
||||
Screenshot, showing windows with arbitrary arrangement in the 'Splits'
|
||||
layout
|
||||
@@ -27,8 +27,6 @@ you can switch layouts using :sc:`next_layout`. To control which layouts
|
||||
are available use :opt:`enabled_layouts`, the first listed layout becomes
|
||||
the default. Individual layouts and how to use them are described below.
|
||||
|
||||
.. contents::
|
||||
|
||||
|
||||
The Stack Layout
|
||||
------------------
|
||||
@@ -147,11 +145,14 @@ define a few extra keybindings in :file:`kitty.conf`::
|
||||
map ctrl+down neighboring_window down
|
||||
|
||||
Now you can create horizontal and vertical splits by using :kbd:`F5` and
|
||||
:kbd:`F6`. You can move them around using :kbd:`shift+arrow keys`
|
||||
and you can move focus to neighboring windows using :kbd:`ctrl+arrow keys`.
|
||||
:kbd:`F6`. You can move them around using :kbd:`shift+arrow` keys
|
||||
and you can move focus to neighboring windows using :kbd:`ctrl+arrow` keys.
|
||||
You can switch an existing split from horizontal to vertical and vice versa
|
||||
using :kbd:`F7`. Finally, windows can be resized using :ref:`window_resizing`.
|
||||
|
||||
Note that you can swap the windows in a split using the ``rotate`` action with
|
||||
an argument of ``180`` and rotate and swap with an argument of ``270``.
|
||||
|
||||
This layout takes one option, ``split_axis`` that controls whether new windows
|
||||
are placed into vertical or horizontal splits, by default::
|
||||
|
||||
|
||||
@@ -1,11 +1,14 @@
|
||||
Marks
|
||||
=================
|
||||
Mark text on screen
|
||||
---------------------
|
||||
|
||||
|
||||
kitty has the ability to mark text on the screen based on regular expressions.
|
||||
This can be useful to highlight words or phrases when browsing output from long
|
||||
running programs or similar. Lets start with a few examples:
|
||||
|
||||
Examples
|
||||
----------
|
||||
|
||||
Suppose we want to be able to highlight the word ERROR in the current window.
|
||||
Add the following to :file:`kitty.conf`::
|
||||
|
||||
@@ -19,12 +22,12 @@ If you want to make it case-insensitive, use::
|
||||
|
||||
To make it match only complete words, use::
|
||||
|
||||
map f1 toggle_marker regex 1 \bERROR\b
|
||||
map f1 toggle_marker regex 1 \\bERROR\\b
|
||||
|
||||
Suppose you want to highlight both :code:`ERROR` and :code:`WARNING`, case
|
||||
insensitively::
|
||||
|
||||
map f1 toggle_marker iregex 1 \bERROR\b 2 \bWARNING\b
|
||||
map f1 toggle_marker iregex 1 \\bERROR\\b 2 \\bWARNING\\b
|
||||
|
||||
kitty supports up to 3 mark groups (the numbers in the commands above). You
|
||||
can control the colors used for these groups in :file:`kitty.conf` with::
|
||||
@@ -89,12 +92,11 @@ The syntax of the :code:`toggle_marker` command is::
|
||||
|
||||
Here :code:`marker-type` is one of:
|
||||
|
||||
* :code:`text` - simple substring matching
|
||||
* :code:`itext` - case-insensitive substring matching
|
||||
* :code:`regex` - A python regular expression
|
||||
* :code:`iregex` - A case-insensitive python regular expression
|
||||
* :code:`function` - An arbitrary function defined in a python file, see
|
||||
:ref:`marker_funcs`.
|
||||
* :code:`text` - simple substring matching
|
||||
* :code:`itext` - case-insensitive substring matching
|
||||
* :code:`regex` - A python regular expression
|
||||
* :code:`iregex` - A case-insensitive python regular expression
|
||||
* :code:`function` - An arbitrary function defined in a python file, see :ref:`marker_funcs`.
|
||||
|
||||
.. _marker_funcs:
|
||||
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
Customizing the actions taken when clicking on links
|
||||
Scripting the mouse click
|
||||
======================================================
|
||||
|
||||
|kitty| has support for `terminal hyperlinks <https://gist.github.com/egmontkob/eb114294efbcd5adb1944c9f3cb5feda>`_. These
|
||||
|kitty| has support for `terminal hyperlinks
|
||||
<https://gist.github.com/egmontkob/eb114294efbcd5adb1944c9f3cb5feda>`_. These
|
||||
are generated by many terminal programs, such as ``ls``, ``gcc``, ``systemd``,
|
||||
``mdcat``, etc. You can customize exactly what happens when clicking on these hyperlinks
|
||||
in |kitty|.
|
||||
:ref:`tool_mdcat`, etc. You can customize exactly what happens when clicking on these
|
||||
hyperlinks in |kitty|.
|
||||
|
||||
You can tell kitty to take arbitrarily many, complex actions
|
||||
when a link is clicked. Let us illustrate with some examples, first. Create
|
||||
@@ -57,13 +58,19 @@ some special variables, documented below:
|
||||
``FRAGMENT``
|
||||
The fragment (unquoted), if any of the URL or the empty string.
|
||||
|
||||
|
||||
.. note::
|
||||
You can use the :opt:`action_alias` option just as in kitty.conf to
|
||||
define aliases for frequently used actions.
|
||||
|
||||
|
||||
.. _matching_criteria:
|
||||
|
||||
Matching criteria
|
||||
------------------
|
||||
|
||||
An entry in :file:`open-actions.conf` must have one or more matching criteria.
|
||||
URLs that match all criteria for an entry will trigger that entries' actions.
|
||||
URLs that match all criteria for an entry will trigger that entry's actions.
|
||||
Processing stops at the first matching entry, so put more specific matching
|
||||
criteria at the start of the list. Entries in the file are separated by blank
|
||||
lines. The various available criteria are:
|
||||
@@ -85,7 +92,7 @@ lines. The various available criteria are:
|
||||
:file:`mime.types` in the kitty configuration directory. Useful if your
|
||||
system MIME database does not have definitions you need. This file is
|
||||
in the standard format of one definition per line, like: ``text/plain rst
|
||||
md``.
|
||||
md``. Note that the MIME type for directories is ``inode/directory``.
|
||||
|
||||
``ext``
|
||||
A comma separated list of file extensions, for example: ``jpeg, tar.gz``
|
||||
|
||||
301
docs/overview.rst
Normal file
@@ -0,0 +1,301 @@
|
||||
Overview
|
||||
==============
|
||||
|
||||
Design philosophy
|
||||
-------------------
|
||||
|
||||
|kitty| is designed for power keyboard users. To that end all its controls
|
||||
work with the keyboard (although it fully supports mouse interactions as
|
||||
well). Its configuration is a simple, human editable, single file for
|
||||
easy reproducibility (I like to store configuration in source control).
|
||||
|
||||
The code in |kitty| is designed to be simple, modular and hackable. It is
|
||||
written in a mix of C (for performance sensitive parts) and Python (for
|
||||
easy hackability of the UI). It does not depend on any large and complex
|
||||
UI toolkit, using only OpenGL for rendering everything.
|
||||
|
||||
Finally, |kitty| is designed from the ground up to support all modern
|
||||
terminal features, such as unicode, true color, bold/italic fonts, text
|
||||
formatting, etc. It even extends existing text formatting escape codes,
|
||||
to add support for features not available elsewhere, such as colored and
|
||||
styled (curly) underlines. One of the design goals of |kitty| is to be
|
||||
easily extensible so that new features can be added in the future with
|
||||
relatively little effort.
|
||||
|
||||
.. include:: basic.rst
|
||||
|
||||
|
||||
Configuring kitty
|
||||
-------------------
|
||||
|
||||
|kitty| is highly configurable, everything from keyboard shortcuts to
|
||||
painting frames-per-second. Press :sc:`edit_config_file` in kitty
|
||||
to open its fully commented sample config file in your text editor.
|
||||
For details see the :doc:`configuration docs <conf>`.
|
||||
|
||||
.. toctree::
|
||||
:hidden:
|
||||
|
||||
conf
|
||||
|
||||
|
||||
.. _layouts:
|
||||
|
||||
Layouts
|
||||
----------
|
||||
|
||||
A :term:`layout` is an arrangement of multiple :term:`kitty windows <window>`
|
||||
inside a top-level :term:`OS window <os_window>`. The layout manages all its
|
||||
windows automatically, resizing and moving them as needed. You can create a new
|
||||
:term:`window` using the :sc:`new_window` key combination.
|
||||
|
||||
Currently, there are seven layouts available:
|
||||
|
||||
* **Fat** -- One (or optionally more) windows are shown full width on the top, the rest of the windows are shown side-by-side on the bottom
|
||||
* **Grid** -- All windows are shown in a grid
|
||||
* **Horizontal** -- All windows are shown side-by-side
|
||||
* **Splits** -- Windows arranged in arbitrary patterns created using horizontal and vertical splits
|
||||
* **Stack** -- Only a single maximized window is shown at a time
|
||||
* **Tall** -- One (or optionally more) windows are shown full height on the left, the rest of the windows are shown one below the other on the right
|
||||
* **Vertical** -- All windows are shown one below the other
|
||||
|
||||
By default, all layouts are enabled and you can switch between layouts using
|
||||
the :sc:`next_layout` key combination. You can also create shortcuts to select
|
||||
particular layouts, and choose which layouts you want to enable/disable, see
|
||||
:ref:`conf-kitty-shortcuts.layout` for examples. The first layout listed in
|
||||
:opt:`enabled_layouts` becomes the default layout.
|
||||
|
||||
For more details on the layouts and how to use them see :doc:`the documentation
|
||||
<layouts>`.
|
||||
|
||||
.. toctree::
|
||||
:hidden:
|
||||
|
||||
layouts
|
||||
|
||||
Extending kitty
|
||||
------------------
|
||||
|
||||
kitty has a powerful framework for scripting. You can create small terminal
|
||||
programs called :doc:`kittens <kittens_intro>`. These can used to add features
|
||||
to kitty, for example, :doc:`editing remote files <kittens/remote_file>` or
|
||||
:doc:`inputting unicode characters <kittens/unicode_input>`. They can also be
|
||||
used to create programs that leverage kitty's powerful features, for example,
|
||||
:doc:`viewing images <kittens/icat>` or :doc:`diffing files with images
|
||||
<kittens/diff>`.
|
||||
|
||||
You can :doc:`create your own kittens to scratch your own itches
|
||||
<kittens/custom>`.
|
||||
|
||||
For a list of all the builtin kittens, :ref:`see here <kittens>`.
|
||||
|
||||
.. toctree::
|
||||
:hidden:
|
||||
|
||||
kittens_intro
|
||||
|
||||
|
||||
Remote control
|
||||
------------------
|
||||
|
||||
|kitty| has a very powerful system that allows you to control it from the
|
||||
:doc:`shell prompt, even over SSH <remote-control>`. You can change colors,
|
||||
fonts, open new :term:`windows <window>`, :term:`tabs <tab>`, set their titles,
|
||||
change window layout, get text
|
||||
from one window and send text to another, etc, etc. The possibilities are
|
||||
endless. See the :doc:`tutorial <remote-control>` to get started.
|
||||
|
||||
.. toctree::
|
||||
:hidden:
|
||||
|
||||
remote-control
|
||||
|
||||
|
||||
.. _sessions:
|
||||
|
||||
Startup Sessions
|
||||
------------------
|
||||
|
||||
You can control the :term:`tabs <tab>`, :term:`kitty window <window>` layout,
|
||||
working directory, startup programs,
|
||||
etc. by creating a "session" file and using the :option:`kitty --session`
|
||||
command line flag or the :opt:`startup_session` option in :file:`kitty.conf`.
|
||||
For example:
|
||||
|
||||
.. code-block:: session
|
||||
|
||||
# Set the layout for the current tab
|
||||
layout tall
|
||||
# Set the working directory for windows in the current tab
|
||||
cd ~
|
||||
# Create a window and run the specified command in it
|
||||
launch zsh
|
||||
# Create a window with some environment variables set and run
|
||||
# vim in it
|
||||
launch --env FOO=BAR vim
|
||||
# Set the title for the next window
|
||||
launch --title "Chat with x" irssi --profile x
|
||||
|
||||
# Create a new tab (the part after new_tab is the optional tab
|
||||
# name which will be displayed in the tab bar, if omitted, the
|
||||
# title of the active window will be used instead)
|
||||
new_tab my tab
|
||||
cd ~/somewhere
|
||||
# Set the layouts allowed in this tab
|
||||
enabled_layouts tall, stack
|
||||
# Set the current layout
|
||||
layout stack
|
||||
launch zsh
|
||||
|
||||
# Create a new OS window
|
||||
new_os_window
|
||||
# set new window size to 80x25 cells
|
||||
os_window_size 80c 25c
|
||||
# set the --class for the new OS window
|
||||
os_window_class mywindow
|
||||
launch sh
|
||||
# Make the current window the active (focused) window
|
||||
focus
|
||||
launch emacs
|
||||
|
||||
.. note::
|
||||
The :doc:`launch <launch>` command when used in a session file
|
||||
cannot create new OS windows, or tabs.
|
||||
|
||||
|
||||
Creating tabs/windows
|
||||
-------------------------------
|
||||
|
||||
kitty can be told to run arbitrary programs in new :term:`tabs <tab>`,
|
||||
:term:`windows <window>` or :term:`overlays <overlay>` at a keypress.
|
||||
To learn how to do this, see :doc:`here <launch>`.
|
||||
|
||||
.. toctree::
|
||||
:hidden:
|
||||
|
||||
launch
|
||||
|
||||
|
||||
Mouse features
|
||||
-------------------
|
||||
|
||||
* You can click on a URL to open it in a browser.
|
||||
* You can double click to select a word and then drag to select more words.
|
||||
* You can triple click to select a line and then drag to select more lines.
|
||||
* You can triple click while holding :kbd:`ctrl+alt` to select from clicked
|
||||
point to end of line.
|
||||
* You can right click to extend a previous selection.
|
||||
* You can hold down :kbd:`ctrl+alt` and drag with the mouse to select in
|
||||
columns.
|
||||
* Selecting text automatically copies it to the primary clipboard (on
|
||||
platforms with a primary clipboard).
|
||||
* You can middle click to paste from the primary clipboard (on platforms
|
||||
with a primary clipboard).
|
||||
* You can right click while holding :kbd:`ctrl+shift` to open the output
|
||||
of the clicked on command in a pager (requires :ref:`shell_integration`)
|
||||
* You can select text with kitty even when a terminal program has grabbed
|
||||
the mouse by holding down the :kbd:`shift` key
|
||||
|
||||
All these actions can be customized in :file:`kitty.conf` as described
|
||||
:ref:`here <conf-kitty-mouse.mousemap>`.
|
||||
|
||||
You can also customize what happens when clicking on :term:`hyperlinks` in kitty,
|
||||
having it open files in your editor, download remote files, open things
|
||||
in your browser, etc.
|
||||
|
||||
For details, see :doc:`here <open_actions>`.
|
||||
|
||||
.. toctree::
|
||||
:hidden:
|
||||
|
||||
open_actions
|
||||
|
||||
Font control
|
||||
-----------------
|
||||
|
||||
|kitty| has extremely flexible and powerful font selection features. You can
|
||||
specify individual families for the regular, bold, italic and bold+italic
|
||||
fonts. You can even specify specific font families for specific ranges of
|
||||
unicode characters. This allows precise control over text rendering. It can
|
||||
come in handy for applications like powerline, without the need to use patched
|
||||
fonts. See the various font related configuration directives in
|
||||
:ref:`conf-kitty-fonts`.
|
||||
|
||||
|
||||
.. _scrollback:
|
||||
|
||||
The scrollback buffer
|
||||
-----------------------
|
||||
|
||||
|kitty| supports scrolling back to view history, just like most terminals. You
|
||||
can use either keyboard shortcuts or the mouse scroll wheel to do so. However,
|
||||
|kitty| has an extra, neat feature. Sometimes you need to explore the
|
||||
scrollback buffer in more detail, maybe search for some text or refer to it
|
||||
side-by-side while typing in a follow-up command. |kitty| allows you to do this
|
||||
by pressing the :sc:`show_scrollback` key-combination, which will open the
|
||||
scrollback buffer in your favorite pager program (which is ``less`` by default).
|
||||
Colors and text formatting are preserved. You can explore the scrollback buffer
|
||||
comfortably within the pager.
|
||||
|
||||
Additionally, you can pipe the contents of the scrollback buffer to an
|
||||
arbitrary, command running in a new :term:`window`, :term:`tab` or :term:`overlay`,
|
||||
for example::
|
||||
|
||||
map f1 launch --stdin-source=@screen_scrollback --stdin-add-formatting less +G -R
|
||||
|
||||
Would open the scrollback buffer in a new :term:`window` when you press the :kbd:`F1`
|
||||
key. See :sc:`show_scrollback <show_scrollback>` for details.
|
||||
|
||||
If you want to use it with an editor such as vim to get more powerful features,
|
||||
you can see tips for doing so, in
|
||||
`this thread <https://github.com/kovidgoyal/kitty/issues/719>`_.
|
||||
|
||||
If you wish to store very large amounts of scrollback to view using the piping or
|
||||
:sc:`show_scrollback <show_scrollback>` features, you can use the
|
||||
:opt:`scrollback_pager_history_size` option.
|
||||
|
||||
|
||||
Integration with shells
|
||||
---------------------------------
|
||||
|
||||
kitty has the ability to integrate closely within common shells, such as `zsh
|
||||
<https://www.zsh.org/>`_, `fish <https://fishshell.com>`_ and `bash
|
||||
<https://www.gnu.org/software/bash/>`_ to enable features such as jumping to
|
||||
previous prompts in the scrollback, viewing the output of the last command in
|
||||
:program:`less`, using the mouse to move the cursor while editing prompts, etc.
|
||||
See :doc:`shell-integration` for details.
|
||||
|
||||
.. toctree::
|
||||
:hidden:
|
||||
|
||||
shell-integration
|
||||
|
||||
.. _cpbuf:
|
||||
|
||||
Multiple copy/paste buffers
|
||||
-----------------------------
|
||||
|
||||
In addition to being able to copy/paste from the system clipboard, in |kitty| you
|
||||
can also setup an arbitrary number of copy paste buffers. To do so, simply add
|
||||
something like the following to your :file:`kitty.conf`::
|
||||
|
||||
map f1 copy_to_buffer a
|
||||
map f2 paste_from_buffer a
|
||||
|
||||
This will allow you to press :kbd:`F1` to copy the current selection to an
|
||||
internal buffer named ``a`` and :kbd:`F2` to paste from that buffer. The buffer
|
||||
names are arbitrary strings, so you can define as many such buffers as you
|
||||
need.
|
||||
|
||||
|
||||
Marks
|
||||
-------------
|
||||
|
||||
kitty has the ability to mark text on the screen based on regular expressions.
|
||||
This can be useful to highlight words or phrases when browsing output from long
|
||||
running programs or similar. To learn how this feature works, see :doc:`marks`.
|
||||
|
||||
.. toctree::
|
||||
:hidden:
|
||||
|
||||
marks
|
||||
@@ -1,4 +1,4 @@
|
||||
|kitty| Performance
|
||||
Performance
|
||||
===================
|
||||
|
||||
The main goals for |kitty| performance are user perceived latency while typing
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
:orphan:
|
||||
|
||||
Working with the screen and history buffer contents
|
||||
======================================================
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
Extensions to the xterm protocol
|
||||
Terminal protocol extensions
|
||||
===================================
|
||||
|
||||
|kitty| has a few extensions to the xterm protocol, to enable advanced features.
|
||||
|kitty| has extensions to the legacy terminal protocol, to enable advanced features.
|
||||
These are typically in the form of new or re-purposed escape codes. While these
|
||||
extensions are currently |kitty| specific, it would be nice to get some of them
|
||||
adopted more broadly, to push the state of terminal emulators forward.
|
||||
@@ -16,266 +16,18 @@ is to make it as easy to implement these protocol extensions as possible,
|
||||
thereby hopefully encouraging their widespread adoption.
|
||||
|
||||
If you wish to discuss these extensions, propose additions/changes to them
|
||||
please do so by opening issues in the github bug tracker.
|
||||
please do so by opening issues in the `GitHub
|
||||
<https://github.com/kovidgoyal/kitty/issues>`_ bug tracker.
|
||||
|
||||
.. contents::
|
||||
|
||||
Colored and styled underlines
|
||||
-------------------------------
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
|kitty| supports colored and styled (wavy) underlines. This is of particular
|
||||
use in terminal editors such as vim and emacs to display red, wavy underlines
|
||||
under mis-spelled words and/or syntax errors. This is done by re-purposing some
|
||||
SGR escape codes that are not used in modern terminals (`CSI codes
|
||||
<https://en.wikipedia.org/wiki/ANSI_escape_code#CSI_sequences>`_)
|
||||
|
||||
To set the underline style::
|
||||
|
||||
<ESC>[4:0m # this is no underline
|
||||
<ESC>[4:1m # this is a straight underline
|
||||
<ESC>[4:2m # this is a double underline
|
||||
<ESC>[4:3m # this is a curly underline
|
||||
<ESC>[4:4m # this is a dotted underline (not implemented in kitty)
|
||||
<ESC>[4:5m # this is a dashed underline (not implemented in kitty)
|
||||
<ESC>[4m # this is a straight underline (for backwards compat)
|
||||
<ESC>[24m # this is no underline (for backwards compat)
|
||||
|
||||
To set the underline color (this is reserved and as far as I can tell not actually used for anything)::
|
||||
|
||||
<ESC>[58...m
|
||||
|
||||
This works exactly like the codes ``38, 48`` that are used to set foreground and
|
||||
background color respectively.
|
||||
|
||||
To reset the underline color (also previously reserved and unused)::
|
||||
|
||||
<ESC>[59m
|
||||
|
||||
The underline color must remain the same under reverse video, if it has a
|
||||
color, if not, it should follow the foreground color.
|
||||
|
||||
To detect support for this feature in a terminal emulator, query the terminfo database
|
||||
for the ``Su`` boolean capability.
|
||||
|
||||
Graphics rendering
|
||||
---------------------
|
||||
|
||||
See :doc:`/graphics-protocol` for a description
|
||||
of this protocol to enable drawing of arbitrary raster images in the terminal.
|
||||
|
||||
|
||||
.. _extended-key-protocol:
|
||||
|
||||
Keyboard handling
|
||||
-------------------
|
||||
|
||||
kitty has a :doc:`keyboard protocol <keyboard-protocol>` for reporting key
|
||||
presses to terminal applications that solves all key handling issues in
|
||||
terminal applications.
|
||||
|
||||
.. _ext_styles:
|
||||
|
||||
Setting text styles/colors in arbitrary regions of the screen
|
||||
------------------------------------------------------------------
|
||||
|
||||
There already exists an escape code to set *some* text attributes in arbitrary
|
||||
regions of the screen, `DECCARA
|
||||
<https://vt100.net/docs/vt510-rm/DECCARA.html>`_. However, it is limited to
|
||||
only a few attributes. |kitty| extends this to work with *all* SGR attributes.
|
||||
So, for example, this can be used to set the background color in an arbitrary
|
||||
region of the screen.
|
||||
|
||||
The motivation for this extension is the various problems with the existing
|
||||
solution for erasing to background color, namely the *background color erase
|
||||
(bce)* capability. See
|
||||
`this discussion <https://github.com/kovidgoyal/kitty/issues/160#issuecomment-346470545>`_
|
||||
and `this FAQ <https://invisible-island.net/ncurses/ncurses.faq.html#bce_mismatches>`_
|
||||
for a summary of problems with *bce*.
|
||||
|
||||
For example, to set the background color to blue in a
|
||||
rectangular region of the screen from (3, 4) to (10, 11), you use::
|
||||
|
||||
<ESC>[2*x<ESC>[4;3;11;10;44$r<ESC>[*x
|
||||
|
||||
|
||||
Saving and restoring colors
|
||||
---------------------------------------------------------------------------------
|
||||
|
||||
It is often useful for a full screen application with its own color themes to
|
||||
set the default foreground, background, selection and cursor colors and the
|
||||
ANSI color table. This allows for various performance optimizations when
|
||||
drawing the screen. The problem is that if the user previously used the escape
|
||||
codes to change these colors herself, then running the full screen application
|
||||
will lose her changes even after it exits. To avoid this, kitty introduces a
|
||||
new pair of *OSC* escape codes to push and pop the current color values from a
|
||||
stack::
|
||||
|
||||
<ESC>]30001<ESC>\ # push onto stack
|
||||
<ESC>]30101<ESC>\ # pop from stack
|
||||
|
||||
These escape codes save/restore the colors, default
|
||||
background, default foreground, selection background, selection foreground and
|
||||
cursor color and the 256 colors of the ANSI color table.
|
||||
|
||||
.. note:: In July 2020, after several years, XTerm copied this protocol
|
||||
extension, without acknowledgement, and using incompatible escape codes
|
||||
(XTPUSHCOLORS, XTPOPCOLORS, XTREPORTCOLORS). And they decided to save not
|
||||
just the dynamic colors but the entire ANSI color table. In the interests of
|
||||
promoting interoperability, kitty added support for XTerm's escape codes as
|
||||
well, and changed this extension to also save/restore the entire ANSI color
|
||||
table.
|
||||
|
||||
|
||||
Pasting to clipboard
|
||||
----------------------
|
||||
|
||||
|kitty| implements the OSC 52 escape code protocol to get/set the clipboard
|
||||
contents (controlled via the :opt:`clipboard_control` setting). There is one
|
||||
difference in kitty's implementation compared to some other terminal emulators.
|
||||
|kitty| allows sending arbitrary amounts of text to the clipboard. It does so
|
||||
by modifying the protocol slightly. Successive OSC 52 escape codes to set the
|
||||
clipboard will concatenate, so::
|
||||
|
||||
<ESC>]52;c;<payload1><ESC>\
|
||||
<ESC>]52;c;<payload2><ESC>\
|
||||
|
||||
will result in the clipboard having the contents ``payload1 + payload2``. To
|
||||
send a new string to the clipboard send an OSC 52 sequence with an invalid payload
|
||||
first, for example::
|
||||
|
||||
<ESC>]52;c;!<ESC>\
|
||||
|
||||
Here ``!`` is not valid base64 encoded text, so it clears the clipboard.
|
||||
Further, since it is invalid, it should be ignored by terminal emulators
|
||||
that do not support this extension, thereby making it safe to use, simply
|
||||
always send it before starting a new OSC 52 paste, even if you aren't chunking
|
||||
up large pastes, that way kitty won't concatenate your paste, and it will have
|
||||
no ill-effects in other terminal emulators.
|
||||
|
||||
In case you're using software that can't be easily adapted to this
|
||||
protocol extension, it can be disabled by specifying ``no-append`` to the
|
||||
:opt:`clipboard_control` setting.
|
||||
|
||||
|
||||
.. _desktop_notifications:
|
||||
|
||||
|
||||
Desktop notifications
|
||||
---------------------------------
|
||||
|
||||
|kitty| implements an extensible escape code (OSC 99) to show desktop
|
||||
notifications. It is easy to use from shell scripts and fully extensible to
|
||||
show title and body. Clicking on the notification can optionally focus the
|
||||
window it came from, and/or send an escape code back to the application running
|
||||
in that window.
|
||||
|
||||
The design of the escape code is partially based on the discussion in
|
||||
the defunct
|
||||
`terminal-wg <https://gitlab.freedesktop.org/terminal-wg/specifications/-/issues/13>`_
|
||||
|
||||
The escape code has the form::
|
||||
|
||||
<OSC> 99 ; metadata ; payload <terminator>
|
||||
|
||||
Here ``<OSC>`` is :code:`<ESC>]` and ``<terminator>`` is
|
||||
:code:`<ESC><backslash>`. The metadata is a section of colon separated
|
||||
:code:`key=value` pairs. Every key must be a single character from the set
|
||||
:code:`a-zA-Z` and every value must be a word consisting of characters from
|
||||
the set :code:`a-zA-Z0-9-_/\+.,(){}[]*&^%$#@!`~`. The payload must be
|
||||
interpreted based on the metadata section. The two semi-colons *must* always be
|
||||
present even when no metadata is present.
|
||||
|
||||
Before going into details, lets see how one can display a simple, single line
|
||||
notification from a shell script::
|
||||
|
||||
printf '\x1b]99;;Hello world\x1b\\'
|
||||
|
||||
To show a message with a title and a body::
|
||||
|
||||
printf '\x1b]99;i=1:d=0;Hello world\x1b\\'
|
||||
printf '\x1b]99;i=1:d=1:p=body;This is cool\x1b\\'
|
||||
|
||||
The most important key in the metadata is the ``p`` key, it controls how the
|
||||
payload is interpreted. A value of ``title`` means the payload is setting the
|
||||
title for the notification. A value of ``body`` means it is setting the body,
|
||||
and so on, see the table below for full details.
|
||||
|
||||
The design of the escape code is fundamentally chunked, this is because
|
||||
different terminal emulators have different limits on how large a single escape
|
||||
code can be. Chunking is accomplished by the ``i`` and ``d`` keys. The ``i``
|
||||
key is the *notification id* which can be any string containing the characters
|
||||
``[a-zA-Z0-9_-+.]``. The ``d`` key stands for *done* and
|
||||
can only take the values ``0`` and ``1``. A value of ``0`` means the
|
||||
notification is not yet done and the terminal emulator should hold off
|
||||
displaying it. A value of ``1`` means the notification is done, and should be
|
||||
displayed. You can specify the title or body multiple times and the terminal
|
||||
emulator will concatenate them, thereby allowing arbitrarily long text
|
||||
(terminal emulators are free to impose a sensible limit to avoid
|
||||
Denial-of-Service attacks).
|
||||
|
||||
Both the ``title`` and ``body`` payloads must be either UTF-8 encoded plain
|
||||
text with no embedded escape codes, or UTF-8 text that is base64 encoded, in
|
||||
which case there must be an ``e=1`` key in the metadata to indicate the payload
|
||||
is base64 encoded.
|
||||
|
||||
When the user clicks the notification, a couple of things can happen, the
|
||||
terminal emulator can focus the window from which the notification came, and/or
|
||||
it can send back an escape code to the application indicating the notification
|
||||
was activated. This is controlled by the ``a`` key which takes a comma
|
||||
separated set of values, ``report`` and ``focus``. The value ``focus`` means
|
||||
focus the window from which the notification was issued and is the default.
|
||||
``report`` means send an escape code back to the application. The format of the
|
||||
returned escape code is::
|
||||
|
||||
<OSC> 99 ; i=identifier ; <terminator>
|
||||
|
||||
The value of ``identifier`` comes from the ``i`` key in the escape code sent by
|
||||
the application. If the application sends no identifier, then the terminal
|
||||
*must* use ``i=0``. Actions can be preceded by a negative sign to turn them
|
||||
off, so for example if you do not want any action, turn off the default
|
||||
``focus`` action with::
|
||||
|
||||
a=-focus
|
||||
|
||||
Complete specification of all the metadata keys is in the table below. If a
|
||||
terminal emulator encounters a key in the metadata it does not understand,
|
||||
the key *must* be ignored, to allow for future extensibility of this escape
|
||||
code. Similarly if values for known keys are unknown, the terminal emulator
|
||||
*should* either ignore the entire escape code or perform a best guess effort
|
||||
to display it based on what it does understand.
|
||||
|
||||
.. note::
|
||||
It is possible to extend this escape code to allow specifying an icon for
|
||||
the notification, however, given that some platforms, such as macOS, dont
|
||||
allow displaying custom icons on a notification, at all, it was decided to
|
||||
leave it out of the spec for the time being.
|
||||
|
||||
Similarly, features such as scheduled notifications could be added in future
|
||||
revisions.
|
||||
|
||||
|
||||
======= ==================== ========= =================
|
||||
Key Value Default Description
|
||||
======= ==================== ========= =================
|
||||
``a`` Comma separated list ``focus`` What action to perform when the
|
||||
of ``report``, notification is clicked
|
||||
``focus``, with
|
||||
optional leading
|
||||
``-``
|
||||
|
||||
``d`` ``0`` or ``1`` ``1`` Indicates if the notification is
|
||||
complete or not.
|
||||
|
||||
``e`` ``0`` or ``1`` ``0`` If set to ``1`` means the payload is base64 encoded UTF-8,
|
||||
otherwise it is plain UTF-8 text with no C0 control codes in it
|
||||
|
||||
``i`` ``[a-zA-Z0-9-_+.]`` ``0`` Identifier for the notification
|
||||
|
||||
``p`` One of ``title`` or ``title`` Whether the payload is the notification title or body. If a
|
||||
``body``. notification has no title, the body will be used as title.
|
||||
======= ==================== ========= =================
|
||||
|
||||
|
||||
.. note::
|
||||
|kitty| also supports the legacy OSC 9 protocol developed by iTerm2 for
|
||||
desktop notifications.
|
||||
underlines
|
||||
graphics-protocol
|
||||
keyboard-protocol
|
||||
file-transfer-protocol
|
||||
desktop-notifications
|
||||
unscroll
|
||||
color-stack
|
||||
deccara
|
||||
|
||||
28
docs/quickstart.rst
Normal file
@@ -0,0 +1,28 @@
|
||||
.. _quickstart:
|
||||
|
||||
Quickstart
|
||||
===========
|
||||
|
||||
.. toctree::
|
||||
:hidden:
|
||||
|
||||
binary
|
||||
build
|
||||
|
||||
Pre-built binaries of |kitty| are available for both macOS and Linux.
|
||||
See the :doc:`binary install instructions </binary>`. You can also
|
||||
:doc:`build from source </build>`.
|
||||
|
||||
Additionally, you can use your favorite package manager to install the |kitty|
|
||||
package, but note that some Linux distribution packages are woefully outdated.
|
||||
|kitty| is available in a vast number of package repositories for macOS
|
||||
and Linux.
|
||||
|
||||
.. image:: https://repology.org/badge/tiny-repos/kitty.svg
|
||||
:target: https://repology.org/project/kitty/versions
|
||||
:alt: Number of repositories kitty is available in
|
||||
|
||||
See :doc:`Configuring kitty <conf>` for help on configuring |kitty| and
|
||||
:doc:`Invocation <invocation>` for the command line arguments |kitty| supports.
|
||||
|
||||
For a tour of kitty's design and features, see the :doc:`/overview`.
|
||||
@@ -1,5 +1,5 @@
|
||||
Documentation for the kitty remote control protocol
|
||||
======================================================
|
||||
The kitty remote control protocol
|
||||
==================================
|
||||
|
||||
The kitty remote control protocol is a simple protocol that involves sending
|
||||
data to kitty in the form of JSON. Any individual command of kitty has the
|
||||
@@ -37,5 +37,4 @@ with the following command line::
|
||||
|
||||
echo -en '\eP@kitty-cmd{"cmd":"ls","version":[0,14,2]}\e\' | socat - unix:/tmp/test | awk '{ print substr($0, 13, length($0) - 14) }' | jq -c '.data | fromjson' | jq .
|
||||
|
||||
|
||||
.. include:: generated/rc.rst
|
||||
|
||||
@@ -1,17 +1,15 @@
|
||||
:tocdepth: 2
|
||||
|
||||
Controlling kitty from scripts or the shell
|
||||
==============================================
|
||||
Control kitty from scripts
|
||||
----------------------------
|
||||
|
||||
.. highlight:: sh
|
||||
|
||||
Tutorial
|
||||
----------
|
||||
|
||||
|kitty| can be controlled from scripts or the shell prompt. You can open new
|
||||
windows, send arbitrary text input to any window, name windows and tabs, etc.
|
||||
Let's walk through a few examples of controlling |kitty|.
|
||||
|
||||
Tutorial
|
||||
------------
|
||||
|
||||
Start by running |kitty| as::
|
||||
|
||||
kitty -o allow_remote_control=yes -o enabled_layouts=tall
|
||||
@@ -142,6 +140,8 @@ running on other computers (for example, over ssh) or as other users.
|
||||
kitty, as if you were running with ``allow_remote_control`` turned on.
|
||||
|
||||
|
||||
.. _rc_mapping:
|
||||
|
||||
Mapping key presses to remote control commands
|
||||
--------------------------------------------------
|
||||
|
||||
@@ -172,10 +172,15 @@ Now press, F1 and start typing, what you type will be sent to all windows,
|
||||
live, as you type it.
|
||||
|
||||
|
||||
Documentation for the remote control protocol
|
||||
The remote control protocol
|
||||
-----------------------------------------------
|
||||
|
||||
If you wish to develop your own client to talk to |kitty|, you
|
||||
can use the :doc:`rc_protocol`.
|
||||
can use the :doc:`protocol specification <rc_protocol>`.
|
||||
|
||||
.. toctree::
|
||||
:hidden:
|
||||
|
||||
rc_protocol
|
||||
|
||||
.. include:: generated/cli-kitty-at.rst
|
||||
|
||||
5
docs/requirements.txt
Normal file
@@ -0,0 +1,5 @@
|
||||
sphinx
|
||||
furo
|
||||
sphinx-copybutton
|
||||
sphinxext-opengraph
|
||||
sphinx-inline-tabs
|
||||
|
Before Width: | Height: | Size: 131 KiB After Width: | Height: | Size: 118 KiB |
|
Before Width: | Height: | Size: 62 KiB After Width: | Height: | Size: 53 KiB |
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 10 KiB |
|
Before Width: | Height: | Size: 55 KiB After Width: | Height: | Size: 46 KiB |
|
Before Width: | Height: | Size: 1.2 MiB After Width: | Height: | Size: 958 KiB |
BIN
docs/screenshots/select-window.png
Normal file
|
After Width: | Height: | Size: 111 KiB |
|
Before Width: | Height: | Size: 42 KiB After Width: | Height: | Size: 40 KiB |
BIN
docs/screenshots/themes.png
Normal file
|
After Width: | Height: | Size: 110 KiB |
BIN
docs/screenshots/transfer.png
Normal file
|
After Width: | Height: | Size: 22 KiB |
|
Before Width: | Height: | Size: 88 KiB After Width: | Height: | Size: 76 KiB |
BIN
docs/screenshots/window-logo.png
Normal file
|
After Width: | Height: | Size: 25 KiB |
264
docs/shell-integration.rst
Normal file
@@ -0,0 +1,264 @@
|
||||
.. _shell_integration:
|
||||
|
||||
Shell integration
|
||||
-------------------
|
||||
|
||||
kitty has the ability to integrate closely within common shells, such as `zsh
|
||||
<https://www.zsh.org/>`_, `fish <https://fishshell.com>`_ and `bash
|
||||
<https://www.gnu.org/software/bash/>`_ to enable features such as jumping to
|
||||
previous prompts in the scrollback, viewing the output of the last command in
|
||||
:program:`less`, using the mouse to move the cursor while editing prompts, etc.
|
||||
|
||||
.. versionadded:: 0.24.0
|
||||
|
||||
Features
|
||||
-------------
|
||||
|
||||
* Open the output of the last command in a pager such as :program:`less`
|
||||
(:sc:`show_last_command_output`)
|
||||
|
||||
* Jump to the previous/next prompt in the scrollback
|
||||
(:sc:`scroll_to_previous_prompt` / :sc:`scroll_to_next_prompt`)
|
||||
|
||||
* Click with the mouse anywhere in the current command to move the cursor there
|
||||
|
||||
* Hold :kbd:`ctrl+shift` and right-click on any command output in the scrollback
|
||||
to view it in a pager
|
||||
|
||||
* The current working directory or the command being executed are automatically
|
||||
displayed in the kitty window titlebar/tab title.
|
||||
|
||||
* The text cursor is changed to a bar when editing commands at the shell prompt
|
||||
|
||||
* Glitch free window resizing even with complex prompts. Achieved by erasing
|
||||
the prompt on resize and allowing the shell to redraw it cleanly.
|
||||
|
||||
* Sophisticated completion for the :program:`kitty` command in the shell.
|
||||
|
||||
* When confirming a quit command if a window is sitting at a shell prompt,
|
||||
it is optionally, not counted (see :opt:`confirm_os_window_close`)
|
||||
|
||||
|
||||
Configuration
|
||||
---------------
|
||||
|
||||
Shell integration is controlled by the :opt:`shell_integration` option. By
|
||||
default, all shell integration is enabled. Individual features can be turned
|
||||
off or it can be disabled entirely as well. The :opt:`shell_integration` option
|
||||
takes a space separated list of keywords:
|
||||
|
||||
disabled
|
||||
Turn off all shell integration
|
||||
|
||||
no-rc
|
||||
Do not modify the shell's launch environment to enable integration. Useful if you prefer
|
||||
to :ref:`manually enable integration <manual_shell_integration>`.
|
||||
|
||||
no-cursor
|
||||
Turn off changing of the text cursor to a bar when editing text
|
||||
|
||||
no-title
|
||||
Turn off setting the kitty window/tab title based on shell state
|
||||
|
||||
no-prompt-mark
|
||||
Turn off marking of prompts. This disables jumping to prompt, browsing
|
||||
output of last command and click to move cursor functionality.
|
||||
|
||||
no-complete
|
||||
Turn off completion for the kitty command.
|
||||
|
||||
|
||||
More ways to browse command output
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
You can add further key and mouse bindings to browse the output of commands
|
||||
easily. For example to select the output of a command by right clicking the mouse
|
||||
on the output, define the following in :file:`kitty.conf`:
|
||||
|
||||
.. code:: conf
|
||||
|
||||
mouse_map right press ungrabbed mouse_select_command_output
|
||||
|
||||
Now, when you right click on the output, the entire output is selected, ready
|
||||
to be copied.
|
||||
|
||||
The feature to jump to previous prompts (
|
||||
:sc:`scroll_to_previous_prompt` and :sc:`scroll_to_next_prompt`) and mouse
|
||||
actions (:ref:`action-mouse_select_command_output` and :ref:`action-mouse_show_command_output`) can
|
||||
be integrated with browsing command output as well. For example, define the
|
||||
following mapping in :file:`kitty.conf`:
|
||||
|
||||
.. code:: conf
|
||||
|
||||
map f1 show_last_visited_command_output
|
||||
|
||||
Now, pressing :kbd:`F1` will cause the output of the last jumped to command or
|
||||
the last mouse clicked command output to be opened in a pager for easy browsing.
|
||||
|
||||
In addition, You can define shortcut to get the first command output on screen.
|
||||
For example, define the following in :file:`kitty.conf`:
|
||||
|
||||
.. code:: conf
|
||||
|
||||
map f1 show_first_command_output_on_screen
|
||||
|
||||
Now, pressing :kbd:`F1` will cause the output of the first command output on
|
||||
screen to be opened in a pager.
|
||||
|
||||
You can also add shortcut to scroll to the last jumped position. For example,
|
||||
define the following in :file:`kitty.conf`:
|
||||
|
||||
.. code:: conf
|
||||
|
||||
map f1 scroll_to_prompt 0
|
||||
|
||||
|
||||
How it works
|
||||
-----------------
|
||||
|
||||
At startup, kitty detects if the shell you have configured (either system wide
|
||||
or in kitty.conf) is a supported shell. If so, kitty injects some shell specific
|
||||
code into the shell, to enable shell integration. How it does so varies for
|
||||
different shells.
|
||||
|
||||
|
||||
.. tab:: zsh
|
||||
|
||||
For zsh, kitty sets the ``ZDOTDIR`` environment variable to make zsh load
|
||||
kitty's :file:`.zshenv` which restores the original value of ``ZDOTDIR``
|
||||
and sources the original :file:`.zshenv`. It then loads the shell integration code.
|
||||
The remainder of zsh's startup process proceeds as normal.
|
||||
|
||||
.. tab:: bash
|
||||
|
||||
For bash, kitty adds a couple of lines to the bottom of :file:`~/.bashrc`
|
||||
(in an atomic manner) to load the shell integration code.
|
||||
|
||||
.. tab:: fish
|
||||
|
||||
For fish, to make it automatically load the integration code provided by
|
||||
kitty, the integration script directory path is prepended to the
|
||||
:code:`XDG_DATA_DIRS` environment variable. This is only applied to the fish
|
||||
process and will be cleaned up by the integration script after startup. No files
|
||||
are added or modified.
|
||||
|
||||
Then, when launching the shell, kitty sets the environment variable
|
||||
:envvar:`KITTY_SHELL_INTEGRATION` to the value of the :opt:`shell_integration`
|
||||
option. The shell integration code reads the environment variable, turns on the
|
||||
specified integration functionality and then unsets the variable so as to not
|
||||
pollute the system. This has the nice effect that the changes to the shell's rc
|
||||
files become no-ops when running the shell in anything other than kitty itself.
|
||||
|
||||
The actual shell integration code uses hooks provided by each shell to send
|
||||
special escape codes to kitty, to perform the various tasks. You can see the
|
||||
code used for each shell below:
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<details>
|
||||
<summary>Click to toggle shell integration code</summary>
|
||||
|
||||
.. tab:: zsh
|
||||
|
||||
.. literalinclude:: ../shell-integration/zsh/kitty-integration
|
||||
:language: zsh
|
||||
|
||||
|
||||
.. tab:: fish
|
||||
|
||||
.. literalinclude:: ../shell-integration/fish/vendor_conf.d/kitty-shell-integration.fish
|
||||
:language: fish
|
||||
|
||||
.. tab:: bash
|
||||
|
||||
.. literalinclude:: ../shell-integration/bash/kitty.bash
|
||||
:language: bash
|
||||
|
||||
.. raw:: html
|
||||
|
||||
</details>
|
||||
|
||||
|
||||
.. _manual_shell_integration:
|
||||
|
||||
Manual shell integration
|
||||
----------------------------
|
||||
|
||||
The automatic shell integration is designed to be minimally intrusive, as such
|
||||
it wont work for sub-shells, terminal multiplexers, containers, remote systems, etc.
|
||||
For such systems, you should setup manual shell integration by adding some code
|
||||
to your shells startup files to load the shell integration script.
|
||||
|
||||
First, in :file:`kitty.conf` set:
|
||||
|
||||
.. code-block:: conf
|
||||
|
||||
shell_integration disabled
|
||||
|
||||
Then in your shell's rc file, add the lines:
|
||||
|
||||
.. tab:: bash
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
if test -n "$KITTY_INSTALLATION_DIR"; then
|
||||
export KITTY_SHELL_INTEGRATION="enabled"
|
||||
source "$KITTY_INSTALLATION_DIR/shell-integration/bash/kitty.bash"
|
||||
fi
|
||||
|
||||
.. tab:: zsh
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
if test -n "$KITTY_INSTALLATION_DIR"; then
|
||||
export KITTY_SHELL_INTEGRATION="enabled"
|
||||
autoload -Uz -- "$KITTY_INSTALLATION_DIR"/shell-integration/zsh/kitty-integration
|
||||
kitty-integration
|
||||
unfunction kitty-integration
|
||||
fi
|
||||
|
||||
.. tab:: fish
|
||||
|
||||
.. code-block:: fish
|
||||
|
||||
if set -q KITTY_INSTALLATION_DIR
|
||||
set --global KITTY_SHELL_INTEGRATION enabled
|
||||
source "$KITTY_INSTALLATION_DIR/shell-integration/fish/vendor_conf.d/kitty-shell-integration.fish"
|
||||
set --prepend fish_complete_path "$KITTY_INSTALLATION_DIR/shell-integration/fish/vendor_completions.d"
|
||||
end
|
||||
|
||||
|
||||
The value of :envvar:`KITTY_SHELL_INTEGRATION` is the same as that for
|
||||
:opt:`shell_integration`, except if you want to disable shell integration
|
||||
completely, in which case simply do not set the
|
||||
:envvar:`KITTY_SHELL_INTEGRATION` variable at all.
|
||||
|
||||
If you want this to work while SSHing into a remote system, then you will
|
||||
need to add some code to the snippets above to check if :code:`KITTY_INSTALLATION_DIR`
|
||||
is empty and if so to set it to some hard coded location with the shell
|
||||
integration scripts that need to be copied onto the remote system.
|
||||
|
||||
|
||||
Notes for shell developers
|
||||
-----------------------------
|
||||
|
||||
The protocol used for marking the prompt is very simple. You should consider
|
||||
adding it to your shell as a builtin. Many modern terminals make use of it, for
|
||||
example: kitty, iTerm2, WezTerm, DomTerm
|
||||
|
||||
Just before starting to draw the PS1 prompt send the escape code::
|
||||
|
||||
<OSC>133;A<ST>
|
||||
|
||||
Just before starting to draw the PS2 prompt send the escape code::
|
||||
|
||||
<OSC>133;A;k=s<ST>
|
||||
|
||||
Just before running a command/program, send the escape code::
|
||||
|
||||
<OSC>133;C<ST>
|
||||
|
||||
Here ``<OSC>`` is the bytes ``0x1b 0x5d`` and ``<ST>`` is the bytes ``0x1b
|
||||
0x5c``. This is exactly what is needed for shell integration in kitty. For the
|
||||
full protocol, that also marks the command region, see `the iTerm2 docs
|
||||
<https://iterm2.com/documentation-escape-codes.html>`_.
|
||||
@@ -1,7 +1,12 @@
|
||||
<style>
|
||||
#support-buttons {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.support-button {
|
||||
box-sizing: border-box;
|
||||
border-radius: 6px;
|
||||
box-shadow: rgb(255, 246, 175) 0px 1px 0px 0px;
|
||||
display: inline-block;
|
||||
cursor: pointer;
|
||||
color: rgb(51, 51, 51);
|
||||
@@ -10,15 +15,16 @@
|
||||
font-weight: bold;
|
||||
padding: 8px 24px;
|
||||
text-decoration: none;
|
||||
margin-left: 1em;
|
||||
outline: 0;
|
||||
border-width: 0;
|
||||
}
|
||||
|
||||
.support-button:hover {
|
||||
transform: scale(1.5);
|
||||
transform: scale(1.2);
|
||||
border: solid 1px rgb(92, 184, 92);
|
||||
}
|
||||
|
||||
.support-button {
|
||||
outline: 0;
|
||||
}
|
||||
.support-button:visited {
|
||||
color: rgb(51, 51, 51);
|
||||
outline: 0;
|
||||
@@ -30,28 +36,34 @@
|
||||
}
|
||||
|
||||
#paypal input[type=submit] {
|
||||
background: linear-gradient(rgb(255, 236, 100) 5%, rgb(255, 171, 35) 100%) rgb(255, 236, 100);
|
||||
border: 1px solid rgb(255, 171, 35);
|
||||
background: linear-gradient(rgb(92, 184, 92) 5%, rgb(62, 142, 62) 100%) rgb(92, 184, 92);
|
||||
padding-top: 10px; padding-bottom: 10px;
|
||||
color: rgb(51, 51, 51);
|
||||
border: 1px solid rgb(92, 184, 92);
|
||||
}
|
||||
|
||||
#liberapay a {
|
||||
a.support-button {
|
||||
background: linear-gradient(rgb(92, 184, 92) 5%, rgb(62, 142, 62) 100%) rgb(92, 184, 92);
|
||||
border: 1px solid rgb(62, 142, 62);
|
||||
color: rgb(51, 51, 51);
|
||||
}
|
||||
|
||||
#patreon a {
|
||||
background: linear-gradient(rgb(11, 100, 163) 5%, rgb(5, 45, 73) 100%) rgb(11, 100, 163);
|
||||
border: 1px solid rgb(5, 45, 73);
|
||||
color: #eee;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div id="support-buttons">
|
||||
|
||||
<div id="github">
|
||||
<a class="support-button" href="https://github.com/sponsors/kovidgoyal">Patronage via GitHub</a>
|
||||
</div>
|
||||
|
||||
|
||||
<div id="patreon">
|
||||
<a class="support-button" href="https://www.patreon.com/bePatron?u=917933">Patronage via Patreon</a>
|
||||
</div>
|
||||
|
||||
<div id="liberapay">
|
||||
<a class="support-button" href="https://liberapay.com/kovidgoyal/donate">Patronage via Liberapay</a>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<form id="paypal" action="https://www.paypal.com/cgi-bin/webscr" method="post" title="Contribute to support calibre development">
|
||||
<input type="hidden" name="cmd" value="_s-xclick" />
|
||||
@@ -61,9 +73,5 @@
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div id="liberapay">
|
||||
<a class="support-button" href="https://liberapay.com/kovidgoyal/donate">Patronage via Liberapay</a>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
Support kitty development
|
||||
===========================
|
||||
Support kitty development ❤️
|
||||
==============================
|
||||
|
||||
My goal with |kitty| is to move the stagnant terminal ecosystem forward. To that
|
||||
end kitty has many foundational features, such as: :doc:`image support
|
||||
@@ -7,7 +7,7 @@ end kitty has many foundational features, such as: :doc:`image support
|
||||
:doc:`various enhancements to the terminal protocol <protocol-extensions>`,
|
||||
etc. These features allow the development of rich terminal applications, such
|
||||
as :doc:`Side-by-side diff <kittens/diff>` and :doc:`Unicode input
|
||||
<kittens/unicode-input>`.
|
||||
<kittens/unicode_input>`.
|
||||
|
||||
If you wish to support this mission and see the terminal ecosystem evolve,
|
||||
consider donating so that I can devote more time to |kitty| development.
|
||||
@@ -15,8 +15,7 @@ I have personally written `almost all kitty code
|
||||
<https://github.com/kovidgoyal/kitty/graphs/contributors>`_.
|
||||
|
||||
You can choose to make either a one-time payment via PayPal or become a
|
||||
*patron* of kitty development via the Patreon or Liberapay services
|
||||
below:
|
||||
*patron* of kitty development via one of the services below:
|
||||
|
||||
|
||||
.. raw:: html
|
||||
|
||||
36
docs/underlines.rst
Normal file
@@ -0,0 +1,36 @@
|
||||
Colored and styled underlines
|
||||
================================
|
||||
|
||||
|kitty| supports colored and styled (wavy) underlines. This is of particular
|
||||
use in terminal editors such as vim and emacs to display red, wavy underlines
|
||||
under mis-spelled words and/or syntax errors. This is done by re-purposing some
|
||||
SGR escape codes that are not used in modern terminals (`CSI codes
|
||||
<https://en.wikipedia.org/wiki/ANSI_escape_code#CSI_(Control_Sequence_Introducer)_sequences>`_)
|
||||
|
||||
To set the underline style::
|
||||
|
||||
<ESC>[4:0m # this is no underline
|
||||
<ESC>[4:1m # this is a straight underline
|
||||
<ESC>[4:2m # this is a double underline
|
||||
<ESC>[4:3m # this is a curly underline
|
||||
<ESC>[4:4m # this is a dotted underline (not implemented in kitty)
|
||||
<ESC>[4:5m # this is a dashed underline (not implemented in kitty)
|
||||
<ESC>[4m # this is a straight underline (for backwards compat)
|
||||
<ESC>[24m # this is no underline (for backwards compat)
|
||||
|
||||
To set the underline color (this is reserved and as far as I can tell not actually used for anything)::
|
||||
|
||||
<ESC>[58...m
|
||||
|
||||
This works exactly like the codes ``38, 48`` that are used to set foreground and
|
||||
background color respectively.
|
||||
|
||||
To reset the underline color (also previously reserved and unused)::
|
||||
|
||||
<ESC>[59m
|
||||
|
||||
The underline color must remain the same under reverse video, if it has a
|
||||
color, if not, it should follow the foreground color.
|
||||
|
||||
To detect support for this feature in a terminal emulator, query the terminfo database
|
||||
for the ``Su`` boolean capability.
|
||||
38
docs/unscroll.rst
Normal file
@@ -0,0 +1,38 @@
|
||||
.. _unscroll:
|
||||
|
||||
Unscrolling the screen
|
||||
========================
|
||||
|
||||
This is a small extension to the `SD (Pan up) escape code
|
||||
<https://vt100.net/docs/vt510-rm/SD.html>`_ from the VT-420 terminal. The
|
||||
``SD`` escape code normally causes the text on screen to scroll down by the
|
||||
specified number of lines, with empty lines appearing at the top of the screen.
|
||||
This extension allows the new lines to be filled in from the scrollback buffer
|
||||
instead of being blank.
|
||||
|
||||
The motivation for this is that many modern shells will show completions in a
|
||||
block of lines under the cursor, this causes some of the on-screen text to be
|
||||
lost even after the completion is completed, because it has scrolled off
|
||||
screen. This escape code allows that text to be restored.
|
||||
|
||||
If the scrollback buffer is empty or there is no scrollback buffer, such as for
|
||||
the alternate screen, then the newly inserted lines must be empty, just as with
|
||||
the original ``SD`` escape code. The maximum number of lines that can be
|
||||
scrolled down is implementation defined, but must be at least one screen worth.
|
||||
|
||||
The syntax of the escape code is identical to that of ``SD`` except that it has
|
||||
a trailing ``+`` modifier. This is legal under the `ECMA 48 standard
|
||||
<https://www.ecma-international.org/publications-and-standards/standards/ecma-48/>`_
|
||||
and unused for any other purpose as far as I can tell. So for example, to
|
||||
unscroll three lines, the escape code would be::
|
||||
|
||||
CSI 3 + T
|
||||
|
||||
See `discussion here
|
||||
<https://gitlab.freedesktop.org/terminal-wg/specifications/-/issues/30>`_.
|
||||
|
||||
.. versionadded:: 0.20.2
|
||||
|
||||
Also supported by the terminals:
|
||||
|
||||
* `mintty <https://github.com/mintty/mintty/releases/tag/3.5.2>`_
|
||||
@@ -1,5 +1,4 @@
|
||||
#!/usr/bin/env python3
|
||||
# vim:fileencoding=utf-8
|
||||
# License: GPLv3 Copyright: 2018, Kovid Goyal <kovid at kovidgoyal.net>
|
||||
|
||||
import subprocess
|
||||
@@ -250,7 +249,7 @@ def write_header(text: str, path: str) -> None:
|
||||
def graphics_parser() -> None:
|
||||
flag = frozenset
|
||||
keymap: KeymapType = {
|
||||
'a': ('action', flag('tTqpdfa')),
|
||||
'a': ('action', flag('tTqpdfac')),
|
||||
'd': ('delete_action', flag('aAiIcCfFnNpPqQxXyYzZ')),
|
||||
't': ('transmission_type', flag('dfts')),
|
||||
'o': ('compressed', flag('z')),
|
||||
|
||||
44
gen-config.py
Executable file
@@ -0,0 +1,44 @@
|
||||
#!/usr/bin/env python
|
||||
# License: GPLv3 Copyright: 2021, Kovid Goyal <kovid at kovidgoyal.net>
|
||||
|
||||
|
||||
import re
|
||||
from typing import List
|
||||
|
||||
from kitty.conf.generate import write_output
|
||||
|
||||
|
||||
def patch_color_list(path: str, colors: List[str], name: str, spc: str = ' ') -> None:
|
||||
with open(path, 'r+') as f:
|
||||
raw = f.read()
|
||||
nraw = re.sub(
|
||||
fr'(# {name}_COLORS_START).+?(\s+# {name}_COLORS_END)',
|
||||
r'\1' + f'\n{spc}' + f'\n{spc}'.join(map(lambda x: f'{x!r},', sorted(colors))) + r'\2',
|
||||
raw, flags=re.DOTALL | re.MULTILINE)
|
||||
if nraw != raw:
|
||||
f.seek(0)
|
||||
f.truncate()
|
||||
f.write(nraw)
|
||||
|
||||
|
||||
def main() -> None:
|
||||
from kitty.options.definition import definition
|
||||
write_output('kitty', definition)
|
||||
nullable_colors = []
|
||||
all_colors = []
|
||||
for opt in definition.iter_all_options():
|
||||
if callable(opt.parser_func):
|
||||
if opt.parser_func.__name__ in ('to_color_or_none', 'cursor_text_color'):
|
||||
nullable_colors.append(opt.name)
|
||||
all_colors.append(opt.name)
|
||||
elif opt.parser_func.__name__ in ('to_color', 'titlebar_color', 'macos_titlebar_color'):
|
||||
all_colors.append(opt.name)
|
||||
patch_color_list('kitty/rc/set_colors.py', nullable_colors, 'NULLABLE')
|
||||
patch_color_list('kittens/themes/collection.py', all_colors, 'ALL', ' ' * 8)
|
||||
|
||||
from kittens.diff.options.definition import definition as kd
|
||||
write_output('kittens.diff', kd)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
@@ -1,5 +1,4 @@
|
||||
#!/usr/bin/env python
|
||||
# vim:fileencoding=utf-8
|
||||
# License: GPLv3 Copyright: 2021, Kovid Goyal <kovid at kovidgoyal.net>
|
||||
|
||||
import string
|
||||
@@ -245,7 +244,7 @@ def patch_file(path: str, what: str, text: str, start_marker: str = '/* ', end_m
|
||||
f.write(raw)
|
||||
|
||||
|
||||
def serialize_dict(x: dict) -> str:
|
||||
def serialize_dict(x: Dict[Any, Any]) -> str:
|
||||
return pformat(x, indent=4).replace('{', '{\n ', 1)
|
||||
|
||||
|
||||
@@ -349,7 +348,7 @@ def generate_legacy_text_key_maps() -> None:
|
||||
patch_file('kitty_tests/keys.py', 'legacy letter tests', '\n'.join(tests), start_marker='# ', end_marker='')
|
||||
|
||||
|
||||
def chunks(lst: List, n: int) -> Any:
|
||||
def chunks(lst: List[Any], n: int) -> Any:
|
||||
"""Yield successive n-sized chunks from lst."""
|
||||
for i in range(0, len(lst), n):
|
||||
yield lst[i:i + n]
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
#!/usr/bin/env python3
|
||||
# vim:fileencoding=utf-8
|
||||
# License: GPL v3 Copyright: 2017, Kovid Goyal <kovid at kovidgoyal.net>
|
||||
|
||||
import os
|
||||
@@ -51,9 +50,26 @@ all_symbols: Set[int] = set()
|
||||
name_map: Dict[int, str] = {}
|
||||
word_search_map: DefaultDict[str, Set[int]] = defaultdict(set)
|
||||
zwj = 0x200d
|
||||
soft_hyphen = 0xad
|
||||
flag_codepoints = frozenset(range(0x1F1E6, 0x1F1E6 + 26))
|
||||
# See https://github.com/harfbuzz/harfbuzz/issues/169
|
||||
marks = set(emoji_skin_tone_modifiers) | {zwj} | flag_codepoints
|
||||
not_assigned = set(range(0, sys.maxunicode))
|
||||
property_maps: Dict[str, Set[int]] = defaultdict(set)
|
||||
|
||||
|
||||
def parse_prop_list() -> None:
|
||||
global marks
|
||||
for line in get_data('ucd/PropList.txt'):
|
||||
if line.startswith('#'):
|
||||
continue
|
||||
cp_or_range, rest = line.split(';', 1)
|
||||
chars = parse_range_spec(cp_or_range.strip())
|
||||
name = rest.strip().split()[0]
|
||||
property_maps[name] |= chars
|
||||
# see https://www.unicode.org/faq/unsup_char.html#3
|
||||
marks |= property_maps['Other_Default_Ignorable_Code_Point']
|
||||
marks.add(soft_hyphen)
|
||||
|
||||
|
||||
def parse_ucd() -> None:
|
||||
@@ -213,7 +229,7 @@ def parse_eaw() -> None:
|
||||
if eaw == 'A':
|
||||
ambiguous |= chars
|
||||
seen |= chars
|
||||
elif eaw == 'W' or eaw == 'F':
|
||||
elif eaw in ('W', 'F'):
|
||||
doublewidth |= chars
|
||||
seen |= chars
|
||||
doublewidth |= set(range(0x3400, 0x4DBF + 1)) - seen
|
||||
@@ -234,15 +250,15 @@ def get_ranges(items: List[int]) -> Generator[Union[int, Tuple[int, int]], None,
|
||||
yield a, b
|
||||
|
||||
|
||||
def write_case(spec: Union[Tuple, int], p: Callable) -> None:
|
||||
def write_case(spec: Union[Tuple[int, ...], int], p: Callable[..., None]) -> None:
|
||||
if isinstance(spec, tuple):
|
||||
p('\t\tcase 0x{:x} ... 0x{:x}:'.format(*spec))
|
||||
else:
|
||||
p('\t\tcase 0x{:x}:'.format(spec))
|
||||
p(f'\t\tcase 0x{spec:x}:')
|
||||
|
||||
|
||||
@contextmanager
|
||||
def create_header(path: str, include_data_types: bool = True) -> Generator[Callable, None, None]:
|
||||
def create_header(path: str, include_data_types: bool = True) -> Generator[Callable[..., None], None, None]:
|
||||
with open(path, 'w') as f:
|
||||
p = partial(print, file=f)
|
||||
p('// unicode data, built from the unicode standard on:', date.today())
|
||||
@@ -282,7 +298,7 @@ def gen_emoji() -> None:
|
||||
|
||||
def category_test(
|
||||
name: str,
|
||||
p: Callable,
|
||||
p: Callable[..., None],
|
||||
classes: Iterable[str],
|
||||
comment: str,
|
||||
use_static: bool = False,
|
||||
@@ -312,7 +328,7 @@ def category_test(
|
||||
p('\treturn false;\n}\n')
|
||||
|
||||
|
||||
def codepoint_to_mark_map(p: Callable, mark_map: List[int]) -> Dict[int, int]:
|
||||
def codepoint_to_mark_map(p: Callable[..., None], mark_map: List[int]) -> Dict[int, int]:
|
||||
p('\tswitch(c) { // {{{')
|
||||
rmap = {c: m for m, c in enumerate(mark_map)}
|
||||
for spec in get_ranges(mark_map):
|
||||
@@ -336,10 +352,10 @@ def classes_to_regex(classes: Iterable[str], exclude: str = '') -> Iterable[str]
|
||||
|
||||
def as_string(codepoint: int) -> str:
|
||||
if codepoint < 256:
|
||||
return r'\x{:02x}'.format(codepoint)
|
||||
return fr'\x{codepoint:02x}'
|
||||
if codepoint <= 0xffff:
|
||||
return r'\u{:04x}'.format(codepoint)
|
||||
return r'\U{:08x}'.format(codepoint)
|
||||
return fr'\u{codepoint:04x}'
|
||||
return fr'\U{codepoint:08x}'
|
||||
|
||||
for spec in get_ranges(list(chars)):
|
||||
if isinstance(spec, tuple):
|
||||
@@ -354,16 +370,21 @@ def gen_ucd() -> None:
|
||||
p('#include "unicode-data.h"')
|
||||
category_test(
|
||||
'is_combining_char', p,
|
||||
{c for c in class_maps if c.startswith('M')},
|
||||
'M category (marks)',
|
||||
# See https://github.com/harfbuzz/harfbuzz/issues/169
|
||||
extra_chars=emoji_skin_tone_modifiers | {zwj},
|
||||
(),
|
||||
'Combining and default ignored characters',
|
||||
extra_chars=marks,
|
||||
least_check_return='false'
|
||||
)
|
||||
category_test(
|
||||
'is_ignored_char', p, 'Cc Cf Cs'.split(),
|
||||
'is_ignored_char', p, 'Cc Cs'.split(),
|
||||
'Control characters and non-characters',
|
||||
extra_chars=non_characters, exclude={zwj},
|
||||
extra_chars=non_characters,
|
||||
ascii_range='false'
|
||||
)
|
||||
category_test(
|
||||
'is_non_rendered_char', p, 'Cc Cs'.split(),
|
||||
'Other_Default_Ignorable_Code_Point and soft hyphen',
|
||||
extra_chars=property_maps['Other_Default_Ignorable_Code_Point'] | {soft_hyphen},
|
||||
ascii_range='false'
|
||||
)
|
||||
category_test('is_word_char', p, {c for c in class_maps if c[0] in 'LN'}, 'L and N categories')
|
||||
@@ -378,17 +399,22 @@ def gen_ucd() -> None:
|
||||
p('combining_type mark_for_codepoint(char_type c) {')
|
||||
rmap = codepoint_to_mark_map(p, mark_map)
|
||||
p('}\n')
|
||||
with open('kitty/unicode-data.h') as f:
|
||||
unicode_data = f.read()
|
||||
m = re.search(r'^#define VS15 (\d+)', unicode_data, re.M)
|
||||
if m is not None:
|
||||
expected = int(m.group(1))
|
||||
if rmap[0xfe0e] != expected:
|
||||
raise ValueError('The mark for 0xfe0e has changed, you have to update VS15 to {} and VS16 to {} in unicode-data.h'.format(
|
||||
rmap[0xfe0e], rmap[0xfe0f]
|
||||
))
|
||||
with open('kitty/unicode-data.h', 'r+') as f:
|
||||
raw = f.read()
|
||||
f.seek(0)
|
||||
raw, num = re.subn(
|
||||
r'^// START_KNOWN_MARKS.+?^// END_KNOWN_MARKS',
|
||||
'// START_KNOWN_MARKS\nstatic const combining_type '
|
||||
f'VS15 = {rmap[0xfe0e]}, VS16 = {rmap[0xfe0f]};'
|
||||
'\n// END_KNOWN_MARKS', raw, flags=re.MULTILINE | re.DOTALL)
|
||||
if not num:
|
||||
raise SystemExit('Faile dto patch mark definitions in unicode-data.h')
|
||||
f.truncate()
|
||||
f.write(raw)
|
||||
|
||||
with open('kittens/hints/url_regex.py', 'w') as f:
|
||||
f.write("url_delimiters = '{}' # noqa".format(''.join(classes_to_regex(cz, exclude='\n'))))
|
||||
f.write('# generated by gen-wcwidth.py, do not edit\n\n')
|
||||
f.write("url_delimiters = '{}' # noqa".format(''.join(classes_to_regex(cz, exclude='\n\r'))))
|
||||
|
||||
|
||||
def gen_names() -> None:
|
||||
@@ -495,7 +521,7 @@ def gen_names() -> None:
|
||||
def gen_wcwidth() -> None:
|
||||
seen: Set[int] = set()
|
||||
|
||||
def add(p: Callable, comment: str, chars_: Union[Set[int], FrozenSet[int]], ret: int) -> None:
|
||||
def add(p: Callable[..., None], comment: str, chars_: Union[Set[int], FrozenSet[int]], ret: int) -> None:
|
||||
chars = chars_ - seen
|
||||
seen.update(chars)
|
||||
p(f'\t\t// {comment} ({len(chars)} codepoints)' + ' {{' '{')
|
||||
@@ -536,6 +562,7 @@ def gen_wcwidth() -> None:
|
||||
|
||||
|
||||
parse_ucd()
|
||||
parse_prop_list()
|
||||
parse_emoji()
|
||||
parse_eaw()
|
||||
gen_ucd()
|
||||
|
||||
8
glfw/backend_utils.c
vendored
@@ -91,7 +91,7 @@ compare_timers(const void *a_, const void *b_) {
|
||||
return (a->trigger_at > b->trigger_at) ? 1 : (a->trigger_at < b->trigger_at) ? -1 : 0;
|
||||
}
|
||||
|
||||
static inline void
|
||||
static void
|
||||
update_timers(EventLoopData *eld) {
|
||||
if (eld->timers_count > 1) qsort(eld->timers, eld->timers_count, sizeof(eld->timers[0]), compare_timers);
|
||||
}
|
||||
@@ -164,7 +164,7 @@ prepareForPoll(EventLoopData *eld, monotonic_t timeout) {
|
||||
return timeout;
|
||||
}
|
||||
|
||||
static inline struct timespec
|
||||
static struct timespec
|
||||
calc_time(monotonic_t nsec) {
|
||||
struct timespec result;
|
||||
result.tv_sec = nsec / (1000LL * 1000LL * 1000LL);
|
||||
@@ -271,7 +271,7 @@ wakeupEventLoop(EventLoopData *eld) {
|
||||
}
|
||||
|
||||
#ifndef HAS_EVENT_FD
|
||||
static inline void
|
||||
static void
|
||||
closeFds(int *fds, size_t count) {
|
||||
while(count--) {
|
||||
if (*fds > 0) {
|
||||
@@ -375,7 +375,7 @@ GLFWAPI char* utf_8_strndup(const char* source, size_t max_length) {
|
||||
int createAnonymousFile(off_t size) {
|
||||
int ret, fd = -1, shm_anon = 0;
|
||||
#ifdef HAS_MEMFD_CREATE
|
||||
fd = memfd_create("glfw-shared", MFD_CLOEXEC | MFD_ALLOW_SEALING);
|
||||
fd = glfw_memfd_create("glfw-shared", MFD_CLOEXEC | MFD_ALLOW_SEALING);
|
||||
if (fd < 0) return -1;
|
||||
// We can add this seal before calling posix_fallocate(), as the file
|
||||
// is currently zero-sized anyway.
|
||||
|
||||
@@ -453,24 +453,74 @@ void* _glfwLoadLocalVulkanLoaderNS(void)
|
||||
////// GLFW platform API //////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static inline bool
|
||||
is_ctrl_tab(NSEvent *event, NSEventModifierFlags modifierFlags) {
|
||||
static bool
|
||||
is_modified_tab(NSEvent *event, NSEventModifierFlags modifierFlags) {
|
||||
switch ((NSUInteger)modifierFlags) {
|
||||
// No need to handle shift+tab, [shift]+option+tab
|
||||
case NSEventModifierFlagShift:
|
||||
case NSEventModifierFlagOption:
|
||||
case (NSEventModifierFlagShift | NSEventModifierFlagOption):
|
||||
// Do not intercept cmd+tab, shift+cmd+tab
|
||||
case NSEventModifierFlagCommand:
|
||||
case (NSEventModifierFlagShift | NSEventModifierFlagCommand):
|
||||
return false;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
// ctrl+whatever+tab, option+cmd+tab
|
||||
if (
|
||||
(modifierFlags == NSEventModifierFlagControl &&
|
||||
[event.charactersIgnoringModifiers isEqualToString:@"\t"]) ||
|
||||
(modifierFlags == (NSEventModifierFlagControl | NSEventModifierFlagShift) &&
|
||||
[event.charactersIgnoringModifiers isEqualToString:@"\x19"])
|
||||
(
|
||||
(modifierFlags & NSEventModifierFlagControl) ||
|
||||
modifierFlags == (NSEventModifierFlagOption | NSEventModifierFlagCommand)
|
||||
) && [event.charactersIgnoringModifiers isEqualToString:@"\t"]
|
||||
) return true;
|
||||
// shift+whatever+tab
|
||||
if (
|
||||
(modifierFlags & NSEventModifierFlagShift) &&
|
||||
[event.charactersIgnoringModifiers isEqualToString:@"\x19"]
|
||||
) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
static bool
|
||||
is_cmd_period(NSEvent *event, NSEventModifierFlags modifierFlags) {
|
||||
if (modifierFlags != NSEventModifierFlagCommand) return false;
|
||||
if ([event.charactersIgnoringModifiers isEqualToString:@"."]) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool
|
||||
is_modified_special_key(NSEvent *event, NSEventModifierFlags modifierFlags) {
|
||||
// really one should use [[NSUserDefaults standardUserDefaults] valueForDefaultsDomain:@"com.apple.symbolichotkeys" key:@"AppleSymbolicHotKeys"]
|
||||
// to get the list of global shortcuts and pass through the important ones,
|
||||
// see https://stackoverflow.com/questions/21878482/what-do-the-parameter-values-in-applesymbolichotkeys-plist-dict-represent
|
||||
// however given that in order to know which integers are which actions in that dict one needs reverse engineering
|
||||
// see https://stackoverflow.com/questions/866056/how-do-i-programmatically-get-the-shortcut-keys-reserved-by-mac-os-x
|
||||
// it's too much effort.
|
||||
if ([event.charactersIgnoringModifiers length] != 1) return false;
|
||||
const unichar ch = [event.charactersIgnoringModifiers characterAtIndex:0];
|
||||
if (modifierFlags == (NSEventModifierFlagControl | NSEventModifierFlagShift)) {
|
||||
switch (ch) {
|
||||
case 0x1b: // Esc
|
||||
case NSF1FunctionKey: case NSF2FunctionKey: case NSF3FunctionKey: case NSF4FunctionKey:
|
||||
case NSF5FunctionKey: case NSF6FunctionKey: case NSF7FunctionKey: case NSF8FunctionKey:
|
||||
case NSF9FunctionKey: case NSF10FunctionKey: case NSF11FunctionKey: case NSF12FunctionKey:
|
||||
case NSF13FunctionKey: case NSF14FunctionKey: case NSF15FunctionKey: case NSF16FunctionKey:
|
||||
case NSF17FunctionKey: case NSF18FunctionKey: case NSF19FunctionKey:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
switch (ch) {
|
||||
case 0x1b: // Esc
|
||||
if (modifierFlags & (NSEventModifierFlagCommand | NSEventModifierFlagControl)) return true;
|
||||
break;
|
||||
case NSHelpFunctionKey: // For some reason keyboards with an insert key have it mapped to help
|
||||
if (!modifierFlags || modifierFlags == NSEventModifierFlagShift) return true;
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
GLFWAPI GLFWapplicationshouldhandlereopenfun glfwSetApplicationShouldHandleReopen(GLFWapplicationshouldhandlereopenfun callback) {
|
||||
GLFWapplicationshouldhandlereopenfun previous = handle_reopen_callback;
|
||||
handle_reopen_callback = callback;
|
||||
@@ -510,10 +560,11 @@ int _glfwPlatformInit(void)
|
||||
|
||||
NSEvent* (^keydown_block)(NSEvent*) = ^ NSEvent* (NSEvent* event)
|
||||
{
|
||||
NSEventModifierFlags modifierFlags = [event modifierFlags] & NSEventModifierFlagDeviceIndependentFlagsMask;
|
||||
if (is_ctrl_tab(event, modifierFlags) || is_cmd_period(event, modifierFlags)) {
|
||||
// Cocoa swallows Ctrl+Tab to cycle between views
|
||||
NSEventModifierFlags modifierFlags = [event modifierFlags] & (NSEventModifierFlagShift | NSEventModifierFlagOption | NSEventModifierFlagCommand | NSEventModifierFlagControl);
|
||||
if (is_modified_special_key(event, modifierFlags) || is_modified_tab(event, modifierFlags) || is_cmd_period(event, modifierFlags)) {
|
||||
// Cocoa swallows various key presses, so route them explicitly
|
||||
[[NSApp keyWindow].contentView keyDown:event];
|
||||
return nil;
|
||||
}
|
||||
|
||||
return event;
|
||||
@@ -521,16 +572,17 @@ int _glfwPlatformInit(void)
|
||||
|
||||
NSEvent* (^keyup_block)(NSEvent*) = ^ NSEvent* (NSEvent* event)
|
||||
{
|
||||
NSEventModifierFlags modifierFlags = [event modifierFlags] & NSEventModifierFlagDeviceIndependentFlagsMask;
|
||||
NSEventModifierFlags modifierFlags = [event modifierFlags] & (NSEventModifierFlagShift | NSEventModifierFlagOption | NSEventModifierFlagCommand | NSEventModifierFlagControl);
|
||||
if (modifierFlags & NSEventModifierFlagCommand) {
|
||||
// From http://cocoadev.com/index.pl?GameKeyboardHandlingAlmost
|
||||
// From https://cocoadev.github.io/GameKeyboardHandlingAlmost/
|
||||
// This works around an AppKit bug, where key up events while holding
|
||||
// down the command key don't get sent to the key window.
|
||||
[[NSApp keyWindow] sendEvent:event];
|
||||
}
|
||||
if (is_ctrl_tab(event, modifierFlags) || is_cmd_period(event, modifierFlags)) {
|
||||
// Cocoa swallows Ctrl+Tab to cycle between views
|
||||
if (is_modified_special_key(event, modifierFlags) || is_modified_tab(event, modifierFlags) || is_cmd_period(event, modifierFlags)) {
|
||||
// Cocoa swallows various key presses, so route them explicitly
|
||||
[[NSApp keyWindow].contentView keyUp:event];
|
||||
return nil;
|
||||
}
|
||||
|
||||
return event;
|
||||
@@ -703,7 +755,7 @@ typedef struct {
|
||||
static Timer timers[128] = {{0}};
|
||||
static size_t num_timers = 0;
|
||||
|
||||
static inline void
|
||||
static void
|
||||
remove_timer_at(size_t idx) {
|
||||
if (idx < num_timers) {
|
||||
Timer *t = timers + idx;
|
||||
|
||||
@@ -41,13 +41,27 @@
|
||||
|
||||
// Get the name of the specified display, or NULL
|
||||
//
|
||||
static char* getDisplayName(CGDirectDisplayID displayID)
|
||||
static char*
|
||||
getDisplayName(CGDirectDisplayID displayID, NSScreen* screen)
|
||||
{
|
||||
// IOKit doesn't work on Apple Silicon anymore
|
||||
// Luckily, 10.15 introduced -[NSScreen localizedName].
|
||||
// Use it if available, and fall back to IOKit otherwise.
|
||||
if (screen)
|
||||
{
|
||||
if ([screen respondsToSelector:@selector(localizedName)])
|
||||
{
|
||||
NSString* name = [screen valueForKey:@"localizedName"];
|
||||
if (name) {
|
||||
return _glfw_strdup([name UTF8String]);
|
||||
}
|
||||
}
|
||||
}
|
||||
io_iterator_t it;
|
||||
io_service_t service;
|
||||
CFDictionaryRef info;
|
||||
|
||||
if (IOServiceGetMatchingServices(kIOMasterPortDefault,
|
||||
if (IOServiceGetMatchingServices(0,
|
||||
IOServiceMatching("IODisplayConnect"),
|
||||
&it) != 0)
|
||||
{
|
||||
@@ -89,7 +103,7 @@ static char* getDisplayName(CGDirectDisplayID displayID)
|
||||
if (!service)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"Cocoa: Failed to find service port for display, cannot get its name, using Unknown");
|
||||
"Cocoa: Failed to find service port for display");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -245,7 +259,7 @@ static double getFallbackRefreshRate(CGDirectDisplayID displayID)
|
||||
io_iterator_t it;
|
||||
io_service_t service;
|
||||
|
||||
if (IOServiceGetMatchingServices(kIOMasterPortDefault,
|
||||
if (IOServiceGetMatchingServices(0,
|
||||
IOServiceMatching("IOFramebuffer"),
|
||||
&it) != 0)
|
||||
{
|
||||
@@ -314,10 +328,9 @@ void _glfwClearDisplayLinks() {
|
||||
if (_glfw.ns.displayLinks.entries[i].displayLink) {
|
||||
CVDisplayLinkStop(_glfw.ns.displayLinks.entries[i].displayLink);
|
||||
CVDisplayLinkRelease(_glfw.ns.displayLinks.entries[i].displayLink);
|
||||
_glfw.ns.displayLinks.entries[i].displayLink = nil;
|
||||
_glfw.ns.displayLinks.entries[i].lastRenderFrameRequestedAt = 0;
|
||||
}
|
||||
}
|
||||
memset(_glfw.ns.displayLinks.entries, 0, sizeof(_GLFWDisplayLinkNS) * _glfw.ns.displayLinks.count);
|
||||
_glfw.ns.displayLinks.count = 0;
|
||||
}
|
||||
|
||||
@@ -333,16 +346,27 @@ static CVReturn displayLinkCallback(
|
||||
return kCVReturnSuccess;
|
||||
}
|
||||
|
||||
static inline void createDisplayLink(CGDirectDisplayID displayID) {
|
||||
if (_glfw.ns.displayLinks.count >= sizeof(_glfw.ns.displayLinks.entries)/sizeof(_glfw.ns.displayLinks.entries[0]) - 1) return;
|
||||
void
|
||||
_glfw_create_cv_display_link(_GLFWDisplayLinkNS *entry) {
|
||||
CVDisplayLinkCreateWithCGDisplay(entry->displayID, &entry->displayLink);
|
||||
CVDisplayLinkSetOutputCallback(entry->displayLink, &displayLinkCallback, (void*)(uintptr_t)entry->displayID);
|
||||
}
|
||||
|
||||
_GLFWDisplayLinkNS*
|
||||
_glfw_create_display_link(CGDirectDisplayID displayID) {
|
||||
if (_glfw.ns.displayLinks.count >= arraysz(_glfw.ns.displayLinks.entries) - 1) {
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR, "Too many monitors cannot create display link");
|
||||
return NULL;
|
||||
}
|
||||
for (size_t i = 0; i < _glfw.ns.displayLinks.count; i++) {
|
||||
if (_glfw.ns.displayLinks.entries[i].displayID == displayID) return;
|
||||
// already created in this run
|
||||
if (_glfw.ns.displayLinks.entries[i].displayID == displayID) return _glfw.ns.displayLinks.entries + i;
|
||||
}
|
||||
_GLFWDisplayLinkNS *entry = &_glfw.ns.displayLinks.entries[_glfw.ns.displayLinks.count++];
|
||||
memset(entry, 0, sizeof(_GLFWDisplayLinkNS));
|
||||
entry->displayID = displayID;
|
||||
CVDisplayLinkCreateWithCGDisplay(displayID, &entry->displayLink);
|
||||
CVDisplayLinkSetOutputCallback(entry->displayLink, &displayLinkCallback, (void*)(uintptr_t)displayID);
|
||||
_glfw_create_cv_display_link(entry);
|
||||
return entry;
|
||||
}
|
||||
|
||||
// Poll for changes in the set of connected monitors
|
||||
@@ -350,11 +374,13 @@ static inline void createDisplayLink(CGDirectDisplayID displayID) {
|
||||
void _glfwPollMonitorsNS(void)
|
||||
{
|
||||
uint32_t displayCount;
|
||||
|
||||
CGGetOnlineDisplayList(0, NULL, &displayCount);
|
||||
CGDirectDisplayID* displays = calloc(displayCount, sizeof(CGDirectDisplayID));
|
||||
CGGetOnlineDisplayList(displayCount, displays, &displayCount);
|
||||
_glfwClearDisplayLinks();
|
||||
if (_glfw.hints.init.debugRendering) {
|
||||
fprintf(stderr, "Polling for monitors: %u found\n", displayCount);
|
||||
}
|
||||
|
||||
for (int i = 0; i < _glfw.monitorCount; i++)
|
||||
_glfw.monitors[i]->ns.screen = nil;
|
||||
@@ -371,32 +397,57 @@ void _glfwPollMonitorsNS(void)
|
||||
|
||||
for (uint32_t i = 0; i < displayCount; i++)
|
||||
{
|
||||
if (CGDisplayIsAsleep(displays[i]))
|
||||
if (CGDisplayIsAsleep(displays[i])) {
|
||||
if (_glfw.hints.init.debugRendering) fprintf(stderr, "Ignoring sleeping display: %u", displays[i]);
|
||||
continue;
|
||||
}
|
||||
|
||||
const uint32_t unitNumber = CGDisplayUnitNumber(displays[i]);
|
||||
NSScreen* screen = nil;
|
||||
|
||||
for (screen in [NSScreen screens])
|
||||
{
|
||||
NSNumber* screenNumber = [screen deviceDescription][@"NSScreenNumber"];
|
||||
|
||||
// HACK: Compare unit numbers instead of display IDs to work around
|
||||
// display replacement on machines with automatic graphics
|
||||
// switching
|
||||
if (CGDisplayUnitNumber([screenNumber unsignedIntValue]) == unitNumber)
|
||||
break;
|
||||
}
|
||||
|
||||
// HACK: Compare unit numbers instead of display IDs to work around
|
||||
// display replacement on machines with automatic graphics
|
||||
// switching
|
||||
const uint32_t unitNumber = CGDisplayUnitNumber(displays[i]);
|
||||
|
||||
for (uint32_t j = 0; j < disconnectedCount; j++)
|
||||
uint32_t j;
|
||||
for (j = 0; j < disconnectedCount; j++)
|
||||
{
|
||||
if (disconnected[j] && disconnected[j]->ns.unitNumber == unitNumber)
|
||||
{
|
||||
disconnected[j]->ns.displayID = displays[i];
|
||||
disconnected[j]->ns.screen = screen;
|
||||
_glfw_create_display_link(displays[i]);
|
||||
disconnected[j] = NULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (j < disconnectedCount)
|
||||
continue;
|
||||
|
||||
const CGSize size = CGDisplayScreenSize(displays[i]);
|
||||
char* name = getDisplayName(displays[i]);
|
||||
if (!name)
|
||||
name = _glfw_strdup("Unknown");
|
||||
char* name = getDisplayName(displays[i], screen);
|
||||
if (!name) {
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"Failed to get name for display, using generic name");
|
||||
name = _glfw_strdup("Display with no name");
|
||||
}
|
||||
|
||||
_GLFWmonitor* monitor = _glfwAllocMonitor(name, (int)size.width, (int)size.height);
|
||||
monitor->ns.displayID = displays[i];
|
||||
monitor->ns.unitNumber = unitNumber;
|
||||
createDisplayLink(monitor->ns.displayID);
|
||||
monitor->ns.screen = screen;
|
||||
_glfw_create_display_link(monitor->ns.displayID);
|
||||
|
||||
free(name);
|
||||
|
||||
@@ -547,15 +598,16 @@ GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* count)
|
||||
|
||||
const GLFWvidmode mode =
|
||||
vidmodeFromCGDisplayMode(dm, monitor->ns.fallbackRefreshRate);
|
||||
CFIndex j;
|
||||
|
||||
for (CFIndex j = 0; j < *count; j++)
|
||||
for (j = 0; j < *count; j++)
|
||||
{
|
||||
if (_glfwCompareVideoModes(result + j, &mode) == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
// Skip duplicate modes
|
||||
if (i < *count)
|
||||
if (j < *count)
|
||||
continue;
|
||||
|
||||
(*count)++;
|
||||
|
||||
4
glfw/cocoa_platform.h
vendored
@@ -158,7 +158,7 @@ typedef struct _GLFWDisplayLinkNS
|
||||
{
|
||||
CVDisplayLinkRef displayLink;
|
||||
CGDirectDisplayID displayID;
|
||||
monotonic_t lastRenderFrameRequestedAt;
|
||||
monotonic_t lastRenderFrameRequestedAt, first_unserviced_render_frame_request_at;
|
||||
} _GLFWDisplayLinkNS;
|
||||
|
||||
// Cocoa-specific global data
|
||||
@@ -246,3 +246,5 @@ void _glfwDispatchTickCallback(void);
|
||||
void _glfwDispatchRenderFrame(CGDirectDisplayID);
|
||||
void _glfwShutdownCVDisplayLink(unsigned long long, void*);
|
||||
void _glfwCocoaPostEmptyEvent(void);
|
||||
void _glfw_create_cv_display_link(_GLFWDisplayLinkNS *entry);
|
||||
_GLFWDisplayLinkNS* _glfw_create_display_link(CGDirectDisplayID);
|
||||
|
||||