mirror of
https://github.com/kovidgoyal/kitty
synced 2026-06-14 20:47:58 +02:00
Compare commits
528 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
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 |
5
.gitattributes
vendored
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
|
||||
|
||||
10
.github/ISSUE_TEMPLATE/bug_report.md
vendored
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+, 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**
|
||||
|
||||
2
.github/workflows/ci.yml
vendored
2
.github/workflows/ci.yml
vendored
@@ -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 .
|
||||
|
||||
7
Makefile
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.html[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:
|
||||
|
||||
30
__main__.py
30
__main__.py
@@ -2,8 +2,8 @@
|
||||
# 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
|
||||
|
||||
|
||||
@@ -30,8 +30,8 @@ def runpy(args: List[str]) -> None:
|
||||
|
||||
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 +49,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 +81,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 = {
|
||||
|
||||
@@ -46,9 +46,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 +92,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 '')
|
||||
|
||||
@@ -31,7 +31,7 @@ def binary_includes():
|
||||
'expat', 'sqlite3', 'ffi', 'z', 'lzma', 'png16', 'lcms2', 'crypt',
|
||||
'iconv', 'pcre', 'graphite2', 'glib-2.0', 'freetype',
|
||||
'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),
|
||||
@@ -124,7 +124,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):
|
||||
|
||||
@@ -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'
|
||||
|
||||
@@ -278,7 +278,6 @@ class Freeze(object):
|
||||
'lcms2.2',
|
||||
'crypto.1.1',
|
||||
'ssl.1.1',
|
||||
'ffi.7',
|
||||
):
|
||||
print('\nAdding', x)
|
||||
x = 'lib%s.dylib' % x
|
||||
@@ -349,7 +348,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 +419,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 +455,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,16 @@
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"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",
|
||||
@@ -72,6 +82,7 @@
|
||||
|
||||
{
|
||||
"name": "libffi",
|
||||
"os": "linux",
|
||||
"unix": {
|
||||
"filename": "libffi-3.3.0.tar.gz",
|
||||
"hash": "sha256:72fba7922703ddfa7a028d513ac15a85c8d54c8d67f55fa5a4802885dc652056",
|
||||
@@ -130,9 +141,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,16 +165,6 @@
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"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": {
|
||||
@@ -222,6 +223,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",
|
||||
|
||||
@@ -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)
|
||||
|
||||
113
docs/_static/custom.css
vendored
113
docs/_static/custom.css
vendored
@@ -5,122 +5,15 @@
|
||||
* 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;
|
||||
.sidebar-logo {
|
||||
max-height: 128px;
|
||||
}
|
||||
|
||||
.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 {
|
||||
.sidebar-tree a.current {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.italic {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.bold {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: larger;
|
||||
font-weight: bold
|
||||
}
|
||||
|
||||
57
docs/_static/custom.js
vendored
Normal file
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.scrollTop = pos;
|
||||
}
|
||||
|
||||
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
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
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
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
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
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 %}
|
||||
9
docs/actions.rst
Normal file
9
docs/actions.rst
Normal file
@@ -0,0 +1,9 @@
|
||||
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`.
|
||||
|
||||
.. include:: /generated/actions.rst
|
||||
131
docs/basic.rst
Normal file
131
docs/basic.rst
Normal file
@@ -0,0 +1,131 @@
|
||||
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
|
||||
----------------------------------
|
||||
|
||||
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:`^+⌘+f5` on macOS)
|
||||
Debug :file:`kitty.conf` :sc:`debug_config` (also :kbd:`⌘+option+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
|
||||
@@ -48,6 +51,13 @@ 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
|
||||
|
||||
@@ -1,37 +1,51 @@
|
||||
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
|
||||
|
||||
|
||||
|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 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``
|
||||
* ``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 ``-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.
|
||||
|
||||
|
||||
Install and run from source
|
||||
------------------------------
|
||||
@@ -67,9 +81,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::
|
||||
@@ -118,18 +131,19 @@ This allows users to install the terminfo file 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``
|
||||
|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``
|
||||
|
||||
@@ -4,6 +4,286 @@ Changelog
|
||||
|kitty| is a feature-rich, cross-platform, *fast*, GPU based terminal.
|
||||
To update |kitty|, :doc:`follow the instructions <binary>`.
|
||||
|
||||
0.22.0 [2021-07-26]
|
||||
----------------------
|
||||
|
||||
- Add a new :ref:`action-toggle_layout` action to easily zoom/unzoom a window
|
||||
|
||||
- When right clicking to extend a selection, move the nearest selection
|
||||
boundary rather than the end of the selection. To restore previous behavior
|
||||
use ``mouse_map right press ungrabbed mouse_selection move-end``.
|
||||
|
||||
- When opening hyperlinks, allow defining open actions for directories
|
||||
(:pull:`3836`)
|
||||
|
||||
- When using the OSC 52 escape code to copy to clipboard allow large
|
||||
copies (up to 8MB) without needing a kitty specific chunking protocol.
|
||||
Note that if you used the chunking protocol in the past, it will no longer
|
||||
work and you should switch to using the unmodified protocol which has the
|
||||
advantage of working with all terminal emulators.
|
||||
|
||||
- Fix a bug in the implementation of the synchronized updates escape code that
|
||||
could cause incorrect parsing if either the pending buffer capacity or the
|
||||
pending timeout were exceeded (:iss:`3779`)
|
||||
|
||||
- A new remote control command to :program:`resize the OS Window <kitty @
|
||||
resize-os-window>`
|
||||
|
||||
- Graphics protocol: Add support for composing rectangles from one animation
|
||||
frame onto another (:iss:`3809`)
|
||||
|
||||
- diff kitten: Remove limit on max line length of 4096 characters (:iss:`3806`)
|
||||
|
||||
- Fix turning off cursor blink via escape codes not working (:iss:`3808`)
|
||||
|
||||
- Allow using neighboring window operations in the stack layout. The previous
|
||||
window is considered the left and top neighbor and the next window is
|
||||
considered the bottom and right neighbor (:iss:`3778`)
|
||||
|
||||
- macOS: Render colors in the sRGB colorspace to match other macOS terminal
|
||||
applications (:iss:`2249`)
|
||||
|
||||
- Add a new variable ``{num_window_groups}`` for the :opt:`tab_title_template`
|
||||
(:iss:`3837`)
|
||||
|
||||
- Wayland: Fix :opt:`initial_window_width/height <remember_window_size>` specified
|
||||
in cells not working on High DPI screens (:iss:`3834`)
|
||||
|
||||
- A new theme for the kitty website with support for dark mode.
|
||||
|
||||
- Render ┄ ┅ ┆ ┇ ┈ ┉ ┊ ┋ with spaces at the edges. Matches rendering in
|
||||
most other programs and allows long chains of them to look better
|
||||
(:iss:`3844`)
|
||||
|
||||
- hints kitten: Detect paths and hashes that appear over multiple lines.
|
||||
Note that this means that all line breaks in the text are no longer \n
|
||||
soft breaks are instead \r. If you use a custom regular expression that
|
||||
is meant to match over line breaks, you will need to match over both.
|
||||
(:iss:`3845`)
|
||||
|
||||
- Allow leading or trailing spaces in :opt:`tab_activity_symbol`
|
||||
|
||||
- Fix mouse actions not working when caps lock or num lock are engaged
|
||||
(:iss:`3859`)
|
||||
|
||||
- macOS: Fix automatic detection of bold/italic faces for fonts that
|
||||
use the family name as the full face name of the regular font not working
|
||||
(:iss:`3861`)
|
||||
|
||||
- clipboard kitten: fix copies to clipboard not working without the
|
||||
:option:`kitty +kitten clipboard --wait-for-completion` option
|
||||
|
||||
|
||||
0.21.2 [2021-06-28]
|
||||
----------------------
|
||||
|
||||
- A new :opt:`adjust_baseline` option to adjust the vertical alignment of text
|
||||
inside a line (:pull:`3734`)
|
||||
|
||||
- A new :opt:`url_excluded_characters` option to exclude additional characters
|
||||
when detecting URLs under the mouse (:pull:`3738`)
|
||||
|
||||
- Fix a regression in 0.21.0 that broke rendering of private use Unicode symbols followed
|
||||
by spaces, when they also exist not followed by spaces (:iss:`3729`)
|
||||
|
||||
- ssh kitten: Support systems where the login shell is a non-POSIX shell
|
||||
(:iss:`3405`)
|
||||
|
||||
- ssh kitten: Add completion (:iss:`3760`)
|
||||
|
||||
- ssh kitten: Fix "Connection closed" message being printed by ssh when running
|
||||
remote commands
|
||||
|
||||
- Add support for the XTVERSION escape code
|
||||
|
||||
- macOS: Fix a regression in 0.21.0 that broke middle-click to paste from clipboard (:iss:`3730`)
|
||||
|
||||
- macOS: Fix shortcuts in the global menu bar responding slowly when cursor blink
|
||||
is disabled/timed out (:iss:`3693`)
|
||||
|
||||
- When displaying scrollback ensure that the window does not quit if the amount
|
||||
of scrollback is less than a screen and the user has the ``--quit-if-one-screen``
|
||||
option enabled for less (:iss:`3740`)
|
||||
|
||||
- Linux: Fix Emoji/bitmapped fonts not use able in symbol_map
|
||||
|
||||
- query terminal kitten: Allow querying font face and size information
|
||||
(:iss:`3756`)
|
||||
|
||||
- hyperlinked grep kitten: Fix context options not generating contextual output (:iss:`3759`)
|
||||
|
||||
- Allow using superscripts in tab titles (:iss:`3763`)
|
||||
|
||||
- Unicode input kitten: Fix searching when a word has more than 1024 matches (:iss:`3773`)
|
||||
|
||||
|
||||
0.21.1 [2021-06-14]
|
||||
----------------------
|
||||
|
||||
- macOS: Fix a regression in the previous release that broke rendering of
|
||||
strikeout (:iss:`3717`)
|
||||
|
||||
- macOS: Fix a crash when rendering ligatures larger than 128 characters
|
||||
(:iss:`3724`)
|
||||
|
||||
- Fix a regression in the previous release that could cause a crash when
|
||||
changing layouts and mousing (:iss:`3713`)
|
||||
|
||||
|
||||
0.21.0 [2021-06-12]
|
||||
----------------------
|
||||
|
||||
- Allow reloading the :file:`kitty.conf` config file by pressing
|
||||
:sc:`reload_config_file`. (:iss:`1292`)
|
||||
|
||||
- Allow clicking URLs to open them without needing to also hold
|
||||
:kbd:`ctrl+shift`
|
||||
|
||||
- Allow remapping all mouse button press/release events to perform arbitrary
|
||||
actions. :ref:`See details <conf-kitty-mouse.mousemap>` (:iss:`1033`)
|
||||
|
||||
- Support infinite length ligatures (:iss:`3504`)
|
||||
|
||||
- **Backward incompatibility**: The options to control which modifiers keys to
|
||||
press for various mouse actions have been removed, if you used these options,
|
||||
you will need to replace them with configuration using the new
|
||||
:ref:`mouse actions framework <conf-kitty-mouse.mousemap>` as they will be
|
||||
ignored. The options were: ``terminal_select_modifiers``,
|
||||
``rectangle_select_modifiers`` and ``open_url_modifiers``.
|
||||
|
||||
- Add a configurable mouse action (:kbd:`ctrl+alt+triplepress` to select from the
|
||||
clicked point to the end of the line. (:iss:`3585`)
|
||||
|
||||
- Add the ability to un-scroll the screen to the ``kitty @ scroll-window``
|
||||
remote control command (:iss:`3604`)
|
||||
|
||||
- A new option, :opt:`tab_bar_margin_height` to add margins around the
|
||||
top and bottom edges of the tab bar (:iss:`3247`)
|
||||
|
||||
- Unicode input kitten: Fix a regression in 0.20.0 that broke keyboard handling
|
||||
when the NumLock or CapsLock modifiers were engaged. (:iss:`3587`)
|
||||
|
||||
- Fix a regression in 0.20.0 that sent incorrect bytes for the :kbd:`F1-F4` keys
|
||||
in rmkx mode (:iss:`3586`)
|
||||
|
||||
- macOS: When the Apple Color Emoji font lacks an emoji glyph search for it in other
|
||||
installed fonts (:iss:`3591`)
|
||||
|
||||
- macOS: Fix rendering getting stuck on some machines after sleep/screensaver
|
||||
(:iss:`2016`)
|
||||
|
||||
- macOS: Add a new ``Shell`` menu to the global menubar with some commonly used
|
||||
actions (:pull:`3653`)
|
||||
|
||||
- macOS: Fix the baseline for text not matching other CoreText based
|
||||
applications for some fonts (:iss:`2022`)
|
||||
|
||||
- Add a few more special commandline arguments for the launch command. Now all
|
||||
``KITTY_PIPE_DATA`` is also available via command line argument substitution
|
||||
(:iss:`3593`)
|
||||
|
||||
- Fix dynamically changing the background color in a window causing rendering
|
||||
artifacts in the tab bar (:iss:`3595`)
|
||||
|
||||
- Fix passing STDIN to launched background processes causing them to not inherit
|
||||
environment variables (:pull:`3603`)
|
||||
|
||||
- Fix deleting windows that are not the last window via remote control leaving
|
||||
no window focused (:iss:`3619`)
|
||||
|
||||
- Add an option :option:`kitty @ get-text --add-cursor` to also get the current
|
||||
cursor position and state as ANSI escape codes (:iss:`3625`)
|
||||
|
||||
- Add an option :option:`kitty @ get-text --add-wrap-markers` to add line wrap
|
||||
markers to the output (:pull:`3633`)
|
||||
|
||||
- Improve rendering of curly underlines on HiDPI screens (:pull:`3637`)
|
||||
|
||||
- ssh kitten: Mimic behavior of ssh command line client more closely by
|
||||
executing any command specified on the command line via the users' shell
|
||||
just as ssh does (:iss:`3638`)
|
||||
|
||||
- Fix trailing parentheses in URLs not being detected (:iss:`3688`)
|
||||
|
||||
- Tab bar: Use a lower contrast color for tab separators (:pull:`3666`)
|
||||
|
||||
- Fix a regression that caused using the ``title`` command in session files
|
||||
to stop working (:iss:`3676`)
|
||||
|
||||
- macOS: Fix a rare crash on exit (:iss:`3686`)
|
||||
|
||||
- Fix ligatures not working with the `Iosevka
|
||||
<https://github.com/be5invis/Iosevka>`_ font (requires Iosevka >= 7.0.4)
|
||||
(:iss:`297`)
|
||||
|
||||
- Remote control: Allow matching tabs by index number in currently active OS
|
||||
Window (:iss:`3708`)
|
||||
|
||||
- ssh kitten: Fix non-standard properties in terminfo such as the ones used for
|
||||
true color not being copied (:iss:`312`)
|
||||
|
||||
|
||||
0.20.3 [2021-05-06]
|
||||
----------------------
|
||||
|
||||
- macOS: Distribute universal binaries with both ARM and Intel architectures
|
||||
|
||||
- A new ``show_key`` kitten to easily see the bytes generated by the terminal
|
||||
for key presses in the various keyboard modes (:pull:`3556`)
|
||||
|
||||
- Linux: Fix keyboard layout change keys defined via compose rules not being
|
||||
ignored
|
||||
|
||||
- macOS: Fix Spotlight search of global menu not working in non-English locales
|
||||
(:pull:`3567`)
|
||||
|
||||
- Fix tab activity symbol not appearing if no other changes happen in tab bar even when
|
||||
there is activity in a tab (:iss:`3571`)
|
||||
|
||||
- Fix focus changes not being sent to windows when focused window changes
|
||||
because of the previously focused window being closed (:iss:`3571`)
|
||||
|
||||
|
||||
0.20.2 [2021-04-28]
|
||||
----------------------
|
||||
|
||||
- A new protocol extension to :ref:`unscroll <unscroll>` text from the
|
||||
scrollback buffer onto the screen. Useful, for example, to restore
|
||||
the screen after showing completions below the shell prompt.
|
||||
|
||||
- A new remote control command :ref:`at_env` to change the default
|
||||
environment passed to newly created windows (:iss:`3529`)
|
||||
|
||||
- Linux: Fix binary kitty builds not able to load fonts in WOFF2 format
|
||||
(:iss:`3506`)
|
||||
|
||||
- macOS: Prevent :kbd:`option` based shortcuts for being used for global menu
|
||||
actions (:iss:`3515`)
|
||||
|
||||
- Fix ``kitty @ close-tab`` not working with pipe based remote control
|
||||
(:iss:`3510`)
|
||||
|
||||
- Fix removal of inactive tab that is before the currently active tab causing
|
||||
the highlighted tab to be incorrect (:iss:`3516`)
|
||||
|
||||
- icat kitten: Respect EXIF orientation when displaying JPEG images
|
||||
(:iss:`3518`)
|
||||
|
||||
- GNOME: Fix maximize state not being remembered when focus changes and window
|
||||
decorations are hidden (:iss:`3507`)
|
||||
|
||||
- GNOME: Add a new :opt:`wayland_titlebar_color` option to control the color of the
|
||||
kitty window title bar
|
||||
|
||||
- Fix reading :option:`kitty --session` from ``STDIN`` not working when the
|
||||
:option:`kitty --detach` option is used (:iss:`3523`)
|
||||
|
||||
- Special case rendering of the few remaining Powerline box drawing chars
|
||||
(:iss:`3535`)
|
||||
|
||||
- Fix ``kitty @ set-colors`` not working for the :opt:`active_tab_foreground`.
|
||||
|
||||
|
||||
0.20.1 [2021-04-19]
|
||||
----------------------
|
||||
|
||||
@@ -619,7 +899,7 @@ To update |kitty|, :doc:`follow the instructions <binary>`.
|
||||
beam and underline cursors (:iss:`2337` and :pull:`2342`)
|
||||
|
||||
- When the application running in the terminal grabs the mouse, pass middle
|
||||
clicks to the application unless :opt:`terminal_select_modifiers` are
|
||||
clicks to the application unless `terminal_select_modifiers` are
|
||||
pressed (:iss:`2368`)
|
||||
|
||||
- A new ``copy_and_clear_or_interrupt`` function (:iss:`2403`)
|
||||
@@ -727,7 +1007,7 @@ To update |kitty|, :doc:`follow the instructions <binary>`.
|
||||
- macOS: Add a :code:`titlebar-only` setting to
|
||||
:opt:`hide_window_decorations` to only hide the title bar (:pull:`2286`)
|
||||
|
||||
- Fix a segfault when using :option:`kitty --debug-config` with maps (:iss:`2270`)
|
||||
- Fix a segfault when using ``--debug-config`` with maps (:iss:`2270`)
|
||||
|
||||
- ``goto_tab`` now maps numbers larger than the last tab to the last tab
|
||||
(:iss:`2291`)
|
||||
@@ -899,7 +1179,7 @@ To update |kitty|, :doc:`follow the instructions <binary>`.
|
||||
the mouse pointer shape when the terminal programs grabs the pointer
|
||||
(:iss:`1808`)
|
||||
|
||||
- Add an option :opt:`terminal_select_modifiers` to control which modifiers
|
||||
- Add an option `terminal_select_modifiers` to control which modifiers
|
||||
are used to override mouse selection even when a terminal application has
|
||||
grabbed the mouse (:iss:`1774`)
|
||||
|
||||
@@ -1472,8 +1752,7 @@ To update |kitty|, :doc:`follow the instructions <binary>`.
|
||||
using standard keyboards) via `IBus
|
||||
<https://github.com/ibus/ibus/wiki/ReadMe>`_ (:iss:`469`)
|
||||
|
||||
- Implement completion for the kitty command in bash and zsh. See
|
||||
:ref:`completion`.
|
||||
- Implement completion for the kitty command in bash and zsh
|
||||
|
||||
- Render the text under the cursor in a fixed color, configurable via
|
||||
the option :opt:`cursor_text_color` (:iss:`126`)
|
||||
@@ -1603,8 +1882,8 @@ To update |kitty|, :doc:`follow the instructions <binary>`.
|
||||
|
||||
- Support "-T" as an alias for "--title" (:pull:`659`)
|
||||
|
||||
- Fix a regression in the previous release that broke using :option:`kitty
|
||||
--debug-config` with custom key mappings (:iss:`695`)
|
||||
- Fix a regression in the previous release that broke using
|
||||
``--debug-config`` with custom key mappings (:iss:`695`)
|
||||
|
||||
|
||||
0.11.1 [2018-06-17]
|
||||
|
||||
26
docs/color-stack.rst
Normal file
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.
|
||||
223
docs/conf.py
223
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
|
||||
@@ -25,17 +22,15 @@ 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
|
||||
|
||||
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.conf.types import Definition # noqa
|
||||
from kitty.constants import str_version # noqa
|
||||
|
||||
|
||||
# config {{{
|
||||
# -- Project information -----------------------------------------------------
|
||||
|
||||
@@ -64,8 +59,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 = 'https://sw.kovidgoyal.net/kitty/'
|
||||
|
||||
# Add any paths that contain templates here, relative to this directory.
|
||||
templates_path = ['_templates']
|
||||
|
||||
@@ -89,13 +90,10 @@ 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
|
||||
@@ -105,7 +103,6 @@ rst_prolog = '''
|
||||
.. role:: bold
|
||||
.. role:: cyan
|
||||
.. role:: title
|
||||
.. role:: env
|
||||
|
||||
'''.replace('VERSION', str_version)
|
||||
|
||||
@@ -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)
|
||||
]
|
||||
|
||||
|
||||
@@ -224,32 +207,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 +225,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 +246,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,7 +259,9 @@ 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:
|
||||
@@ -349,6 +317,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(
|
||||
@@ -390,12 +360,14 @@ class SessionLexer(RegexLexer):
|
||||
|
||||
|
||||
def link_role(name: str, rawtext: str, text: str, lineno: int, inliner: Any, options: Any = {}, content: Any = []) -> Tuple[List, List]:
|
||||
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], []
|
||||
@@ -447,87 +419,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 +462,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 +510,10 @@ 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('commit', commit_role)
|
||||
app.connect('html-page-context', add_html_context)
|
||||
|
||||
@@ -1,17 +1,16 @@
|
||||
: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` or sending kitty the ``SIGUSR1`` signal. You can also
|
||||
display the current configuration by pressing the :sc:`debug_config` key.
|
||||
|
||||
.. _confloc:
|
||||
|
||||
@@ -33,12 +32,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
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
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.
|
||||
48
docs/faq.rst
48
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?
|
||||
@@ -54,7 +52,8 @@ type it each time::
|
||||
alias ssh="kitty +kitten ssh"
|
||||
|
||||
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 +62,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
|
||||
@@ -119,7 +118,7 @@ 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>`_
|
||||
`OSC terminal escape codes <https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h3-Operating-System-Commands>`_
|
||||
to set colors or you can define keyboard shortcuts to set colors, for example::
|
||||
|
||||
map f1 set_colors --configured /path/to/some/config/file/colors.conf
|
||||
@@ -169,6 +168,19 @@ 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?
|
||||
---------------------------------------------
|
||||
@@ -226,26 +238,14 @@ 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?
|
||||
--------------------------------------------------------------------------------------------
|
||||
@@ -304,10 +304,6 @@ 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
|
||||
|
||||
111
docs/glossary.rst
Normal file
111
docs/glossary.rst
Normal file
@@ -0,0 +1,111 @@
|
||||
: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`.
|
||||
|
||||
|
||||
Variables that kitty sets when running child programs
|
||||
|
||||
.. 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:: 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:: 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.
|
||||
@@ -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,19 @@ 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
|
||||
|
||||
|
||||
.. contents::
|
||||
* `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
|
||||
|
||||
|
||||
Getting the window size
|
||||
@@ -56,28 +51,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
|
||||
@@ -100,7 +100,8 @@ features of the graphics protocol:
|
||||
import sys
|
||||
from base64 import standard_b64encode
|
||||
|
||||
def serialize_gr_command(cmd, payload=None):
|
||||
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
|
||||
@@ -111,18 +112,17 @@ features of the graphics protocol:
|
||||
w(b'\033\\')
|
||||
return b''.join(ans)
|
||||
|
||||
def write_chunked(cmd, data):
|
||||
data = standard_b64encode(data)
|
||||
def write_chunked(**cmd):
|
||||
data = standard_b64encode(cmd.pop('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.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}, f.read())
|
||||
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
|
||||
@@ -225,8 +225,13 @@ Value of `t` Meaning
|
||||
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.
|
||||
================== ============
|
||||
|
||||
Local client
|
||||
@@ -311,7 +316,7 @@ 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
|
||||
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 +476,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 +590,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 +632,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 +693,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 +750,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 base 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**
|
||||
-----------------------------------------------------------
|
||||
|
||||
568
docs/index.rst
568
docs/index.rst
@@ -1,542 +1,66 @@
|
||||
:tocdepth: 2
|
||||
|
||||
==========================================================
|
||||
kitty - the fast, featureful, GPU based terminal emulator
|
||||
kitty
|
||||
==========================================================
|
||||
|
||||
.. container:: major-features
|
||||
*The fast, feature-rich, GPU based terminal emulator*
|
||||
|
||||
* Offloads rendering to the GPU for :doc:`lower system load <performance>` and
|
||||
buttery smooth scrolling. Uses threaded rendering to minimize input latency.
|
||||
.. toctree::
|
||||
:hidden:
|
||||
|
||||
* 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>`.
|
||||
quickstart
|
||||
overview
|
||||
faq
|
||||
support
|
||||
performance
|
||||
changelog
|
||||
integrations
|
||||
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.
|
||||
.. tab:: Fast
|
||||
|
||||
* 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>`.
|
||||
* Offloads rendering to the GPU for :doc:`lower system load <performance>`
|
||||
* Uses threaded rendering for absolutely minimal latency
|
||||
* Performance tradeoffs can be :ref:`tuned <conf-kitty-performance>`
|
||||
|
||||
* Supports :ref:`startup sessions <sessions>` which allow you to specify
|
||||
the window/tab layout, working directories and programs to run on startup.
|
||||
.. tab:: Capable
|
||||
|
||||
* 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.
|
||||
* 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>`
|
||||
|
||||
* 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.
|
||||
.. tab:: Scriptable
|
||||
|
||||
* Has :ref:`multiple copy/paste buffers <cpbuf>`, like vim.
|
||||
* 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
|
||||
|
||||
* Programmble tabs, :ref:`splits <splits_layout>` and multiple :doc:`layouts <layouts>` to manage windows
|
||||
* Browse the :ref:`entire history <scrollback>` or the output from the last command 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`
|
||||
|
||||
|
||||
.. 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
|
||||
|
||||
|
||||
.. _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`.
|
||||
|
||||
.. toctree::
|
||||
:hidden:
|
||||
:glob:
|
||||
|
||||
*
|
||||
kittens/*
|
||||
generated/rc
|
||||
To get started see :doc:`quickstart`.
|
||||
|
||||
@@ -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,7 +28,7 @@ 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.
|
||||
|
||||
@@ -41,12 +41,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
|
||||
@@ -110,7 +112,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
|
||||
@@ -266,6 +268,15 @@ 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:: 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.
|
||||
|
||||
.. 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
|
||||
@@ -296,7 +307,7 @@ 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
|
||||
bytes as in legacy mode this is to allow the user to type and execute commands
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -103,7 +103,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 +186,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,7 +34,7 @@ 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
|
||||
`pygments <https://pygments.org/>`_ must be installed (note that pygments is
|
||||
included in the macOS kitty app).
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -88,8 +88,14 @@ 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 ever invocation,
|
||||
you can use the :opt:`kitten_alias` option in :file:`kitty.conf` to create aliases
|
||||
that have common sets of options. For example::
|
||||
|
||||
kitten_alias myhints hints --alphabet qfjdkslaureitywovmcxzpq1234567890
|
||||
|
||||
Documentation for the full set of options is below.
|
||||
|
||||
@@ -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,7 +11,7 @@ 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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -24,10 +24,8 @@ 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+]`.
|
||||
: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
|
||||
|
||||
66
docs/kittens_intro.rst
Normal file
66
docs/kittens_intro.rst
Normal file
@@ -0,0 +1,66 @@
|
||||
.. _kittens:
|
||||
|
||||
Extend with kittens
|
||||
-----------------------
|
||||
|
||||
.. toctree::
|
||||
:hidden:
|
||||
:glob:
|
||||
|
||||
kittens/icat
|
||||
kittens/diff
|
||||
kittens/unicode-input
|
||||
kittens/hints
|
||||
kittens/remote_file
|
||||
kittens/hyperlinked_grep
|
||||
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:`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,6 +28,10 @@ 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
|
||||
@@ -39,7 +42,7 @@ 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,9 +57,34 @@ 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
|
||||
|
||||
|
||||
@@ -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
|
||||
------------------
|
||||
|
||||
@@ -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
|
||||
@@ -63,7 +64,7 @@ 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 +86,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``
|
||||
|
||||
283
docs/overview.rst
Normal file
283
docs/overview.rst
Normal file
@@ -0,0 +1,283 @@
|
||||
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 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` 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`.
|
||||
|
||||
.. 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,17 @@ 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
|
||||
desktop-notifications
|
||||
unscroll
|
||||
color-stack
|
||||
deccara
|
||||
|
||||
28
docs/quickstart.rst
Normal file
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
5
docs/requirements.txt
Normal file
@@ -0,0 +1,5 @@
|
||||
sphinx
|
||||
furo
|
||||
sphinx-copybutton
|
||||
sphinxext-opengraph
|
||||
sphinx-inline-tabs
|
||||
36
docs/underlines.rst
Normal file
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.
|
||||
34
docs/unscroll.rst
Normal file
34
docs/unscroll.rst
Normal file
@@ -0,0 +1,34 @@
|
||||
.. _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
|
||||
@@ -250,7 +250,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')),
|
||||
|
||||
17
gen-config.py
Executable file
17
gen-config.py
Executable file
@@ -0,0 +1,17 @@
|
||||
#!/usr/bin/env python
|
||||
# vim:fileencoding=utf-8
|
||||
# License: GPLv3 Copyright: 2021, Kovid Goyal <kovid at kovidgoyal.net>
|
||||
|
||||
|
||||
from kitty.conf.generate import write_output
|
||||
|
||||
|
||||
def main() -> None:
|
||||
from kitty.options.definition import definition
|
||||
write_output('kitty', definition)
|
||||
from kittens.diff.options.definition import definition as kd
|
||||
write_output('kittens.diff', kd)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
@@ -388,7 +388,8 @@ def gen_ucd() -> None:
|
||||
rmap[0xfe0e], rmap[0xfe0f]
|
||||
))
|
||||
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:
|
||||
|
||||
2
glfw/backend_utils.c
vendored
2
glfw/backend_utils.c
vendored
@@ -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.
|
||||
|
||||
@@ -47,7 +47,7 @@ static char* getDisplayName(CGDirectDisplayID displayID)
|
||||
io_service_t service;
|
||||
CFDictionaryRef info;
|
||||
|
||||
if (IOServiceGetMatchingServices(kIOMasterPortDefault,
|
||||
if (IOServiceGetMatchingServices(kIOMainPortDefault,
|
||||
IOServiceMatching("IODisplayConnect"),
|
||||
&it) != 0)
|
||||
{
|
||||
@@ -245,7 +245,7 @@ static double getFallbackRefreshRate(CGDirectDisplayID displayID)
|
||||
io_iterator_t it;
|
||||
io_service_t service;
|
||||
|
||||
if (IOServiceGetMatchingServices(kIOMasterPortDefault,
|
||||
if (IOServiceGetMatchingServices(kIOMainPortDefault,
|
||||
IOServiceMatching("IOFramebuffer"),
|
||||
&it) != 0)
|
||||
{
|
||||
@@ -316,6 +316,7 @@ void _glfwClearDisplayLinks() {
|
||||
CVDisplayLinkRelease(_glfw.ns.displayLinks.entries[i].displayLink);
|
||||
_glfw.ns.displayLinks.entries[i].displayLink = nil;
|
||||
_glfw.ns.displayLinks.entries[i].lastRenderFrameRequestedAt = 0;
|
||||
_glfw.ns.displayLinks.entries[i].first_unserviced_render_frame_request_at = 0;
|
||||
}
|
||||
}
|
||||
_glfw.ns.displayLinks.count = 0;
|
||||
@@ -333,7 +334,14 @@ static CVReturn displayLinkCallback(
|
||||
return kCVReturnSuccess;
|
||||
}
|
||||
|
||||
static inline void createDisplayLink(CGDirectDisplayID displayID) {
|
||||
void
|
||||
_glfw_create_cv_display_link(_GLFWDisplayLinkNS *entry) {
|
||||
CVDisplayLinkCreateWithCGDisplay(entry->displayID, &entry->displayLink);
|
||||
CVDisplayLinkSetOutputCallback(entry->displayLink, &displayLinkCallback, (void*)(uintptr_t)entry->displayID);
|
||||
}
|
||||
|
||||
static void
|
||||
createDisplayLink(CGDirectDisplayID displayID) {
|
||||
if (_glfw.ns.displayLinks.count >= sizeof(_glfw.ns.displayLinks.entries)/sizeof(_glfw.ns.displayLinks.entries[0]) - 1) return;
|
||||
for (size_t i = 0; i < _glfw.ns.displayLinks.count; i++) {
|
||||
if (_glfw.ns.displayLinks.entries[i].displayID == displayID) return;
|
||||
@@ -341,8 +349,7 @@ static inline void createDisplayLink(CGDirectDisplayID displayID) {
|
||||
_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);
|
||||
}
|
||||
|
||||
// Poll for changes in the set of connected monitors
|
||||
|
||||
6
glfw/cocoa_platform.h
vendored
6
glfw/cocoa_platform.h
vendored
@@ -39,6 +39,9 @@ typedef void* CVDisplayLinkRef;
|
||||
// NOTE: Many Cocoa enum values have been renamed and we need to build across
|
||||
// SDK versions where one is unavailable or the other deprecated
|
||||
// We use the newer names in code and these macros to handle compatibility
|
||||
#if (MAC_OS_X_VERSION_MAX_ALLOWED < 120000) // Before macOS 12 Monterey
|
||||
#define kIOMainPortDefault kIOMasterPortDefault
|
||||
#endif
|
||||
#if MAC_OS_X_VERSION_MAX_ALLOWED < 101200
|
||||
#define NSBitmapFormatAlphaNonpremultiplied NSAlphaNonpremultipliedBitmapFormat
|
||||
#define NSEventMaskAny NSAnyEventMask
|
||||
@@ -158,7 +161,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 +249,4 @@ void _glfwDispatchTickCallback(void);
|
||||
void _glfwDispatchRenderFrame(CGDirectDisplayID);
|
||||
void _glfwShutdownCVDisplayLink(unsigned long long, void*);
|
||||
void _glfwCocoaPostEmptyEvent(void);
|
||||
void _glfw_create_cv_display_link(_GLFWDisplayLinkNS *entry);
|
||||
|
||||
@@ -32,6 +32,12 @@
|
||||
#include <float.h>
|
||||
#include <string.h>
|
||||
|
||||
#if (MAC_OS_X_VERSION_MAX_ALLOWED < 101300)
|
||||
#define NSControlStateValueOn NSOnState
|
||||
#define NSControlStateValueOff NSOffState
|
||||
#define NSControlStateValueMixed NSMixedState
|
||||
#endif
|
||||
|
||||
|
||||
static uint32_t
|
||||
vk_code_to_functional_key_code(uint8_t key_code) { // {{{
|
||||
@@ -311,6 +317,7 @@ _glfwShutdownCVDisplayLink(unsigned long long timer_id UNUSED, void *user_data U
|
||||
_GLFWDisplayLinkNS *dl = &_glfw.ns.displayLinks.entries[i];
|
||||
if (dl->displayLink) CVDisplayLinkStop(dl->displayLink);
|
||||
dl->lastRenderFrameRequestedAt = 0;
|
||||
dl->first_unserviced_render_frame_request_at = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -334,10 +341,22 @@ requestRenderFrame(_GLFWwindow *w, GLFWcocoarenderframefun callback) {
|
||||
_GLFWDisplayLinkNS *dl = &_glfw.ns.displayLinks.entries[i];
|
||||
if (dl->displayID == displayID) {
|
||||
dl->lastRenderFrameRequestedAt = now;
|
||||
if (!dl->first_unserviced_render_frame_request_at) dl->first_unserviced_render_frame_request_at = now;
|
||||
if (!CVDisplayLinkIsRunning(dl->displayLink)) CVDisplayLinkStart(dl->displayLink);
|
||||
else if (now - dl->first_unserviced_render_frame_request_at > s_to_monotonic_t(1ll)) {
|
||||
// display link is stuck need to recreate it because Apple cant even
|
||||
// get a simple timer right
|
||||
CVDisplayLinkRelease(dl->displayLink); dl->displayLink = nil;
|
||||
dl->first_unserviced_render_frame_request_at = now;
|
||||
_glfw_create_cv_display_link(dl);
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"CVDisplayLink stuck possibly because of sleep/screensaver + Apple's incompetence, recreating.");
|
||||
if (!CVDisplayLinkIsRunning(dl->displayLink)) CVDisplayLinkStart(dl->displayLink);
|
||||
}
|
||||
} else if (dl->displayLink && dl->lastRenderFrameRequestedAt && now - dl->lastRenderFrameRequestedAt >= DISPLAY_LINK_SHUTDOWN_CHECK_INTERVAL) {
|
||||
CVDisplayLinkStop(dl->displayLink);
|
||||
dl->lastRenderFrameRequestedAt = 0;
|
||||
dl->first_unserviced_render_frame_request_at = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -454,7 +473,8 @@ static void releaseMonitor(_GLFWwindow* window)
|
||||
|
||||
// Translates macOS key modifiers into GLFW ones
|
||||
//
|
||||
static int translateFlags(NSUInteger flags)
|
||||
static int
|
||||
translateFlags(NSUInteger flags)
|
||||
{
|
||||
int mods = 0;
|
||||
|
||||
@@ -472,7 +492,7 @@ static int translateFlags(NSUInteger flags)
|
||||
return mods;
|
||||
}
|
||||
|
||||
#define debug_key(...) if (_glfw.hints.init.debugKeyboard) NSLog(__VA_ARGS__)
|
||||
#define debug_key(...) if (_glfw.hints.init.debugKeyboard) { fprintf(stderr, __VA_ARGS__); fflush(stderr); }
|
||||
|
||||
static inline const char*
|
||||
format_mods(int mods) {
|
||||
@@ -613,7 +633,7 @@ static const NSRange kEmptyRange = { NSNotFound, 0 };
|
||||
- (void)toggle {
|
||||
// Set _desired to the opposite of the current state.
|
||||
_desired = !_desired;
|
||||
debug_key(@"toggle called. Setting desired to %@", @(_desired));
|
||||
debug_key("toggle called. Setting desired to %d", _desired);
|
||||
|
||||
// Try to set the system's state of secure input to the desired state.
|
||||
[self update];
|
||||
@@ -632,7 +652,7 @@ static const NSRange kEmptyRange = { NSNotFound, 0 };
|
||||
- (void)applicationDidResignActive:(NSNotification *)notification {
|
||||
(void)notification;
|
||||
if (_count > 0) {
|
||||
debug_key(@"Application resigning active.");
|
||||
debug_key("Application resigning active.");
|
||||
[self update];
|
||||
}
|
||||
}
|
||||
@@ -640,7 +660,7 @@ static const NSRange kEmptyRange = { NSNotFound, 0 };
|
||||
- (void)applicationDidBecomeActive:(NSNotification *)notification {
|
||||
(void)notification;
|
||||
if (self.isDesired) {
|
||||
debug_key(@"Application became active.");
|
||||
debug_key("Application became active.");
|
||||
[self update];
|
||||
}
|
||||
}
|
||||
@@ -652,39 +672,39 @@ static const NSRange kEmptyRange = { NSNotFound, 0 };
|
||||
}
|
||||
|
||||
- (void)update {
|
||||
debug_key(@"Update secure keyboard entry. desired=%@ active=%@",
|
||||
@(self.isDesired), @([NSApp isActive]));
|
||||
debug_key("Update secure keyboard entry. desired=%d active=%d\n",
|
||||
(int)self.isDesired, (int)[NSApp isActive]);
|
||||
const BOOL secure = self.isDesired && [self allowed];
|
||||
|
||||
if (secure && _count > 0) {
|
||||
debug_key(@"Want to turn on secure input but it's already on");
|
||||
debug_key("Want to turn on secure input but it's already on\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!secure && _count == 0) {
|
||||
debug_key(@"Want to turn off secure input but it's already off");
|
||||
debug_key("Want to turn off secure input but it's already off\n");
|
||||
return;
|
||||
}
|
||||
|
||||
debug_key(@"Before: IsSecureEventInputEnabled returns %d", (int)self.isEnabled);
|
||||
debug_key("Before: IsSecureEventInputEnabled returns %d ", (int)self.isEnabled);
|
||||
if (secure) {
|
||||
OSErr err = EnableSecureEventInput();
|
||||
debug_key(@"EnableSecureEventInput err=%d", (int)err);
|
||||
debug_key("EnableSecureEventInput err=%d ", (int)err);
|
||||
if (err) {
|
||||
debug_key(@"EnableSecureEventInput failed with error %d", (int)err);
|
||||
debug_key("EnableSecureEventInput failed with error %d ", (int)err);
|
||||
} else {
|
||||
_count += 1;
|
||||
}
|
||||
} else {
|
||||
OSErr err = DisableSecureEventInput();
|
||||
debug_key(@"DisableSecureEventInput err=%d", (int)err);
|
||||
debug_key("DisableSecureEventInput err=%d ", (int)err);
|
||||
if (err) {
|
||||
debug_key(@"DisableSecureEventInput failed with error %d", (int)err);
|
||||
debug_key("DisableSecureEventInput failed with error %d ", (int)err);
|
||||
} else {
|
||||
_count -= 1;
|
||||
}
|
||||
}
|
||||
debug_key(@"After: IsSecureEventInputEnabled returns %d", (int)self.isEnabled);
|
||||
debug_key("After: IsSecureEventInputEnabled returns %d\n", (int)self.isEnabled);
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -1200,7 +1220,7 @@ is_ascii_control_char(char x) {
|
||||
}
|
||||
} else {
|
||||
if (input_source_changed) {
|
||||
debug_key(@"Input source changed, clearing pre-edit text and resetting deadkey state\n");
|
||||
debug_key("Input source changed, clearing pre-edit text and resetting deadkey state\n");
|
||||
glfw_keyevent.text = NULL;
|
||||
glfw_keyevent.ime_state = GLFW_IME_PREEDIT_CHANGED;
|
||||
window->ns.deadKeyState = 0;
|
||||
@@ -1222,13 +1242,13 @@ is_ascii_control_char(char x) {
|
||||
&char_count,
|
||||
text
|
||||
) != noErr) {
|
||||
debug_key(@"UCKeyTranslate failed for keycode: 0x%x (%@) %@\n",
|
||||
keycode, @(safe_name_for_keycode(keycode)), @(format_mods(mods)));
|
||||
debug_key("UCKeyTranslate failed for keycode: 0x%x (%s) %s\n",
|
||||
keycode, safe_name_for_keycode(keycode), format_mods(mods));
|
||||
window->ns.deadKeyState = 0;
|
||||
return;
|
||||
}
|
||||
debug_key(@"keycode: 0x%x (%@) %@char_count: %lu deadKeyState: %u repeat: %d",
|
||||
keycode, @(safe_name_for_keycode(keycode)), @(format_mods(mods)), char_count, window->ns.deadKeyState, event.ARepeat);
|
||||
debug_key("\x1b[31mPress:\x1b[m native_key: 0x%x (%s) glfw_key: 0x%x %schar_count: %lu deadKeyState: %u repeat: %d ",
|
||||
keycode, safe_name_for_keycode(keycode), key, format_mods(mods), char_count, window->ns.deadKeyState, event.ARepeat);
|
||||
if (process_text) {
|
||||
// this will call insertText which will fill up _glfw.ns.text
|
||||
[self interpretKeyEvents:[NSArray arrayWithObject:event]];
|
||||
@@ -1237,22 +1257,22 @@ is_ascii_control_char(char x) {
|
||||
}
|
||||
if (window->ns.deadKeyState && (char_count == 0 || keycode == 0x75)) {
|
||||
// 0x75 is the delete key which needs to be ignored during a compose sequence
|
||||
debug_key(@"Sending pre-edit text for dead key (text: %@ markedText: %@).\n", @(format_text(_glfw.ns.text)), markedText);
|
||||
glfw_keyevent.text = [[markedText string] UTF8String];
|
||||
debug_key("Sending pre-edit text for dead key (text: %s markedText: %s).\n", format_text(_glfw.ns.text), glfw_keyevent.text);
|
||||
glfw_keyevent.ime_state = GLFW_IME_PREEDIT_CHANGED;
|
||||
_glfwInputKeyboard(window, &glfw_keyevent); // update pre-edit text
|
||||
return;
|
||||
}
|
||||
if (in_compose_sequence) {
|
||||
debug_key(@"Clearing pre-edit text at end of compose sequence\n");
|
||||
debug_key("Clearing pre-edit text at end of compose sequence\n");
|
||||
glfw_keyevent.text = NULL;
|
||||
glfw_keyevent.ime_state = GLFW_IME_PREEDIT_CHANGED;
|
||||
_glfwInputKeyboard(window, &glfw_keyevent); // clear pre-edit text
|
||||
}
|
||||
}
|
||||
if (is_ascii_control_char(_glfw.ns.text[0])) _glfw.ns.text[0] = 0; // don't send text for ascii control codes
|
||||
debug_key(@"text: %@ glfw_key: %@ marked_text: %@\n",
|
||||
@(format_text(_glfw.ns.text)), @(_glfwGetKeyName(key)), markedText);
|
||||
debug_key("text: %s glfw_key: %s marked_text: %s\n",
|
||||
format_text(_glfw.ns.text), _glfwGetKeyName(key), [[markedText string] UTF8String]);
|
||||
if (!window->ns.deadKeyState) {
|
||||
if ([self hasMarkedText]) {
|
||||
glfw_keyevent.text = [[markedText string] UTF8String];
|
||||
@@ -1310,6 +1330,8 @@ is_ascii_control_char(char x) {
|
||||
|
||||
GLFWkeyevent glfw_keyevent = {.key = key, .native_key = keycode, .action = GLFW_RELEASE, .mods = mods};
|
||||
add_alternate_keys(&glfw_keyevent, event);
|
||||
debug_key("\x1b[32mRelease:\x1b[m native_key: 0x%x (%s) glfw_key: 0x%x %s\n",
|
||||
keycode, safe_name_for_keycode(keycode), key, format_mods(mods));
|
||||
_glfwInputKeyboard(window, &glfw_keyevent);
|
||||
}
|
||||
|
||||
@@ -1439,7 +1461,7 @@ void _glfwPlatformUpdateIMEState(_GLFWwindow *w, const GLFWIMEUpdateEvent *ev) {
|
||||
top /= window->ns.yscale;
|
||||
cellWidth /= window->ns.xscale;
|
||||
cellHeight /= window->ns.yscale;
|
||||
debug_key(@"updateIMEState: %f, %f, %f, %f\n", left, top, cellWidth, cellHeight);
|
||||
debug_key("updateIMEState: %f, %f, %f, %f\n", left, top, cellWidth, cellHeight);
|
||||
const NSRect frame = [window->ns.view frame];
|
||||
const NSRect rectInView = NSMakeRect(left,
|
||||
frame.size.height - top - cellHeight,
|
||||
@@ -1690,6 +1712,7 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window,
|
||||
|
||||
if (!createNativeWindow(window, wndconfig, fbconfig))
|
||||
return false;
|
||||
[window->ns.object setColorSpace:[NSColorSpace sRGBColorSpace]];
|
||||
|
||||
if (ctxconfig->client != GLFW_NO_API)
|
||||
{
|
||||
@@ -2132,6 +2155,12 @@ _glfwDispatchRenderFrame(CGDirectDisplayID displayID) {
|
||||
}
|
||||
w = w->next;
|
||||
}
|
||||
for (size_t i = 0; i < _glfw.ns.displayLinks.count; i++) {
|
||||
_GLFWDisplayLinkNS *dl = &_glfw.ns.displayLinks.entries[i];
|
||||
if (dl->displayID == displayID) {
|
||||
dl->first_unserviced_render_frame_request_at = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void _glfwPlatformGetCursorPos(_GLFWwindow* window, double* xpos, double* ypos)
|
||||
|
||||
@@ -218,6 +218,7 @@ def generate_wrappers(glfw_header: str) -> None:
|
||||
const char* glfwGetPrimarySelectionString(GLFWwindow* window, void)
|
||||
int glfwGetNativeKeyForName(const char* key_name, int case_sensitive)
|
||||
void glfwRequestWaylandFrameEvent(GLFWwindow *handle, unsigned long long id, GLFWwaylandframecallbackfunc callback)
|
||||
bool glfwWaylandSetTitlebarColor(GLFWwindow *handle, uint32_t color, bool use_system_color)
|
||||
unsigned long long glfwDBusUserNotify(const char *app_name, const char* icon, const char *summary, const char *body, \
|
||||
const char *action_text, int32_t timeout, GLFWDBusnotificationcreatedfun callback, void *data)
|
||||
void glfwDBusSetUserNotificationHandler(GLFWDBusnotificationactivatedfun handler)
|
||||
|
||||
26
glfw/glfw3.h
vendored
26
glfw/glfw3.h
vendored
@@ -523,18 +523,20 @@ typedef enum {
|
||||
*
|
||||
* @ingroup input
|
||||
* @{ */
|
||||
#define GLFW_MOUSE_BUTTON_1 0
|
||||
#define GLFW_MOUSE_BUTTON_2 1
|
||||
#define GLFW_MOUSE_BUTTON_3 2
|
||||
#define GLFW_MOUSE_BUTTON_4 3
|
||||
#define GLFW_MOUSE_BUTTON_5 4
|
||||
#define GLFW_MOUSE_BUTTON_6 5
|
||||
#define GLFW_MOUSE_BUTTON_7 6
|
||||
#define GLFW_MOUSE_BUTTON_8 7
|
||||
#define GLFW_MOUSE_BUTTON_LAST GLFW_MOUSE_BUTTON_8
|
||||
#define GLFW_MOUSE_BUTTON_LEFT GLFW_MOUSE_BUTTON_1
|
||||
#define GLFW_MOUSE_BUTTON_RIGHT GLFW_MOUSE_BUTTON_2
|
||||
#define GLFW_MOUSE_BUTTON_MIDDLE GLFW_MOUSE_BUTTON_3
|
||||
typedef enum GLFWMouseButton {
|
||||
GLFW_MOUSE_BUTTON_1 = 0,
|
||||
GLFW_MOUSE_BUTTON_LEFT = 0,
|
||||
GLFW_MOUSE_BUTTON_2 = 1,
|
||||
GLFW_MOUSE_BUTTON_RIGHT = 1,
|
||||
GLFW_MOUSE_BUTTON_3 = 2,
|
||||
GLFW_MOUSE_BUTTON_MIDDLE = 2,
|
||||
GLFW_MOUSE_BUTTON_4 = 3,
|
||||
GLFW_MOUSE_BUTTON_5 = 4,
|
||||
GLFW_MOUSE_BUTTON_6 = 5,
|
||||
GLFW_MOUSE_BUTTON_7 = 6,
|
||||
GLFW_MOUSE_BUTTON_8 = 7,
|
||||
GLFW_MOUSE_BUTTON_LAST = 7
|
||||
} GLFWMouseButton;
|
||||
/*! @} */
|
||||
|
||||
/*! @defgroup joysticks Joysticks
|
||||
|
||||
4
glfw/memfd.h
vendored
4
glfw/memfd.h
vendored
@@ -10,8 +10,8 @@
|
||||
|
||||
#include <unistd.h>
|
||||
#include <sys/syscall.h>
|
||||
static inline int memfd_create(const char *name, unsigned int flags) {
|
||||
return syscall(__NR_memfd_create, name, flags);
|
||||
static inline int glfw_memfd_create(const char *name, unsigned int flags) {
|
||||
return (int)syscall(__NR_memfd_create, name, flags);
|
||||
}
|
||||
|
||||
#ifndef F_LINUX_SPECIFIC_BASE
|
||||
|
||||
4
glfw/window.c
vendored
4
glfw/window.c
vendored
@@ -701,8 +701,8 @@ GLFWAPI void glfwSetWindowSizeIncrements(GLFWwindow* handle, int widthincr, int
|
||||
{
|
||||
_GLFWwindow* window = (_GLFWwindow*) handle;
|
||||
assert(window != NULL);
|
||||
assert(widthincr >= 0);
|
||||
assert(heightincr >= 0);
|
||||
assert(widthincr >= 0 || widthincr == GLFW_DONT_CARE);
|
||||
assert(heightincr >= 0 || heightincr == GLFW_DONT_CARE);
|
||||
|
||||
_GLFW_REQUIRE_INIT();
|
||||
|
||||
|
||||
25
glfw/wl_client_side_decorations.c
vendored
25
glfw/wl_client_side_decorations.c
vendored
@@ -146,6 +146,17 @@ static void
|
||||
render_title_bar(_GLFWwindow *window, bool to_front_buffer) {
|
||||
const bool is_focused = window->id == _glfw.focusedWindowId;
|
||||
uint32_t bg_color = is_focused ? active_bg_color : passive_bg_color;
|
||||
uint32_t fg_color = is_focused ? 0xff444444 : 0xff888888;
|
||||
if (decs.use_custom_titlebar_color) {
|
||||
bg_color = 0xff000000 | (decs.titlebar_color & 0xffffff);
|
||||
double red = ((bg_color >> 16) & 0xFF) / 255.0;
|
||||
double green = ((bg_color >> 8) & 0xFF) / 255.0;
|
||||
double blue = (bg_color & 0xFF) / 255.0;
|
||||
double luma = 0.2126 * red + 0.7152 * green + 0.0722 * blue;
|
||||
if (luma < 0.5) {
|
||||
fg_color = is_focused ? 0xffeeeeee : 0xff888888;
|
||||
}
|
||||
}
|
||||
uint8_t *output = to_front_buffer ? decs.top.buffer.data.front : decs.top.buffer.data.back;
|
||||
|
||||
// render shadow part
|
||||
@@ -169,7 +180,6 @@ render_title_bar(_GLFWwindow *window, bool to_front_buffer) {
|
||||
// render text part
|
||||
output += decs.top.buffer.stride * margin;
|
||||
if (window->wl.title && window->wl.title[0] && _glfw.callbacks.draw_text) {
|
||||
uint32_t fg_color = is_focused ? 0xff444444 : 0xff888888;
|
||||
if (_glfw.callbacks.draw_text((GLFWwindow*)window, window->wl.title, fg_color, bg_color, output, decs.top.buffer.width, decs.top.buffer.height - margin, 0, 0, 0)) return;
|
||||
}
|
||||
for (uint32_t *px = (uint32_t*)output, *end = (uint32_t*)(output + decs.top.buffer.size_in_bytes); px < end; px++) {
|
||||
@@ -413,3 +423,16 @@ set_csd_window_geometry(_GLFWwindow *window, int32_t *width, int32_t *height) {
|
||||
*height -= decs.metrics.visible_titlebar_height;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
set_titlebar_color(_GLFWwindow *window, uint32_t color, bool use_system_color) {
|
||||
bool use_custom_color = !use_system_color;
|
||||
if (use_custom_color != decs.use_custom_titlebar_color || color != decs.titlebar_color) {
|
||||
decs.use_custom_titlebar_color = use_custom_color;
|
||||
decs.titlebar_color = color;
|
||||
}
|
||||
if (window->decorated && decs.top.surface) {
|
||||
update_title_bar(window);
|
||||
damage_csd(top, decs.top.buffer.front);
|
||||
}
|
||||
}
|
||||
|
||||
1
glfw/wl_client_side_decorations.h
vendored
1
glfw/wl_client_side_decorations.h
vendored
@@ -14,3 +14,4 @@ void free_csd_surfaces(_GLFWwindow *window);
|
||||
void change_csd_title(_GLFWwindow *window);
|
||||
bool ensure_csd_resources(_GLFWwindow *window);
|
||||
void set_csd_window_geometry(_GLFWwindow *window, int32_t *width, int32_t *height);
|
||||
void set_titlebar_color(_GLFWwindow *window, uint32_t color, bool use_system_color);
|
||||
|
||||
3
glfw/wl_platform.h
vendored
3
glfw/wl_platform.h
vendored
@@ -195,6 +195,9 @@ typedef struct _GLFWwindowWayland
|
||||
size_t for_decoration_size, stride, segments, corner_size;
|
||||
} shadow_tile;
|
||||
monotonic_t last_click_on_top_decoration_at;
|
||||
|
||||
uint32_t titlebar_color;
|
||||
bool use_custom_titlebar_color;
|
||||
} decorations;
|
||||
|
||||
struct {
|
||||
|
||||
26
glfw/wl_window.c
vendored
26
glfw/wl_window.c
vendored
@@ -396,7 +396,16 @@ _glfwPlatformToggleFullscreen(_GLFWwindow *window, unsigned int flags UNUSED) {
|
||||
return !already_fullscreen;
|
||||
}
|
||||
|
||||
static void xdgToplevelHandleConfigure(void* data,
|
||||
static void
|
||||
inform_compositor_of_window_geometry(_GLFWwindow *window, const char *event) {
|
||||
#define geometry window->wl.decorations.geometry
|
||||
debug("Setting window geometry in %s event: x=%d y=%d %dx%d\n", event, geometry.x, geometry.y, geometry.width, geometry.height);
|
||||
xdg_surface_set_window_geometry(window->wl.xdg.surface, geometry.x, geometry.y, geometry.width, geometry.height);
|
||||
#undef geometry
|
||||
}
|
||||
|
||||
static void
|
||||
xdgToplevelHandleConfigure(void* data,
|
||||
struct xdg_toplevel* toplevel UNUSED,
|
||||
int32_t width,
|
||||
int32_t height,
|
||||
@@ -451,11 +460,8 @@ static void xdgToplevelHandleConfigure(void* data,
|
||||
debug("final window content size: %dx%d\n", window->wl.width, window->wl.height);
|
||||
_glfwInputWindowFocus(window, window->wl.toplevel_states & TOPLEVEL_STATE_ACTIVATED);
|
||||
ensure_csd_resources(window);
|
||||
#define geometry window->wl.decorations.geometry
|
||||
debug("Setting window geometry: x=%d y=%d %dx%d\n", geometry.x, geometry.y, geometry.width, geometry.height);
|
||||
xdg_surface_set_window_geometry(window->wl.xdg.surface, geometry.x, geometry.y, geometry.width, geometry.height);
|
||||
#undef geometry
|
||||
wl_surface_commit(window->wl.surface);
|
||||
inform_compositor_of_window_geometry(window, "configure");
|
||||
if (live_resize_done) _glfwInputLiveResize(window, false);
|
||||
}
|
||||
|
||||
@@ -872,6 +878,7 @@ void _glfwPlatformSetWindowSize(_GLFWwindow* window, int width, int height)
|
||||
resizeFramebuffer(window);
|
||||
ensure_csd_resources(window);
|
||||
wl_surface_commit(window->wl.surface);
|
||||
inform_compositor_of_window_geometry(window, "SetWindowSize");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2001,3 +2008,12 @@ GLFWAPI unsigned long long glfwDBusUserNotify(const char *app_name, const char*
|
||||
GLFWAPI void glfwDBusSetUserNotificationHandler(GLFWDBusnotificationactivatedfun handler) {
|
||||
glfw_dbus_set_user_notification_activated_handler(handler);
|
||||
}
|
||||
|
||||
GLFWAPI bool glfwWaylandSetTitlebarColor(GLFWwindow *handle, uint32_t color, bool use_system_color) {
|
||||
_GLFWwindow* window = (_GLFWwindow*) handle;
|
||||
if (!window->wl.decorations.serverSide) {
|
||||
set_titlebar_color(window, color, use_system_color);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
22
glfw/xkb_glfw.c
vendored
22
glfw/xkb_glfw.c
vendored
@@ -324,8 +324,14 @@ glfw_xkb_update_masks(_GLFWXKBData *xkb) {
|
||||
unsigned used_bits = 0; /* To avoid using the same bit twice */
|
||||
XkbDescPtr xkb_ptr = XkbGetMap( _glfw.x11.display, XkbVirtualModsMask | XkbVirtualModMapMask, XkbUseCoreKbd );
|
||||
|
||||
/* shift, control, and capsLock are special; they cannot be identified reliably on X11 */
|
||||
#define S(a, n) xkb->a##Idx = xkb_keymap_mod_get_index(xkb->keymap, n); xkb->a##Mask = 1 << xkb->a##Idx; used_bits |= xkb->a##Mask;
|
||||
S(control, XKB_MOD_NAME_CTRL);
|
||||
S(shift, XKB_MOD_NAME_SHIFT);
|
||||
S(capsLock, XKB_MOD_NAME_CAPS);
|
||||
#undef S
|
||||
#define S( a ) xkb->a##Idx = XKB_MOD_INVALID; xkb->a##Mask = 0
|
||||
S(control); S(alt); S(shift); S(super); S(hyper); S(meta); S(capsLock); S(numLock);
|
||||
S(alt); S(super); S(hyper); S(meta); S(numLock);
|
||||
#undef S
|
||||
if (xkb_ptr) {
|
||||
Status status = XkbGetNames(_glfw.x11.display, XkbVirtualModNamesMask, xkb_ptr);
|
||||
@@ -361,9 +367,6 @@ glfw_xkb_update_masks(_GLFWXKBData *xkb) {
|
||||
}
|
||||
}
|
||||
#define S(a, n) xkb->a##Idx = xkb_keymap_mod_get_index(xkb->keymap, n); xkb->a##Mask = 1 << xkb->a##Idx;
|
||||
S(control, XKB_MOD_NAME_CTRL);
|
||||
S(shift, XKB_MOD_NAME_SHIFT);
|
||||
S(capsLock, XKB_MOD_NAME_CAPS);
|
||||
if (!succeeded) {
|
||||
S(numLock, XKB_MOD_NAME_NUM);
|
||||
S(alt, XKB_MOD_NAME_ALT);
|
||||
@@ -699,6 +702,11 @@ glfw_xkb_key_from_ime(_GLFWIBUSKeyEvent *ev, bool handled_by_ime, bool failed) {
|
||||
last_handled_press_keycode = ev->glfw_ev.native_key;
|
||||
}
|
||||
|
||||
static bool
|
||||
is_switch_layout_key(xkb_keysym_t xkb_sym) {
|
||||
return xkb_sym == XKB_KEY_ISO_First_Group || xkb_sym == XKB_KEY_ISO_Last_Group || xkb_sym == XKB_KEY_ISO_Next_Group || xkb_sym == XKB_KEY_ISO_Prev_Group || xkb_sym == XKB_KEY_Mode_switch;
|
||||
}
|
||||
|
||||
void
|
||||
glfw_xkb_handle_key_event(_GLFWwindow *window, _GLFWXKBData *xkb, xkb_keycode_t xkb_keycode, int action) {
|
||||
static char key_text[64] = {0};
|
||||
@@ -742,7 +750,7 @@ glfw_xkb_handle_key_event(_GLFWwindow *window, _GLFWXKBData *xkb, xkb_keycode_t
|
||||
xkb_mod_mask_t consumed_unknown_mods = xkb_state_key_get_consumed_mods(sg->state, code_for_sym) & sg->activeUnknownModifiers;
|
||||
if (sg->activeUnknownModifiers) debug("%s", format_xkb_mods(xkb, "active_unknown_mods", sg->activeUnknownModifiers));
|
||||
if (consumed_unknown_mods) { debug("%s", format_xkb_mods(xkb, "consumed_unknown_mods", consumed_unknown_mods)); }
|
||||
else xkb_sym = clean_syms[0];
|
||||
else if (!is_switch_layout_key(xkb_sym)) xkb_sym = clean_syms[0];
|
||||
// xkb returns text even if alt and/or super are pressed
|
||||
if ( ((GLFW_MOD_CONTROL | GLFW_MOD_ALT | GLFW_MOD_SUPER | GLFW_MOD_HYPER | GLFW_MOD_META) & sg->modifiers) == 0) {
|
||||
xkb_state_key_get_utf8(sg->state, code_for_sym, key_text, sizeof(key_text));
|
||||
@@ -754,9 +762,7 @@ glfw_xkb_handle_key_event(_GLFWwindow *window, _GLFWXKBData *xkb, xkb_keycode_t
|
||||
}
|
||||
if (key_text[0]) { debug("%s: %s ", text_type, key_text); }
|
||||
}
|
||||
if (xkb_sym == XKB_KEY_ISO_First_Group || xkb_sym == XKB_KEY_ISO_Last_Group || xkb_sym == XKB_KEY_ISO_Next_Group || xkb_sym == XKB_KEY_ISO_Prev_Group || xkb_sym == XKB_KEY_Mode_switch) {
|
||||
return;
|
||||
}
|
||||
if (is_switch_layout_key(xkb_sym)) { debug(" is a keyboard layout shift key, ignoring.\n"); return; }
|
||||
if (sg->modifiers & GLFW_MOD_NUM_LOCK && XKB_KEY_KP_Space <= xkb_sym && xkb_sym <= XKB_KEY_KP_9) {
|
||||
xkb_sym = xkb_state_key_get_one_sym(sg->state, code_for_sym);
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ class Clipboard(Handler):
|
||||
self.args = args
|
||||
self.clipboard_contents: Optional[str] = None
|
||||
self.data_to_send = data_to_send
|
||||
self.quit_on_write = False
|
||||
|
||||
def initialize(self) -> None:
|
||||
if self.data_to_send is not None:
|
||||
@@ -30,10 +31,14 @@ class Clipboard(Handler):
|
||||
self.print('\x1bP+q544e\x1b\\', end='')
|
||||
self.print('Waiting for completion...')
|
||||
return
|
||||
self.quit_loop(0)
|
||||
self.quit_on_write = True
|
||||
return
|
||||
self.cmd.request_from_clipboard(self.args.use_primary)
|
||||
|
||||
def on_writing_finished(self) -> None:
|
||||
if self.quit_on_write:
|
||||
self.quit_loop(0)
|
||||
|
||||
def on_clipboard_response(self, text: str, from_primary: bool = False) -> None:
|
||||
self.clipboard_contents = text
|
||||
self.quit_loop(0)
|
||||
|
||||
@@ -155,7 +155,7 @@ def sanitize(text: str) -> str:
|
||||
|
||||
@lru_cache(maxsize=1024)
|
||||
def mime_type_for_path(path: str) -> str:
|
||||
return guess_type(path) or 'application/octet-stream'
|
||||
return guess_type(path, allow_filesystem_access=True) or 'application/octet-stream'
|
||||
|
||||
|
||||
@lru_cache(maxsize=1024)
|
||||
|
||||
@@ -3,21 +3,16 @@
|
||||
# License: GPL v3 Copyright: 2018, Kovid Goyal <kovid at kovidgoyal.net>
|
||||
|
||||
import os
|
||||
from typing import Any, Dict, Iterable, Optional, Tuple, Type, Union
|
||||
from typing import Any, Dict, Iterable, Optional
|
||||
|
||||
from kitty.conf.definition import config_lines
|
||||
from kitty.cli_stub import DiffCLIOptions
|
||||
from kitty.conf.utils import (
|
||||
init_config as _init_config, key_func, load_config as _load_config,
|
||||
merge_dicts, parse_config_base, parse_kittens_key, resolve_config
|
||||
load_config as _load_config, parse_config_base, resolve_config
|
||||
)
|
||||
from kitty.constants import config_dir
|
||||
from kitty.options_stub import DiffOptions
|
||||
from kitty.cli_stub import DiffCLIOptions
|
||||
from kitty.rgb import color_as_sgr
|
||||
|
||||
from .config_data import all_options, type_convert
|
||||
|
||||
defaults: Optional[DiffOptions] = None
|
||||
from .options.types import Options as DiffOptions, defaults
|
||||
|
||||
formats: Dict[str, str] = {
|
||||
'title': '',
|
||||
@@ -42,94 +37,30 @@ def set_formats(opts: DiffOptions) -> None:
|
||||
formats['added_highlight'] = '48' + color_as_sgr(opts.highlight_added_bg)
|
||||
|
||||
|
||||
func_with_args, args_funcs = key_func()
|
||||
|
||||
|
||||
@func_with_args('scroll_by')
|
||||
def parse_scroll_by(func: str, rest: str) -> Tuple[str, int]:
|
||||
try:
|
||||
return func, int(rest)
|
||||
except Exception:
|
||||
return func, 1
|
||||
|
||||
|
||||
@func_with_args('scroll_to')
|
||||
def parse_scroll_to(func: str, rest: str) -> Tuple[str, str]:
|
||||
rest = rest.lower()
|
||||
if rest not in {'start', 'end', 'next-change', 'prev-change', 'next-page', 'prev-page', 'next-match', 'prev-match'}:
|
||||
rest = 'start'
|
||||
return func, rest
|
||||
|
||||
|
||||
@func_with_args('change_context')
|
||||
def parse_change_context(func: str, rest: str) -> Tuple[str, Union[int, str]]:
|
||||
rest = rest.lower()
|
||||
if rest in {'all', 'default'}:
|
||||
return func, rest
|
||||
try:
|
||||
amount = int(rest)
|
||||
except Exception:
|
||||
amount = 5
|
||||
return func, amount
|
||||
|
||||
|
||||
@func_with_args('start_search')
|
||||
def parse_start_search(func: str, rest: str) -> Tuple[str, Tuple[bool, bool]]:
|
||||
rest_ = rest.lower().split()
|
||||
is_regex = bool(rest_ and rest_[0] == 'regex')
|
||||
is_backward = bool(len(rest_) > 1 and rest_[1] == 'backward')
|
||||
return func, (is_regex, is_backward)
|
||||
|
||||
|
||||
def special_handling(key: str, val: str, ans: Dict) -> bool:
|
||||
if key == 'map':
|
||||
x = parse_kittens_key(val, args_funcs)
|
||||
if x is not None:
|
||||
action, key_def = x
|
||||
ans['key_definitions'][key_def] = action
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def parse_config(lines: Iterable[str], check_keys: bool = True) -> Dict[str, Any]:
|
||||
ans: Dict[str, Any] = {'key_definitions': {}}
|
||||
parse_config_base(
|
||||
lines,
|
||||
defaults,
|
||||
type_convert,
|
||||
special_handling,
|
||||
ans,
|
||||
check_keys=check_keys
|
||||
)
|
||||
return ans
|
||||
|
||||
|
||||
def merge_configs(defaults: Dict, vals: Dict) -> Dict:
|
||||
ans = {}
|
||||
for k, v in defaults.items():
|
||||
if isinstance(v, dict):
|
||||
newvals = vals.get(k, {})
|
||||
ans[k] = merge_dicts(v, newvals)
|
||||
else:
|
||||
ans[k] = vals.get(k, v)
|
||||
return ans
|
||||
|
||||
|
||||
def parse_defaults(lines: Iterable[str], check_keys: bool = False) -> Dict[str, Any]:
|
||||
return parse_config(lines, check_keys)
|
||||
|
||||
|
||||
x = _init_config(config_lines(all_options), parse_defaults)
|
||||
Options: Type[DiffOptions] = x[0]
|
||||
defaults = x[1]
|
||||
SYSTEM_CONF = '/etc/xdg/kitty/diff.conf'
|
||||
defconf = os.path.join(config_dir, 'diff.conf')
|
||||
|
||||
|
||||
def load_config(*paths: str, overrides: Optional[Iterable[str]] = None) -> DiffOptions:
|
||||
return _load_config(Options, defaults, parse_config, merge_configs, *paths, overrides=overrides)
|
||||
from .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
|
||||
|
||||
SYSTEM_CONF = '/etc/xdg/kitty/diff.conf'
|
||||
defconf = os.path.join(config_dir, 'diff.conf')
|
||||
overrides = tuple(overrides) if overrides is not None else ()
|
||||
opts_dict, paths = _load_config(defaults, parse_config, merge_result_dicts, *paths, overrides=overrides)
|
||||
opts = DiffOptions(opts_dict)
|
||||
opts.config_paths = paths
|
||||
opts.config_overrides = overrides
|
||||
return opts
|
||||
|
||||
|
||||
def init_config(args: DiffCLIOptions) -> DiffOptions:
|
||||
@@ -137,4 +68,6 @@ def init_config(args: DiffCLIOptions) -> DiffOptions:
|
||||
overrides = (a.replace('=', ' ', 1) for a in args.override or ())
|
||||
opts = load_config(*config, overrides=overrides)
|
||||
set_formats(opts)
|
||||
for (sc, action) in opts.map:
|
||||
opts.key_definitions[sc] = action
|
||||
return opts
|
||||
|
||||
@@ -1,131 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
# vim:fileencoding=utf-8
|
||||
# License: GPL v3 Copyright: 2018, Kovid Goyal <kovid at kovidgoyal.net>
|
||||
|
||||
|
||||
# Utils {{{
|
||||
from functools import partial
|
||||
from gettext import gettext as _
|
||||
from typing import Any, Dict, Sequence, Union
|
||||
|
||||
from kitty.conf.definition import Option, Shortcut, option_func
|
||||
from kitty.conf.utils import python_string, to_color, to_color_or_none
|
||||
from kitty.utils import positive_int
|
||||
|
||||
# }}}
|
||||
|
||||
all_options: Dict[str, Union[Option, Sequence[Shortcut]]] = {}
|
||||
o, k, g, all_groups = option_func(all_options, {
|
||||
'colors': [_('Colors')],
|
||||
'diff': [_('Diffing'), ],
|
||||
'shortcuts': [_('Keyboard shortcuts')],
|
||||
})
|
||||
|
||||
|
||||
g('diff')
|
||||
|
||||
|
||||
def syntax_aliases(raw: str) -> Dict[str, str]:
|
||||
ans = {}
|
||||
for x in raw.split():
|
||||
a, b = x.partition(':')[::2]
|
||||
if a and b:
|
||||
ans[a.lower()] = b
|
||||
return ans
|
||||
|
||||
|
||||
o('syntax_aliases', 'pyj:py pyi:py recipe:py', option_type=syntax_aliases, long_text=_('''
|
||||
File extension aliases for syntax highlight
|
||||
For example, to syntax highlight :file:`file.xyz` as
|
||||
:file:`file.abc` use a setting of :code:`xyz:abc`
|
||||
'''))
|
||||
|
||||
o('num_context_lines', 3, option_type=positive_int, long_text=_('''
|
||||
The number of lines of context to show around each change.'''))
|
||||
|
||||
o('diff_cmd', 'auto', long_text=_('''
|
||||
The diff command to use. Must contain the placeholder :code:`_CONTEXT_`
|
||||
which will be replaced by the number of lines of context. The default
|
||||
is to search the system for either git or diff and use that, if found.
|
||||
'''))
|
||||
|
||||
o('replace_tab_by', r'\x20\x20\x20\x20', option_type=python_string, long_text=_('''
|
||||
The string to replace tabs with. Default is to use four spaces.'''))
|
||||
|
||||
|
||||
g('colors')
|
||||
|
||||
o('pygments_style', 'default', long_text=_('''
|
||||
The pygments color scheme to use for syntax highlighting.
|
||||
See :link:`pygments colors schemes <https://help.farbox.com/pygments.html>` for a list of schemes.'''))
|
||||
|
||||
|
||||
c = partial(o, option_type=to_color)
|
||||
c('foreground', 'black', long_text=_('Basic colors'))
|
||||
c('background', 'white')
|
||||
|
||||
c('title_fg', 'black', long_text=_('Title colors'))
|
||||
c('title_bg', 'white')
|
||||
|
||||
c('margin_bg', '#fafbfc', long_text=_('Margin colors'))
|
||||
c('margin_fg', '#aaaaaa')
|
||||
|
||||
c('removed_bg', '#ffeef0', long_text=_('Removed text backgrounds'))
|
||||
c('highlight_removed_bg', '#fdb8c0')
|
||||
c('removed_margin_bg', '#ffdce0')
|
||||
|
||||
c('added_bg', '#e6ffed', long_text=_('Added text backgrounds'))
|
||||
c('highlight_added_bg', '#acf2bd')
|
||||
c('added_margin_bg', '#cdffd8')
|
||||
|
||||
c('filler_bg', '#fafbfc', long_text=_('Filler (empty) line background'))
|
||||
c('margin_filler_bg', 'none', option_type=to_color_or_none, long_text=_(
|
||||
'Filler (empty) line background in margins, defaults to the filler background'))
|
||||
|
||||
c('hunk_margin_bg', '#dbedff', long_text=_('Hunk header colors'))
|
||||
c('hunk_bg', '#f1f8ff')
|
||||
|
||||
c('search_bg', '#444', long_text=_('Highlighting'))
|
||||
c('search_fg', 'white')
|
||||
c('select_bg', '#b4d5fe')
|
||||
o('select_fg', 'black', option_type=to_color_or_none)
|
||||
|
||||
g('shortcuts')
|
||||
k('quit', 'q', 'quit', _('Quit'))
|
||||
k('quit', 'esc', 'quit', _('Quit'))
|
||||
|
||||
k('scroll_down', 'j', 'scroll_by 1', _('Scroll down'))
|
||||
k('scroll_down', 'down', 'scroll_by 1', _('Scroll down'))
|
||||
k('scroll_up', 'k', 'scroll_by -1', _('Scroll up'))
|
||||
k('scroll_up', 'up', 'scroll_by -1', _('Scroll up'))
|
||||
|
||||
k('scroll_top', 'home', 'scroll_to start', _('Scroll to top'))
|
||||
k('scroll_bottom', 'end', 'scroll_to end', _('Scroll to bottom'))
|
||||
|
||||
k('scroll_page_down', 'page_down', 'scroll_to next-page', _('Scroll to next page'))
|
||||
k('scroll_page_down', 'space', 'scroll_to next-page', _('Scroll to next page'))
|
||||
k('scroll_page_up', 'page_up', 'scroll_to prev-page', _('Scroll to previous page'))
|
||||
|
||||
k('next_change', 'n', 'scroll_to next-change', _('Scroll to next change'))
|
||||
k('prev_change', 'p', 'scroll_to prev-change', _('Scroll to previous change'))
|
||||
|
||||
k('all_context', 'a', 'change_context all', _('Show all context'))
|
||||
k('default_context', '=', 'change_context default', _('Show default context'))
|
||||
k('increase_context', '+', 'change_context 5', _('Increase context'))
|
||||
k('decrease_context', '-', 'change_context -5', _('Decrease context'))
|
||||
|
||||
k('search_forward', '/', 'start_search regex forward', _('Search forward'))
|
||||
k('search_backward', '?', 'start_search regex backward', _('Search backward'))
|
||||
k('next_match', '.', 'scroll_to next-match', _('Scroll to next search match'))
|
||||
k('prev_match', ',', 'scroll_to prev-match', _('Scroll to previous search match'))
|
||||
k('next_match', '>', 'scroll_to next-match', _('Scroll to next search match'))
|
||||
k('prev_match', '<', 'scroll_to prev-match', _('Scroll to previous search match'))
|
||||
k('search_forward_simple', 'f', 'start_search substring forward', _('Search forward (no regex)'))
|
||||
k('search_backward_simple', 'b', 'start_search substring backward', _('Search backward (no regex)'))
|
||||
|
||||
|
||||
def type_convert(name: str, val: Any) -> Any:
|
||||
o = all_options.get(name)
|
||||
if isinstance(o, Option):
|
||||
val = o.option_type(val)
|
||||
return val
|
||||
@@ -159,13 +159,12 @@ def highlight_collection(collection: Collection, aliases: Optional[Dict[str, str
|
||||
|
||||
|
||||
def main() -> None:
|
||||
from .config import defaults
|
||||
# kitty +runpy "from kittens.diff.highlight import main; main()" file
|
||||
from .options.types import defaults
|
||||
import sys
|
||||
initialize_highlighter()
|
||||
if defaults is not None:
|
||||
with open(sys.argv[-1]) as f:
|
||||
highlighted = highlight_data(f.read(), f.name, defaults.syntax_aliases)
|
||||
if highlighted is None:
|
||||
raise SystemExit('Unknown filetype: {}'.format(sys.argv[-1]))
|
||||
print(highlighted)
|
||||
with open(sys.argv[-1]) as f:
|
||||
highlighted = highlight_data(f.read(), f.name, defaults.syntax_aliases)
|
||||
if highlighted is None:
|
||||
raise SystemExit('Unknown filetype: {}'.format(sys.argv[-1]))
|
||||
print(highlighted)
|
||||
|
||||
@@ -19,11 +19,10 @@ from typing import (
|
||||
|
||||
from kitty.cli import CONFIG_HELP, parse_args
|
||||
from kitty.cli_stub import DiffCLIOptions
|
||||
from kitty.conf.utils import KittensKeyAction
|
||||
from kitty.conf.utils import KeyAction
|
||||
from kitty.constants import appname
|
||||
from kitty.fast_data_types import wcswidth
|
||||
from kitty.key_encoding import EventType, KeyEvent
|
||||
from kitty.options_stub import DiffOptions
|
||||
from kitty.utils import ScreenSize
|
||||
|
||||
from ..tui.handler import Handler
|
||||
@@ -33,10 +32,11 @@ from ..tui.loop import Loop
|
||||
from ..tui.operations import styled
|
||||
from . import global_data
|
||||
from .collect import (
|
||||
Collection, create_collection, data_for_path, lines_for_path, sanitize,
|
||||
set_highlight_data, add_remote_dir
|
||||
Collection, add_remote_dir, create_collection, data_for_path,
|
||||
lines_for_path, sanitize, set_highlight_data
|
||||
)
|
||||
from .config import init_config
|
||||
from .options.types import Options as DiffOptions
|
||||
from .patch import Differ, Patch, set_diff_command, worker_processes
|
||||
from .render import (
|
||||
ImagePlacement, ImageSupportWarning, Line, LineRef, Reference, render_diff
|
||||
@@ -95,14 +95,14 @@ class DiffHandler(Handler):
|
||||
for key_def, action in self.opts.key_definitions.items():
|
||||
self.add_shortcut(action, key_def)
|
||||
|
||||
def perform_action(self, action: KittensKeyAction) -> None:
|
||||
def perform_action(self, action: KeyAction) -> None:
|
||||
func, args = action
|
||||
if func == 'quit':
|
||||
self.quit_loop(0)
|
||||
return
|
||||
if self.state <= DIFFED:
|
||||
if func == 'scroll_by':
|
||||
return self.scroll_lines(int(args[0]))
|
||||
return self.scroll_lines(int(args[0] or 0))
|
||||
if func == 'scroll_to':
|
||||
where = str(args[0])
|
||||
if 'change' in where:
|
||||
@@ -122,7 +122,7 @@ class DiffHandler(Handler):
|
||||
elif to == 'default':
|
||||
new_ctx = self.original_context_count
|
||||
else:
|
||||
new_ctx += int(to)
|
||||
new_ctx += int(to or 0)
|
||||
return self.change_context_count(new_ctx)
|
||||
if func == 'start_search':
|
||||
self.start_search(bool(args[0]), bool(args[1]))
|
||||
@@ -658,5 +658,5 @@ elif __name__ == '__doc__':
|
||||
cd['options'] = OPTIONS
|
||||
cd['help_text'] = help_text
|
||||
elif __name__ == '__conf__':
|
||||
from .config_data import all_options
|
||||
sys.all_options = all_options # type: ignore
|
||||
from .options.definition import definition
|
||||
sys.options_definition = definition # type: ignore
|
||||
|
||||
247
kittens/diff/options/definition.py
Normal file
247
kittens/diff/options/definition.py
Normal file
@@ -0,0 +1,247 @@
|
||||
#!/usr/bin/env python
|
||||
# vim:fileencoding=utf-8
|
||||
# License: GPLv3 Copyright: 2021, Kovid Goyal <kovid at kovidgoyal.net>
|
||||
|
||||
# After editing this file run ./gen-config.py to apply the changes
|
||||
|
||||
from kitty.conf.types import Action, Definition
|
||||
|
||||
|
||||
definition = Definition(
|
||||
'kittens.diff',
|
||||
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
|
||||
mma = definition.add_mouse_map
|
||||
|
||||
# diff {{{
|
||||
agr('diff', 'Diffing')
|
||||
|
||||
opt('syntax_aliases', 'pyj:py pyi:py recipe:py',
|
||||
option_type='syntax_aliases',
|
||||
long_text='''
|
||||
File extension aliases for syntax highlight For example, to syntax highlight
|
||||
:file:`file.xyz` as :file:`file.abc` use a setting of :code:`xyz:abc`
|
||||
'''
|
||||
)
|
||||
|
||||
opt('num_context_lines', '3',
|
||||
option_type='positive_int',
|
||||
long_text='The number of lines of context to show around each change.'
|
||||
)
|
||||
|
||||
opt('diff_cmd', 'auto',
|
||||
long_text='''
|
||||
The diff command to use. Must contain the placeholder :code:`_CONTEXT_` which
|
||||
will be replaced by the number of lines of context. The default is to search the
|
||||
system for either git or diff and use that, if found.
|
||||
'''
|
||||
)
|
||||
|
||||
opt('replace_tab_by', '\\x20\\x20\\x20\\x20',
|
||||
option_type='python_string',
|
||||
long_text='The string to replace tabs with. Default is to use four spaces.'
|
||||
)
|
||||
egr() # }}}
|
||||
|
||||
# colors {{{
|
||||
agr('colors', 'Colors')
|
||||
|
||||
opt('pygments_style', 'default',
|
||||
long_text='''
|
||||
The pygments color scheme to use for syntax highlighting. See :link:`pygments
|
||||
colors schemes <https://help.farbox.com/pygments.html>` for a list of schemes.
|
||||
'''
|
||||
)
|
||||
|
||||
opt('foreground', 'black',
|
||||
option_type='to_color',
|
||||
long_text='Basic colors'
|
||||
)
|
||||
|
||||
opt('background', 'white',
|
||||
option_type='to_color',
|
||||
)
|
||||
|
||||
opt('title_fg', 'black',
|
||||
option_type='to_color',
|
||||
long_text='Title colors'
|
||||
)
|
||||
|
||||
opt('title_bg', 'white',
|
||||
option_type='to_color',
|
||||
)
|
||||
|
||||
opt('margin_bg', '#fafbfc',
|
||||
option_type='to_color',
|
||||
long_text='Margin colors'
|
||||
)
|
||||
|
||||
opt('margin_fg', '#aaaaaa',
|
||||
option_type='to_color',
|
||||
)
|
||||
|
||||
opt('removed_bg', '#ffeef0',
|
||||
option_type='to_color',
|
||||
long_text='Removed text backgrounds'
|
||||
)
|
||||
|
||||
opt('highlight_removed_bg', '#fdb8c0',
|
||||
option_type='to_color',
|
||||
)
|
||||
|
||||
opt('removed_margin_bg', '#ffdce0',
|
||||
option_type='to_color',
|
||||
)
|
||||
|
||||
opt('added_bg', '#e6ffed',
|
||||
option_type='to_color',
|
||||
long_text='Added text backgrounds'
|
||||
)
|
||||
|
||||
opt('highlight_added_bg', '#acf2bd',
|
||||
option_type='to_color',
|
||||
)
|
||||
|
||||
opt('added_margin_bg', '#cdffd8',
|
||||
option_type='to_color',
|
||||
)
|
||||
|
||||
opt('filler_bg', '#fafbfc',
|
||||
option_type='to_color',
|
||||
long_text='Filler (empty) line background'
|
||||
)
|
||||
|
||||
opt('margin_filler_bg', 'none',
|
||||
option_type='to_color_or_none',
|
||||
long_text='Filler (empty) line background in margins, defaults to the filler background'
|
||||
)
|
||||
|
||||
opt('hunk_margin_bg', '#dbedff',
|
||||
option_type='to_color',
|
||||
long_text='Hunk header colors'
|
||||
)
|
||||
|
||||
opt('hunk_bg', '#f1f8ff',
|
||||
option_type='to_color',
|
||||
)
|
||||
|
||||
opt('search_bg', '#444',
|
||||
option_type='to_color',
|
||||
long_text='Highlighting'
|
||||
)
|
||||
|
||||
opt('search_fg', 'white',
|
||||
option_type='to_color',
|
||||
)
|
||||
|
||||
opt('select_bg', '#b4d5fe',
|
||||
option_type='to_color',
|
||||
)
|
||||
|
||||
opt('select_fg', 'black',
|
||||
option_type='to_color_or_none',
|
||||
)
|
||||
egr() # }}}
|
||||
|
||||
# shortcuts {{{
|
||||
agr('shortcuts', 'Keyboard shortcuts')
|
||||
|
||||
map('Quit',
|
||||
'quit q quit',
|
||||
)
|
||||
map('Quit',
|
||||
'quit esc quit',
|
||||
)
|
||||
|
||||
map('Scroll down',
|
||||
'scroll_down j scroll_by 1',
|
||||
)
|
||||
map('Scroll down',
|
||||
'scroll_down down scroll_by 1',
|
||||
)
|
||||
|
||||
map('Scroll up',
|
||||
'scroll_up k scroll_by -1',
|
||||
)
|
||||
map('Scroll up',
|
||||
'scroll_up up scroll_by -1',
|
||||
)
|
||||
|
||||
map('Scroll to top',
|
||||
'scroll_top home scroll_to start',
|
||||
)
|
||||
|
||||
map('Scroll to bottom',
|
||||
'scroll_bottom end scroll_to end',
|
||||
)
|
||||
|
||||
map('Scroll to next page',
|
||||
'scroll_page_down page_down scroll_to next-page',
|
||||
)
|
||||
map('Scroll to next page',
|
||||
'scroll_page_down space scroll_to next-page',
|
||||
)
|
||||
|
||||
map('Scroll to previous page',
|
||||
'scroll_page_up page_up scroll_to prev-page',
|
||||
)
|
||||
|
||||
map('Scroll to next change',
|
||||
'next_change n scroll_to next-change',
|
||||
)
|
||||
|
||||
map('Scroll to previous change',
|
||||
'prev_change p scroll_to prev-change',
|
||||
)
|
||||
|
||||
map('Show all context',
|
||||
'all_context a change_context all',
|
||||
)
|
||||
|
||||
map('Show default context',
|
||||
'default_context = change_context default',
|
||||
)
|
||||
|
||||
map('Increase context',
|
||||
'increase_context + change_context 5',
|
||||
)
|
||||
|
||||
map('Decrease context',
|
||||
'decrease_context - change_context -5',
|
||||
)
|
||||
|
||||
map('Search forward',
|
||||
'search_forward / start_search regex forward',
|
||||
)
|
||||
|
||||
map('Search backward',
|
||||
'search_backward ? start_search regex backward',
|
||||
)
|
||||
|
||||
map('Scroll to next search match',
|
||||
'next_match . scroll_to next-match',
|
||||
)
|
||||
map('Scroll to next search match',
|
||||
'next_match > scroll_to next-match',
|
||||
)
|
||||
|
||||
map('Scroll to previous search match',
|
||||
'prev_match , scroll_to prev-match',
|
||||
)
|
||||
map('Scroll to previous search match',
|
||||
'prev_match < scroll_to prev-match',
|
||||
)
|
||||
|
||||
map('Search forward (no regex)',
|
||||
'search_forward_simple f start_search substring forward',
|
||||
)
|
||||
|
||||
map('Search backward (no regex)',
|
||||
'search_backward_simple b start_search substring backward',
|
||||
)
|
||||
egr() # }}}
|
||||
120
kittens/diff/options/parse.py
generated
Normal file
120
kittens/diff/options/parse.py
generated
Normal file
@@ -0,0 +1,120 @@
|
||||
# generated by gen-config.py DO NOT edit
|
||||
# vim:fileencoding=utf-8
|
||||
|
||||
import typing
|
||||
from kittens.diff.options.utils import parse_map, syntax_aliases
|
||||
from kitty.conf.utils import merge_dicts, positive_int, python_string, to_color, to_color_or_none
|
||||
|
||||
|
||||
class Parser:
|
||||
|
||||
def added_bg(self, val: str, ans: typing.Dict[str, typing.Any]) -> None:
|
||||
ans['added_bg'] = to_color(val)
|
||||
|
||||
def added_margin_bg(self, val: str, ans: typing.Dict[str, typing.Any]) -> None:
|
||||
ans['added_margin_bg'] = to_color(val)
|
||||
|
||||
def background(self, val: str, ans: typing.Dict[str, typing.Any]) -> None:
|
||||
ans['background'] = to_color(val)
|
||||
|
||||
def diff_cmd(self, val: str, ans: typing.Dict[str, typing.Any]) -> None:
|
||||
ans['diff_cmd'] = str(val)
|
||||
|
||||
def filler_bg(self, val: str, ans: typing.Dict[str, typing.Any]) -> None:
|
||||
ans['filler_bg'] = to_color(val)
|
||||
|
||||
def foreground(self, val: str, ans: typing.Dict[str, typing.Any]) -> None:
|
||||
ans['foreground'] = to_color(val)
|
||||
|
||||
def highlight_added_bg(self, val: str, ans: typing.Dict[str, typing.Any]) -> None:
|
||||
ans['highlight_added_bg'] = to_color(val)
|
||||
|
||||
def highlight_removed_bg(self, val: str, ans: typing.Dict[str, typing.Any]) -> None:
|
||||
ans['highlight_removed_bg'] = to_color(val)
|
||||
|
||||
def hunk_bg(self, val: str, ans: typing.Dict[str, typing.Any]) -> None:
|
||||
ans['hunk_bg'] = to_color(val)
|
||||
|
||||
def hunk_margin_bg(self, val: str, ans: typing.Dict[str, typing.Any]) -> None:
|
||||
ans['hunk_margin_bg'] = to_color(val)
|
||||
|
||||
def margin_bg(self, val: str, ans: typing.Dict[str, typing.Any]) -> None:
|
||||
ans['margin_bg'] = to_color(val)
|
||||
|
||||
def margin_fg(self, val: str, ans: typing.Dict[str, typing.Any]) -> None:
|
||||
ans['margin_fg'] = to_color(val)
|
||||
|
||||
def margin_filler_bg(self, val: str, ans: typing.Dict[str, typing.Any]) -> None:
|
||||
ans['margin_filler_bg'] = to_color_or_none(val)
|
||||
|
||||
def num_context_lines(self, val: str, ans: typing.Dict[str, typing.Any]) -> None:
|
||||
ans['num_context_lines'] = positive_int(val)
|
||||
|
||||
def pygments_style(self, val: str, ans: typing.Dict[str, typing.Any]) -> None:
|
||||
ans['pygments_style'] = str(val)
|
||||
|
||||
def removed_bg(self, val: str, ans: typing.Dict[str, typing.Any]) -> None:
|
||||
ans['removed_bg'] = to_color(val)
|
||||
|
||||
def removed_margin_bg(self, val: str, ans: typing.Dict[str, typing.Any]) -> None:
|
||||
ans['removed_margin_bg'] = to_color(val)
|
||||
|
||||
def replace_tab_by(self, val: str, ans: typing.Dict[str, typing.Any]) -> None:
|
||||
ans['replace_tab_by'] = python_string(val)
|
||||
|
||||
def search_bg(self, val: str, ans: typing.Dict[str, typing.Any]) -> None:
|
||||
ans['search_bg'] = to_color(val)
|
||||
|
||||
def search_fg(self, val: str, ans: typing.Dict[str, typing.Any]) -> None:
|
||||
ans['search_fg'] = to_color(val)
|
||||
|
||||
def select_bg(self, val: str, ans: typing.Dict[str, typing.Any]) -> None:
|
||||
ans['select_bg'] = to_color(val)
|
||||
|
||||
def select_fg(self, val: str, ans: typing.Dict[str, typing.Any]) -> None:
|
||||
ans['select_fg'] = to_color_or_none(val)
|
||||
|
||||
def syntax_aliases(self, val: str, ans: typing.Dict[str, typing.Any]) -> None:
|
||||
ans['syntax_aliases'] = syntax_aliases(val)
|
||||
|
||||
def title_bg(self, val: str, ans: typing.Dict[str, typing.Any]) -> None:
|
||||
ans['title_bg'] = to_color(val)
|
||||
|
||||
def title_fg(self, val: str, ans: typing.Dict[str, typing.Any]) -> None:
|
||||
ans['title_fg'] = to_color(val)
|
||||
|
||||
def map(self, val: str, ans: typing.Dict[str, typing.Any]) -> None:
|
||||
for k in parse_map(val):
|
||||
ans['map'].append(k)
|
||||
|
||||
|
||||
def create_result_dict() -> typing.Dict[str, typing.Any]:
|
||||
return {
|
||||
'map': [],
|
||||
}
|
||||
|
||||
|
||||
actions = frozenset(('map',))
|
||||
|
||||
|
||||
def merge_result_dicts(defaults: typing.Dict[str, typing.Any], vals: typing.Dict[str, typing.Any]) -> typing.Dict[str, typing.Any]:
|
||||
ans = {}
|
||||
for k, v in defaults.items():
|
||||
if isinstance(v, dict):
|
||||
ans[k] = merge_dicts(v, vals.get(k, {}))
|
||||
elif k in actions:
|
||||
ans[k] = v + vals.get(k, [])
|
||||
else:
|
||||
ans[k] = vals.get(k, v)
|
||||
return ans
|
||||
|
||||
|
||||
parser = Parser()
|
||||
|
||||
|
||||
def parse_conf_item(key: str, val: str, ans: typing.Dict[str, typing.Any]) -> bool:
|
||||
func = getattr(parser, key, None)
|
||||
if func is not None:
|
||||
func(val, ans)
|
||||
return True
|
||||
return False
|
||||
168
kittens/diff/options/types.py
generated
Normal file
168
kittens/diff/options/types.py
generated
Normal file
@@ -0,0 +1,168 @@
|
||||
# generated by gen-config.py DO NOT edit
|
||||
# vim:fileencoding=utf-8
|
||||
|
||||
import typing
|
||||
from kitty.conf.utils import KeyAction, KittensKeyMap
|
||||
import kitty.conf.utils
|
||||
from kitty.rgb import Color
|
||||
import kitty.rgb
|
||||
from kitty.types import ParsedShortcut
|
||||
import kitty.types
|
||||
|
||||
|
||||
option_names = ( # {{{
|
||||
'added_bg',
|
||||
'added_margin_bg',
|
||||
'background',
|
||||
'diff_cmd',
|
||||
'filler_bg',
|
||||
'foreground',
|
||||
'highlight_added_bg',
|
||||
'highlight_removed_bg',
|
||||
'hunk_bg',
|
||||
'hunk_margin_bg',
|
||||
'map',
|
||||
'margin_bg',
|
||||
'margin_fg',
|
||||
'margin_filler_bg',
|
||||
'num_context_lines',
|
||||
'pygments_style',
|
||||
'removed_bg',
|
||||
'removed_margin_bg',
|
||||
'replace_tab_by',
|
||||
'search_bg',
|
||||
'search_fg',
|
||||
'select_bg',
|
||||
'select_fg',
|
||||
'syntax_aliases',
|
||||
'title_bg',
|
||||
'title_fg') # }}}
|
||||
|
||||
|
||||
class Options:
|
||||
added_bg: Color = Color(red=230, green=255, blue=237)
|
||||
added_margin_bg: Color = Color(red=205, green=255, blue=216)
|
||||
background: Color = Color(red=255, green=255, blue=255)
|
||||
diff_cmd: str = 'auto'
|
||||
filler_bg: Color = Color(red=250, green=251, blue=252)
|
||||
foreground: Color = Color(red=0, green=0, blue=0)
|
||||
highlight_added_bg: Color = Color(red=172, green=242, blue=189)
|
||||
highlight_removed_bg: Color = Color(red=253, green=184, blue=192)
|
||||
hunk_bg: Color = Color(red=241, green=248, blue=255)
|
||||
hunk_margin_bg: Color = Color(red=219, green=237, blue=255)
|
||||
margin_bg: Color = Color(red=250, green=251, blue=252)
|
||||
margin_fg: Color = Color(red=170, green=170, blue=170)
|
||||
margin_filler_bg: typing.Optional[kitty.rgb.Color] = None
|
||||
num_context_lines: int = 3
|
||||
pygments_style: str = 'default'
|
||||
removed_bg: Color = Color(red=255, green=238, blue=240)
|
||||
removed_margin_bg: Color = Color(red=255, green=220, blue=224)
|
||||
replace_tab_by: str = ' '
|
||||
search_bg: Color = Color(red=68, green=68, blue=68)
|
||||
search_fg: Color = Color(red=255, green=255, blue=255)
|
||||
select_bg: Color = Color(red=180, green=213, blue=254)
|
||||
select_fg: typing.Optional[kitty.rgb.Color] = Color(red=0, green=0, blue=0)
|
||||
syntax_aliases: typing.Dict[str, str] = {'pyj': 'py', 'pyi': 'py', 'recipe': 'py'}
|
||||
title_bg: Color = Color(red=255, green=255, blue=255)
|
||||
title_fg: Color = Color(red=0, green=0, blue=0)
|
||||
map: typing.List[typing.Tuple[kitty.types.ParsedShortcut, kitty.conf.utils.KeyAction]] = []
|
||||
key_definitions: KittensKeyMap = {}
|
||||
config_paths: typing.Tuple[str, ...] = ()
|
||||
config_overrides: typing.Tuple[str, ...] = ()
|
||||
|
||||
def __init__(self, options_dict: typing.Optional[typing.Dict[str, typing.Any]] = None) -> None:
|
||||
if options_dict is not None:
|
||||
for key in option_names:
|
||||
setattr(self, key, options_dict[key])
|
||||
|
||||
@property
|
||||
def _fields(self) -> typing.Tuple[str, ...]:
|
||||
return option_names
|
||||
|
||||
def __iter__(self) -> typing.Iterator[str]:
|
||||
return iter(self._fields)
|
||||
|
||||
def __len__(self) -> int:
|
||||
return len(self._fields)
|
||||
|
||||
def _copy_of_val(self, name: str) -> typing.Any:
|
||||
ans = getattr(self, name)
|
||||
if isinstance(ans, dict):
|
||||
ans = ans.copy()
|
||||
elif isinstance(ans, list):
|
||||
ans = ans[:]
|
||||
return ans
|
||||
|
||||
def _asdict(self) -> typing.Dict[str, typing.Any]:
|
||||
return {k: self._copy_of_val(k) for k in self}
|
||||
|
||||
def _replace(self, **kw: typing.Any) -> "Options":
|
||||
ans = Options()
|
||||
for name in self:
|
||||
setattr(ans, name, self._copy_of_val(name))
|
||||
for name, val in kw.items():
|
||||
setattr(ans, name, val)
|
||||
return ans
|
||||
|
||||
def __getitem__(self, key: typing.Union[int, str]) -> typing.Any:
|
||||
k = option_names[key] if isinstance(key, int) else key
|
||||
try:
|
||||
return getattr(self, k)
|
||||
except AttributeError:
|
||||
pass
|
||||
raise KeyError(f"No option named: {k}")
|
||||
|
||||
|
||||
defaults = Options()
|
||||
defaults.map = [
|
||||
# quit
|
||||
(ParsedShortcut(mods=0, key_name='q'), KeyAction('quit')),
|
||||
# quit
|
||||
(ParsedShortcut(mods=0, key_name='ESCAPE'), KeyAction('quit')),
|
||||
# scroll_down
|
||||
(ParsedShortcut(mods=0, key_name='j'), KeyAction('scroll_by', (1,))),
|
||||
# scroll_down
|
||||
(ParsedShortcut(mods=0, key_name='DOWN'), KeyAction('scroll_by', (1,))),
|
||||
# scroll_up
|
||||
(ParsedShortcut(mods=0, key_name='k'), KeyAction('scroll_by', (-1,))),
|
||||
# scroll_up
|
||||
(ParsedShortcut(mods=0, key_name='UP'), KeyAction('scroll_by', (-1,))),
|
||||
# scroll_top
|
||||
(ParsedShortcut(mods=0, key_name='HOME'), KeyAction('scroll_to', ('start',))),
|
||||
# scroll_bottom
|
||||
(ParsedShortcut(mods=0, key_name='END'), KeyAction('scroll_to', ('end',))),
|
||||
# scroll_page_down
|
||||
(ParsedShortcut(mods=0, key_name='PAGE_DOWN'), KeyAction('scroll_to', ('next-page',))),
|
||||
# scroll_page_down
|
||||
(ParsedShortcut(mods=0, key_name=' '), KeyAction('scroll_to', ('next-page',))),
|
||||
# scroll_page_up
|
||||
(ParsedShortcut(mods=0, key_name='PAGE_UP'), KeyAction('scroll_to', ('prev-page',))),
|
||||
# next_change
|
||||
(ParsedShortcut(mods=0, key_name='n'), KeyAction('scroll_to', ('next-change',))),
|
||||
# prev_change
|
||||
(ParsedShortcut(mods=0, key_name='p'), KeyAction('scroll_to', ('prev-change',))),
|
||||
# all_context
|
||||
(ParsedShortcut(mods=0, key_name='a'), KeyAction('change_context', ('all',))),
|
||||
# default_context
|
||||
(ParsedShortcut(mods=0, key_name='='), KeyAction('change_context', ('default',))),
|
||||
# increase_context
|
||||
(ParsedShortcut(mods=0, key_name='+'), KeyAction('change_context', (5,))),
|
||||
# decrease_context
|
||||
(ParsedShortcut(mods=0, key_name='-'), KeyAction('change_context', (-5,))),
|
||||
# search_forward
|
||||
(ParsedShortcut(mods=0, key_name='/'), KeyAction('start_search', (True, False))),
|
||||
# search_backward
|
||||
(ParsedShortcut(mods=0, key_name='?'), KeyAction('start_search', (True, True))),
|
||||
# next_match
|
||||
(ParsedShortcut(mods=0, key_name='.'), KeyAction('scroll_to', ('next-match',))),
|
||||
# next_match
|
||||
(ParsedShortcut(mods=0, key_name='>'), KeyAction('scroll_to', ('next-match',))),
|
||||
# prev_match
|
||||
(ParsedShortcut(mods=0, key_name=','), KeyAction('scroll_to', ('prev-match',))),
|
||||
# prev_match
|
||||
(ParsedShortcut(mods=0, key_name='<'), KeyAction('scroll_to', ('prev-match',))),
|
||||
# search_forward_simple
|
||||
(ParsedShortcut(mods=0, key_name='f'), KeyAction('start_search', (False, False))),
|
||||
# search_backward_simple
|
||||
(ParsedShortcut(mods=0, key_name='b'), KeyAction('start_search', (False, True))),
|
||||
]
|
||||
62
kittens/diff/options/utils.py
Normal file
62
kittens/diff/options/utils.py
Normal file
@@ -0,0 +1,62 @@
|
||||
#!/usr/bin/env python
|
||||
# vim:fileencoding=utf-8
|
||||
# License: GPLv3 Copyright: 2021, Kovid Goyal <kovid at kovidgoyal.net>
|
||||
|
||||
|
||||
from typing import Any, Dict, Iterable, Sequence, Tuple, Union
|
||||
|
||||
from kitty.conf.utils import KittensKeyDefinition, key_func, parse_kittens_key
|
||||
|
||||
func_with_args, args_funcs = key_func()
|
||||
FuncArgsType = Tuple[str, Sequence[Any]]
|
||||
|
||||
|
||||
@func_with_args('scroll_by')
|
||||
def parse_scroll_by(func: str, rest: str) -> Tuple[str, int]:
|
||||
try:
|
||||
return func, int(rest)
|
||||
except Exception:
|
||||
return func, 1
|
||||
|
||||
|
||||
@func_with_args('scroll_to')
|
||||
def parse_scroll_to(func: str, rest: str) -> Tuple[str, str]:
|
||||
rest = rest.lower()
|
||||
if rest not in {'start', 'end', 'next-change', 'prev-change', 'next-page', 'prev-page', 'next-match', 'prev-match'}:
|
||||
rest = 'start'
|
||||
return func, rest
|
||||
|
||||
|
||||
@func_with_args('change_context')
|
||||
def parse_change_context(func: str, rest: str) -> Tuple[str, Union[int, str]]:
|
||||
rest = rest.lower()
|
||||
if rest in {'all', 'default'}:
|
||||
return func, rest
|
||||
try:
|
||||
amount = int(rest)
|
||||
except Exception:
|
||||
amount = 5
|
||||
return func, amount
|
||||
|
||||
|
||||
@func_with_args('start_search')
|
||||
def parse_start_search(func: str, rest: str) -> Tuple[str, Tuple[bool, bool]]:
|
||||
rest_ = rest.lower().split()
|
||||
is_regex = bool(rest_ and rest_[0] == 'regex')
|
||||
is_backward = bool(len(rest_) > 1 and rest_[1] == 'backward')
|
||||
return func, (is_regex, is_backward)
|
||||
|
||||
|
||||
def syntax_aliases(raw: str) -> Dict[str, str]:
|
||||
ans = {}
|
||||
for x in raw.split():
|
||||
a, b = x.partition(':')[::2]
|
||||
if a and b:
|
||||
ans[a.lower()] = b
|
||||
return ans
|
||||
|
||||
|
||||
def parse_map(val: str) -> Iterable[KittensKeyDefinition]:
|
||||
x = parse_kittens_key(val, args_funcs)
|
||||
if x is not None:
|
||||
yield x
|
||||
@@ -6,7 +6,7 @@ import re
|
||||
from typing import TYPE_CHECKING, Callable, Dict, Iterable, List, Tuple
|
||||
|
||||
from kitty.fast_data_types import wcswidth
|
||||
from kitty.options_stub import DiffOptions
|
||||
from .options.types import Options as DiffOptions
|
||||
|
||||
from ..tui.operations import styled
|
||||
|
||||
|
||||
@@ -71,28 +71,48 @@ next_segment(SegmentPointer *s, PyObject *highlights) {
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
insert_code(PyObject *code, Py_UCS4 *buf, size_t bufsz, unsigned int *buf_pos) {
|
||||
unsigned int csz = PyUnicode_GET_LENGTH(code);
|
||||
if (*buf_pos + csz >= bufsz) return false;
|
||||
for (unsigned int s = 0; s < csz; s++) buf[(*buf_pos)++] = PyUnicode_READ(PyUnicode_KIND(code), PyUnicode_DATA(code), s);
|
||||
typedef struct LineBuffer {
|
||||
Py_UCS4 *buf;
|
||||
size_t pos, capacity;
|
||||
} LineBuffer;
|
||||
|
||||
|
||||
static bool
|
||||
ensure_space(LineBuffer *b, size_t num) {
|
||||
if (b->pos + num >= b->capacity) {
|
||||
size_t new_cap = MAX(b->capacity * 2, 4096u);
|
||||
new_cap = MAX(b->pos + num + 1024u, new_cap);
|
||||
b->buf = realloc(b->buf, new_cap * sizeof(b->buf[0]));
|
||||
if (!b->buf) { PyErr_NoMemory(); return false; }
|
||||
b->capacity = new_cap;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
add_line(Segment *bg_segment, Segment *fg_segment, Py_UCS4 *buf, size_t bufsz, unsigned int *buf_pos, PyObject *ans) {
|
||||
bool bg_is_active = bg_segment->current_pos == bg_segment->end_pos, fg_is_active = fg_segment->current_pos == fg_segment->end_pos;
|
||||
if (bg_is_active) { if(!insert_code(bg_segment->end_code, buf, bufsz, buf_pos)) return false; }
|
||||
if (fg_is_active) { if(!insert_code(fg_segment->end_code, buf, bufsz, buf_pos)) return false; }
|
||||
PyObject *wl = PyUnicode_FromKindAndData(PyUnicode_4BYTE_KIND, buf, *buf_pos);
|
||||
if (!wl) return false;
|
||||
int ret = PyList_Append(ans, wl); Py_DECREF(wl); if (ret != 0) return false;
|
||||
*buf_pos = 0;
|
||||
if (bg_is_active) { if(!insert_code(bg_segment->start_code, buf, bufsz, buf_pos)) return false; }
|
||||
if (fg_is_active) { if(!insert_code(fg_segment->start_code, buf, bufsz, buf_pos)) return false; }
|
||||
insert_code(PyObject *code, LineBuffer *b) {
|
||||
unsigned int csz = PyUnicode_GET_LENGTH(code);
|
||||
if (!ensure_space(b, csz)) return false;
|
||||
for (unsigned int s = 0; s < csz; s++) b->buf[b->pos++] = PyUnicode_READ(PyUnicode_KIND(code), PyUnicode_DATA(code), s);
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
add_line(Segment *bg_segment, Segment *fg_segment, LineBuffer *b, PyObject *ans) {
|
||||
bool bg_is_active = bg_segment->current_pos == bg_segment->end_pos, fg_is_active = fg_segment->current_pos == fg_segment->end_pos;
|
||||
if (bg_is_active) { if(!insert_code(bg_segment->end_code, b)) return false; }
|
||||
if (fg_is_active) { if(!insert_code(fg_segment->end_code, b)) return false; }
|
||||
PyObject *wl = PyUnicode_FromKindAndData(PyUnicode_4BYTE_KIND, b->buf, b->pos);
|
||||
if (!wl) return false;
|
||||
int ret = PyList_Append(ans, wl); Py_DECREF(wl); if (ret != 0) return false;
|
||||
b->pos = 0;
|
||||
if (bg_is_active) { if(!insert_code(bg_segment->start_code, b)) return false; }
|
||||
if (fg_is_active) { if(!insert_code(fg_segment->start_code, b)) return false; }
|
||||
return true;
|
||||
}
|
||||
|
||||
static LineBuffer b;
|
||||
|
||||
static PyObject*
|
||||
split_with_highlights(PyObject *self UNUSED, PyObject *args) {
|
||||
PyObject *line, *truncate_points_py, *fg_highlights, *bg_highlight;
|
||||
@@ -106,19 +126,19 @@ split_with_highlights(PyObject *self UNUSED, PyObject *args) {
|
||||
}
|
||||
SegmentPointer fg_segment = { .sg = EMPTY_SEGMENT, .num = PyList_GET_SIZE(fg_highlights)}, bg_segment = { .sg = EMPTY_SEGMENT };
|
||||
if (bg_highlight != Py_None) { if (!convert_segment(bg_highlight, &bg_segment.sg)) { Py_CLEAR(ans); return NULL; }; bg_segment.num = 1; }
|
||||
#define CHECK_CALL(func, ...) if (!func(__VA_ARGS__)) { Py_CLEAR(ans); if (!PyErr_Occurred()) PyErr_SetString(PyExc_ValueError, "line too long"); return NULL; }
|
||||
#define CHECK_CALL(func, ...) if (!func(__VA_ARGS__)) { Py_CLEAR(ans); if (!PyErr_Occurred()) PyErr_SetString(PyExc_ValueError, "unknown error while processing line"); return NULL; }
|
||||
CHECK_CALL(next_segment, &fg_segment, fg_highlights);
|
||||
|
||||
#define NEXT_TRUNCATE_POINT truncate_point = (truncate_pos < num_truncate_pts) ? truncate_points[truncate_pos++] : UINT_MAX
|
||||
NEXT_TRUNCATE_POINT;
|
||||
|
||||
#define INSERT_CODE(x) { CHECK_CALL(insert_code, x, buf, arraysz(buf), &buf_pos); }
|
||||
#define INSERT_CODE(x) { CHECK_CALL(insert_code, x, &b); }
|
||||
|
||||
#define ADD_LINE CHECK_CALL(add_line, &bg_segment.sg, &fg_segment.sg, buf, arraysz(buf), &buf_pos, ans);
|
||||
#define ADD_LINE CHECK_CALL(add_line, &bg_segment.sg, &fg_segment.sg, &b, ans);
|
||||
|
||||
#define ADD_CHAR(x) { \
|
||||
buf[buf_pos++] = x; \
|
||||
if (buf_pos >= arraysz(buf)) { Py_CLEAR(ans); PyErr_SetString(PyExc_ValueError, "line too long"); return NULL; } \
|
||||
if (!ensure_space(&b, 1)) { Py_CLEAR(ans); return NULL; } \
|
||||
b.buf[b.pos++] = x; \
|
||||
}
|
||||
#define CHECK_SEGMENT(sgp, is_fg) { \
|
||||
if (i == sgp.sg.current_pos) { \
|
||||
@@ -137,15 +157,15 @@ split_with_highlights(PyObject *self UNUSED, PyObject *args) {
|
||||
}
|
||||
|
||||
const unsigned int line_sz = PyUnicode_GET_LENGTH(line);
|
||||
static Py_UCS4 buf[4096];
|
||||
unsigned int i = 0, buf_pos = 0;
|
||||
b.pos = 0;
|
||||
unsigned int i = 0;
|
||||
for (; i < line_sz; i++) {
|
||||
if (i == truncate_point) { ADD_LINE; NEXT_TRUNCATE_POINT; }
|
||||
CHECK_SEGMENT(bg_segment, false);
|
||||
CHECK_SEGMENT(fg_segment, true)
|
||||
ADD_CHAR(PyUnicode_READ(PyUnicode_KIND(line), PyUnicode_DATA(line), i));
|
||||
}
|
||||
if (buf_pos) ADD_LINE;
|
||||
if (b.pos) ADD_LINE;
|
||||
return ans;
|
||||
#undef INSERT_CODE
|
||||
#undef CHECK_SEGMENT
|
||||
@@ -155,6 +175,11 @@ split_with_highlights(PyObject *self UNUSED, PyObject *args) {
|
||||
#undef NEXT_TRUNCATE_POINT
|
||||
}
|
||||
|
||||
static void
|
||||
free_resources(void) {
|
||||
free(b.buf); b.buf = NULL; b.capacity = 0; b.pos = 0;
|
||||
}
|
||||
|
||||
static PyMethodDef module_methods[] = {
|
||||
{"changed_center", (PyCFunction)changed_center, METH_VARARGS, ""},
|
||||
{"split_with_highlights", (PyCFunction)split_with_highlights, METH_VARARGS, ""},
|
||||
@@ -175,5 +200,6 @@ PyInit_diff_speedup(void) {
|
||||
|
||||
m = PyModule_Create(&module);
|
||||
if (m == NULL) return NULL;
|
||||
Py_AtExit(free_resources);
|
||||
return m;
|
||||
}
|
||||
|
||||
@@ -94,6 +94,11 @@ def highlight_mark(m: Mark, text: str, current_input: str, alphabet: str, colors
|
||||
)
|
||||
|
||||
|
||||
def debug(*a: Any, **kw: Any) -> None:
|
||||
from ..tui.loop import debug as d
|
||||
d(*a, **kw)
|
||||
|
||||
|
||||
def render(text: str, current_input: str, all_marks: Sequence[Mark], ignore_mark_indices: Set[int], alphabet: str, colors: Dict[str, str]) -> str:
|
||||
for mark in reversed(all_marks):
|
||||
if mark.index in ignore_mark_indices:
|
||||
@@ -102,8 +107,7 @@ def render(text: str, current_input: str, all_marks: Sequence[Mark], ignore_mark
|
||||
text = text[:mark.start] + mtext + text[mark.end:]
|
||||
|
||||
text = text.replace('\0', '')
|
||||
|
||||
return text.replace('\n', '\r\n').rstrip()
|
||||
return re.sub('[\r\n]', '\r\n', text).rstrip()
|
||||
|
||||
|
||||
class Hints(Handler):
|
||||
@@ -306,7 +310,7 @@ def mark(pattern: str, post_processors: Iterable[PostprocessorFunc], text: str,
|
||||
except InvalidMatch:
|
||||
continue
|
||||
|
||||
mark_text = text[s:e].replace('\n', '').replace('\0', '')
|
||||
mark_text = re.sub('[\r\n\0]', '', text[s:e])
|
||||
yield Mark(idx, s, e, mark_text, groupdict)
|
||||
|
||||
|
||||
@@ -342,12 +346,12 @@ def functions_for(args: HintsCLIOptions) -> Tuple[str, List[PostprocessorFunc]]:
|
||||
)
|
||||
post_processors.append(url)
|
||||
elif args.type == 'path':
|
||||
pattern = r'(?:\S*/\S+)|(?:\S+[.][a-zA-Z0-9]{2,7})'
|
||||
pattern = r'(?:\S*?/[\r\S]+)|(?:\S[\r\S]*\.[a-zA-Z0-9\r]{2,7})'
|
||||
post_processors.extend((brackets, quotes))
|
||||
elif args.type == 'line':
|
||||
pattern = '(?m)^\\s*(.+)[\\s\0]*$'
|
||||
elif args.type == 'hash':
|
||||
pattern = '[0-9a-f]{7,128}'
|
||||
pattern = '[0-9a-f][0-9a-f\r]{6,127}'
|
||||
elif args.type == 'ip':
|
||||
pattern = (
|
||||
# # IPv4 with no validation
|
||||
@@ -370,16 +374,22 @@ def functions_for(args: HintsCLIOptions) -> Tuple[str, List[PostprocessorFunc]]:
|
||||
|
||||
def convert_text(text: str, cols: int) -> str:
|
||||
lines: List[str] = []
|
||||
empty_line = '\0' * cols
|
||||
empty_line = '\0' * cols + '\n'
|
||||
for full_line in text.split('\n'):
|
||||
if full_line:
|
||||
if not full_line.rstrip('\r'): # empty lines
|
||||
lines.extend(repeat(empty_line, len(full_line)))
|
||||
continue
|
||||
appended = False
|
||||
for line in full_line.split('\r'):
|
||||
if line:
|
||||
lines.append(line.ljust(cols, '\0'))
|
||||
return '\n'.join(lines)
|
||||
lines.append('\r')
|
||||
appended = True
|
||||
if appended:
|
||||
lines[-1] = '\n'
|
||||
rstripped = re.sub('[\r\n]+$', '', ''.join(lines))
|
||||
return rstripped
|
||||
|
||||
|
||||
def parse_input(text: str) -> str:
|
||||
|
||||
@@ -1 +1,3 @@
|
||||
url_delimiters = '\x00-\x09\x0b-\x20\x7f-\xa0\xad\u0600-\u0605\u061c\u06dd\u070f\u08e2\u1680\u180e\u2000-\u200f\u2028-\u202f\u205f-\u2064\u2066-\u206f\u3000\ud800-\uf8ff\ufeff\ufff9-\ufffb\U000110bd\U000110cd\U00013430-\U00013438\U0001bca0-\U0001bca3\U0001d173-\U0001d17a\U000e0001\U000e0020-\U000e007f\U000f0000-\U000ffffd\U00100000-\U0010fffd' # noqa
|
||||
# generated by gen-wcwidth.py, do not edit
|
||||
|
||||
url_delimiters = '\x00-\x09\x0b-\x0c\x0e-\x20\x7f-\xa0\xad\u0600-\u0605\u061c\u06dd\u070f\u08e2\u1680\u180e\u2000-\u200f\u2028-\u202f\u205f-\u2064\u2066-\u206f\u3000\ud800-\uf8ff\ufeff\ufff9-\ufffb\U000110bd\U000110cd\U00013430-\U00013438\U0001bca0-\U0001bca3\U0001d173-\U0001d17a\U000e0001\U000e0020-\U000e007f\U000f0000-\U000ffffd\U00100000-\U0010fffd' # noqa
|
||||
@@ -29,7 +29,7 @@ def main() -> None:
|
||||
write: Callable[[bytes], None] = cast(Callable[[bytes], None], sys.stdout.buffer.write)
|
||||
sgr_pat = re.compile(br'\x1b\[.*?m')
|
||||
osc_pat = re.compile(b'\x1b\\].*?\x1b\\\\')
|
||||
num_pat = re.compile(b'^(\\d+):')
|
||||
num_pat = re.compile(br'^(\d+)[:-]')
|
||||
|
||||
in_result: bytes = b''
|
||||
hostname = socket.gethostname().encode('utf-8')
|
||||
@@ -46,6 +46,8 @@ def main() -> None:
|
||||
m = num_pat.match(clean_line)
|
||||
if m is not None:
|
||||
write_hyperlink(write, in_result, line, frag=m.group(1))
|
||||
else:
|
||||
write(line)
|
||||
else:
|
||||
if line.strip():
|
||||
path = quote_from_bytes(os.path.abspath(clean_line)).encode('utf-8')
|
||||
@@ -55,8 +57,9 @@ def main() -> None:
|
||||
write(line)
|
||||
except KeyboardInterrupt:
|
||||
p.send_signal(signal.SIGINT)
|
||||
p.stdout.close()
|
||||
except EOFError:
|
||||
pass
|
||||
finally:
|
||||
p.stdout.close()
|
||||
raise SystemExit(p.wait())
|
||||
|
||||
|
||||
@@ -4,22 +4,27 @@
|
||||
|
||||
import re
|
||||
import sys
|
||||
from binascii import unhexlify, hexlify
|
||||
from binascii import hexlify, unhexlify
|
||||
from contextlib import suppress
|
||||
from typing import Dict, Iterable, List, Type
|
||||
from typing import Dict, Iterable, List, Type, Optional
|
||||
|
||||
from kitty.cli import parse_args
|
||||
from kitty.cli_stub import QueryTerminalCLIOptions
|
||||
from kitty.constants import appname
|
||||
from kitty.utils import TTYIO
|
||||
from kitty.constants import appname, str_version
|
||||
from kitty.options.types import Options
|
||||
from kitty.terminfo import names
|
||||
from kitty.utils import TTYIO
|
||||
|
||||
|
||||
class Query:
|
||||
name: str = ''
|
||||
ans: str = ''
|
||||
query_name: str = ''
|
||||
help_text: str = ''
|
||||
override_query_name: str = ''
|
||||
|
||||
@property
|
||||
def query_name(self) -> str:
|
||||
return self.override_query_name or f'kitty-query-{self.name}'
|
||||
|
||||
def __init__(self) -> None:
|
||||
self.encoded_query_name = hexlify(self.query_name.encode('utf-8')).decode('ascii')
|
||||
@@ -45,6 +50,10 @@ class Query:
|
||||
def output_line(self) -> str:
|
||||
return self.ans
|
||||
|
||||
@staticmethod
|
||||
def get_result(opts: Options) -> str:
|
||||
raise NotImplementedError()
|
||||
|
||||
|
||||
all_queries: Dict[str, Type[Query]] = {}
|
||||
|
||||
@@ -57,22 +66,108 @@ def query(cls: Type[Query]) -> Type[Query]:
|
||||
@query
|
||||
class TerminalName(Query):
|
||||
name: str = 'name'
|
||||
query_name: str = 'TN'
|
||||
override_query_name: str = 'name'
|
||||
help_text: str = f'Terminal name ({names[0]})'
|
||||
|
||||
@staticmethod
|
||||
def get_result(opts: Options) -> str:
|
||||
return appname
|
||||
|
||||
|
||||
@query
|
||||
class TerminalVersion(Query):
|
||||
name: str = 'version'
|
||||
query_name: str = 'kitty-query-version'
|
||||
help_text: str = 'Terminal version, for e.g.: 0.19.2'
|
||||
|
||||
@staticmethod
|
||||
def get_result(opts: Options) -> str:
|
||||
return str_version
|
||||
|
||||
|
||||
@query
|
||||
class AllowHyperlinks(Query):
|
||||
name: str = 'allow_hyperlinks'
|
||||
query_name: str = 'kitty-query-allow_hyperlinks'
|
||||
help_text: str = 'yes, no or ask'
|
||||
help_text: str = 'The :opt:`setting <allow_hyperlinks>` for allowing hyperlinks can be yes, no or ask'
|
||||
|
||||
@staticmethod
|
||||
def get_result(opts: Options) -> str:
|
||||
return 'ask' if opts.allow_hyperlinks == 0b11 else ('yes' if opts.allow_hyperlinks else 'no')
|
||||
|
||||
|
||||
@query
|
||||
class FontFamily(Query):
|
||||
name: str = 'font_family'
|
||||
help_text: str = 'The current font\'s PostScript name'
|
||||
|
||||
@staticmethod
|
||||
def get_result(opts: Options) -> str:
|
||||
from kitty.fast_data_types import current_fonts
|
||||
cf = current_fonts()
|
||||
return str(cf['medium'].display_name())
|
||||
|
||||
|
||||
@query
|
||||
class BoldFont(Query):
|
||||
name: str = 'bold_font'
|
||||
help_text: str = 'The current bold font\'s PostScript name'
|
||||
|
||||
@staticmethod
|
||||
def get_result(opts: Options) -> str:
|
||||
from kitty.fast_data_types import current_fonts
|
||||
cf = current_fonts()
|
||||
return str(cf['bold'].display_name())
|
||||
|
||||
|
||||
@query
|
||||
class ItalicFont(Query):
|
||||
name: str = 'italic_font'
|
||||
help_text: str = 'The current italic font\'s PostScript name'
|
||||
|
||||
@staticmethod
|
||||
def get_result(opts: Options) -> str:
|
||||
from kitty.fast_data_types import current_fonts
|
||||
cf = current_fonts()
|
||||
return str(cf['italic'].display_name())
|
||||
|
||||
|
||||
@query
|
||||
class BiFont(Query):
|
||||
name: str = 'bold_italic_font'
|
||||
help_text: str = 'The current bold-italic font\'s PostScript name'
|
||||
|
||||
@staticmethod
|
||||
def get_result(opts: Options) -> str:
|
||||
from kitty.fast_data_types import current_fonts
|
||||
cf = current_fonts()
|
||||
return str(cf['bi'].display_name())
|
||||
|
||||
|
||||
@query
|
||||
class FontSize(Query):
|
||||
name: str = 'font_size'
|
||||
help_text: str = 'The current overall font size (individual windows can have different per window font sizes)'
|
||||
|
||||
@staticmethod
|
||||
def get_result(opts: Options) -> str:
|
||||
return f'{opts.font_size:g}'
|
||||
|
||||
|
||||
@query
|
||||
class ClipboardControl(Query):
|
||||
name: str = 'clipboard_control'
|
||||
help_text: str = 'The :opt:`setting <clipboard_control>` for allowing reads/writes to/from the clipboard'
|
||||
|
||||
@staticmethod
|
||||
def get_result(opts: Options) -> str:
|
||||
return ' '.join(opts.clipboard_control)
|
||||
|
||||
|
||||
def get_result(name: str) -> Optional[str]:
|
||||
from kitty.fast_data_types import get_options
|
||||
q = all_queries.get(name)
|
||||
if q is None:
|
||||
return None
|
||||
return q.get_result(get_options())
|
||||
|
||||
|
||||
def do_queries(queries: Iterable, cli_opts: QueryTerminalCLIOptions) -> Dict[str, str]:
|
||||
@@ -124,11 +219,12 @@ Note that when calling this from another program, be very
|
||||
careful not to perform any I/O on the terminal device
|
||||
until the kitten exits.
|
||||
|
||||
Available queries are::
|
||||
Available queries are:
|
||||
|
||||
{}
|
||||
'''.format(' ' + '\n '.join(
|
||||
f'{name}: {c.help_text}' for name, c in all_queries.items()))
|
||||
|
||||
'''.format('\n'.join(
|
||||
f'``{name}``\n {c.help_text}\n' for name, c in all_queries.items()))
|
||||
usage = '[query1 query2 ...]'
|
||||
|
||||
|
||||
|
||||
@@ -151,7 +151,7 @@ class ControlMaster:
|
||||
cp = subprocess.run(self.batch_cmd_prefix + [self.conn_data.hostname, 'hostname', '-f'], stdout=subprocess.PIPE,
|
||||
stderr=subprocess.DEVNULL, stdin=subprocess.DEVNULL)
|
||||
if cp.returncode == 0:
|
||||
q = cp.stdout.decode('utf-8').strip()
|
||||
q = tuple(filter(None, cp.stdout.decode('utf-8').strip().splitlines()))[-1]
|
||||
if not hostname_matches(self.cli_opts.hostname or '', q):
|
||||
print(reset_terminal(), end='')
|
||||
print(f'The remote hostname {styled(q, fg="green")} does not match the')
|
||||
@@ -317,7 +317,8 @@ def handle_action(action: str, cli_opts: RemoteFileCLIOptions) -> Result:
|
||||
@result_handler()
|
||||
def handle_result(args: List[str], data: Result, target_window_id: int, boss: BossType) -> None:
|
||||
if data:
|
||||
cmd = command_for_open(boss.opts.open_url_with)
|
||||
from kitty.fast_data_types import get_options
|
||||
cmd = command_for_open(get_options().open_url_with)
|
||||
open_cmd(cmd, data)
|
||||
|
||||
|
||||
|
||||
@@ -74,7 +74,7 @@ class Resize(Handler):
|
||||
if key_event.matches('esc'):
|
||||
self.quit_loop(0)
|
||||
return
|
||||
if key_event.key in ('w', 'n', 't', 's') and key_event.mods == CTRL:
|
||||
if key_event.key in ('w', 'n', 't', 's') and key_event.mods_without_locks == CTRL:
|
||||
self.do_window_resize(is_decrease=key_event.key in 'ns', is_horizontal=key_event.key in 'wn', multiplier=2)
|
||||
|
||||
def on_resize(self, new_size: ScreenSize) -> None:
|
||||
|
||||
@@ -6,16 +6,24 @@
|
||||
import importlib
|
||||
import os
|
||||
import sys
|
||||
from contextlib import contextmanager
|
||||
from functools import partial
|
||||
from typing import Any, Dict, FrozenSet, List
|
||||
from typing import TYPE_CHECKING, Any, Dict, FrozenSet, Generator, List, cast
|
||||
|
||||
from kitty.types import run_once
|
||||
|
||||
aliases = {'url_hints': 'hints'}
|
||||
if TYPE_CHECKING:
|
||||
from kitty.conf.types import Definition
|
||||
else:
|
||||
Definition = object
|
||||
|
||||
|
||||
def resolved_kitten(k: str) -> str:
|
||||
return aliases.get(k, k).replace('-', '_')
|
||||
ans = aliases.get(k, k)
|
||||
head, tail = os.path.split(ans)
|
||||
tail = tail.replace('-', '_')
|
||||
return os.path.join(head, tail)
|
||||
|
||||
|
||||
def path_to_custom_kitten(config_dir: str, kitten: str) -> str:
|
||||
@@ -26,21 +34,29 @@ def path_to_custom_kitten(config_dir: str, kitten: str) -> str:
|
||||
return path
|
||||
|
||||
|
||||
@contextmanager
|
||||
def preserve_sys_path() -> Generator[None, None, None]:
|
||||
orig = sys.path[:]
|
||||
try:
|
||||
yield
|
||||
finally:
|
||||
if sys.path != orig:
|
||||
del sys.path[:]
|
||||
sys.path.extend(orig)
|
||||
|
||||
|
||||
def import_kitten_main_module(config_dir: str, kitten: str) -> Dict[str, Any]:
|
||||
if kitten.endswith('.py'):
|
||||
path_modified = False
|
||||
path = path_to_custom_kitten(config_dir, kitten)
|
||||
if os.path.dirname(path):
|
||||
sys.path.insert(0, os.path.dirname(path))
|
||||
path_modified = True
|
||||
with open(path) as f:
|
||||
src = f.read()
|
||||
code = compile(src, path, 'exec')
|
||||
g = {'__name__': 'kitten'}
|
||||
exec(code, g)
|
||||
hr = g.get('handle_result', lambda *a, **kw: None)
|
||||
if path_modified:
|
||||
del sys.path[0]
|
||||
with preserve_sys_path():
|
||||
path = path_to_custom_kitten(config_dir, kitten)
|
||||
if os.path.dirname(path):
|
||||
sys.path.insert(0, os.path.dirname(path))
|
||||
with open(path) as f:
|
||||
src = f.read()
|
||||
code = compile(src, path, 'exec')
|
||||
g = {'__name__': 'kitten'}
|
||||
exec(code, g)
|
||||
hr = g.get('handle_result', lambda *a, **kw: None)
|
||||
return {'start': g['main'], 'end': hr}
|
||||
|
||||
kitten = resolved_kitten(kitten)
|
||||
@@ -117,7 +133,7 @@ def run_kitten(kitten: str, run_name: str = '__main__') -> None:
|
||||
for kitten in all_kitten_names():
|
||||
print(kitten, file=sys.stderr)
|
||||
raise SystemExit('No kitten named {}'.format(original_kitten_name))
|
||||
m = runpy.run_path(path, init_globals={'sys': sys, 'os': os}, run_name='__run_kitten__') # type: ignore
|
||||
m = runpy.run_path(path, init_globals={'sys': sys, 'os': os}, run_name='__run_kitten__')
|
||||
m['main'](sys.argv)
|
||||
|
||||
|
||||
@@ -151,14 +167,22 @@ def get_kitten_cli_docs(kitten: str) -> Any:
|
||||
return ans
|
||||
|
||||
|
||||
def get_kitten_conf_docs(kitten: str) -> Any:
|
||||
setattr(sys, 'all_options', None)
|
||||
run_kitten(kitten, run_name='__conf__')
|
||||
ans = getattr(sys, 'all_options')
|
||||
delattr(sys, 'all_options')
|
||||
def get_kitten_completer(kitten: str) -> Any:
|
||||
run_kitten(kitten, run_name='__completer__')
|
||||
ans = getattr(sys, 'kitten_completer', None)
|
||||
if ans is not None:
|
||||
delattr(sys, 'kitten_completer')
|
||||
return ans
|
||||
|
||||
|
||||
def get_kitten_conf_docs(kitten: str) -> Definition:
|
||||
setattr(sys, 'options_definition', None)
|
||||
run_kitten(kitten, run_name='__conf__')
|
||||
ans = getattr(sys, 'options_definition')
|
||||
delattr(sys, 'options_definition')
|
||||
return cast(Definition, ans)
|
||||
|
||||
|
||||
def main() -> None:
|
||||
try:
|
||||
args = sys.argv[1:]
|
||||
|
||||
0
kittens/show_key/__init__.py
Normal file
0
kittens/show_key/__init__.py
Normal file
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user