Compare commits

..

1874 Commits

Author SHA1 Message Date
Kovid Goyal
70111d130e version 0.27.0 2023-01-31 10:48:56 +05:30
Kovid Goyal
ce6dacd0d4 Also build 32-bit kitten for Linux 2023-01-31 10:48:56 +05:30
Kovid Goyal
f3c434b7c1 Now that we are releasing 0.27.0 dont need to fetch release version to download latest kitten 2023-01-31 10:48:56 +05:30
Kovid Goyal
54b6344985 Add a note that --spacing is ignored for overlay windows 2023-01-30 12:00:41 +05:30
Kovid Goyal
18fc8dad37 Instead of calling insertText duplicate some of its code so we arent limited in the size of text we can insert 2023-01-29 19:56:53 +05:30
Kovid Goyal
9b5034f904 macOS: Integrate with system services 2023-01-29 19:47:50 +05:30
Kovid Goyal
f2c8819d25 Add an example for displaying a PNG with bash 2023-01-29 10:27:03 +05:30
Kovid Goyal
53482f4c84 Show bad length in base64 decode error message 2023-01-29 10:17:00 +05:30
Kovid Goyal
e1c50cf124 Merge branch 'revert' of https://github.com/page-down/kitty 2023-01-27 21:12:53 +05:30
pagedown
aacb4db2dc Remote control: Improve create-marker error messages
No more missing color errors when text/regex are missing.
Use `mark group` in error messages instead of `color`.
2023-01-27 23:31:06 +08:00
pagedown
8638e42135 Revert "Fix #5937"
This reverts commit 4b322560c3.
Only two arguments are required to create a marker.
2023-01-27 23:15:13 +08:00
Kovid Goyal
4b322560c3 Fix #5937 2023-01-27 15:15:47 +05:30
Kovid Goyal
0a4ad1fe12 Merge branch 'indent' of https://github.com/page-down/kitty 2023-01-27 11:19:54 +05:30
pagedown
907f658fcc ... 2023-01-27 13:40:31 +08:00
pagedown
1e7e10f96f Docs: Fix mixed tab and space indentation in the example code 2023-01-27 13:39:27 +08:00
Kovid Goyal
5338fcdc1e Add a note about why we play with file descriptors 2023-01-26 21:50:10 +05:30
Kovid Goyal
f8991ce3c8 ask kitten: Get readline to work even when stdout is redirected 2023-01-26 21:47:43 +05:30
Kovid Goyal
b408abe304 Move compile_commands.json to build directory 2023-01-26 14:25:22 +05:30
Kovid Goyal
084671b26e Also preread STDIN when using /dev/stdin as the source 2023-01-26 12:57:12 +05:30
Kovid Goyal
1cc69b3edd Move pre-read code into a separate function for clarity 2023-01-26 12:49:21 +05:30
Kovid Goyal
d88105319d clipboard kitten: Allow STDIN to be connected to a program that itself uses the tty directly
Read in STDIN first, and only then start terminal IO, hopefully allowing
the other program to finish its terminal IO before we start.

Fixes #5934
2023-01-26 12:40:08 +05:30
Kovid Goyal
eb50fac8de Add a test for creation of anonymous tempfiles 2023-01-26 11:51:02 +05:30
Kovid Goyal
4185e30d73 Code to more securely create anonymous temp files on Linux 2023-01-26 11:41:01 +05:30
Kovid Goyal
3a126ffa9d Restore permissions check on pwfile
just use RW instead of R as the expected mode
2023-01-26 08:48:35 +05:30
Kovid Goyal
4f5e3f6cf1 Fix ruff invocation in ALE 2023-01-26 08:44:16 +05:30
Kovid Goyal
dd6e206f9b Remove unused import 2023-01-26 08:29:37 +05:30
Kovid Goyal
ea920ffdf9 Merge branch 'master' of https://github.com/schlomie/kitty 2023-01-26 08:21:16 +05:30
Loren Schlomer
366d65f592 Fixes the ssh kitten
kovidgoyal@5e645a7 fixes the password file creation, allowing it to be
unlinked, but read_data_from_shared_memory/1 rejects the shared object
if it is not read only, and will break the ssh kitten for all
platforms.

This change removes the read only check, relying only on the file
ownership check.

This fully fixes #5928

Signed-off-by: Loren Schlomer <me@schlomie.com>
2023-01-25 11:14:12 -08:00
Kovid Goyal
5e645a7be7 Fix ssh kitten not working on FreeBSD
Apparently on FreeBSD one cannot unlink shared mem if it is not created
with write permissions.

Adding IWRITE to the permissions when creating the shared memory is
harmless. It means any process running as the user can either write to
the file or delete it. Deleting was already possible except on FreeBSD.
As for writing, it's needed on FreeBSD for shared memory to be useable
at all, and since processes running as the user can already completely
access all their data, kitty config files, tty pipes, etc. allowing them
to write to the SHM used here doesnt grant any significant new
capability, since they could just write to ssh.conf in the kitty config
folder to get the ssh kitten to do whatever they like.

Fixes #5928
2023-01-25 23:34:31 +05:30
Kovid Goyal
e3040a9c91 Make the various path finding functions thread safe and cache their results 2023-01-25 16:24:27 +05:30
Kovid Goyal
a01d68ed85 ... 2023-01-25 16:12:47 +05:30
Kovid Goyal
f070b17fee Also load ~/.config/kitty/mime.types in Go code 2023-01-25 16:08:12 +05:30
Kovid Goyal
22d562ca41 DRYer 2023-01-25 15:38:23 +05:30
Kovid Goyal
102197fabe Merge branch 'mime-types' of https://github.com/page-down/kitty 2023-01-25 15:28:40 +05:30
pagedown
83f505e209 Update known textual mimes to Python
Also add default aliases for JavaScript and XML in Go.
2023-01-25 16:42:15 +08:00
Kovid Goyal
5a86bc2411 Add default aliases for YAML and TOML 2023-01-25 11:54:09 +05:30
Kovid Goyal
b9c324586e Also recognize a few well known MIME types as being textual 2023-01-24 18:30:46 +05:30
Kovid Goyal
41fb3c79c5 DRYer 2023-01-24 18:26:01 +05:30
Kovid Goyal
5066623089 better fix for file completion in Go
When neither extensions for mime are specified assume we want to match
all files.
2023-01-23 18:01:17 +05:30
Kovid Goyal
8e98b4123e Fix completion for --password-file not completing file names 2023-01-23 17:58:31 +05:30
Kovid Goyal
8f88aab9d2 remove unused code 2023-01-23 17:51:10 +05:30
Kovid Goyal
d8bbb16d5e Make the single instance data type checked 2023-01-23 17:45:11 +05:30
Kovid Goyal
60791bb57b Session files: Expand environment variables 2023-01-23 17:34:53 +05:30
Kovid Goyal
11f98592f7 We still need full keyboard protocol for @ send-text 2023-01-23 16:33:08 +05:30
Kovid Goyal
97467acb1f kitten @ cmd: Dont generate key release events
We dont need them and they sometimes can spill over into the prompt if
the command is very fast.
2023-01-23 16:18:46 +05:30
Kovid Goyal
cc1f0bc3fe Function to drain controlling tty 2023-01-23 16:07:00 +05:30
Kovid Goyal
a009d6b258 kitty shell: Add completion for help and exit commands 2023-01-23 15:34:45 +05:30
Kovid Goyal
0903ae7b4d Do not use prewarming for wrapped kittens 2023-01-23 15:21:04 +05:30
Kovid Goyal
35c1ebd3f9 Merge branch 'fix-open-actions-shell' of https://github.com/page-down/kitty 2023-01-23 14:03:54 +05:30
pagedown
352f940010 Fix SHELL env var in open-actions.conf and launch-actions.conf
Only the executable path is used when expanding `$SHELL`.
Also fix the non-working example `{SHELL}` in the documentation.
2023-01-23 14:15:27 +08:00
Kovid Goyal
1f00c27097 Also create an automatic text/plain alias when reading from clipboard 2023-01-22 22:04:53 +05:30
Kovid Goyal
6b2d37366f Add trailing newline when printing available MIME types 2023-01-22 21:57:17 +05:30
Kovid Goyal
a4075ff041 X11: Fix a crash when listing clipboard MIME types and the clipboard is owned by self
Fixes #5920
2023-01-22 21:19:03 +05:30
Kovid Goyal
7a526d9588 clipboard kitten: When copying, automatically add a text/plain alias if there is at least one text/* MIME and no actual text/plain MIME 2023-01-22 20:41:37 +05:30
Kovid Goyal
5b4e4f032d ask kitten: Output JSON when used standalone 2023-01-22 11:48:51 +05:30
Kovid Goyal
0a1b399447 ... 2023-01-22 08:58:14 +05:30
Kovid Goyal
6a64df1afb Abort show_error kitten if stdin is a tty 2023-01-22 08:48:55 +05:30
Kovid Goyal
dc1851acdb Add some messages to kitten help for kittens that are not meant to be run by end users. 2023-01-22 08:46:29 +05:30
Kovid Goyal
096c1e328e Improve progress printout 2023-01-22 08:41:38 +05:30
Kovid Goyal
1a44c2117b GitHub requires a User-Agent 2023-01-22 08:00:29 +05:30
Kovid Goyal
bd13238d9b Should only return ENOTSUPP if SHM_DIR doesnt exist, not the fil we are trying to open 2023-01-21 17:46:37 +05:30
Kovid Goyal
b1c27d4c2f ... 2023-01-21 17:42:50 +05:30
Kovid Goyal
dc0093cb51 SHM FS: Return a not supported error if SHM_DIR does not exist 2023-01-21 17:40:59 +05:30
Kovid Goyal
b1934ce267 kitten: When guessing MIME types use a builtin list as a fallback, generated from the MIME type definitions available on the build system 2023-01-21 17:35:41 +05:30
Kovid Goyal
16f767de7e Remove unneeded code 2023-01-21 13:20:29 +05:30
Kovid Goyal
93e9332474 Use separate connections for every request to github
GitHub has been flaking out a lot of late with SSL errors when re-using
connections. Also allows us to get rid of the dependency on requests.
2023-01-21 12:56:00 +05:30
Kovid Goyal
81cc09aa61 Increase number of retries when uploading to github as it is getting flakier than ever 2023-01-20 07:11:52 +05:30
Kovid Goyal
e5bc7255b2 ... 2023-01-20 07:07:28 +05:30
Kovid Goyal
75048d56bc ... 2023-01-19 07:54:03 +05:30
Kovid Goyal
19f853c29f Add a note about all the things wrong with modifyOtherKeys 2023-01-18 22:57:56 +05:30
Kovid Goyal
26ca3f9bad Simplify code 2023-01-18 16:16:11 +05:30
Kovid Goyal
bf7d27691c Also add the EINTR fix from previous commit to writing to loop 2023-01-18 16:09:19 +05:30
Kovid Goyal
22532b4805 kitten @: Fix occasional hang until key is pressed while waiting for response from terminal
Fixes #5890
2023-01-18 16:07:42 +05:30
Kovid Goyal
68a006444e Ensure that marking a child for removal works even when the child is still in the queue to be added
Fixes #5895
2023-01-18 15:43:41 +05:30
Kovid Goyal
2d846f53a1 ... 2023-01-18 14:44:40 +05:30
Kovid Goyal
63077e5432 Dont do extremely small reads 2023-01-18 10:13:07 +05:30
Kovid Goyal
5edb1e2d6b micro-optimization 2023-01-18 09:58:29 +05:30
Kovid Goyal
0c7b4df6fc Ensure we are not using iterators when closing 2023-01-18 09:40:31 +05:30
Kovid Goyal
03abbb315a Fix using cursor=none not working on text that has reverse video
Fixes #5897
2023-01-18 09:23:49 +05:30
Kovid Goyal
dc03c14af2 Fix #5896 2023-01-18 08:51:17 +05:30
Kovid Goyal
821f52a748 ... 2023-01-17 12:39:41 +05:30
Kovid Goyal
750f2fa4d0 Use go 1.20 facilities for unsafe string <-> bytes 2023-01-17 12:38:54 +05:30
Kovid Goyal
009fd6418c Fix #5894 2023-01-17 12:05:23 +05:30
Kovid Goyal
ce161e610f ... 2023-01-17 11:52:06 +05:30
Kovid Goyal
b1b9c3704b Merge branch 'patch-2' of https://github.com/eltociear/kitty 2023-01-17 08:38:57 +05:30
Ikko Eltociear Ashimine
fd245e894b Fix typo in overview.rst
specifed -> specified
2023-01-17 12:05:46 +09:00
Kovid Goyal
59170a3627 Add a note to CONTRIBUTING.md about bug management 2023-01-16 17:16:58 +05:30
Kovid Goyal
61143557a9 Re-organize the terminfo FAQ entries into a single one 2023-01-16 16:32:35 +05:30
Kovid Goyal
9a77fdcd04 A new option undercurl_style to control the rendering of undercurls
Fixes #5883
2023-01-16 14:23:10 +05:30
Kovid Goyal
0c8ec3c57b Cleanup previous PR 2023-01-15 13:01:43 +05:30
Jake(Jaehak Song)
b799eba81e Save the overlay when DECTCEM is turned off and restore it when turned on. 2023-01-15 13:01:43 +05:30
Jake(Jaehak Song)
9d1de50bf9 shell.nix: add a missing dependency 'UniformTypeIdentifiers' for macOS 2023-01-15 13:01:43 +05:30
Kovid Goyal
d55a9b582b Use ruff for import sorting 2023-01-15 11:07:10 +05:30
Kovid Goyal
865fc24975 When reporting unused activity in a window, ignore activity that occurs soon after a window resize
Fixes #5881
2023-01-15 09:09:07 +05:30
Kovid Goyal
45b0788f28 Dont rely on existence of sh to report exec failure 2023-01-14 16:03:34 +05:30
Kovid Goyal
bc73273cb3 ... 2023-01-14 15:58:26 +05:30
Kovid Goyal
dd5cfe38b7 Update README 2023-01-14 15:56:03 +05:30
Kovid Goyal
6b8e5ea225 Rename kitty-tool to kitten
It's easier to type, and cuter.

Also, most, if not all of the TUI parts of
kitty's kittens will eventually be re-written into kitten.

The only downside I can see is that we cant tab complete kitty
anymore, but hopefully there will be less reason to run kitty
from the shell as command line tools migrate to kitten.

Meowrrrr!!!
2023-01-14 15:44:52 +05:30
Kovid Goyal
60310ced05 Also build 32-bit ARM kitty-tool for Linux 2023-01-14 11:20:31 +05:30
Kovid Goyal
f61b007645 ... 2023-01-11 11:53:43 +05:30
Kovid Goyal
d4e34a4c31 themes kitten: Nicer error message when no internet connection is present
Fixes #5877
2023-01-11 09:00:58 +05:30
Kovid Goyal
15524ee0fb ... 2023-01-10 19:41:46 +05:30
Kovid Goyal
58a4b4218e ... 2023-01-10 17:35:15 +05:30
Kovid Goyal
ac67d9c72d Allow dumping bytes sent to child for debugging 2023-01-10 15:39:56 +05:30
Kovid Goyal
b9692d480a Allow passing memoryview to paste() 2023-01-10 10:56:03 +05:30
Kovid Goyal
3a2da22509 DRYer 2023-01-10 09:35:15 +05:30
Kovid Goyal
bf8d0c9732 Fix a bug when copying large amounts of text with OSC 52 introduced by the new multi-format clipboard support 2023-01-10 09:29:54 +05:30
Kovid Goyal
836b652f4d Enable checks for unused noqa 2023-01-09 17:28:35 +05:30
Kovid Goyal
69255f7525 broadcast kitten: Allow pressing a key to stop echoing of input into the broadcast window itself 2023-01-09 17:19:35 +05:30
Kovid Goyal
6e41409a3f Dont run isort on generated conf files 2023-01-09 16:51:59 +05:30
Kovid Goyal
7fe5d7b58f Replace isort with ruff 2023-01-09 16:47:42 +05:30
Kovid Goyal
f15d27bb62 Use ruff on CI 2023-01-09 15:55:45 +05:30
Kovid Goyal
a068e3e655 Fix issues reported by ruff 2023-01-09 15:54:41 +05:30
Kovid Goyal
d248d5ad75 Move to pyproject.toml and ruff 2023-01-09 15:49:49 +05:30
Kovid Goyal
44866a6e79 Add sample Go code to get screen size 2023-01-07 15:00:51 +05:30
Kovid Goyal
1fe84f6057 Update icat kitten docs 2023-01-07 14:37:32 +05:30
Kovid Goyal
41207aa830 kitty @ get-colors: Report the current tab bar colors for the active OS window rather than configured values. Fixes #5865 2023-01-07 13:56:36 +05:30
Kovid Goyal
66a2e6f80d ... 2023-01-06 22:06:58 +05:30
Kovid Goyal
397ac36011 Also mention terminal multiplxers can cause graphics to fail 2023-01-06 16:36:39 +05:30
Kovid Goyal
02063a5a6a Make some variables local no need for them to be global 2023-01-06 16:35:17 +05:30
Kovid Goyal
b3926ae9e7 Remove unused code 2023-01-06 16:32:04 +05:30
Kovid Goyal
3743ae50e7 Simplify icat code and write to STDOUT rather than the terminal device
The terminal device is now used only for detection.
2023-01-06 16:16:15 +05:30
Kovid Goyal
2205bf4426 add a comment 2023-01-06 14:42:14 +05:30
Kovid Goyal
def35078d1 ... 2023-01-06 14:26:15 +05:30
Kovid Goyal
1b5fac3189 Cleanup previous PR 2023-01-06 14:25:21 +05:30
Kovid Goyal
dab7f71d2f Merge branch 'master' of https://github.com/TrellixVulnTeam/kitty_864P 2023-01-06 14:17:38 +05:30
TrellixVulnTeam
1223130ef7 Adding tarfile member sanitization to extractall() 2023-01-06 08:07:51 +00:00
Kovid Goyal
4e90ae68a4 ... 2023-01-06 11:33:47 +05:30
Kovid Goyal
e16e3c1582 Clarify the common use case for --config-file-name 2023-01-06 10:42:46 +05:30
Kovid Goyal
ddf36383b4 Dont need to fetch the current version since GitHub provides a redirecting constant download URL 2023-01-05 20:09:32 +05:30
Kovid Goyal
77a3916f6f We need go >= 1.19 2023-01-05 19:41:42 +05:30
Kovid Goyal
5d42d1f955 Remove the old python icat implementation
Keep the python backend code as it is used by the diff kitten to display
image diffs.
2023-01-05 19:34:12 +05:30
Kovid Goyal
a2c68a927e icat: When using --place ensure screen doesnt scroll by leaving cursor at top-left corner of image. 2023-01-05 19:15:13 +05:30
Kovid Goyal
cab7856495 Finish resize handling for the magick engine 2023-01-05 19:15:13 +05:30
Kovid Goyal
c317c934f3 More work on ImageMagick 2023-01-05 19:15:13 +05:30
Kovid Goyal
4d21be9eb5 Port python's shutil.which() 2023-01-05 19:15:13 +05:30
Kovid Goyal
fd71d2035d Start work on rendering with ImageMagick 2023-01-05 19:15:13 +05:30
Kovid Goyal
7ebb281855 Allow controlling num of CPUs for images operations 2023-01-05 19:15:13 +05:30
Kovid Goyal
2d3da1db6d Dont scan all pixels of JPEG images when EXIF rotated to check for opacity 2023-01-05 19:15:13 +05:30
Kovid Goyal
458adf967a Dont use extra memory for mirror operations 2023-01-05 19:15:13 +05:30
Kovid Goyal
eec4c6b802 Dont transmit animation control commands for non-animated images 2023-01-05 19:15:13 +05:30
Kovid Goyal
0b9b207513 Implement scaling for GIF as well 2023-01-05 19:15:13 +05:30
Kovid Goyal
7e8017604e Copy comment explaining min gap and set it to the correct value 2023-01-05 19:15:13 +05:30
Kovid Goyal
520b935cd3 ... 2023-01-05 19:15:12 +05:30
Kovid Goyal
9cb83a6ec2 ... 2023-01-05 19:15:12 +05:30
Kovid Goyal
7c2317d301 Fix divide by zero 2023-01-05 19:15:12 +05:30
Kovid Goyal
7237e5cf9c Get GIF basically working 2023-01-05 19:15:12 +05:30
Kovid Goyal
cd5dab581b DRYer 2023-01-05 19:15:12 +05:30
Kovid Goyal
481cebbd29 Transmission format should be per frame 2023-01-05 19:15:12 +05:30
Kovid Goyal
4623f580b9 Get 24 bit RGB transmission working 2023-01-05 19:15:12 +05:30
Kovid Goyal
6291d0d400 Code to check if an image is Opaque 2023-01-05 19:15:12 +05:30
Kovid Goyal
36d82267bb ... 2023-01-05 19:15:12 +05:30
Kovid Goyal
f9feb4954a Wire up pasting to RGB 2023-01-05 19:15:12 +05:30
Kovid Goyal
d192dcb0d7 Code to convert images to NRGB 2023-01-05 19:15:12 +05:30
Kovid Goyal
143fd6e4dd Start work on transmitting RGB images 2023-01-05 19:15:12 +05:30
Kovid Goyal
df06578c2d Implement --scale-up and --place 2023-01-05 19:15:12 +05:30
Kovid Goyal
73a055fe12 Fix failing test 2023-01-05 19:15:12 +05:30
Kovid Goyal
1fa1a478d9 Get --background working 2023-01-05 19:15:12 +05:30
Kovid Goyal
5a3a547c65 Work on adding support for rendering transforms 2023-01-05 19:15:12 +05:30
Kovid Goyal
373ab95f14 Basic go based rendering 2023-01-05 19:15:11 +05:30
Kovid Goyal
7f866b2b1f Start work on rendering images with Go 2023-01-05 19:15:11 +05:30
Kovid Goyal
24db38ba7e Set data size for SHM transmission as on some platforms the actual SHM size is not equal to the requested size 2023-01-05 19:15:11 +05:30
Kovid Goyal
efdfaaec30 ... 2023-01-05 19:15:11 +05:30
Kovid Goyal
d694f48c91 Get the other two transmission modes working as well 2023-01-05 19:15:11 +05:30
Kovid Goyal
5562a4d52f Get file mode transmission working for unmodified PNG 2023-01-05 19:15:11 +05:30
Kovid Goyal
ce4c71c465 Start work on the transmit backend 2023-01-05 19:15:11 +05:30
Kovid Goyal
31df90a64e Dont allow abort while waiting for query response 2023-01-05 19:15:11 +05:30
Kovid Goyal
22d69d24d0 Fix panic when no timers are left after dispatch 2023-01-05 19:15:11 +05:30
Kovid Goyal
d76e0850ae More work on porting icat 2023-01-05 19:15:11 +05:30
Kovid Goyal
b520882b62 ... 2023-01-05 19:15:11 +05:30
Kovid Goyal
79acab1547 More work on porting icat 2023-01-05 19:15:11 +05:30
Kovid Goyal
4690f3c7c0 ... 2023-01-05 19:15:11 +05:30
Kovid Goyal
cf1d9eb303 Parse more icat cli flags 2023-01-05 19:15:11 +05:30
Kovid Goyal
ba2a3f228d Implement --detect-timeout 2023-01-05 19:15:11 +05:30
Kovid Goyal
a757587ea2 Fix SHM on OpenBSD 2023-01-05 19:15:10 +05:30
Kovid Goyal
ea756db544 Get transmission medium detection working 2023-01-05 19:15:10 +05:30
Kovid Goyal
2d1a2c30bf MMap.Name() should return the SHM name not the full filesystem path 2023-01-05 19:15:10 +05:30
Kovid Goyal
6ace082bc2 Add openbsd and dragonfly support to shm 2023-01-05 19:15:10 +05:30
Kovid Goyal
7e161ea94b Get syscall based SHM working 2023-01-05 19:15:10 +05:30
Kovid Goyal
d01d5297b8 Start work on a SHM implementation in Go 2023-01-05 19:15:10 +05:30
Kovid Goyal
7a1140cd03 Start work on porting icat to Go 2023-01-05 19:15:10 +05:30
Kovid Goyal
aab81c2d32 Turn off hyperlink target display by default
I find it too intrusive for limited benefit. Most the hyperlinks I
click come from trusted programs anyway.
2023-01-05 15:30:43 +05:30
Kovid Goyal
49418c2f53 Show the hyperlink target bar on the top more often than the bottom. This is because the text cursor is usually closer to the bottom. 2023-01-05 15:28:02 +05:30
Kovid Goyal
a548e3eb4d Fix some animations pausing before starting 2023-01-04 11:18:17 +05:30
Kovid Goyal
779a7b7deb ... 2023-01-04 11:15:47 +05:30
Kovid Goyal
c83a8b0773 zsh completion; Fix leading ~ in filenames being quoted on insertion into commandline 2023-01-04 11:07:56 +05:30
Kovid Goyal
035c3de4bb Add completion for file args to clipboard kitten 2023-01-04 10:39:24 +05:30
Kovid Goyal
e2543e8968 Fix #5852 2023-01-04 08:20:04 +05:30
Kovid Goyal
bc2492c212 dont show URL targetbar when mouse is hidden 2023-01-01 12:11:19 +05:30
Kovid Goyal
c03310b5e5 Cleanup previous PR 2022-12-31 14:03:16 +05:30
Kovid Goyal
bd33cef092 Merge branch 'sequence' of https://github.com/ppwwyyxx/kitty 2022-12-31 13:38:37 +05:30
Yuxin Wu
832506d785 move is_modifier_key to glfw.c and expose in Python 2022-12-30 23:32:46 -08:00
Yuxin Wu
13b09346b9 reset current window after processing sequence 2022-12-30 23:07:50 -08:00
Yuxin Wu
1c10c5fcc4 replay modifier key as well 2022-12-30 23:07:50 -08:00
Yuxin Wu
510c5bd73b handle release 2022-12-30 23:07:49 -08:00
Yuxin Wu
774fdd7e94 Send sequence events to child if they don't match kitty. 2022-12-30 23:07:36 -08:00
Kovid Goyal
58497161c0 X11: When pasting text/plain try UTF8_STRING first then text/plain/charset=utf-8
Fixes #5842
Also fixes pasting from GTK+2 applications like leafpad.
2022-12-30 22:20:43 +05:30
Kovid Goyal
f831c34813 Update the FAQ on vim with a comprehensive set of settings needed to get it to work with modern terminals 2022-12-30 13:52:08 +05:30
Kovid Goyal
456af90ad2 Remote control: Allow matching for self window even over sockets when run inside a kitty window
Have kitty-tool send the value of KITTY_WINDOW_ID if present.
2022-12-30 12:17:31 +05:30
Kovid Goyal
c18bff7821 Remote control: Allow matching the parent of an overlay window 2022-12-30 11:29:05 +05:30
Kovid Goyal
080d1bf935 Fox object lifetime management 2022-12-30 10:08:49 +05:30
Kovid Goyal
4f9ed6546a Pass key events mapped to scroll actions to the program running in the terminal when the terminal is in alternate screen mode
Fixes #5839
2022-12-30 08:54:31 +05:30
Kovid Goyal
c76bbeabd6 ... 2022-12-30 08:34:58 +05:30
Kovid Goyal
0f24ce60f8 Fix @ send-text --stdin always assuming STDIN is a tty 2022-12-30 08:29:30 +05:30
Kovid Goyal
6a06769931 ... 2022-12-29 17:27:57 +05:30
Kovid Goyal
468b6fab02 Also use sanitized URL for allow_hyperlinks=ask 2022-12-29 17:05:18 +05:30
Kovid Goyal
306f9e5735 Prettify URLs before displaying them to the user 2022-12-29 17:04:02 +05:30
Kovid Goyal
f4ac03b791 Show the target of terminal hyperlinks when hovering over them with the mouse
Fixes #5830
2022-12-29 16:43:45 +05:30
Kovid Goyal
b8abdd2b50 Retry failed deletes from github 2022-12-29 12:50:16 +05:30
Kovid Goyal
e673747ef4 readline: add alt+arrow to move by word default binding. Common on macOS 2022-12-27 10:59:13 +05:30
Kovid Goyal
6e4376e44e A few more wrapping serialization tests 2022-12-27 09:11:15 +05:30
Kovid Goyal
f6801d48d1 Add a test to ensure \n does not change wrapping status 2022-12-27 08:48:26 +05:30
Kovid Goyal
ca57198927 Merge branch 'patch-1' of https://github.com/eltociear/kitty 2022-12-26 21:00:33 +05:30
Ikko Ashimine
e78000c879 Fix typo in iqsort.h
comparision -> comparison
2022-12-27 00:27:16 +09:00
Kovid Goyal
68cf9f7514 Switch to tracking linewrap on the last cell in a line
This allows us to have newline not affect the wrap status of a line.

Now a lines wrapping status is changed only when the last cell
in the line is changed. This actually matches the behavior of many other
terminal emulators so is probably a good thing from a ecosystem
compatibility perspective.

The fish shell expects this weird behavior of newline not changing
wrapping status, for unknown reasons, which is the actual motivation for
doing all this work.

Fixes #5766
2022-12-26 20:26:21 +05:30
Kovid Goyal
4556f5b8f1 Merge branch 'pr-fix-image-scrolling' of https://github.com/sergei-grechanik/kitty 2022-12-26 09:51:22 +05:30
Sergei Grechanik
32d8aac808 Fix scrolling images within margins
This commit fixes an off-by-one error in image scrolling that caused
images to not be scrolled or to be cropped at the wrong line.
2022-12-25 15:34:54 -08:00
Kovid Goyal
2e81d00c92 make go fmt happy 2022-12-24 10:53:17 +05:30
Kovid Goyal
cd92d50a0d Keyboard protocol: Remove CSI R from the allowed encodings of the F3 key as it conflicts with the *Cursor Position Report* escape code 2022-12-24 10:32:28 +05:30
Kovid Goyal
155dd426c5 Merge branch 'ssh-kitten' of https://github.com/page-down/kitty 2022-12-24 10:04:58 +05:30
pagedown
a8f2816ac2 ssh kitten: Compile terminfo with tic coming from pkgsrc under NetBSD 2022-12-24 11:53:52 +08:00
pagedown
0ddc5d030c ssh kitten: Fall back to using openssl when base64 does not exist 2022-12-24 11:53:45 +08:00
Kovid Goyal
a2c2d81373 Cleanup readline prompt rendering 2022-12-23 15:23:42 +05:30
Kovid Goyal
307ce1cf87 Remove not needed wrapper function since now we use a struct to set attrs 2022-12-23 13:50:55 +05:30
Kovid Goyal
61ceb12e07 Merge branch 'singlekey-endian' of https://github.com/jamessan/kitty
Fixes #5802
2022-12-23 08:12:23 +05:30
James McCoy
b45dc20693 Define SingleKey bitfields according to endianness
Closes #5802
2022-12-22 15:07:54 -05:00
Kovid Goyal
bcedbe5ec1 Revert "Change the terminfo entry for cud1 to not alter text to comply with the terminfo man page"
This reverts commit d8284befd3.
See https://github.com/kovidgoyal/kitty/issues/5766#issuecomment-1363025173
2022-12-22 21:49:32 +05:30
Kovid Goyal
038639e2d3 Bump bundled zlib 2022-12-22 19:26:34 +05:30
Kovid Goyal
c857492f37 Merge pull request #5803 from jamessan/runtime-dir
tests: Use tempdir for XDG_RUNTIME_DIR
2022-12-22 11:07:44 +05:30
Kovid Goyal
42923ab673 ... 2022-12-22 10:19:34 +05:30
James McCoy
9afd0309fc tests: Use tempdir for XDG_RUNTIME_DIR 2022-12-21 22:21:48 -05:00
Kovid Goyal
b9d098de2d Update mpv support link to point to the actual merged commit 2022-12-22 07:16:53 +05:30
Kovid Goyal
09e6f740de Merge branch 'macos-shortcuts' of https://github.com/page-down/kitty 2022-12-21 16:41:43 +05:30
pagedown
1023084eb9 macOS: Allow to customize Hide, Minimize, and Quit global menu shortcuts
All previously hard-coded shortcuts under macOS can be configured now.
2022-12-20 21:08:26 +08:00
Kovid Goyal
aa9679e56b Fix typo in key definition 2022-12-20 15:01:40 +05:30
Kovid Goyal
d8284befd3 Change the terminfo entry for cud1 to not alter text to comply with the terminfo man page
Fixes #5766
2022-12-20 09:16:05 +05:30
Kovid Goyal
e4ee2cf995 Move the alt+left/right binding into zsh integration
It works OOTB in bash and fish already.
2022-12-19 11:25:12 +05:30
Kovid Goyal
e3f6f47f10 ... 2022-12-19 05:35:18 +05:30
Kovid Goyal
e5941b1b44 Add a link for the vim t_ut issue 2022-12-18 22:32:20 +05:30
Kovid Goyal
65c64d8745 macOS: Bind :kbd:option+left and :kbd:option+right to :kbd:alt+b and :kbd:alt+f. This mimics the default bindings in Terminal.app
Fixes #5793
2022-12-18 20:34:42 +05:30
Kovid Goyal
40093a4702 Add tests for GraphicsCommand serialization 2022-12-18 11:56:30 +05:30
Kovid Goyal
3815cba8f3 Add stringer interface to GraphicsCommand 2022-12-17 15:34:43 +05:30
Kovid Goyal
7410cd62f9 remove unused code 2022-12-17 09:00:44 +05:30
Kovid Goyal
ae0a8e73d2 ... 2022-12-17 08:59:56 +05:30
Kovid Goyal
8f3a8c828f Add an APC to GraphicsCommand parser 2022-12-16 21:05:17 +05:30
Kovid Goyal
6efb5dc2c2 Auto-create an OS Window if none exists on new_tab 2022-12-16 19:34:37 +05:30
Kovid Goyal
bb33f6c0ac Start work on graphics support in kitty-tool 2022-12-16 18:06:52 +05:30
Kovid Goyal
d34284ee1c Merge branch 'docs' of https://github.com/page-down/kitty 2022-12-16 13:06:20 +05:30
pagedown
74cae7b787 ... 2022-12-16 14:27:02 +08:00
Kovid Goyal
c6360537e5 Try to fix tests failing on Python 3.11 2022-12-16 10:05:05 +05:30
Kovid Goyal
7d28d7413f Merge branch 'patch-1' of https://github.com/lodisy/kitty 2022-12-16 09:41:10 +05:30
Michael
d3f3e9ec38 docs: fix overview.rst
add missing `be`, L88
2022-12-16 12:06:25 +08:00
Kovid Goyal
928becece4 Fix #5773 2022-12-14 15:45:43 +05:30
Kovid Goyal
80db167abb Add mpv to the list of things that speak the graphics protocol 2022-12-14 10:31:56 +05:30
Kovid Goyal
a5a6880a19 Respect enable_audio_bell when a layout action fails 2022-12-14 06:53:14 +05:30
Kovid Goyal
da13d03b98 Merge branch 'rc-launch' of https://github.com/page-down/kitty 2022-12-13 20:32:20 +05:30
pagedown
0a5c409a12 Remote control: Add the missing option value overlay-main 2022-12-13 22:48:46 +08:00
Kovid Goyal
eeb772ad07 @launch: When an overlay window is specified in a particular tab via --match use the active window of that tab as the base, not the current tab. Fixes #5768 2022-12-13 20:15:21 +05:30
Kovid Goyal
2b66775f45 explicitly ignore a few errors 2022-12-13 16:19:46 +05:30
Kovid Goyal
3f65ce0e71 Make sizes explicit in a few reallocs 2022-12-13 12:11:37 +05:30
Kovid Goyal
d235b673d1 also test \ is escaped 2022-12-13 10:21:19 +05:30
Kovid Goyal
0ab618c2dc Fix #5767 2022-12-13 10:20:02 +05:30
Kovid Goyal
fefafda9a0 Fix #5764 2022-12-12 21:26:54 +05:30
Kovid Goyal
902373ed20 Also make lists and dicts of strings escape code safe 2022-12-12 19:24:44 +05:30
Kovid Goyal
aac57550c9 rc protocol: Encode strings values in an escape code safe way
Go emits UTF-8 encoded JSON not ascii encoded JSON. Still need to fix
lists and dicts of strings
2022-12-12 18:48:54 +05:30
Kovid Goyal
95e05ce9ec Fix #5761 2022-12-12 16:49:18 +05:30
Kovid Goyal
b6c6316b7b Merge branch 'rc-ls' of https://github.com/page-down/kitty 2022-12-12 10:32:51 +05:30
pagedown
91576cc42f Remote control: Keep the same naming style for ls command output 2022-12-12 12:53:58 +08:00
Kovid Goyal
032e01ebf7 ... 2022-12-11 20:55:06 +05:30
Kovid Goyal
bd70100e09 Fix typo in FAQ 2022-12-10 13:00:09 +05:30
Kovid Goyal
ff6d2e3c10 Merge branch 'kitten-hyperlink-grep' of https://github.com/page-down/kitty 2022-12-10 12:58:57 +05:30
pagedown
2f292bb5d2 DRYer 2022-12-10 15:13:19 +08:00
pagedown
52cf443daf Docs: rg --no-heading has been handled 2022-12-10 15:12:32 +08:00
Kovid Goyal
f03a665e09 Remote control: When matching windows allow using negative id numbers to match recently created windows
Fixes #5753
2022-12-10 11:17:55 +05:30
Kovid Goyal
66e7919171 Add a FAQ entry about not being able to use a keybinding in a terminal program
I am tired of people asking this same question endlessly. At least now I
can just point them to this link.
2022-12-08 14:16:01 +05:30
Kovid Goyal
1289dd2ff0 Cleanup previous PR 2022-12-08 13:30:54 +05:30
Kovid Goyal
fa50e0d6cc Merge branch 'kitten-hyperlinked-grep' of https://github.com/page-down/kitty 2022-12-08 13:26:28 +05:30
pagedown
8c7a5288ae hyperlinked_grep kitten: Handle more rg command line options
Skip for unsupported options.
2022-12-08 14:51:13 +08:00
Kovid Goyal
7fe5c79d53 Also mask signals when SIGNALFD is not available
This makes behavior across platforms consistent.
Fixes #4636
2022-12-07 12:25:14 +05:30
Kovid Goyal
ea5ffa4304 ... 2022-12-07 10:18:15 +05:30
Kovid Goyal
89b32e4545 Update changelog with clipboard kitten new features 2022-12-07 10:04:02 +05:30
Kovid Goyal
879b27a045 ... 2022-12-07 06:48:19 +05:30
Kovid Goyal
9cb0e4d09d Block handled signals early in startup before glfw is initialized to ensure that if the graphics libraries start a thread behind our backs, that threads defaults to haveing the signals blocked unless the library explicitly unblocks them. See #4636 2022-12-07 06:35:18 +05:30
Kovid Goyal
94410f2866 Handle EBUSY as well 2022-12-06 12:20:20 +05:30
Kovid Goyal
a3ba8647ba Document the new OSC 5522 protocol 2022-12-06 12:18:55 +05:30
Kovid Goyal
f35ee1bb40 Fix using primary selection with the extended protocol 2022-12-06 11:15:52 +05:30
Kovid Goyal
23b3b171fa Merge branch 'conf' of https://github.com/page-down/kitty 2022-12-05 17:54:10 +05:30
pagedown
30b25709d2 Fix the base path for envinclude 2022-12-05 14:53:26 +08:00
pagedown
9c488bb877 Docs: Remove extra backslashes from commented config
Update docs to use \e in the example.
2022-12-05 14:27:40 +08:00
Kovid Goyal
14a33dbd94 Put the non-boilerplate functions in their proper place 2022-12-05 08:07:50 +05:30
Kovid Goyal
e37ee422b6 ... 2022-12-05 07:53:30 +05:30
Kovid Goyal
d7d96c2e7b When using the include directive in kitty.conf make the environment variable KITTY_OS available for OS specific config 2022-12-04 21:03:24 +05:30
Kovid Goyal
fda4aa21a1 When drawing the tab bar have the default left and right margins drawn in a color matching the neighboring tab
Fixes #5719
2022-12-04 20:51:41 +05:30
Kovid Goyal
3cbca4955e ... 2022-12-04 20:48:15 +05:30
Kovid Goyal
8e0e70e2d6 Simplify passing colors to the borders shader 2022-12-04 16:08:32 +05:30
Kovid Goyal
7a348d6ef1 Store updated tab bar edge colors on every tab bar redraw 2022-12-04 14:38:56 +05:30
Kovid Goyal
cf8f904720 Function to guess the effective color at the edge of the current screen line 2022-12-04 14:23:21 +05:30
Kovid Goyal
fe53555dba Document the additions to the clipboard kitten 2022-12-04 11:37:02 +05:30
Kovid Goyal
b644a42a48 Allow using wildcard mime types when copying from clipboard 2022-12-03 14:06:16 +05:30
Kovid Goyal
5c9c9a67bc Fix make asan
Suppress leak detection when running gen-go-code.py otherwise it fails
since python always leaks
2022-12-03 12:34:32 +05:30
Kovid Goyal
76f6288e69 ... 2022-12-03 12:25:23 +05:30
Kovid Goyal
6422b323c6 Implement MIME aliases for clipboard 2022-12-03 12:20:03 +05:30
Kovid Goyal
a622a149f6 Allow arbitrary bytes in the mime metadata key 2022-12-03 09:21:36 +05:30
Kovid Goyal
fa6527cdf3 add note about how MIME types are detected 2022-12-03 08:35:58 +05:30
Kovid Goyal
0b293428c4 X11: Fix reading list of available mime types 2022-12-03 08:16:59 +05:30
Kovid Goyal
26e8a5186a Avoid extra roundtrip when only reading clipboard mime types 2022-12-03 08:06:48 +05:30
Kovid Goyal
bde737fa38 Finish implementation of clipboard writing 2022-12-03 08:02:27 +05:30
Kovid Goyal
71e09ba1fb Fix show_key kitten showing incorrect CSI encoding for F3 2022-12-01 23:33:08 +05:30
Kovid Goyal
3e69cf81af DRYer 2022-12-01 22:40:47 +05:30
Kovid Goyal
f5d2c35755 Move implementation of +hold to Go
No need to pay python interpreter startup cost for --hold
2022-12-01 22:34:56 +05:30
Kovid Goyal
38a7fa73e3 Simplify filter mode operation
Dont need channels and goroutines as writing in the loop is already
asnychronous
2022-12-01 19:54:57 +05:30
Kovid Goyal
fdd42d5f19 Implement kitty side write OSC 5522 2022-12-01 18:18:06 +05:30
Kovid Goyal
fe75493c37 Better error messages 2022-12-01 18:17:53 +05:30
Kovid Goyal
e187265d04 Dont truncate the output file just to get tis permission bits 2022-12-01 14:13:28 +05:30
Kovid Goyal
0a985134e2 Ensure permissions are correct when using atomic writes 2022-12-01 14:04:52 +05:30
Kovid Goyal
e555d963b1 DRYer 2022-12-01 13:58:06 +05:30
Kovid Goyal
3601488b26 Add a generic Values() 2022-12-01 13:47:06 +05:30
Kovid Goyal
f29ce19097 Reading arbitrary MIME from clipboard now works 2022-12-01 13:35:44 +05:30
Kovid Goyal
f6ab641b00 Clarify the action of CSI < u in Quickstart 2022-11-30 16:28:34 +05:30
Kovid Goyal
722a1020fa Cleaner implementation of max_tab_title_length
Ensures that tab decorations are not affected
2022-11-29 23:20:39 +05:30
Kovid Goyal
fbd19f3bde Merge branch 'docs' of https://github.com/page-down/kitty 2022-11-29 22:10:57 +05:30
Kovid Goyal
3cf874f6e9 Work on implementing read support in the clipboard kitten 2022-11-29 22:07:51 +05:30
pagedown
02b206eeb8 Docs: Slightly adjust the description of tab_title_max_length
Note the associated GitHub PR ID in the changelog.
2022-11-30 00:20:32 +08:00
Kovid Goyal
5c50e3869c Change the new option to limit tab title lengths to apply to the length of the title, as documented, nit the full tab 2022-11-29 17:41:27 +05:30
Kovid Goyal
6f66bbd424 ... 2022-11-29 15:15:01 +05:30
Kovid Goyal
2697ddaec3 Dont ask for permission when reading only the mime types available in the clipboard 2022-11-29 15:09:01 +05:30
Kovid Goyal
d6dcdf0751 Merge branch 'tab_max_length' of https://github.com/fratajczak/kitty 2022-11-29 14:59:18 +05:30
Kovid Goyal
11724c8a5f Terminal end of OSC 5522 read requests 2022-11-29 14:55:40 +05:30
Ferdinand Ratajczak
b6792a6d71 Add option to limit length of tab titles 2022-11-29 09:50:32 +01:00
Kovid Goyal
f0d61c2de9 Add debug output for key encoding state modifications 2022-11-29 11:20:19 +05:30
Kovid Goyal
35ae689818 Improve debug encoded key output 2022-11-29 08:06:07 +05:30
Kovid Goyal
1305199bdf Output the bytes sent to the child in --debug-input 2022-11-29 07:56:06 +05:30
Kovid Goyal
c62c31f776 More mypy bugs
It cant handle putting a ClipboardTyple fielf on ReadRequest. SO just
use a bool as we really only have two types anyway.
2022-11-28 22:03:04 +05:30
Kovid Goyal
defef3f88c Make mypy happy 2022-11-28 21:05:10 +05:30
Kovid Goyal
3ee9f723f2 The legacy osc 52 protocol now works with the new clipboard requests manager class 2022-11-28 20:53:56 +05:30
Kovid Goyal
a8725d6307 Start work on a new clipboard protocol to allow terminal programs to access more than just text/plain content from the clipboard 2022-11-28 14:23:03 +05:30
Kovid Goyal
4c72f92939 Wayland GNOME: Workaround for latest mutter release breaking full screen for semi-transparent kitty windows
Destroy the CSD surfaces when window goes full screen.
Fixes #5677
2022-11-28 14:19:13 +05:30
Kovid Goyal
2150f261ee Merge branch 'ksi-fish-cwd' of https://github.com/page-down/kitty 2022-11-27 11:46:42 +05:30
pagedown
f720bc9fab Shell integration: Report cwd on the fish prompt event 2022-11-27 14:07:19 +08:00
Kovid Goyal
d92f89e47f ZSH integration: Report cwd on every new prompt draw
Handles the case of a command reporting a different cwd to the terminal.
2022-11-27 10:09:25 +05:30
Kovid Goyal
c54a4021ef Update docs to use \e instead of \x1b for esc since we now support it 2022-11-27 10:06:04 +05:30
Kovid Goyal
375fa73826 Delegate kitty +kitten clipboard to kitty-tool 2022-11-26 20:09:43 +05:30
Kovid Goyal
5eb2142d70 Use a define rather than a generated file for wrapped kittens 2022-11-26 16:16:45 +05:30
Kovid Goyal
00223c5bba Merge branch 'hostname' of https://github.com/page-down/kitty 2022-11-26 15:43:46 +05:30
Kovid Goyal
aa9080d375 Add a note about using single quotes when passing arguments with backslash escapes to send-text
One could of course also use double quotes and escape the backslash or
just escape the backslash but I dont think we need to explain shell
quoting fully here.
2022-11-26 15:38:22 +05:30
Kovid Goyal
8d45f5011b Add support for the 🔗 role to prettify 2022-11-26 15:34:20 +05:30
Kovid Goyal
b3f096b03b kitty shell: Fix pressing enter while cursor is not at end of line causes line to be truncated visually 2022-11-26 15:30:49 +05:30
Kovid Goyal
a721ffeb7d Finish porting clipboard kitten to Go 2022-11-26 15:15:30 +05:30
pagedown
6a1b456bac DRYer: Get hostname 2022-11-26 16:08:40 +08:00
Kovid Goyal
63a08dc6cc kitty-tool @: Fix extra newline being printed when a command returns no response 2022-11-26 05:02:32 +05:30
Kovid Goyal
4969611bdb Handle backslash escapes in :code: blocks 2022-11-25 22:03:13 +05:30
Kovid Goyal
5d3a9f2628 Use base64 for args in old rc code as well 2022-11-25 21:12:59 +05:30
Kovid Goyal
15a7aeff4d Fix kitty-tool @ send-text not processing ANSI escapes 2022-11-25 21:09:51 +05:30
Kovid Goyal
f9a22d0bc7 Port ANSI escape code parser to Go 2022-11-25 21:03:09 +05:30
Kovid Goyal
402c8b6803 Use ANSI C escapes rather than python string literals 2022-11-25 19:10:15 +05:30
Kovid Goyal
ac60715ee2 Merge branch 'docs' of https://github.com/page-down/kitty 2022-11-25 17:34:46 +05:30
Kovid Goyal
cfc6bd4da5 Native code implementation for expanding ANSI escape codes 2022-11-25 17:33:41 +05:30
Kovid Goyal
4d3f3b5e91 Start moving clipboard kitten to kitty-tool 2022-11-25 12:58:10 +05:30
pagedown
55b5a45e27 Docs: Fix missing backslashes 2022-11-25 12:03:34 +08:00
Kovid Goyal
fbce5e7524 Merge branch 'patch-1' of https://github.com/zeertzjq/kitty 2022-11-24 10:16:56 +05:30
zeertzjq
daeb1b6c50 Add note about Vim's support for kitty keyboard protocol 2022-11-24 11:30:40 +08:00
Kovid Goyal
8fb2c209a9 Query for existing assets and then delete 2022-11-23 07:53:14 +05:30
Kovid Goyal
2b676b63b1 sleep defaults to one second 2022-11-22 21:56:10 +05:30
Kovid Goyal
c0d06adcb5 New sleep action
useful in combine based mappings to make kitty sleep before executing the next action
2022-11-22 21:45:19 +05:30
Kovid Goyal
51bba9110e Bash integration: Fix clone-in-kitty not working on bash >= 5.2 if environment variable values contain newlines or other special characters
Bash >= 5.2 changed the export command to output values using $' escaping when they contain special characters.
Fixes #5629
2022-11-22 16:38:24 +05:30
Kovid Goyal
4fc91dcc03 There should be no trailing space when completing directories for a file match based on patterns 2022-11-21 11:05:36 +05:30
Kovid Goyal
3c0667afd6 add some motivation for background_tint_gaps 2022-11-21 10:19:25 +05:30
Kovid Goyal
03dc24f913 Merge branch 'background-tint-gaps' of https://github.com/page-down/kitty 2022-11-21 10:17:36 +05:30
pagedown
73b5857916 Keep two blank lines between each version in the changelog 2022-11-21 12:21:13 +08:00
pagedown
08d74a6c56 Add an option to control background image tinting for window gaps 2022-11-21 12:21:06 +08:00
Kovid Goyal
4290a8f9ba Change the Accept header to current github api recommedation 2022-11-20 07:22:00 +05:30
Kovid Goyal
c6dd6ccc68 Apparently github's deletion api is flakey, retry 2022-11-20 07:18:38 +05:30
Kovid Goyal
fd7cc66689 Increase wait timeout before retry 2022-11-20 07:15:31 +05:30
Kovid Goyal
1c19fc77f1 ... 2022-11-20 06:55:22 +05:30
Kovid Goyal
4080a09748 More upload code cleanup 2022-11-19 11:31:43 +05:30
Kovid Goyal
b91eaa3b2a Cleanup the asset upload code 2022-11-19 11:23:31 +05:30
Kovid Goyal
bdb25831a7 Merge branch 'refactor-cursor-shape' of https://github.com/page-down/kitty 2022-11-19 11:08:17 +05:30
pagedown
a131f9a82e Refactor: Use a consistent name for beam cursor shape 2022-11-19 10:34:50 +08:00
Kovid Goyal
ffefd0f581 Cleanup previous PR 2022-11-18 10:42:06 +05:30
Kovid Goyal
43c0e0f586 Merge branch 'unicode' of https://github.com/page-down/kitty 2022-11-18 10:40:50 +05:30
pagedown
76669ad14d Note the Unicode version in the generated files
Files generated from the same Unicode version will be consistent
regardless of the date they were built.
2022-11-18 13:01:32 +08:00
Kovid Goyal
a9bb341e43 Add an option to control max file size for edit-in-kitty 2022-11-18 10:24:38 +05:30
Kovid Goyal
0757fcc451 Dont fail on github responses without JSON payloads 2022-11-18 10:16:29 +05:30
Kovid Goyal
dd4051bfd5 Allow getting the exe name of the active foreground process in the tab title template 2022-11-17 22:06:06 +05:30
Kovid Goyal
a6dcbe9c1d ... 2022-11-17 20:51:01 +05:30
Kovid Goyal
efaf9faa38 Implement edit-in-kitty using kitty-tool
Fixes #5546
Fixes #5630
2022-11-17 20:48:20 +05:30
Kovid Goyal
36631ddc49 ... 2022-11-17 20:25:35 +05:30
Kovid Goyal
e5e8cc72c6 Make the Unicode database version used available 2022-11-17 20:11:50 +05:30
Kovid Goyal
38547c9e7a Documentation: distinguish between examples and default values for multi-valued options 2022-11-17 17:20:40 +05:30
Kovid Goyal
e00a5ce911 Merge branch 'master' of https://github.com/ppwwyyxx/kitty 2022-11-17 17:06:56 +05:30
Kovid Goyal
0af48a4d05 Start work on implementing edit-in-kitty in kitty-tool 2022-11-17 17:05:25 +05:30
Yuxin Wu
c0d80f9a47 [docs]: don't show config codeblocks that only has a name 2022-11-17 00:05:50 -08:00
Kovid Goyal
d2dabc7d57 ... 2022-11-17 11:10:17 +05:30
Kovid Goyal
81db5eb82f Use nightly to get kitty-tool until 0.27 is released 2022-11-17 11:05:46 +05:30
Kovid Goyal
1addfea261 Avoid an extra HTTP request to set the uploaded file description
Also delete partial asset when receiving 502 errors
2022-11-17 10:44:52 +05:30
Kovid Goyal
e5be31ee14 build in non-interactive mode while publishing 2022-11-17 10:27:53 +05:30
Kovid Goyal
9cef714078 Merge branch 'pr-end-iter' of https://github.com/sergei-grechanik/kitty 2022-11-17 10:03:01 +05:30
Kovid Goyal
a5a4a1bf8f Increase timeout in test 2022-11-17 10:02:44 +05:30
Kovid Goyal
281ad13f6b Retry uploading file to Github 2022-11-17 08:45:26 +05:30
Kovid Goyal
5ad2ac259b When truncating descriptions for completion truncate at word boundaries 2022-11-17 08:29:01 +05:30
Kovid Goyal
a2f022d166 Add support for the repeat escape code to TruncatetoVisualLength() 2022-11-17 08:17:11 +05:30
Sergei Grechanik
4df6c172a3 Define END_ITER to prevent brace imbalance
Otherwise some editors/plugins get confused
2022-11-16 09:54:49 -08:00
Kovid Goyal
9db1d581f7 DRYer 2022-11-16 22:37:27 +05:30
Kovid Goyal
b3bc5a5565 ... 2022-11-16 22:35:59 +05:30
Kovid Goyal
fc20e8d04b Fix spurious EOF error when select for reading from the tty fails with a temporary error 2022-11-16 22:32:35 +05:30
Kovid Goyal
86af1d5c16 Wrap EOF errors when doing terminal I/O 2022-11-16 22:23:00 +05:30
Kovid Goyal
d8574f8f85 Fix another bug in readline cursor position tracking 2022-11-16 21:28:36 +05:30
Kovid Goyal
bdd04f37d6 Better error message for kitty shell when running unknown command 2022-11-16 20:53:08 +05:30
Kovid Goyal
a4e43b3925 Use a pager for the help interactive command as well 2022-11-16 20:44:13 +05:30
Kovid Goyal
5e880b92f5 Ensure active hyperlink is cleared when truncating output for completion descriptions 2022-11-16 20:32:42 +05:30
Kovid Goyal
d4c103e53e zsh breaks when there are escape codes in completion descriptions 2022-11-16 19:32:16 +05:30
Kovid Goyal
3e4df7d812 ... 2022-11-16 19:06:22 +05:30
Kovid Goyal
3b18f90319 Merge branch 'completion' of https://github.com/page-down/kitty 2022-11-16 19:05:58 +05:30
Kovid Goyal
e31587ec1e Ensure auto-generated entries such as --help are present for completion by calling Validate() 2022-11-16 18:05:27 +05:30
pagedown
5dc97af4d5 Add completion for kitty +list-fonts 2022-11-16 20:23:58 +08:00
Kovid Goyal
81916d0f02 Finish implementation of update-self 2022-11-16 17:44:21 +05:30
Kovid Goyal
ae93d95bbe Get progress bar rendering working 2022-11-16 16:35:15 +05:30
Kovid Goyal
dd1fcf6855 Support the repeat prev char escape code when calculating the width of a string 2022-11-16 16:25:16 +05:30
Kovid Goyal
4b05822474 Merge branch 'ksi-completion-fish' of https://github.com/page-down/kitty 2022-11-16 14:00:28 +05:30
Kovid Goyal
337f1fad3f fix double signatures 2022-11-16 13:45:27 +05:30
Kovid Goyal
463c9debe7 More work on update-self 2022-11-16 13:41:58 +05:30
pagedown
9225919112 Fix completion for fish 2022-11-16 16:03:07 +08:00
Kovid Goyal
e70c021371 Some basic TUI widgets ported to Go 2022-11-16 12:48:47 +05:30
Kovid Goyal
f3b3d6c0ef Workaround for mypy bug 2022-11-15 22:47:53 +05:30
Kovid Goyal
0c0b9e6b9c Fix deadlock in update-self 2022-11-15 22:33:23 +05:30
Kovid Goyal
d9215feda5 Allow using the cwd of the original process for launch --cwd
Fixes #5672
2022-11-15 22:18:19 +05:30
Kovid Goyal
d54fe3c16a Start work on a command to self update kitty-tool 2022-11-15 21:29:11 +05:30
Kovid Goyal
36dd5b2d00 More minor loop API additions 2022-11-15 21:00:19 +05:30
Kovid Goyal
87108a18ef Add a callback for wakeups 2022-11-15 18:01:21 +05:30
Kovid Goyal
234274c1df ... 2022-11-15 16:54:14 +05:30
Kovid Goyal
b42677b343 Utility function to download a URL to a file path with progress reporting 2022-11-15 16:53:43 +05:30
Kovid Goyal
c03af4d294 Build static binaries on CI 2022-11-15 15:07:33 +05:30
Kovid Goyal
8d12e60f62 Set a flag available at runtime when cross compiling kitty-tool 2022-11-15 15:04:28 +05:30
Kovid Goyal
5a71b8c209 Merge branch 'macos-custom-icon' of https://github.com/page-down/kitty 2022-11-15 13:28:03 +05:30
Kovid Goyal
16775c5539 ssh kitten: Add a kitty-tool wrapper script to auto-download and use kitty-tool
Needs testing.
2022-11-15 13:26:48 +05:30
pagedown
8b8263d0ff macOS: Failure to set custom app icon should not prevent launch
When running `kitty/launcher/kitty` and no bundle path is provided,
the icon of `kitty/launcher/kitty.app` should be changed instead of
the `launcher` folder.
2022-11-15 15:21:40 +08:00
Kovid Goyal
9ddd7d070e Add a note to changelog about kitty @ speed improvements 2022-11-15 12:05:59 +05:30
Kovid Goyal
780d5400cb Use full kitty-tool exe name in github description 2022-11-15 12:01:55 +05:30
Kovid Goyal
63d7b2a80b Shutdown macOS build VM after building 2022-11-15 11:32:34 +05:30
Kovid Goyal
1958d67847 Sign kitty-tool on macOS 2022-11-15 11:32:12 +05:30
Kovid Goyal
737919505d Update docs to mention kitty-tool 2022-11-14 20:58:24 +05:30
Kovid Goyal
d60ecfa8a6 Install go 1.18 for codeql build 2022-11-14 20:35:41 +05:30
Kovid Goyal
e3b22a87e4 Upload static kitty-tool builds when publishing 2022-11-14 17:07:32 +05:30
Kovid Goyal
c7d47a59f1 When running kitty-tool without arguments show usage 2022-11-14 16:36:05 +05:30
Kovid Goyal
7eae176b88 Code to build static versions of kitty-tool 2022-11-14 16:27:19 +05:30
Kovid Goyal
9361c62a1c Linux: Use a separate thread to play the beep sound
This is because on misconfigured systems canberra hangs while queueing a
sound to play. And these misconfigured systems are quite common in
Linux-land. See for example #5646

Sigh. Even playing a simple sound is failure prone on Linux.
2022-11-14 15:42:09 +05:30
Kovid Goyal
018811c96c Remove unused code
Completion and remote control have moved into kitty-tool
2022-11-14 15:42:09 +05:30
Kovid Goyal
129646c199 Use kitty-tool for all kitty @ incovations 2022-11-14 15:42:09 +05:30
Kovid Goyal
1881f4582e ... 2022-11-14 15:42:09 +05:30
Kovid Goyal
a5d05a2954 ... 2022-11-14 15:42:09 +05:30
Kovid Goyal
59b43ee844 prettify :option:--xyz> better 2022-11-14 15:42:09 +05:30
Kovid Goyal
29bde6c72c Improve formatting of completion entries with descriptions 2022-11-14 15:42:09 +05:30
Kovid Goyal
a7ce642a00 Fix rendering in cells 2022-11-14 15:42:08 +05:30
Kovid Goyal
723a9c91b5 Get completion basically working 2022-11-14 15:42:08 +05:30
Kovid Goyal
9e2c96653f More work on readline completion 2022-11-14 15:42:08 +05:30
Kovid Goyal
4974219e0f Add function to shlex for completion
Also remove the google header since we have diverged from
the original a fair bit. Add a link to the original for credit.
2022-11-14 15:42:08 +05:30
Kovid Goyal
a4de4b7c6f Report stream start position for tokens 2022-11-14 15:42:08 +05:30
Kovid Goyal
eae4899df4 Use a string builder instead of appending to a slice 2022-11-14 15:42:08 +05:30
Kovid Goyal
87b4800fdf Get rid of comment parsing from shlex
POSIX does not define comments
2022-11-14 15:42:08 +05:30
Kovid Goyal
64156fd6e6 Have the shlex tokenizer return space tokens as well 2022-11-14 15:42:08 +05:30
Kovid Goyal
1485981b11 Have the shlex tokenizer track position in stream and return defined error types 2022-11-14 15:42:08 +05:30
Kovid Goyal
8d76cf8d32 Import the google shlex package as we need more sophisticated parsing 2022-11-14 15:42:08 +05:30
Kovid Goyal
7c23536bfe Start work on readline completions 2022-11-14 15:42:08 +05:30
Kovid Goyal
f919efcd42 Move basic multi key shortcut handling into its own package 2022-11-14 15:42:08 +05:30
Kovid Goyal
388e47a2df DRYer 2022-11-14 15:42:08 +05:30
Kovid Goyal
dc787a6529 Allow pretty printing members of the Action enum 2022-11-14 15:42:08 +05:30
Kovid Goyal
cfb6d93dc0 Move cursor to end of input when traversing history list 2022-11-14 15:42:08 +05:30
Kovid Goyal
1523fef000 tests for history searching 2022-11-14 15:42:08 +05:30
Kovid Goyal
31dcb13836 cursor_y should be zero when resetting 2022-11-14 15:42:07 +05:30
Kovid Goyal
0c82832356 more work on history search 2022-11-14 15:42:07 +05:30
Kovid Goyal
ffea66357a Start work on incremental history search 2022-11-14 15:42:07 +05:30
Kovid Goyal
6b48624b81 Reset keyboard state when resetting text 2022-11-14 15:42:07 +05:30
Kovid Goyal
5a425ccaad Implement number args for repeats 2022-11-14 15:42:07 +05:30
Kovid Goyal
2f2dbfb45f Cleanup prompt handling 2022-11-14 15:42:07 +05:30
Kovid Goyal
13a266aa42 Map ctrl+c to abort the current line 2022-11-14 15:42:07 +05:30
Kovid Goyal
67b12159f4 make clean should also clean go caches 2022-11-14 15:42:07 +05:30
Kovid Goyal
8ad55f7562 Add some tests for history 2022-11-14 15:42:07 +05:30
Kovid Goyal
e1ab2383b3 Add basic history operations 2022-11-14 15:42:07 +05:30
Kovid Goyal
f77d07259a Fix mutable default value in dataclass 2022-11-14 15:42:07 +05:30
Kovid Goyal
2e07f90baf ... 2022-11-14 15:42:07 +05:30
Kovid Goyal
8574e136cd Store cwd in history 2022-11-14 15:42:07 +05:30
Kovid Goyal
c8e8cb5ad5 Add some tests for yanking 2022-11-14 15:42:07 +05:30
Kovid Goyal
f127523ae9 Get rid of the unneccessary swap on first configure
Instead use the new flag to indicate the surface should not be committed
till the next swap.
2022-11-14 15:42:07 +05:30
Kovid Goyal
22f7145e34 Add yank actions 2022-11-14 15:42:07 +05:30
Kovid Goyal
1f115870bb Need to install x11-xcb-dev explicitly in jammy 2022-11-14 15:42:06 +05:30
Kovid Goyal
3237db00fc Implement word killing actions 2022-11-14 15:42:06 +05:30
Kovid Goyal
ea583f60b3 Start work on kill ring 2022-11-14 15:42:06 +05:30
Kovid Goyal
b7816d26be Implement clear screen c-l binding 2022-11-14 15:42:06 +05:30
Kovid Goyal
19bf07abd9 Use the more efficient cell iterator api for single char horizontal cursor movement as well 2022-11-14 15:42:06 +05:30
Kovid Goyal
a008c627e3 Implement bindings for moving by simple word 2022-11-14 15:42:06 +05:30
Kovid Goyal
0068ae8f66 An easy to use iterator to iterate over the cells in a string 2022-11-14 15:42:06 +05:30
Kovid Goyal
5436408463 Fix the escape code parser not preserving complete utf-8 state between calls to ParseBytes()
Also allow it to be driven byte-by-byte
2022-11-14 15:42:06 +05:30
Kovid Goyal
d260d2f480 Add some test for vertical movement 2022-11-14 15:42:06 +05:30
Kovid Goyal
00ef9c1955 Implement vertical cursor movement 2022-11-14 15:42:06 +05:30
Kovid Goyal
5509673ff3 More tests 2022-11-14 15:42:06 +05:30
Kovid Goyal
3c4a411cad Rewrite the readline redraw code to make the screen lines explicit 2022-11-14 15:42:06 +05:30
Kovid Goyal
f945ef8ee8 handle ctrl-c better when interrupting go test 2022-11-14 15:42:06 +05:30
Kovid Goyal
260249491d Avoid Querying screen size on every resize 2022-11-14 15:42:05 +05:30
Kovid Goyal
595a78c956 DRYer 2022-11-14 15:42:05 +05:30
Kovid Goyal
cbbf8a2d34 Port output of active window and tab ids at shell startup 2022-11-14 15:42:05 +05:30
Kovid Goyal
88567f69b2 Start work on history support for readline 2022-11-14 15:42:05 +05:30
Kovid Goyal
fe91af5e09 Go stdlib doesnt even have a way to lock files 2022-11-14 15:42:05 +05:30
Kovid Goyal
5e2255591c Dont send invalid kitty-cmd escape code over tty 2022-11-14 15:42:05 +05:30
Kovid Goyal
01969cae1a More useful PARSE ERROR msg for unknown @ commands 2022-11-14 15:42:05 +05:30
Kovid Goyal
b89dfc6d1d Actually run the remote control commands from the shell 2022-11-14 15:42:05 +05:30
Kovid Goyal
59edf1d349 Code to show help 2022-11-14 15:42:05 +05:30
Kovid Goyal
9419fbc77c Fix rendering when line wraps 2022-11-14 15:42:05 +05:30
Kovid Goyal
d27cf045e5 ... 2022-11-14 15:42:05 +05:30
Kovid Goyal
f7d44330a2 remove unused code 2022-11-14 15:42:05 +05:30
Kovid Goyal
834385baff Improve performance when pasting large amounts of text into readline by not redrawing on every char 2022-11-14 15:42:05 +05:30
Kovid Goyal
c0f17c279e Add a generic ring buffer
Go's stdlib is very anemic
2022-11-14 15:42:05 +05:30
Kovid Goyal
7264bea8c9 Fix selector incorrectly marking fd as ready on EINTR 2022-11-14 15:42:04 +05:30
Kovid Goyal
1058c999c8 ... 2022-11-14 15:42:04 +05:30
Kovid Goyal
bf7dd1c369 Fix multiline prompts 2022-11-14 15:42:04 +05:30
Kovid Goyal
936a7a5f97 Dont write escape code for zero movement 2022-11-14 15:42:04 +05:30
Kovid Goyal
350060e0f6 ... 2022-11-14 15:42:04 +05:30
Kovid Goyal
430bd23870 Fix decoding of letter trailer CSI key event 2022-11-14 15:42:04 +05:30
Kovid Goyal
9f2b2eac85 More work on shell 2022-11-14 15:42:04 +05:30
Kovid Goyal
fd36435262 Add some default readline bindings 2022-11-14 15:42:04 +05:30
Kovid Goyal
27418eed88 Beep when action could not be performed 2022-11-14 15:42:04 +05:30
Kovid Goyal
48f1690913 Wire up key event handling 2022-11-14 15:42:04 +05:30
Kovid Goyal
eff239a195 Code to erase character ranges 2022-11-14 15:42:04 +05:30
Kovid Goyal
5e5cae8391 Code to move cursor right 2022-11-14 15:42:04 +05:30
Kovid Goyal
57310a772a Code to move cursor left 2022-11-14 15:42:04 +05:30
Kovid Goyal
066465bce7 Some tests for add_text 2022-11-14 15:42:04 +05:30
Kovid Goyal
1792c2268a Start writing tests for readline internal functions 2022-11-14 15:42:04 +05:30
Kovid Goyal
32059dba7e More work on readline 2022-11-14 15:42:03 +05:30
Kovid Goyal
c8296a44eb More work on readline 2022-11-14 15:42:03 +05:30
Kovid Goyal
565526624f Start work on porting kitty shell to Go 2022-11-14 15:42:03 +05:30
Kovid Goyal
f57832f501 Fix spurious rebuilds of generated go code 2022-11-14 15:42:03 +05:30
Kovid Goyal
e536ef7844 Suggestions for sub command names as well 2022-11-14 15:42:03 +05:30
Kovid Goyal
0dab006733 Allow un-ambiguous prefixes for command names 2022-11-14 15:42:03 +05:30
Kovid Goyal
75ead358a2 Show suggestions for options based on levenshtein distance 2022-11-14 15:42:03 +05:30
Kovid Goyal
654bd23109 DRYer 2022-11-14 15:42:03 +05:30
Kovid Goyal
6b04c42730 update wcswidth go version to match unicode 15 update in master 2022-11-14 15:42:03 +05:30
Kovid Goyal
8f5302a650 Hook up kitty-tool completions with shell integration 2022-11-14 15:42:03 +05:30
Kovid Goyal
74b1cac344 Allow using unabiguous long option prefixes 2022-11-14 15:42:03 +05:30
Kovid Goyal
7d5849cc17 ... 2022-11-14 15:42:03 +05:30
Kovid Goyal
d2a2af9672 Add completion for kitty-tool 2022-11-14 15:42:02 +05:30
Kovid Goyal
2633356842 No need to use a map 2022-11-14 15:42:02 +05:30
Kovid Goyal
3bd4fd999a All completion tests pass again 2022-11-14 15:42:02 +05:30
Kovid Goyal
262e2fb7a3 Various fixes from the completion merge 2022-11-14 15:42:02 +05:30
Kovid Goyal
97716fea8b More work on merging completions with parse tree 2022-11-14 15:42:02 +05:30
Kovid Goyal
bf74413c1f Work on merging completion tree with parse tree 2022-11-14 15:42:02 +05:30
Kovid Goyal
79ca0408e7 split up types.go 2022-11-14 15:42:02 +05:30
Kovid Goyal
97acb60981 Move completion package into cli 2022-11-14 15:42:02 +05:30
Kovid Goyal
3662efdf80 Nicer handling of python for typecheck 2022-11-14 15:42:02 +05:30
Kovid Goyal
e608a945de Output version information at bottom of help 2022-11-14 15:42:02 +05:30
Kovid Goyal
5771bd0c01 Make adding subcommands a bit nicer 2022-11-14 15:42:02 +05:30
Kovid Goyal
4396dede85 Get rid of the cobra dependency 2022-11-14 15:42:02 +05:30
Kovid Goyal
cbc569af64 Remove no_response from json specs 2022-11-14 15:42:02 +05:30
Kovid Goyal
90c1745976 Fix parsing of list options 2022-11-14 15:42:02 +05:30
Kovid Goyal
c4ab964d09 Tests for CLI parsing 2022-11-14 15:42:02 +05:30
Kovid Goyal
04022ed363 Various fixes to CLI parsing 2022-11-14 15:42:02 +05:30
Kovid Goyal
79cfc1e70a Move kitty-tool __complete__ to use the new CLI framework 2022-11-14 15:42:01 +05:30
Kovid Goyal
e7c14c78d0 Work on outputting help for commands 2022-11-14 15:42:01 +05:30
Kovid Goyal
cb2389efa5 Use the standard library deque
Drops a dependency
2022-11-14 15:42:01 +05:30
Kovid Goyal
49f5f25fb9 Run tests in the writeable src dir as the generated go files are present there 2022-11-14 15:42:01 +05:30
Kovid Goyal
ff4353b209 ... 2022-11-14 15:42:01 +05:30
Kovid Goyal
c07dc220a8 Fix frozen builds 2022-11-14 15:42:01 +05:30
Kovid Goyal
4316018966 ... 2022-11-14 15:42:01 +05:30
Kovid Goyal
a0bf6177e2 Use a LRUCache rather than an Unbounded one 2022-11-14 15:42:01 +05:30
Kovid Goyal
3078b9074a Also report submatch positions 2022-11-14 15:42:01 +05:30
Kovid Goyal
dffb87ced9 Make the cache re-useable 2022-11-14 15:42:01 +05:30
Kovid Goyal
4adea5b7fe Make ReplaceAll re-useable 2022-11-14 15:42:01 +05:30
Kovid Goyal
317b108497 Allow using :role:'payload' in addition to :role:payload as the former can be used in Go `` string literals 2022-11-14 15:42:01 +05:30
Kovid Goyal
7c41737370 Couple more errors found by linting 2022-11-14 15:42:01 +05:30
Kovid Goyal
4b6bae576d configure staticcheck 2022-11-14 15:42:01 +05:30
Kovid Goyal
8221713995 Allow defining options using a struct 2022-11-14 15:42:01 +05:30
Kovid Goyal
ef49634353 Fix some issues reported by staticcheck 2022-11-14 15:42:01 +05:30
Kovid Goyal
d6f42a11d7 Run go vet on CI 2022-11-14 15:42:00 +05:30
Kovid Goyal
800dbf1f4d extra message when tests have failed 2022-11-14 15:42:00 +05:30
Kovid Goyal
b1e08adbce Utility function to sort with key 2022-11-14 15:42:00 +05:30
Kovid Goyal
e7f38929d9 DRYer 2022-11-14 15:42:00 +05:30
Kovid Goyal
d0e133885c Install Go 1.18 on CI 2022-11-14 15:42:00 +05:30
Kovid Goyal
2cacd7a64a get rid of interface{} since we now require Go 1.18 2022-11-14 15:42:00 +05:30
Kovid Goyal
a44c89504b More convenient interface for sorting 2022-11-14 15:42:00 +05:30
Kovid Goyal
8807f6d539 Code to get exe name for usage message 2022-11-14 15:42:00 +05:30
Kovid Goyal
2f83bbdc85 command validation 2022-11-14 15:42:00 +05:30
Kovid Goyal
41a841c83d Validate string slice fields 2022-11-14 15:42:00 +05:30
Kovid Goyal
0cf8876f8a Validate count struct fields 2022-11-14 15:42:00 +05:30
Kovid Goyal
a3a89b3e21 More efficient multi line scanning 2022-11-14 15:42:00 +05:30
Kovid Goyal
2ddbe2a2bc Automatically camel-case destination 2022-11-14 15:42:00 +05:30
Kovid Goyal
707963b694 Code to conveniently read option values into a struct 2022-11-14 15:42:00 +05:30
Kovid Goyal
1811949706 Implement cloning of commands 2022-11-14 15:42:00 +05:30
Kovid Goyal
bc38bd75fd Start work on getting rid of the cobra dependency
Command line parsing is easy and I can do it better.
2022-11-14 15:42:00 +05:30
Kovid Goyal
54ec486d3a Now completion for hyperlinked_grep is automatic thanks to delegation
Also fix delegation for zsh when the command being completed differs
from the current command.
2022-11-14 15:42:00 +05:30
Kovid Goyal
5666b1b0fd Implement completion for fish 2022-11-14 15:41:59 +05:30
Kovid Goyal
ef9b765f81 Dont count bash's idiotic option equals as arguments 2022-11-14 15:41:59 +05:30
Kovid Goyal
a2bb360eec Dont output escape strings in descriptions 2022-11-14 15:41:59 +05:30
Kovid Goyal
e3b8de1ac0 Update test for new exe search 2022-11-14 15:41:59 +05:30
Kovid Goyal
4cbd2a0ee0 ... 2022-11-14 15:41:59 +05:30
Kovid Goyal
7cf9b21fc0 Show local executables for kityt command completion even without ./ 2022-11-14 15:41:59 +05:30
Kovid Goyal
454c2e32e7 ... 2022-11-14 15:41:59 +05:30
Kovid Goyal
53dc079c10 Use compopt to manage files and spaces 2022-11-14 15:41:59 +05:30
Kovid Goyal
08c697e99a Get delegate based completion working for bash 2022-11-14 15:41:59 +05:30
Kovid Goyal
1dce092ac0 Add trailing spaces for bash completion 2022-11-14 15:41:59 +05:30
Kovid Goyal
24c2d27eea handle bash splitting completion cmdline on equals 2022-11-14 15:41:59 +05:30
Kovid Goyal
b04b483b3f Remove common prefix for bash as well 2022-11-14 15:41:59 +05:30
Kovid Goyal
a7c997c6ef Add a debug function to print to parent kitty stdout 2022-11-14 15:41:59 +05:30
Kovid Goyal
266e51310c Basic BASH completion 2022-11-14 15:41:59 +05:30
Kovid Goyal
928a4db817 Implement delegate based completion fof the ssh and hyperlinked_grep kittens 2022-11-14 15:41:59 +05:30
Kovid Goyal
fd631bf402 Delegate based completion for @launch args 2022-11-14 15:41:59 +05:30
Kovid Goyal
dc403156a9 Delegate based completion for kitty cmd 2022-11-14 15:41:59 +05:30
Kovid Goyal
2cc359ccc8 Get zsh completion working apart from delegation 2022-11-14 15:41:58 +05:30
Kovid Goyal
cbbda23e01 Utility code to find longest common prefix/suffix and to quote strings for various shells 2022-11-14 15:41:58 +05:30
Kovid Goyal
1ff4f2df4f Refactor the CLI markup code to make it re-useable 2022-11-14 15:41:58 +05:30
Kovid Goyal
8796168469 Port code to truncate strings to visual width to Go 2022-11-14 15:41:58 +05:30
Kovid Goyal
d16ad40bbf avoid extra string copy in Stringwidth 2022-11-14 15:41:58 +05:30
Kovid Goyal
5c0858d6b7 Start work on zsh completion serialization 2022-11-14 15:41:58 +05:30
Kovid Goyal
a32a8d096d Allow commands to customize argument parsing 2022-11-14 15:41:58 +05:30
Kovid Goyal
67f556bd7c Add completion for the launch wrappers 2022-11-14 15:41:58 +05:30
Kovid Goyal
7737369fc9 Add completion for the kittens 2022-11-14 15:41:58 +05:30
Kovid Goyal
25a7ec9a07 Extra completion for some kitty options 2022-11-14 15:41:58 +05:30
Kovid Goyal
c2a2b4c087 Add various special purpose entry points 2022-11-14 15:41:58 +05:30
Kovid Goyal
3bf20594b7 Wire up completion for rc command options 2022-11-14 15:41:58 +05:30
Kovid Goyal
3a8bab90dc Get rid of WordPrefix 2022-11-14 15:41:58 +05:30
Kovid Goyal
0ff2446a1a More completion work 2022-11-14 15:41:58 +05:30
Kovid Goyal
946d44c43f Implement completespec in go 2022-11-14 15:41:58 +05:30
Kovid Goyal
26d4f5bcc9 Use the new completionspec for rc cmds 2022-11-14 15:41:58 +05:30
Kovid Goyal
d84efe105c ... 2022-11-14 15:41:58 +05:30
Kovid Goyal
f657e6e916 Allow using a base directory other than the cwd when completing files 2022-11-14 15:41:57 +05:30
Kovid Goyal
c5afceb4cb Basic completion for options 2022-11-14 15:41:57 +05:30
Kovid Goyal
18c3e46ac6 When completing on patterns exclude directories that only contain files that dont match 2022-11-14 15:41:57 +05:30
Kovid Goyal
3c29ce936b Dont recurse for file completion
We could potentially end up recursing over the entire file system. And
for completion we only present the candidates in the immediate directory
anyway.
2022-11-14 15:41:57 +05:30
Kovid Goyal
c9d986f9a8 args completion for rc commands 2022-11-14 15:41:57 +05:30
Kovid Goyal
d4b67f3b6a ... 2022-11-14 15:41:57 +05:30
Kovid Goyal
6faa908733 And more corner cases 2022-11-14 15:41:57 +05:30
Kovid Goyal
ced741b247 More corner cases 2022-11-14 15:41:57 +05:30
Kovid Goyal
c47ccc8a59 ... 2022-11-14 15:41:57 +05:30
Kovid Goyal
3326e9ef49 Move code to walk with symlinks to the utils module 2022-11-14 15:41:57 +05:30
Kovid Goyal
134fce8507 Allow completing paths with ~ prefix 2022-11-14 15:41:57 +05:30
Kovid Goyal
5d89a6c3c4 Work on completion of file args 2022-11-14 15:41:57 +05:30
Kovid Goyal
833e9625f9 Add a generated comment in *_generated.go in the style used by go generate 2022-11-14 15:41:57 +05:30
Kovid Goyal
21b572d69a Allow building kitty-tool as a static binary 2022-11-14 15:41:57 +05:30
Kovid Goyal
12d9787d0e update go deps 2022-11-14 15:41:57 +05:30
Kovid Goyal
8c6b391eda ... 2022-11-14 15:41:57 +05:30
Kovid Goyal
8c2e435793 Code to complete executables in PATH 2022-11-14 15:41:57 +05:30
Kovid Goyal
10cf7f06c6 Code to get file/dir completion candidates for a prefix 2022-11-14 15:41:56 +05:30
Kovid Goyal
4575a14873 work on framework for testing completion 2022-11-14 15:41:56 +05:30
Kovid Goyal
d679ea2cdf Allow generating completions for multiple command lines for more efficient testing 2022-11-14 15:41:56 +05:30
Kovid Goyal
54378de52b More work on command completion 2022-11-14 15:41:56 +05:30
Kovid Goyal
63287e4115 More work on completions 2022-11-14 15:41:56 +05:30
Kovid Goyal
d0efe00449 Use replace_if_needed() for at commands 2022-11-14 15:41:56 +05:30
Kovid Goyal
d703cb51cd ... 2022-11-14 15:41:56 +05:30
Kovid Goyal
005a9c7090 Add an entry point for the completion tool 2022-11-14 15:41:56 +05:30
Kovid Goyal
f4de6d2a10 More work on completions 2022-11-14 15:41:56 +05:30
Kovid Goyal
e60b331152 start work on porting completion to Go 2022-11-14 15:41:56 +05:30
Kovid Goyal
3d79eb5730 more tests for indent and wrap 2022-11-14 15:41:56 +05:30
Kovid Goyal
af7f4e97cf More work on the new formatter 2022-11-14 15:41:56 +05:30
Kovid Goyal
aad8cb3d1e Use the new formatter for CLI help output 2022-11-14 15:41:56 +05:30
Kovid Goyal
40a9ab8929 Allow ignoring lines containing a sentinel 2022-11-14 15:41:56 +05:30
Kovid Goyal
e433b90297 Dont drop trailing escape codes when stripping trailing whitespace 2022-11-14 15:41:56 +05:30
Kovid Goyal
1ac7d9c10d Basic wrap is working 2022-11-14 15:41:56 +05:30
Kovid Goyal
ef5f0025e1 Start work on more sophisticated indent+wrap implementation 2022-11-14 15:41:56 +05:30
Kovid Goyal
32804f01b2 Allow parsing strings with escape code parser 2022-11-14 15:41:55 +05:30
Kovid Goyal
7ecc1b7950 Remove markup from ref_hyperlink text 2022-11-14 15:41:55 +05:30
Kovid Goyal
a7f6105393 Use Unsafe rather than Dangerous to be consistent 2022-11-14 15:41:55 +05:30
Kovid Goyal
081390b5a2 Utility functions to allow using string/[]byte interchangeably without copies 2022-11-14 15:41:55 +05:30
Kovid Goyal
61094c6bfb Add strikethrough formatting 2022-11-14 15:41:55 +05:30
Kovid Goyal
6672904e64 Fix spurious error message when setting image to none 2022-11-14 15:41:55 +05:30
Kovid Goyal
905c4d641c Allow using many image formats in RC commands 2022-11-14 15:41:55 +05:30
Kovid Goyal
fa7a6dfd4a Implement stdin echo loop for socket i/o as well 2022-11-14 15:41:55 +05:30
Kovid Goyal
cb452ba9fc Implement sen text from stdin for the tty backend 2022-11-14 15:41:55 +05:30
Kovid Goyal
85169c989f ... 2022-11-14 15:41:55 +05:30
Kovid Goyal
e8a321d097 Port code to serialize key events as CSI to Go 2022-11-14 15:41:55 +05:30
Kovid Goyal
3a198833da Simplify escape code wrapping 2022-11-14 15:41:55 +05:30
Kovid Goyal
ea8fb10c05 Password input: Handle SIGTSTP 2022-11-14 15:41:55 +05:30
Kovid Goyal
67115530b4 Make the loop API a thin wrapper around internal methods 2022-11-14 15:41:55 +05:30
Kovid Goyal
7325921070 Allow cancel async commands without auth 2022-11-14 15:41:55 +05:30
Kovid Goyal
f86ce03d3b Fix set-colors 2022-11-14 15:41:55 +05:30
Kovid Goyal
5cf10023c9 Nicer API for setting loop options 2022-11-14 15:41:55 +05:30
Kovid Goyal
93d08011f1 ... 2022-11-14 15:41:54 +05:30
Kovid Goyal
7f77f7e408 Only send cancel async if there is an async id 2022-11-14 15:41:54 +05:30
Kovid Goyal
65c3630099 send_text other than from stdin works 2022-11-14 15:41:54 +05:30
Kovid Goyal
457aab7c41 Simplify timer removal 2022-11-14 15:41:54 +05:30
Kovid Goyal
dcec926590 Do not allow adding timers before loop is run 2022-11-14 15:41:54 +05:30
Kovid Goyal
0a2455c8be Get scroll_window working 2022-11-14 15:41:54 +05:30
Kovid Goyal
bacca88213 Get set_font_size working 2022-11-14 15:41:54 +05:30
Kovid Goyal
bd1b3d9f6e Implement streaming mode for socket IO 2022-11-14 15:41:54 +05:30
Kovid Goyal
364533b1ed Work on supporting streaming remote commands with passwords 2022-11-14 15:41:54 +05:30
Kovid Goyal
d7985689c9 Allow debugprintln to controlling tty easily 2022-11-14 15:41:54 +05:30
Kovid Goyal
6d6bba4a4c debugprintln should be in-band for the loop 2022-11-14 15:41:54 +05:30
Kovid Goyal
5cc5759f3e flush_pending_writes must be non-blocking 2022-11-14 15:41:54 +05:30
Kovid Goyal
a388a658ce Fix payload update code in multi send commands 2022-11-14 15:41:54 +05:30
Kovid Goyal
b5e2871aa0 Remove not needed chunking code 2022-11-14 15:41:54 +05:30
Kovid Goyal
192eccc6cc More work on porting rc commands 2022-11-14 15:41:54 +05:30
Kovid Goyal
a4b2e2a196 more work on porting command parsing to Go 2022-11-14 15:41:54 +05:30
Kovid Goyal
6f4968305a more work on porting rc command parsing to Go 2022-11-14 15:41:54 +05:30
Kovid Goyal
79c8862d4c Work on conversion of args parsing to go code 2022-11-14 15:41:53 +05:30
Kovid Goyal
441e4edfb2 Also ensure kitty-tool bootstrap is executable 2022-11-14 15:41:53 +05:30
Kovid Goyal
ef71b071db Automap a bunch of json fields from identically named options 2022-11-14 15:41:53 +05:30
Kovid Goyal
b33a684357 ... 2022-11-14 15:41:53 +05:30
Kovid Goyal
43b35f6f4e Move GoOption migration code to cli.py for re-use 2022-11-14 15:41:53 +05:30
Kovid Goyal
3b2c4561c2 Dont change the env for go tests
This prevents got test caching from working greatly increasing the time
for running a test
2022-11-14 15:41:53 +05:30
Kovid Goyal
e69b02ad46 ... 2022-11-14 15:41:53 +05:30
Kovid Goyal
85b6053380 Run go tests in parallel 2022-11-14 15:41:53 +05:30
Kovid Goyal
249df69ac9 Use the new styling API for CLI infra 2022-11-14 15:41:53 +05:30
Kovid Goyal
4a4500d56b Dont make urls part of styling, instead have a dedicated UrlFunc API
Since urls can potentially change a lot, caching them makes no sense
2022-11-14 15:41:53 +05:30
Kovid Goyal
be22f49012 Fix usage of numbered colors for underlines 2022-11-14 15:41:53 +05:30
Kovid Goyal
f9695a7947 Add url support to styling 2022-11-14 15:41:53 +05:30
Kovid Goyal
29d9b70f0c More ansi styling tests 2022-11-14 15:41:53 +05:30
Kovid Goyal
42a8ca0842 Write some tests for the style wrapper 2022-11-14 15:41:53 +05:30
Kovid Goyal
91c61478dd Start work on easily generating ANSI formatted strings 2022-11-14 15:41:53 +05:30
Kovid Goyal
fb482e28f6 ... 2022-11-14 15:41:53 +05:30
Kovid Goyal
387333492b Generate color names and table for Go
Also exclude generated files from gofmt checking
2022-11-14 15:41:53 +05:30
Kovid Goyal
9c58cb3f41 ... 2022-11-14 15:41:52 +05:30
Kovid Goyal
b2e610f9b1 Implement socket I/O 2022-11-14 15:41:52 +05:30
Kovid Goyal
a960937095 Simplify serialization code and avoid extra copy 2022-11-14 15:41:52 +05:30
Kovid Goyal
0cda5d43a6 Fix final write detection 2022-11-14 15:41:52 +05:30
Kovid Goyal
a75d59643c Use one less channel 2022-11-14 15:41:52 +05:30
Kovid Goyal
bf35817d73 No need to store most channels on self 2022-11-14 15:41:52 +05:30
Kovid Goyal
f103f8d5db Create a in src symlink for kitty-tool as well 2022-11-14 15:41:52 +05:30
Kovid Goyal
b382587776 another attempt 2022-11-14 15:41:52 +05:30
Kovid Goyal
6fe0c8ba2f dump tree 2022-11-14 15:41:52 +05:30
Kovid Goyal
7b2991de02 ... 2022-11-14 15:41:52 +05:30
Kovid Goyal
1b90c03304 Refactor loop code into its own package 2022-11-14 15:41:52 +05:30
Kovid Goyal
0aa05b02e8 Cleanup 2022-11-14 15:41:52 +05:30
Kovid Goyal
5412a0126c we generate more than just rc commands 2022-11-14 15:41:52 +05:30
Kovid Goyal
841b368021 DRYer 2022-11-14 15:41:52 +05:30
Kovid Goyal
b1f9139ca5 Use a fully random async_id rather than a uuid 2022-11-14 15:41:52 +05:30
Kovid Goyal
4a49c3940a Switch to using goroutines rather than a select()
More complex code since now we have to synchronize between threads,
but a good way to teach myself more about goroutines.
2022-11-14 15:41:52 +05:30
Kovid Goyal
ee12349a50 Use Go's os.File this allows us to implement WriteString without using unsafe 2022-11-14 15:41:52 +05:30
Kovid Goyal
69c847a48f Fix failing test 2022-11-14 15:41:51 +05:30
Kovid Goyal
03705cbec0 Fix transmission of async rc commands 2022-11-14 15:41:51 +05:30
Kovid Goyal
ff2ff9c04f Port short uuid code to Go 2022-11-14 15:41:51 +05:30
Kovid Goyal
a22ba9f739 Fix failing test 2022-11-14 15:41:51 +05:30
Kovid Goyal
c86f8a698c @ ls works phew 2022-11-14 15:41:51 +05:30
Kovid Goyal
fa4711bd04 Give the kill signal time to be delivered 2022-11-14 15:41:51 +05:30
Kovid Goyal
a939bbb3ec ... 2022-11-14 15:41:51 +05:30
Kovid Goyal
174bc25afb Make timeout checking more efficient 2022-11-14 15:41:51 +05:30
Kovid Goyal
2ffba1c422 Work on implementing ttyio via TUI 2022-11-14 15:41:51 +05:30
Kovid Goyal
0913b64c6b Dont vendor base85 2022-11-14 15:41:51 +05:30
Kovid Goyal
32e59257d2 Refactor io in preparation for using tui 2022-11-14 15:41:51 +05:30
Kovid Goyal
6f8c884bb5 Also handle SIGPIPE as the Go runtime does funky things with this signal 2022-11-14 15:41:51 +05:30
Kovid Goyal
80c5ac891d Add license info to Go files 2022-11-14 15:41:51 +05:30
Kovid Goyal
ccb60687b6 Prefix names of cmd files 2022-11-14 15:41:51 +05:30
Kovid Goyal
6a2393299b Add a write completed callback 2022-11-14 15:41:51 +05:30
Kovid Goyal
ab66b3f4c0 Add timer infra to the loop 2022-11-14 15:41:51 +05:30
Kovid Goyal
c8292d77f1 Re-use the escape code parser for wcswidth calculation 2022-11-14 15:41:51 +05:30
Kovid Goyal
7280c712d6 Move escape code parser into wcswidth package 2022-11-14 15:41:50 +05:30
Kovid Goyal
9be2247081 Dont use the syscall package 2022-11-14 15:41:50 +05:30
Kovid Goyal
e68b5fa504 Add callback for screen resize handling 2022-11-14 15:41:50 +05:30
Kovid Goyal
c2ef6c986b Password input now works 2022-11-14 15:41:50 +05:30
Kovid Goyal
619fcb0681 Allow debug printing 2022-11-14 15:41:50 +05:30
Kovid Goyal
10a39d3757 Fix reset mode incorrectly setting mode instead 2022-11-14 15:41:50 +05:30
Kovid Goyal
d2a15a2009 Make using alternate screen the default 2022-11-14 15:41:50 +05:30
Kovid Goyal
235eb868b2 More misc fixes for TUI 2022-11-14 15:41:50 +05:30
Kovid Goyal
5703a3370e Move wcswidth into its own package as it is very slow to build 2022-11-14 15:41:50 +05:30
Kovid Goyal
5dca2a1a25 Fix stringifying mods 2022-11-14 15:41:50 +05:30
Kovid Goyal
4b18b575cd Misc fixes for TUI 2022-11-14 15:41:50 +05:30
Kovid Goyal
818f68ec53 Initialize various maps 2022-11-14 15:41:50 +05:30
Kovid Goyal
cd54fefa99 Ignore more types of temporary errors 2022-11-14 15:41:50 +05:30
Kovid Goyal
4ab5456ead Less layering 2022-11-14 15:41:49 +05:30
Kovid Goyal
10d11bc749 Drop another dependency 2022-11-14 15:41:49 +05:30
Kovid Goyal
19ffbc6f3d Implement wcswidth() for Go 2022-11-14 15:41:49 +05:30
Kovid Goyal
79b1af28b4 Fix errors reported by compiler 2022-11-14 15:41:49 +05:30
Kovid Goyal
05d768d8df Generate a wcwidth for Go as well 2022-11-14 15:41:49 +05:30
Kovid Goyal
7bb310d3af Port recent changes from cli.py to Go 2022-11-14 15:41:49 +05:30
Kovid Goyal
9d56f8eed2 Use TUI to build a nice password read control 2022-11-14 15:41:49 +05:30
Kovid Goyal
42a5129553 Wire up key handling 2022-11-14 15:41:49 +05:30
Kovid Goyal
d6ed20323b Implement key event parsing and matching 2022-11-14 15:41:49 +05:30
Kovid Goyal
63fdbd3fa0 Start work on decoding key events in Go 2022-11-14 15:41:49 +05:30
Kovid Goyal
99fde8723a Wire up the signal handlers 2022-11-14 15:41:49 +05:30
Kovid Goyal
526a331f47 Wire up a bunch of callbacks 2022-11-14 15:41:49 +05:30
Kovid Goyal
e18b6638bb Allow propagating errors from the escape code handlers 2022-11-14 15:41:49 +05:30
Kovid Goyal
3c3e7b7f70 Start work on proper TUI support 2022-11-14 15:41:49 +05:30
Kovid Goyal
67f03621ae Handle EINTR in IsTerminal 2022-11-14 15:41:49 +05:30
Kovid Goyal
10cef16210 DRYer 2022-11-14 15:41:49 +05:30
Kovid Goyal
6a79b450f7 Drop another dependency and get a better read password function 2022-11-14 15:41:48 +05:30
Kovid Goyal
eb4ee13f73 Drop another dependency 2022-11-14 15:41:48 +05:30
Kovid Goyal
cf287015de ... 2022-11-14 15:41:48 +05:30
Kovid Goyal
246277e7af Refactor tty code into its own package 2022-11-14 15:41:48 +05:30
Kovid Goyal
13758e9600 Drop one dependency 2022-11-14 15:41:48 +05:30
Kovid Goyal
73e4deb1c2 Show suggestions based on levenshtein distance 2022-11-14 15:41:48 +05:30
Kovid Goyal
68d589826a ... 2022-11-14 15:41:48 +05:30
Kovid Goyal
7457746d65 Fix @command form not supporting global options 2022-11-14 15:41:48 +05:30
Kovid Goyal
eec8f04e93 fix reading from tty 2022-11-14 15:41:48 +05:30
Kovid Goyal
3a7d26a3ef Work on reading command responses 2022-11-14 15:41:48 +05:30
Kovid Goyal
91b15d1a90 Fix incorrect err handling 2022-11-14 15:41:48 +05:30
Kovid Goyal
12b0f632bd Allow OSC to be terminated by BEL
Also prevent changing streaming state unless in reset state
2022-11-14 15:41:48 +05:30
Kovid Goyal
84cb2638d6 Work on an escape code parser 2022-11-14 15:41:48 +05:30
Kovid Goyal
7eb6cb2407 Update script that counts lines of code 2022-11-14 15:41:48 +05:30
Kovid Goyal
ce3062cbde UTF-8 decode/encode for Go
The builtin utf-8 package has semantics not suitable for us
2022-11-14 15:41:48 +05:30
Kovid Goyal
e599a2c87f The stupid term package is not EINTR safe 2022-11-14 15:41:48 +05:30
Kovid Goyal
15e1f376a4 EINTR safe function to get tty size 2022-11-14 15:41:48 +05:30
Kovid Goyal
82d0bd9364 Use the term package to get tty size since it has a function for it 2022-11-14 15:41:47 +05:30
Kovid Goyal
6a9f3feba2 ... 2022-11-14 15:41:47 +05:30
Kovid Goyal
2e31178980 Workaround for go unix package not wrapping pselect() on darwin 2022-11-14 15:41:47 +05:30
Kovid Goyal
141b9c8f08 Adjust select() timeout on EINTR 2022-11-14 15:41:47 +05:30
Kovid Goyal
17629add66 Handle EINTR 2022-11-14 15:41:47 +05:30
Kovid Goyal
352a78f056 Add a debug print method to tty and use pselect rather than select for greater timeout precision 2022-11-14 15:41:47 +05:30
Kovid Goyal
2ef5d0a140 ... 2022-11-14 15:41:47 +05:30
Kovid Goyal
08b4741024 Get rid of a couple of unneeded dependencies 2022-11-14 15:41:47 +05:30
Kovid Goyal
11ffa961bc Use local hyperlinks for :doc: 2022-11-14 15:41:47 +05:30
Kovid Goyal
ad6d928c12 Port various recent changes to CLI help output 2022-11-14 15:41:47 +05:30
Kovid Goyal
74b768bfc2 ... 2022-11-14 15:41:47 +05:30
Kovid Goyal
9b703078dd See if at least the field names are the same 2022-11-14 15:41:47 +05:30
Kovid Goyal
43e93414ea Some work on implementing TTYIO 2022-11-14 15:41:47 +05:30
Kovid Goyal
6c3a439455 Use the io.Reader interface 2022-11-14 15:41:47 +05:30
Kovid Goyal
a7bc2fcba8 Code to parse socket addresses 2022-11-14 15:41:47 +05:30
Kovid Goyal
417c8887b9 Start on testing infra for command to JSON serialization 2022-11-14 15:41:47 +05:30
Kovid Goyal
47feb73cdf Code to generate structs for JSON marshalling 2022-11-14 15:41:47 +05:30
Kovid Goyal
0aa1bacbe7 ... 2022-11-14 15:41:47 +05:30
Kovid Goyal
63512f0512 Implement setting of option values into a struct 2022-11-14 15:41:46 +05:30
Kovid Goyal
a32251cab4 Handle aliased flags 2022-11-14 15:41:46 +05:30
Kovid Goyal
2ca8ae8e5f normalize flag names so that underscores are interchangeable with hyphens 2022-11-14 15:41:46 +05:30
Kovid Goyal
2d466f343d Finish mapping of python cli opt to go cli opt 2022-11-14 15:41:46 +05:30
Kovid Goyal
4596dc39ce Fix formatting of lines with only spaces 2022-11-14 15:41:46 +05:30
Kovid Goyal
605882582e Transfer response_timeout 2022-11-14 15:41:46 +05:30
Kovid Goyal
a5876e5231 Refactor conversion of py opt to go opt 2022-11-14 15:41:46 +05:30
Kovid Goyal
e127579ae6 DRYer 2022-11-14 15:41:46 +05:30
Kovid Goyal
b3be6792fd General cleanup 2022-11-14 15:41:46 +05:30
Kovid Goyal
6c25f0cf4b Use cobra's builtin machinery for creating new types 2022-11-14 15:41:46 +05:30
Kovid Goyal
a0bff4abab Let kitty-tool know if it was built for a frozen kitty 2022-11-14 15:41:46 +05:30
Kovid Goyal
82410c58ed Hide the default completion command 2022-11-14 15:41:46 +05:30
Kovid Goyal
3a87cfce3e Get bool set flags ported 2022-11-14 15:41:46 +05:30
Kovid Goyal
15ffd8e6d8 Support older Go 2022-11-14 15:41:46 +05:30
Kovid Goyal
33e16df586 Add some basic RC serialization tests 2022-11-14 15:41:46 +05:30
Kovid Goyal
4432c1a2ea Move the command types into a separate package 2022-11-14 15:41:46 +05:30
Kovid Goyal
45540561cc More debug info about PATH in CI 2022-11-14 15:41:46 +05:30
Kovid Goyal
f90753c69b Use whatever version of go is available on CI 2022-11-14 15:41:46 +05:30
Kovid Goyal
bab914c497 Create hidden alias commands so kitty-tool @ls also works 2022-11-14 15:41:45 +05:30
Kovid Goyal
d3bb69a0ac strip whitespace from long descriptions just to be safe 2022-11-14 15:41:45 +05:30
Kovid Goyal
e356af2dc4 Build kitty-tool as a universal binary for freeze builds on macOS 2022-11-14 15:41:45 +05:30
Kovid Goyal
e9e7b97c48 And we have frozen builds working with kitty-tool 2022-11-14 15:41:45 +05:30
Kovid Goyal
1c7d6f8bc6 Dont sync kitty-tool to build vms 2022-11-14 15:41:45 +05:30
Kovid Goyal
82a0e56eb2 Fix go tests not being excluded correctly 2022-11-14 15:41:45 +05:30
Kovid Goyal
54fd2c6773 Get linux freeze working 2022-11-14 15:41:45 +05:30
Kovid Goyal
fb4c7db25e Add a test for existence of kitty-tool 2022-11-14 15:41:45 +05:30
Kovid Goyal
c85af36116 Simplify cleanup and ignoring of generated go files 2022-11-14 15:41:45 +05:30
Kovid Goyal
780b5ca8bd misc fixes 2022-11-14 15:41:45 +05:30
Kovid Goyal
20ad7ca437 Output VCSRevision with --version 2022-11-14 15:41:45 +05:30
Kovid Goyal
d39036de2a Add vcs revision to version string 2022-11-14 15:41:45 +05:30
Kovid Goyal
4ac4ee643e Have the rc command wrapper sauto-generated on build 2022-11-14 15:41:45 +05:30
Kovid Goyal
47f35a06e6 Start work on generating rc cmd wrappers 2022-11-14 15:41:45 +05:30
Kovid Goyal
77f7ce82c0 Parse global options 2022-11-14 15:41:45 +05:30
Kovid Goyal
10b74d0703 Update documentation of --to 2022-11-14 15:41:45 +05:30
Kovid Goyal
393820e77a Dont sort flags by default 2022-11-14 15:41:45 +05:30
Kovid Goyal
1b8805bc6f document we need go >= 1.19 2022-11-14 15:41:44 +05:30
Kovid Goyal
07dc83670b Fix go in home dir getting removed from PATH on CI 2022-11-14 15:41:44 +05:30
Kovid Goyal
1429be3a19 Run gofmt via python, easier to debug 2022-11-14 15:41:44 +05:30
Kovid Goyal
4b69a600e5 Nicer error when go is not found during build 2022-11-14 15:41:44 +05:30
Kovid Goyal
ce9a5528bc Pass verbose to go build 2022-11-14 15:41:44 +05:30
Kovid Goyal
2ea3fa36d2 ... 2022-11-14 15:41:44 +05:30
Kovid Goyal
14262b158d Log which go exe is being used to run the tests 2022-11-14 15:41:44 +05:30
Kovid Goyal
2fd013b593 Add source code linting for go to CI 2022-11-14 15:41:44 +05:30
Kovid Goyal
1325844539 Add some go testing infrastructure 2022-11-14 15:41:44 +05:30
Kovid Goyal
3a21605b05 ... 2022-11-14 15:41:44 +05:30
Kovid Goyal
cea9ff30dc Add the go dependency to CI and Brewfile 2022-11-14 15:41:44 +05:30
Kovid Goyal
63da2e1ec6 gofmt 2022-11-14 15:41:44 +05:30
Kovid Goyal
083deec663 Build kitty-tool via the build system 2022-11-14 15:41:44 +05:30
Kovid Goyal
8b91c227f6 ... 2022-11-14 15:41:44 +05:30
Kovid Goyal
06bd1f5d48 DRYer 2022-11-14 15:41:44 +05:30
Kovid Goyal
a7f0a471ed Dont fail to output usage when less is not present 2022-11-14 15:41:44 +05:30
Kovid Goyal
2a7aa46b77 Use pager even for usage + error 2022-11-14 15:41:44 +05:30
Kovid Goyal
c04b002d4e Use a pager for displaying usage, matches kitty behavior
Also dont tell less to squeeze lines
2022-11-14 15:41:44 +05:30
Kovid Goyal
46840df1ad CLI help output make kitty.conf a clickable URL 2022-11-14 15:41:43 +05:30
Kovid Goyal
aaf0dea8dc Use a single wrapper binary for all command line tools
This is because Go has a multi megabyte overhead for its binaries
2022-11-14 15:41:43 +05:30
Kovid Goyal
abaafc2d68 Parse roles in the help strings 2022-11-14 15:41:43 +05:30
Kovid Goyal
c97556de65 Show help when command is specified 2022-11-14 15:41:43 +05:30
Kovid Goyal
bbf7504303 Start work on implementing kitty @ as a static binary using Go 2022-11-14 15:41:43 +05:30
Kovid Goyal
126468a5dd Fix #5668 2022-11-14 15:40:24 +05:30
Kovid Goyal
8280899ce1 IBUS: When creating the connection mark as focused if any top level window has focus. Fixes #5655 2022-11-10 07:21:34 +05:30
Kovid Goyal
b15c9f7419 Function should be static 2022-11-10 07:18:17 +05:30
Kovid Goyal
2e8ef66496 Another mypy update another round of spurious errors 2022-11-08 17:17:40 +05:30
Kovid Goyal
72f92b395f version 0.26.5 2022-11-07 15:36:42 +05:30
Kovid Goyal
c9c8eb6e94 ... 2022-11-05 11:37:07 +05:30
Kovid Goyal
59ded41f7a When no OS Window is focused the active_* should return those belonging to the last focused OS Window 2022-11-05 11:34:10 +05:30
Kovid Goyal
10ad56885e Properly specify semantics of active and focused
active means active in parent. focused means actually has keyboard
focus.
2022-11-04 10:38:18 +05:30
Kovid Goyal
d1eb9340ac Output the actual tab id in its repr 2022-11-04 09:29:33 +05:30
Kovid Goyal
a856c64104 Have the semantics of is_focused match that of state:focused otherwise things are liable to get confusing
The previous value is now available as is_active_window
2022-11-03 22:32:07 +05:30
Kovid Goyal
c0b11c5656 Also change the behavior of state:focused matching for tabs 2022-11-03 21:56:23 +05:30
Kovid Goyal
935c4ded6b Remote control: When matching window by state:focused match the window belonging to the OS window that was last focused
Fixes #5602
2022-11-03 21:52:20 +05:30
Kovid Goyal
f5de08d5fa Splits layout: Add a new mappable action to move the active window to the screen edge
Fixes #5643
2022-11-03 17:40:04 +05:30
Kovid Goyal
9d471782dd Increase some more timeouts 2022-11-03 13:13:14 +05:30
Kovid Goyal
dea3df66f8 system python appears broken on macos-latest image
The pip scripts install directory is not on PATH
2022-11-03 13:05:03 +05:30
Kovid Goyal
ec80a1532c Try to make mypy happy with the contortions needed for importlib.resources 2022-11-03 12:41:13 +05:30
Kovid Goyal
93563f1280 More pointless code churn thanks to importlib.resources
They've deprecated a bunch of API but the suggested replacement is
either not present in versions of python that are not EOLed or doesn't
actually work.
2022-11-03 12:13:47 +05:30
Kovid Goyal
e309e54002 Allow using the re module in tab title templates
Fix #5639
2022-11-01 22:25:58 +05:30
Kovid Goyal
0b3228ab16 ... 2022-11-01 12:51:36 +05:30
Kovid Goyal
3f28cf45d4 Dont use the deprecated importlib.resources API 2022-11-01 12:38:24 +05:30
Kovid Goyal
88b829fc9b cleanup comment 2022-11-01 12:22:05 +05:30
Kovid Goyal
458ac6953f Update changelog for last PR 2022-11-01 12:21:09 +05:30
Kovid Goyal
a6855bde3c Merge branch 'no_cursor_update_if_not_changed' of https://github.com/wengxt/kitty 2022-11-01 12:20:18 +05:30
Kovid Goyal
f6f2f00c53 Add a note about wayland semantics 2022-11-01 12:13:23 +05:30
Kovid Goyal
00324c96fc ... 2022-10-31 22:09:01 +05:30
Kovid Goyal
2435a8ccfd Wayland GNOME: Fix incorrect window size when in some circumstances when switching between windows with window decorations disabled
Only call wl_surface_commit() after a resize when the correct size buffer is
attached to the surface. This is ensured by setting a flag on the window that prevents
all surface commits till it is cleared. The flag is cleared at next
eglSwapBuffers().

I dont actually understand if this guarantees that the
buffer size is always correct. For example, if the back buffer is
latched when wl_egl_resize_window() is called, the backbuffer will be
correct only after two swaps (I think). Or maybe the old back buffer is
discarded, I cant find any documentation about it.

All I can say is that doing it this way seems to fix the issue.

Thanks to @jadahl for his help with tracking down the root cause.

Fixes #4802
2022-10-31 21:59:01 +05:30
Kovid Goyal
de122ed727 Bind eglQuerySurface 2022-10-31 21:03:39 +05:30
Kovid Goyal
c2ead407ae ... 2022-10-31 18:14:38 +05:30
Kovid Goyal
16b322616a Fix cursor position at x=0 changing to x=1 on resize
Fixes #5635
2022-10-31 08:03:42 +05:30
Kovid Goyal
e0b4c7edc5 Increase the timeout for shell integration tests
Needed for ARM running non-natively
2022-10-30 11:09:36 +05:30
Kovid Goyal
a8ab4eaf23 Use a larger timeout when running prewarm test 2022-10-30 10:36:10 +05:30
Kovid Goyal
3847837bd0 Forgot to run gen-config.py 2022-10-19 20:50:53 +05:30
Kovid Goyal
1747bbbbcb ssh kitten: Allow using absolute paths for the location of transferred data
Fixes #5607
2022-10-19 20:43:53 +05:30
Kovid Goyal
90e80477e9 Fix background_tint with background_opacity < 1 causing colors in cell area and padding to not match 2022-10-19 19:24:37 +05:30
Kovid Goyal
4f90110a7c Fix ghosting when using background_tint under GNOME+Wayland
The problem was that on Wayland if the buffer contains pixels with alpha
< 1 they are blended with something, even if the window is opaque. Under
mutter that something was the previous frame, under sway it was the
background/whatever is under the window.

So when blending the tint color, use a blend mode that results in opaque
pixels.

Fixes #5605
2022-10-19 19:02:05 +05:30
Kovid Goyal
28c616d3ff Move blend mode selection into draw_tint 2022-10-19 17:13:46 +05:30
Kovid Goyal
f5126c664c Wayland KDE: Fix abort when pasting into Firefox
Dunno why kwin uses drag and drop callbacks when pasting into Firefox on
Wayland, but then this is Wayland, so every stupid thing imaginable will
be done at least once.

Fixes #5603
2022-10-19 11:28:33 +05:30
Kovid Goyal
0f340086c0 Fix resize_draw_strategy=static
The text is now static again but the background image is still scaled, cant be
bothered about that. Fixes #5601
2022-10-19 08:26:31 +05:30
Kovid Goyal
5c34f16ab4 Fix #5600 2022-10-19 07:45:27 +05:30
Kovid Goyal
03fe928e3f show progress while compressing release tarballs 2022-10-17 09:55:09 +05:30
Kovid Goyal
55b53bcac6 version 0.26.4 2022-10-17 08:18:51 +05:30
Kovid Goyal
57d044861f Merge branch 'patch-1' of https://github.com/ms-test/kitty 2022-10-16 13:28:06 +05:30
ms-test
aab149366d Check correct pair member
I haven't looked deeply, but this looked to be a simple typo unless it's checking one both times because of a type invariant. If that is the case, and the check is correct, then a comment and/or code refactoring to call attention to this would likely be a good idea.
2022-10-16 03:53:16 -04:00
Kovid Goyal
896f93822d kitty shell: Also output active tab id
Fixes #5590
2022-10-16 08:52:35 +05:30
Kovid Goyal
6890e265b6 GNOME Wayland: Fix a memory leak in gnome-shell when using client side decorations
destroy CSD buffers that were never attached explicitly, as mutter does
not send release events for these even when the pool is destroyed.
2022-10-12 17:52:47 +05:30
Kovid Goyal
48a4edc199 Merge branch 'action_cwd_doc' of https://github.com/cbosdo/kitty 2022-10-10 14:04:29 +05:30
Cédric Bosdonnat
d63be90a7f Recommend using --cwd=current in open-actions.conf
Editors like Vim are basing path-related commands on the current working
directory. Launching the action with the current CWD in hyperlink opens
makes life easier and would work with every editor.
2022-10-10 10:12:20 +02:00
Kovid Goyal
6af020e4ef Merge branch 'marksisson/simple-docs-change' of https://github.com/marksisson/kitty 2022-10-09 12:18:25 +05:30
Mark Sisson
ca24e9ca67 change linux_package build instructions to use make target 2022-10-09 00:02:38 -05:00
Kovid Goyal
fbfaefd72a Wayland: Fix an abort when changing background colors with wayland_titlebar_color set to background
Fixes #5562
2022-10-07 14:13:12 +05:30
Kovid Goyal
94b3776066 Merge branch 'master' of https://github.com/Diff-fusion/kitty 2022-10-05 09:09:23 +05:30
Felix
15e4be9051 Fix clipboard target properties and memory leak 2022-10-04 17:22:15 +02:00
Kovid Goyal
ae8f3de070 Allow centering the background image
Fixes #5525
2022-10-04 08:26:28 +05:30
Kovid Goyal
c8d18ffe26 Add a note about yet another gnome bug 2022-10-03 22:06:00 +05:30
Kovid Goyal
4d80427908 Wayland: Fix background image scaling using tiled mode on high DPI screens 2022-10-03 21:49:52 +05:30
Kovid Goyal
0e69324469 Fix resize draw strategy == static causing background image/borders to not be drawn 2022-10-03 21:40:00 +05:30
Kovid Goyal
cf22729dfa Fix background_tint not applying to window margins and padding
Fixes #3933
2022-10-03 21:39:57 +05:30
Kovid Goyal
1402c5bbfa Forgot to change check for space for next tab to use its max tab length rather than the current tabs max tab length, since they can now be different 2022-10-03 16:21:50 +05:30
Kovid Goyal
f0f0c8f4fe max_title_length -> max_tab_length 2022-10-03 16:15:24 +05:30
Kovid Goyal
96faac95db DRYer 2022-10-03 15:32:42 +05:30
Kovid Goyal
08041415d1 Document the purpose of for_layout 2022-10-03 13:26:55 +05:30
Kovid Goyal
647b18d345 Tab bar: Improve empty space management when some tabs have short titles, allocate the saved space to the active tab
Fixes #5548
2022-10-03 13:24:21 +05:30
Kovid Goyal
a116e3cadd Merge branch 'patch-1' of https://github.com/sorrycc/kitty 2022-09-30 07:46:32 +05:30
chencheng (云谦)
52c9b5f5b8 Update custom.css 2022-09-30 08:44:09 +08:00
Kovid Goyal
bbc9f588f1 Merge branch 'unicode-15' of https://github.com/page-down/kitty 2022-09-29 09:17:02 +05:30
pagedown
13a3c6b5b2 Update to Unicode 15.0 2022-09-29 10:13:21 +08:00
pagedown
fc15b20f24 Update to Nerd Fonts 2.2.2 2022-09-29 10:13:10 +08:00
Kovid Goyal
cd8f2e5cc6 another mypy update another round of breakage 2022-09-27 07:19:03 +05:30
Kovid Goyal
267798a277 Update the docs of open_url_with to indicate that open-actions.conf is read by the "default" handler 2022-09-26 20:21:44 +05:30
Kovid Goyal
921ac12e90 Clear both actions caches when config file is reloaded 2022-09-26 20:15:08 +05:30
Kovid Goyal
901e00cab1 Cleanup previous PR
1) Dont use deprecated code
2) Always set the dock icon on startup as the dock icon doesnt change
   till the dock is restarted
3) Update the app icon automatically if the mtime on the custom icon in
   the config dir is newer than the mtime of the sentinel file apple
   puts inside the application bundle to indicate it has a custom icon
2022-09-25 18:11:17 +05:30
Kovid Goyal
d0769f3979 ... 2022-09-25 17:36:32 +05:30
Kovid Goyal
7e4dd8cf1e Merge branch 'macos-set-icon' of https://github.com/page-down/kitty 2022-09-25 14:40:36 +05:30
Kovid Goyal
5ea0519f62 Pass through python used for type check to the test code from before the env is sanitized 2022-09-25 14:36:12 +05:30
pagedown
a1029418f8 macOS: Allow to set custom app icon automatically 2022-09-25 15:25:43 +08:00
Kovid Goyal
98eacb2067 panel kitten: Do not depend on xprop 2022-09-24 15:44:54 +05:30
Kovid Goyal
2cef9abbd3 Get rid of one call to xprop in the panel kitten 2022-09-24 15:17:11 +05:30
Kovid Goyal
0fa158c809 Merge branch 'docs' of https://github.com/page-down/kitty 2022-09-24 14:38:42 +05:30
pagedown
c54a6b398b Add some missing no_response for rc commands 2022-09-24 12:43:13 +08:00
pagedown
27ea367123 Docs: Remove the extra backslashes from the install commands 2022-09-24 12:39:05 +08:00
Kovid Goyal
42178a4570 X11: Fix a regression in the previous release that caused pasting from GTK based applications to have extra newlines
Fixes #5528

And let me just re-iterate, GNOME/GTK is developed by morons.
2022-09-24 08:56:50 +05:30
Kovid Goyal
e98ecc1c4f Another auto-indent fix 2022-09-24 08:34:07 +05:30
Kovid Goyal
0d64246209 fix vim autoindent 2022-09-24 08:31:14 +05:30
Kovid Goyal
a0495219ab ... 2022-09-24 08:30:40 +05:30
Kovid Goyal
9d98aa3159 Merge branch 'patch-2' of https://github.com/sashashura/kitty 2022-09-24 07:29:42 +05:30
Alex
5c82f4beca build: harden ci.yml permissions
Signed-off-by: Alex <aleksandrosansan@gmail.com>
2022-09-23 22:14:57 +02:00
Alex
13539bd8c6 build: harden codeql-analysis.yml permissions
Signed-off-by: Alex <aleksandrosansan@gmail.com>
2022-09-23 22:14:16 +02:00
Kovid Goyal
26b8ab9adf Use a regex for bracketed paste sanitization 2022-09-23 22:18:03 +05:30
Kovid Goyal
dbb97a62bf version 0.26.3 2022-09-22 13:48:20 +05:30
Kovid Goyal
b1fa1c9820 Make test a bit more robust 2022-09-21 23:16:34 +05:30
Kovid Goyal
2dc9488909 switch python autoformatter to isort+black+autoflake 2022-09-21 13:40:37 +05:30
Kovid Goyal
e2a251224d ssh kitten: Better error message when tar is missing 2022-09-21 07:34:15 +05:30
Kovid Goyal
2a2dca8a58 ... 2022-09-18 08:26:40 +05:30
Kovid Goyal
e1f3cb85c0 Window for id should not fail when not called from a callback 2022-09-18 08:24:02 +05:30
Kovid Goyal
13cf38d6c6 Update changelog 2022-09-17 18:21:28 +05:30
Kovid Goyal
5180a41e87 Fix a use-after-free when handling fake mouse clicks and the action causes windows to be removed/re-allocated
Fixes #5506
2022-09-17 18:21:10 +05:30
Kovid Goyal
1c44da2b4a Nicer error message when trying to open the config file and no editor is available 2022-09-13 17:24:11 +05:30
Kovid Goyal
bcd78c3940 Fix a regression that caused kitty not to restore SIGPIPE after python nukes it when launching children. Affects bash which does not sanitize its signal mask.
Fixes #5500
2022-09-13 07:51:32 +05:30
Kovid Goyal
fe2f3d9870 Wayland: Remove the mutter specific ignoring of the first empty surface configure event. It seems to be no longer necessary on current mutter, with the recent Wayland changes 2022-09-11 14:37:50 +05:30
Kovid Goyal
dcf2152a7a Wayland: Generate a XDG_ACTIVATION_TOKEN when opening URLs or running programs in the background via the launch action 2022-09-11 14:25:49 +05:30
Kovid Goyal
58a3baaf0f Wayland: Use XDG_ACTIVATION_TOKEN when present at launch 2022-09-11 13:43:52 +05:30
Kovid Goyal
b247759d30 DRYer 2022-09-11 13:15:42 +05:30
Kovid Goyal
ba8d30896b Try to use the activation protocol to focus windows 2022-09-11 10:39:28 +05:30
Kovid Goyal
4d30ae55f3 Wayland: Mark windows in which a bell as urgent on compositors that support the xdg-activation protocol 2022-09-11 09:33:41 +05:30
Kovid Goyal
983ab3c67d build wayland xdg-activation protocol 2022-09-10 16:08:38 +05:30
Kovid Goyal
0bf228b030 Wayland: Micro-optimization: Assume window will be shown on primary monitor so create it with its scale set to that of the primary monitor 2022-09-10 15:23:56 +05:30
Kovid Goyal
29b3a92ffc Wayland: swap buffers immediately on scale change to ensure attached buffer is a multiple of the new scale
Earlier we were only swapping buffers when ready to draw, but the
Wayland protocol  requires the attached buffer to be a multiple of the
scale. We cannot guarantee an application side swap will be triggered
before the next commit, so instead we blank the new buffer swap it in
the GLFW backend itself.

Fixes #5467
2022-09-10 15:09:46 +05:30
Kovid Goyal
23d73ec933 ... 2022-09-10 12:52:27 +05:30
Kovid Goyal
bc650f6230 Output initial window creation size in debug 2022-09-10 12:28:53 +05:30
Kovid Goyal
5272318d67 Update changelog 2022-09-10 12:10:30 +05:30
Kovid Goyal
5ba887ff68 Wayland: Fix for bug in NVIDIA drivers that prevents transparency working
Fixes #5479
2022-09-10 11:57:18 +05:30
Kovid Goyal
67d70f8b8f Apparently on Wayland we need to set the swap interval on every window not just the first. It's somehow not shared even though the context is shared? Fixes #5495 2022-09-10 10:41:31 +05:30
Kovid Goyal
0fac6e4de9 render frames should be always respected on macOS
Only Wayland suffers from flicker on resize when using render frames.
2022-09-10 10:25:42 +05:30
Kovid Goyal
1e7a11b278 Wayland: When swapping buffers in response to a configure event ensure the window is the current context otherwise the swap fails
The swap failing will mean the buffer is not attached which might cause
issues with some compsitors.
2022-09-10 10:22:09 +05:30
Kovid Goyal
6741ac2087 Sessions: Allow controlling which OS Window is active via the focus_os_window directive 2022-09-10 08:27:36 +05:30
Kovid Goyal
7b2e29a6a8 ... 2022-09-10 07:52:26 +05:30
Kovid Goyal
6f147544d2 Add ! to env var serialization test 2022-09-10 07:21:15 +05:30
Kovid Goyal
89570d3b52 ssh kitten: Fix KITTY_PUBLIC_KEY not being encoded properly when transmitting
Fixes #5496
2022-09-10 07:09:58 +05:30
Kovid Goyal
dd4a65e0c9 ... 2022-09-09 15:41:45 +05:30
Kovid Goyal
79fba9dd9a Use the dynamic property instead of testing identifier serialization 2022-09-09 15:39:00 +05:30
Kovid Goyal
b123c21010 Update changelog
Fixes #5483
2022-09-09 13:13:58 +05:30
Kovid Goyal
9c5d1f9771 Pass null bytes through the clipboard on cocoa 2022-09-09 13:12:12 +05:30
Kovid Goyal
5131224b59 Convenience code for debugging 2022-09-09 12:20:28 +05:30
Kovid Goyal
be89da2271 Handle dyn prefixes 2022-09-09 11:59:49 +05:30
Kovid Goyal
45b408a78b Allow setting arbitrary mime types 2022-09-09 11:14:12 +05:30
Kovid Goyal
0e7da8643e Get cocoa clipboard backend working 2022-09-09 10:59:10 +05:30
Kovid Goyal
410b1816ad More work on cocoa clipboard backend 2022-09-09 07:39:38 +05:30
Kovid Goyal
bcfa2a64e4 Start work on new clipboard api support for macos 2022-09-08 21:45:13 +05:30
Kovid Goyal
91c00fb5ac Implement the new clipboard API for Wayland 2022-09-08 17:29:18 +05:30
Kovid Goyal
c58d217d32 Only warn about cursor size once 2022-09-08 16:28:40 +05:30
Kovid Goyal
a9b6047741 Simplify handling of self offers 2022-09-08 15:34:14 +05:30
Kovid Goyal
6b432bee4f Cleanup sending/receiving mimetype atoms 2022-09-08 12:45:35 +05:30
Kovid Goyal
087f0b449f ... 2022-09-08 12:45:35 +05:30
Kovid Goyal
96160b52b6 Code to get the available mime types in the clipboard 2022-09-08 12:45:34 +05:30
Kovid Goyal
d17a6cd3a3 Get reading from clipboard working 2022-09-08 12:45:34 +05:30
Kovid Goyal
7e1380cc0d Start work on giving GLFW a proper clipboard API 2022-09-08 12:45:34 +05:30
Kovid Goyal
9a99554ed3 Also have confirm() and get_line() return their results on overlay removal 2022-09-08 12:06:25 +05:30
Kovid Goyal
19799bd538 When choosing an option call the callback after the popup window is removed. This ensures the active window is unchanged when the callback is called. Fixes #5488 2022-09-08 12:01:38 +05:30
Kovid Goyal
902e94ceac Fix #5484 2022-09-07 15:09:24 +05:30
Kovid Goyal
5bb2cb06a9 Fix #5477 2022-09-05 21:43:56 +05:30
Kovid Goyal
1559a2e15a Cleanup previous PR 2022-09-05 21:19:58 +05:30
Kovid Goyal
35f94963cd Merge branch 'skip-tests-bash-debug' of https://github.com/jamessan/kitty 2022-09-05 21:18:52 +05:30
James McCoy
f0d497dfe0 Skip bash shell_integration tests if bash is a debug build
Switch to using BASH_VERSINFO rather than BASH_VERSION, since it
provides structured data.

    BASH_VERSINFO
           A readonly array variable whose members hold version information for this instance of bash.  The values assigned to the array members are as follows:
           BASH_VERSINFO[0]        The major version number (the release).
           BASH_VERSINFO[1]        The minor version number (the version).
           BASH_VERSINFO[2]        The patch level.
           BASH_VERSINFO[3]        The build version.
           BASH_VERSINFO[4]        The release status (e.g., beta1).
           BASH_VERSINFO[5]        The value of MACHTYPE.

When release status is not "release", bash builds are in debug mode and
output extra information which disturbs the integration.

Closes #5473
2022-09-05 11:37:37 -04:00
Kovid Goyal
5bdf27fd78 version 0.26.2 2022-09-05 10:49:50 +05:30
Kovid Goyal
f05783e64d Sanitize notifications ids as they are retransmitted over the TTY 2022-09-05 10:41:19 +05:30
Kovid Goyal
c455fea729 Also output screen contents when test fails 2022-09-05 07:52:36 +05:30
Kovid Goyal
5bf5454dbe Nicer fix for #5469 2022-09-04 22:15:17 +05:30
Kovid Goyal
b60d9f73ce Wayland: Fix remembering window size not accurate when client side decorations are present 2022-09-04 14:25:04 +05:30
Kovid Goyal
31fe35cd38 Fix #5469 2022-09-04 13:58:16 +05:30
Kovid Goyal
607bc845fc Allow creating overlay-main windows, which are treated as the active window unlike normal overlays
Fixes #5392
2022-09-03 19:04:31 +05:30
Kovid Goyal
a420d9d19c spacing is a clone safe option 2022-09-02 23:28:58 +05:30
Kovid Goyal
4b81e4936e launch: Allow setting the margin and padding for the newly created window
Fixes #5463
2022-09-02 19:41:05 +05:30
Kovid Goyal
295743a96e Fix ref to launch doc 2022-09-02 16:31:21 +05:30
Kovid Goyal
d3a1848c27 Remove markup from ref_hyperlink text 2022-09-02 16:24:50 +05:30
Kovid Goyal
9cec924f32 hints kitten: Allow using launch as the program to run, to open the result in a new kitty tab/window/etc.
Fixes #5462
2022-09-02 16:23:00 +05:30
Kovid Goyal
67c963ab89 Pass KITTY_LISTEN_ON to programs opened via open_url
Useful if those programs want to talk to kitty via the rc socket
2022-09-02 16:01:30 +05:30
Kovid Goyal
0f7ced25c1 ... 2022-09-01 13:55:48 +05:30
Kovid Goyal
42948ffff0 Merge branch 'docs' of https://github.com/page-down/kitty 2022-09-01 13:55:30 +05:30
pagedown
922ce5bdea Docs: Put example commands in code blocks 2022-09-01 15:35:51 +08:00
pagedown
1b42486026 Docs: Remove the extra empty line in the CLI help
Also keep the example code in a code block, in the HTML documentation.
2022-09-01 15:35:41 +08:00
pagedown
95f1a971b2 Docs: Mention clear_all_shortcuts in the FAQ about show_key kitten 2022-09-01 15:35:17 +08:00
Kovid Goyal
7968c88c67 ... 2022-09-01 07:54:36 +05:30
Kovid Goyal
992e90b0a3 Fix a regression in 0.26.0 that broke mapping of native keys who key codes did not fit in 21 bits
Fixes #5452
2022-08-31 22:19:51 +05:30
Kovid Goyal
afada84f52 Cleanup previous PR
Use wcswidth() for line width calculation. Works with emoji and ignores
escape codes automatically. Add changelog entry.
2022-08-31 08:01:52 +05:30
Kovid Goyal
b978ff8930 Merge branch 'fix/hints-next-line' of https://github.com/trygveaa/kitty 2022-08-31 07:56:38 +05:30
Kovid Goyal
053cede581 Use git rev-parse to get nightly commit hash 2022-08-31 07:22:56 +05:30
Trygve Aaberge
03720402a7 Fix hints sometimes matching next line as part of URL
For URLs where there's fewer characters left to the right edge of the
window than the number of escape characters in the line, the next line
would be included in the URL, as if the URL went all the way to the
right edge.

For example with a 40 chars wide terminal, if you run:

    echo -e '\e[31m1\e[m https://github.com/kovidgoyal/kitty\ntest'

And launch the hints kitten, you'll see that test on the next line will
be included in the URL.

This happened because the calculation for filling the rest of the line
with NUL characters counted the escape characters as well as the visible
characters, so it filled in too few characters.

This is a regression introduced in commit 91966712.
2022-08-30 22:24:58 +02:00
Kovid Goyal
fca0999814 Eureka! Figured out why libedit is breaking in prewarm on macOS via launchd
The prewarm zygote imports the world. shell.py had a top level import
for readline. Which means readline was being imported pre-fork. And of
course as is traditional with Apple libedit is not fork safe. Probably
because it initializes its internal IO routines based on the stdio
handles at time of import which are the handles kitty gets from launchd
2022-08-30 19:35:17 +05:30
Kovid Goyal
78056c659c Another place we cant use readline on macOS 2022-08-30 19:27:55 +05:30
Kovid Goyal
30e1b4680d Only override LANG in default env if it was not set either in the original os env or via the env config directive 2022-08-30 19:17:53 +05:30
Kovid Goyal
89a0c04d19 Fix exec in prewarm forked process sometimes inheriting env vars from grandparent process 2022-08-30 19:03:32 +05:30
Kovid Goyal
1ba027c277 Dont show LC_CTYPE in show_kitty_env_vars when running with system python on macOS 2022-08-30 16:55:17 +05:30
Kovid Goyal
d8e43a3412 macOS: Fix regression in 0.26.0 that caused asking the user for a line of input such as for set_tab_title to not work
Apparently libedit doesn't work in the forked process when the parent
process is run via Launch Services. I cant be bothered to investigate
why, given that libedit is closed source. macOS users will just have to
live without history/completion in the ask kitten until I get around to
writing a replacement for readline/libedit.

And on a personal note, macOS >> Necrotizing fasciitis

Fixes #5447
2022-08-30 16:45:14 +05:30
Kovid Goyal
644e46e91d Reconfigure all stdio streams in the prefork process 2022-08-30 16:22:59 +05:30
Kovid Goyal
e2a1f8dde7 ... 2022-08-30 10:40:59 +05:30
Kovid Goyal
7d09c6b762 Link to start of actual changelog 2022-08-30 10:27:53 +05:30
Kovid Goyal
6604e0d015 Fix regression in 0.26.0 that caused launching kitty without working STDIO handles to result in high CPU usage and prewarming failing
Fixes #5444
2022-08-30 08:15:13 +05:30
Kovid Goyal
bb2ec9cde7 ... 2022-08-30 07:50:36 +05:30
Kovid Goyal
89a2545855 Cleanup previous PR
Allow disabling hyperlinking of rg output. Also parse
--kitten=hyperlink=... form of CLI args.
2022-08-30 07:41:14 +05:30
Kovid Goyal
49f8c0eae6 Merge branch 'hyperlinked-grep-only-matches' of https://github.com/groves/kitty 2022-08-30 06:59:53 +05:30
Kovid Goyal
268d687814 version 0.26.1
Bloody macOS. I have better things to do that play whack-a-mole with all
the bug reports caused macOS not bothering to set LANG.
2022-08-30 01:04:42 +05:30
Charlie Groves
db5b4da388 Add options for linking different parts of ripgrep output 2022-08-29 13:23:42 -04:00
Kovid Goyal
71f8e50460 Update changelog 2022-08-29 21:01:59 +05:30
Kovid Goyal
22fbdbca40 Fix a regression in 0.26.0 that caused kitty to no longer set the LANG environment variable on macOS
Happened because reading the locale uses cocoa APIs and they are not fork
safe, so it was moved to after prewarm forking, but at that point the
default child env had already been set.

Fixes #5439
2022-08-29 20:58:48 +05:30
Kovid Goyal
6253ee2a74 Allow resetting the tab title to default 2022-08-29 20:41:07 +05:30
Kovid Goyal
5b28aed0b1 Allow the set_tab_title action to take an argument 2022-08-29 20:11:18 +05:30
Kovid Goyal
9eabc9ecf1 Merge branch 'bash-inherit_errexit' of https://github.com/grimm26/kovidgoyal-kitty 2022-08-29 19:47:24 +05:30
Mark Keisler
a77852466c bash shell integration: Send STDERR of unsetting inherit_errexit to
/dev/null

Some bash versions may not have that option and rather than checking if
they even have it or if it is set, just quiet the STDERR it may throw.

```
$ kssh myhost
bash: shopt: inherit_errexit: invalid shell option name
myhost:~$ bash --version
GNU bash, version 4.3.48(1)-release (x86_64-pc-linux-gnu)
Copyright (C) 2013 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>

This is free software; you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
```
2022-08-29 08:58:54 -05:00
Kovid Goyal
c68b82e4d0 ssh kitten: Fix executable permission missing from kitty bootstrap script
Fixes #5438
2022-08-29 18:20:09 +05:30
Kovid Goyal
16a4845a72 version 0.26.0 2022-08-29 05:05:11 +05:30
Kovid Goyal
16da031f68 Wait till prompt appears before issuing clear 2022-08-28 21:54:55 +05:30
Kovid Goyal
43b2935e52 Make fish shell integration test for XDG_DATA_DIRS work even if the shells rc files add to XDG_DATA_DIRS.
My Linux distro has now started installing system wide rc files that do
this :((
2022-08-28 21:15:26 +05:30
Charlie Groves
8c7968a4d6 Describe --hyperlink-only-matches in the docs 2022-08-28 07:02:39 -04:00
Kovid Goyal
fba759a47c missed some at_ -> at- 2022-08-28 12:04:00 +05:30
Kovid Goyal
3bcb694b1b Switch over to at-cmd form for references.
Sphinx anyway converts at_cmd to at-cmd for anchors in HTML so using at-cmd
consistently.
2022-08-28 11:54:32 +05:30
Kovid Goyal
555020cfd5 Also allow using at-cmd 2022-08-28 10:26:38 +05:30
Kovid Goyal
391e2b8488 Fix resolution of anchor names for kitty @ command docs 2022-08-28 10:25:00 +05:30
Kovid Goyal
c856d5c058 Fix hyperlinks not present when fetching text from the history buffer
Fixes #5427
2022-08-28 08:54:53 +05:30
Charlie Groves
f5a70adf0b Add a --hyperlink-only-matches flag to hyperlinked_grep
If it's active, only matching lines get links, not file headers or context lines.
2022-08-26 17:05:50 -04:00
Kovid Goyal
e330c38d4a ssh kitten: Delegate to ssh when -T is used
Fixes #5411
2022-08-24 15:23:41 +05:30
Kovid Goyal
d595084395 DRYer 2022-08-24 15:02:36 +05:30
Kovid Goyal
b32ee5ee46 Forgot to change code to remove markup for github links 2022-08-24 15:00:39 +05:30
Kovid Goyal
098dd10789 ... 2022-08-24 14:42:40 +05:30
Kovid Goyal
b5fa643c5d Allow ignoring failures when mapping remote control commands 2022-08-24 14:21:54 +05:30
Kovid Goyal
664dd29970 Merge branch 'rc-no-response' of https://github.com/page-down/kitty 2022-08-24 14:15:13 +05:30
Kovid Goyal
b7a4281985 Allow ignoring failure to close windows/tabs via rc commands 2022-08-24 14:13:31 +05:30
Kovid Goyal
9e9aa52553 Ensure extract_rt_targets is run only once per build 2022-08-24 14:00:44 +05:30
Kovid Goyal
77fbdfbb53 Fix finding local docs when running from source on macOS 2022-08-24 13:54:14 +05:30
Kovid Goyal
214416f1e3 Fix handling of :doc: in CLI help output 2022-08-24 13:43:47 +05:30
pagedown
800437ec6b Remote control: Add --no-response to some commands 2022-08-24 15:14:53 +08:00
Kovid Goyal
957eafbef0 Merge branch 'docs' of https://github.com/page-down/kitty 2022-08-24 12:35:00 +05:30
pagedown
7f228bcbf5 Docs: Unify the list style of available values
Highlight the value and provide hyperlink in the description.
2022-08-24 13:30:52 +08:00
pagedown
fd4a682c5b Fix doc website URL with duplicate slashes 2022-08-24 13:29:51 +08:00
pagedown
ba9afc61a4 Hyperlink doc text role 2022-08-24 13:29:07 +08:00
pagedown
9a70709bba Shorten the reference link to the top of the page
Reduce the length of the link :ref:`shell_integration` in commented conf.
2022-08-24 13:27:19 +08:00
pagedown
c437a36794 Fix GitHub links in commented configuration
Hyperlink GitHub related text roles: iss, pull, disc
2022-08-24 13:27:12 +08:00
pagedown
0e0578ff49 Docs: Use --help long option name in the document
Remove the extra empty line in the CLI help for `--replay-commands`.
2022-08-24 13:27:06 +08:00
pagedown
64a202a125 Docs: Using the lowercase form of the key name consistently 2022-08-24 13:26:50 +08:00
Kovid Goyal
740d1ca146 Merge branch 'high-sierra-compat' of https://github.com/rkitover/kitty 2022-08-20 22:15:10 +05:30
Rafael Kitover
7b75f055ea Fix build on macOS High Sierra
Check for >= 10.14 using Availability.h to use the accessibilityRole
callback which does not seem to be available in 10.13.

Signed-off-by: Rafael Kitover <rkitover@gmail.com>
2022-08-20 16:08:28 +00:00
Kovid Goyal
8d6a3cff25 Fix docs build error 2022-08-20 16:26:49 +05:30
Kovid Goyal
10fdde6647 Hyperlink :envvar: as well 2022-08-20 16:24:46 +05:30
Kovid Goyal
e1c45dc23f ... 2022-08-20 16:20:30 +05:30
Kovid Goyal
2efb8f6dc2 Create an API to easily use remote control commands from kittens 2022-08-20 16:19:16 +05:30
Kovid Goyal
3b77f3b4bc Also hyperlink :term: 2022-08-20 15:40:39 +05:30
Kovid Goyal
31f763282f Document the show help shortcut 2022-08-20 14:03:16 +05:30
Kovid Goyal
39434fb1f6 A new default shortcut to show the kitty documentation 2022-08-20 13:55:10 +05:30
Kovid Goyal
44ccdd36d6 Remove socket prewarming
The potential for breakage is too high, and I am working on an
alternative solution that will be better long term.

Prewarming is still used for kittens launched via keybindings
2022-08-20 13:38:33 +05:30
Kovid Goyal
4cc0138a28 Delete the frozen python dir
I verified that all the files remaining in it are loaded via the python
resource system and so are not needed.
2022-08-20 13:05:12 +05:30
Kovid Goyal
6ca39d9d83 Move code to delete empty folders into bypy
So it applies to both linux and mac builds automatically
2022-08-20 12:46:55 +05:30
Kovid Goyal
26c099639c Remove empty folders from macOS package builds 2022-08-20 12:20:18 +05:30
Kovid Goyal
329043ba08 Cleanup build documentation
Note how to build the kitty docs wherever needed instead of in a
separate section
2022-08-20 12:09:36 +05:30
Kovid Goyal
e289f4959f DRYer 2022-08-20 12:03:33 +05:30
Kovid Goyal
b6760a59fa Another bug in resolve_ref 2022-08-20 11:45:48 +05:30
Kovid Goyal
cd35f92607 Fix resolve_ref() 2022-08-20 11:29:40 +05:30
Kovid Goyal
ea8f223298 Cleanup the wrap implementation
Make it more efficient and add support for hyperlink escapes
2022-08-20 09:17:05 +05:30
Kovid Goyal
a4c3154dab ... 2022-08-20 08:27:24 +05:30
Kovid Goyal
6aa3405c78 Clean up build docs a bit 2022-08-20 08:13:42 +05:30
Kovid Goyal
da618584af Fix some outdated docs 2022-08-19 15:48:17 +05:30
Kovid Goyal
9bc31a5651 Use locally built docs when running from source if they exist 2022-08-19 15:01:20 +05:30
Kovid Goyal
314dd97059 Command line tools shouldnt need to resolve documentation refs
Instead use a new kitty+doc protocol and have kitty navigate to the
docs. Uses a default open action for the protocol, which can be
overriden by the user should they so desire.
2022-08-19 14:35:17 +05:30
Kovid Goyal
0b66f20934 Fix mapping of ref targets with underscores 2022-08-19 14:34:25 +05:30
Kovid Goyal
aba634ce88 Fix building of docs on macOS without warnings
--detach doesnt exist on macOS
2022-08-19 14:16:28 +05:30
Kovid Goyal
033950dae9 Only hyperlink when stdout is a tty 2022-08-19 14:05:53 +05:30
Kovid Goyal
a59e1adee1 Also hyperlink the :ac: role in CLI help output 2022-08-19 14:05:11 +05:30
Kovid Goyal
5350eb29c1 A new mappable action to show kitty docs in the browser 2022-08-19 14:00:30 +05:30
Kovid Goyal
2bb42e67d7 We have to build docs to test building of package now 2022-08-19 13:51:35 +05:30
Kovid Goyal
8745c4cd4a Make the kitty man pages automatically available inside kitty when using a binary build 2022-08-19 12:59:10 +05:30
Kovid Goyal
3288400005 Make the docs and man pages available in the macos bundle as well 2022-08-19 12:38:10 +05:30
Kovid Goyal
1f499a7c6c Add newline to end of generated file 2022-08-19 11:29:47 +05:30
Kovid Goyal
012731c3be Clean _generated.h files 2022-08-19 11:22:30 +05:30
Kovid Goyal
5deed81737 Dont maintain ref_map manually 2022-08-19 11:20:50 +05:30
Kovid Goyal
6f6e23bf61 Update docs 2022-08-19 10:00:06 +05:30
Kovid Goyal
d2d0487356 Hyperlink :ref: roles in CLI help 2022-08-19 09:57:52 +05:30
Kovid Goyal
30df4e5de2 Improve formatting of --stdin-source 2022-08-19 09:34:52 +05:30
Kovid Goyal
3f4588c408 Improve formatting of launch --type help message 2022-08-19 09:30:22 +05:30
Kovid Goyal
4e4ca366d9 Merge branch 'docs' of https://github.com/page-down/kitty 2022-08-18 17:52:24 +05:30
pagedown
040ff0cc9d For running the new code KITTY_PREWARM_SOCKET needs to be dropped 2022-08-18 17:06:07 +08:00
pagedown
b01ad4bb3b ... 2022-08-18 17:05:35 +08:00
pagedown
4476251b76 List the available data names for tab_title_template in commented conf
List syntax starting with * becomes a block of text in the commented
configuration file.
2022-08-18 17:05:24 +08:00
pagedown
0f4cb1955f Use the plus sign to connect shortcut keys consistently 2022-08-18 17:05:00 +08:00
Kovid Goyal
c161ee7b5e Merge branch 'rc-password' of https://github.com/page-down/kitty 2022-08-17 18:41:48 +05:30
pagedown
a5bb2548a6 Do not set KITTY_LISTEN_ON after the window rc password is configured 2022-08-17 19:37:52 +08:00
Kovid Goyal
2898a3ef8c Some documentation cleanup 2022-08-17 06:48:33 +05:30
Kovid Goyal
a0568334b5 Change the default for allow_remote_control back to no
That way if there are any bugs in the implementation, we wont be
exposing users by default. In the future after the implementation has
been battle tested, we can revisit.
2022-08-17 06:42:51 +05:30
Kovid Goyal
4005cfdff2 Disallow passwords that start with - to allow for future addition of options 2022-08-17 00:58:11 +05:30
Kovid Goyal
1d8c5e65b9 Ignore generated .go files 2022-08-17 00:55:12 +05:30
Kovid Goyal
56f45e8b0f Fix unhandled exceptions not being printed to stderr on macOS when run from launch services and using prewarming 2022-08-16 15:28:07 +05:30
Kovid Goyal
48a9584688 Hide the password when asking for rc permission
Can press a key or click on it to reveal it
2022-08-16 14:07:36 +05:30
Kovid Goyal
bfcd324993 ask kitten: allow having hidden text in the message 2022-08-16 13:57:58 +05:30
Kovid Goyal
a75235a260 rcp ars should be a sequnce not a set 2022-08-16 12:10:15 +05:30
Kovid Goyal
e8de2def96 Fix --allow-remote-control not working with allow_remote_control=no 2022-08-16 11:42:39 +05:30
Kovid Goyal
5ffc4c6498 DRYer 2022-08-16 11:37:31 +05:30
Kovid Goyal
d0c50248ea Graphics protocol: Only delete temp files if they have the string tty-graphics-protocol in their file paths.
This prevents deletion of arbitrary files in /tmp via the graphics
protocol.
2022-08-16 11:25:33 +05:30
Kovid Goyal
ca2a121696 Nicer error when listen on socket is not found 2022-08-16 10:59:51 +05:30
Kovid Goyal
02d06d6726 Fix --allow-remote-control without passwords not working 2022-08-16 10:51:54 +05:30
Kovid Goyal
18bf76d49e Dont set KITTY_LISTEN_ON for windows with --allow-remote-control 2022-08-16 10:50:17 +05:30
Kovid Goyal
6961845167 ask kitten: fix button click area offset vertically 2022-08-16 10:35:51 +05:30
Kovid Goyal
4c5f7f50f7 Control KITTY_LISTEN_ON more precisely 2022-08-16 10:16:18 +05:30
Kovid Goyal
572e920466 Allow restricting the remote control actions in specific windows 2022-08-16 07:08:51 +05:30
Kovid Goyal
b81fb3c865 Disable pre-warming when running gen-config.py 2022-08-16 05:41:46 +05:30
Kovid Goyal
814dd8a275 allow_remote_control should be per window not per child 2022-08-15 21:32:14 +05:30
Kovid Goyal
1619687d1d Allow specifying allowed actions when no password is sent 2022-08-15 21:05:53 +05:30
Kovid Goyal
65fc61a507 Remove unused code 2022-08-15 20:54:17 +05:30
Kovid Goyal
d027f524ce Make allow_remote_control a little more fine grained
Also, only respect listen_on if there is a possiblility of rc commands
over it being accepted
2022-08-15 20:51:11 +05:30
Kovid Goyal
df5e6e1563 simpler ignore pattern 2022-08-15 20:15:30 +05:30
Kovid Goyal
5541e3c2ff More robust cleaning of launcher dir 2022-08-14 23:39:26 +05:30
Kovid Goyal
57dfc379ae Fix cocoa being loaded before the fork on macOS 2022-08-14 22:17:27 +05:30
Kovid Goyal
b5467b8e26 Set the cocoa uncaught exception handler during glfw init not at module import time 2022-08-14 19:33:32 +05:30
Kovid Goyal
a9f1928913 ... 2022-08-14 19:16:47 +05:30
Kovid Goyal
ae16fed39b Fix repeated make app failing on macOS 2022-08-14 19:01:58 +05:30
Kovid Goyal
848a795d26 Fix minimal macos bundle build 2022-08-14 13:48:45 +05:30
Kovid Goyal
deb8c3dacd Dont put the launcher source files in the root directory 2022-08-14 13:01:29 +05:30
Kovid Goyal
3cb572b47a Fix build on older gcc 2022-08-14 10:12:17 +05:30
Kovid Goyal
df3846fbb8 Add instructions on how to install the man pages under desktop integration 2022-08-12 23:33:06 +05:30
Kovid Goyal
d73ceb26ae Use the RFC as the reference for base-85 encoding 2022-08-12 15:38:28 +05:30
Kovid Goyal
da9ffc9b93 Allow using IV and tags longer than the minimum lengths 2022-08-12 13:21:57 +05:30
Kovid Goyal
63fa0c4e94 Nicer fix for human_repr of keys defined with kitty_mod 2022-08-12 12:37:15 +05:30
Kovid Goyal
ce91b6d9d9 Switch to using the new SingleKey implementation 2022-08-12 12:21:06 +05:30
Kovid Goyal
c982f24faf Add some tests for hashing and __eq__ 2022-08-12 12:02:22 +05:30
Kovid Goyal
9f865adb83 DRYer 2022-08-12 11:39:26 +05:30
Kovid Goyal
b54dd1cb48 Increase the max key num that is storeable 2022-08-12 11:37:54 +05:30
Kovid Goyal
ef621aa099 DRYer
Also dont store negative values for key. Unset is 0 not -1
2022-08-12 11:35:45 +05:30
Kovid Goyal
df4738f080 ... 2022-08-12 11:24:18 +05:30
Kovid Goyal
8d0a06325c Update config types for new value of KITTY_MOD 2022-08-12 11:07:11 +05:30
Kovid Goyal
f3329fcd34 Fix storage for GLFW_MOD_KITTY 2022-08-12 09:58:50 +05:30
Kovid Goyal
af48547d8b Implement SingleKey._replace 2022-08-12 09:40:58 +05:30
Kovid Goyal
f228f8368a A faster version of SingleKey 2022-08-12 09:17:42 +05:30
Kovid Goyal
9bb2c1a27b Type objects should be static 2022-08-12 08:32:11 +05:30
Kovid Goyal
aa0b07a90d Fix #5371 2022-08-12 08:15:25 +05:30
Kovid Goyal
d4075bfa9a ... 2022-08-12 07:01:40 +05:30
Weng Xuetian
7fd119d0eb Fix message recursion between wayland compositor (#5360)
1. Only update preedit if preedit changed.
2. Only send cursor update if cursor position is not changed.
2022-08-11 15:45:45 -07:00
Kovid Goyal
2b7455e353 Use kitty_mod in debug config output
Fixes #5367
2022-08-11 23:45:23 +05:30
Kovid Goyal
f42d2c63a6 Add type annotations to rc protocol field definitions 2022-08-11 22:14:33 +05:30
Kovid Goyal
6be3ae9efc Start work on standalone remote control script 2022-08-11 21:05:04 +05:30
Kovid Goyal
2fd2e07342 Fix #5366 2022-08-11 15:47:06 +05:30
Kovid Goyal
1e0e32e282 DRYer 2022-08-11 13:42:38 +05:30
Kovid Goyal
b2d8f24499 Clean up the text a bit 2022-08-11 07:47:15 +05:30
Kovid Goyal
12c99741a0 Add an example of restricting the launch command 2022-08-11 07:35:18 +05:30
Kovid Goyal
91dbcf4df0 Link to encryption spec 2022-08-11 07:29:56 +05:30
Kovid Goyal
6ebd82a84c Note which version remote_control_password was added 2022-08-11 06:52:37 +05:30
Kovid Goyal
c07178f43a Avoid transmitting the currently un-needed enc_proto 2022-08-11 06:48:35 +05:30
Kovid Goyal
78a5957863 Highlight the JSON blocks appropriately 2022-08-11 06:46:42 +05:30
Kovid Goyal
cd6882d21e ... 2022-08-11 06:40:44 +05:30
Kovid Goyal
926a2828ab 5 minutes does not actually prevent replay just minimise it 2022-08-11 06:38:59 +05:30
Kovid Goyal
daa7df96d1 ... 2022-08-11 06:38:04 +05:30
Kovid Goyal
84ca83ef69 Document the encryption used by remote_control_password 2022-08-11 06:35:25 +05:30
Kovid Goyal
ac9c85e783 Add a note about password auth over SSH 2022-08-11 06:08:28 +05:30
Kovid Goyal
331f6d4903 Document remote_control_password more thoroughly
Also ignore failures in custom auth functions
2022-08-11 05:58:02 +05:30
Kovid Goyal
2e422e5ba8 Use getpass() to read the password from STDIN when it is a tty 2022-08-11 05:20:05 +05:30
Kovid Goyal
20cffc728e Close tty_fd after dup2 2022-08-11 05:10:15 +05:30
Kovid Goyal
b06cbc9465 Use the OS secure random number generator rather than the OpenSSL one to generate IVs
The OpenSSL one is not fork safe, and in general I trust kernel CSRNG
more than OpenSSL
2022-08-11 05:07:38 +05:30
Kovid Goyal
1348327414 Pressing esc for the permission dialog should be same as reject this request 2022-08-10 20:36:15 +05:30
Kovid Goyal
cd3eeb7a95 Center choice message correctly when it is multi-line
Also fix button wrap calculation. It was not taking the borders into
account.
2022-08-10 20:34:25 +05:30
Kovid Goyal
7be6b28011 Preserve blanks lines and per line formatting in the ask kitten for the message with choices 2022-08-10 20:10:17 +05:30
Kovid Goyal
ef1bee0f48 Shorten text 2022-08-10 20:00:20 +05:30
Kovid Goyal
702da542dd Use a as the default accelerator rather than t 2022-08-10 19:11:18 +05:30
Kovid Goyal
5ba92d06cf Get async response working with sockets 2022-08-10 19:10:04 +05:30
Kovid Goyal
34a7b42063 Dont print traceback when socket is unexpectedly closed 2022-08-10 19:06:57 +05:30
Kovid Goyal
963d1b58f8 Better error message when socket is closed without response 2022-08-10 18:53:15 +05:30
Kovid Goyal
fe598bac8a Quote ^ as it is a special char in some shells 2022-08-10 17:39:05 +05:30
Kovid Goyal
45736d7f1d ... 2022-08-10 17:28:22 +05:30
Kovid Goyal
0fe4f5a686 Fix password based rc not working with generator responses 2022-08-10 17:24:10 +05:30
Kovid Goyal
e9ce5c02d0 Allow remote control commands to be interrupted by ctrl-c while waiting for a response 2022-08-10 17:00:04 +05:30
Kovid Goyal
5916d82580 Send disallowed responses when permission for rc is denied 2022-08-10 16:28:14 +05:30
Kovid Goyal
2c83b9902e Implement the permissions system for password based rc requests 2022-08-10 15:49:50 +05:30
Kovid Goyal
fe07825ad9 Work on new permissions framework for rc commands 2022-08-10 12:36:04 +05:30
Kovid Goyal
56e83d7d07 Write code to decrypt commands received in kitty 2022-08-10 12:36:04 +05:30
Kovid Goyal
c7e3c92a0a Allow listen_on to be used even without allow_remote_control
Since we intend to allow password based access, which works regardless
of the value of allow_remote_control
2022-08-10 12:36:04 +05:30
Kovid Goyal
1a643441f3 Make the kitty public key available as an env var to child processes 2022-08-10 12:36:04 +05:30
Kovid Goyal
2aee746da9 Write the code to encrypt rc messages to kitty 2022-08-10 12:36:04 +05:30
Kovid Goyal
e64b1ba67c Start work on remote control passwords 2022-08-10 12:36:04 +05:30
Kovid Goyal
31be4f041e remove unused code 2022-08-10 12:31:47 +05:30
Kovid Goyal
1f5ebc408d When searching macOS for openssl search for the same version as used by the python we are running 2022-08-10 12:30:36 +05:30
Kovid Goyal
b4d9a22df8 Install the same version of OpenSSL as used by python on brew based CI 2022-08-10 12:21:01 +05:30
Kovid Goyal
d4168e3b80 Dont add openssl to the brewfile
We only need to install it on CI because the python on CI doesnt come
from brew. Normal brewfile based installation will install openssl as a
dependency of python
2022-08-10 12:02:43 +05:30
Kovid Goyal
241c7af855 DRYer 2022-08-10 11:45:07 +05:30
Kovid Goyal
080fcd8fc1 Link against newer rather than older openssl 2022-08-10 11:36:56 +05:30
Kovid Goyal
1aad4c7ec3 Only search for brew openssl on failure 2022-08-10 11:35:43 +05:30
Kovid Goyal
e0e0582b53 Fix #5364
macOS is *the* worst UNIX I have ever seen.
2022-08-10 11:33:30 +05:30
Kovid Goyal
0a6276b007 Implement completion for kitty @ global options 2022-08-09 18:54:38 +05:30
Kovid Goyal
2a2256f7d9 ... 2022-08-09 16:11:23 +05:30
Kovid Goyal
ed81a60065 Add keywords completion for --cwd and --config 2022-08-09 16:07:04 +05:30
Kovid Goyal
5ad55dd165 Allow using file completion for any type of command line arg 2022-08-09 15:57:01 +05:30
Kovid Goyal
6860f7ffd6 fix zsh serialization of directory candidates ending with / 2022-08-09 14:51:14 +05:30
Kovid Goyal
33a3e3fb61 Add completion for kitty @ launch --logo 2022-08-09 14:30:13 +05:30
Kovid Goyal
d4df3f67b6 Allow specifying completion for command line arguments that expect paths 2022-08-09 14:21:12 +05:30
Kovid Goyal
f15a2f0c1f Change --session to resolve relative paths from the kitty config dir 2022-08-09 12:36:16 +05:30
Kovid Goyal
252288aff2 kitten completion: Fix --long-opt <TAB> not working 2022-08-09 12:02:25 +05:30
Kovid Goyal
65a20a2407 Merge branch 'show-key-kitten' of https://github.com/page-down/kitty 2022-08-09 11:32:10 +05:30
pagedown
5f180dbd9a ... 2022-08-09 12:29:22 +08:00
pagedown
ee4e9aa678 Add missing modifier key aliases 2022-08-09 12:15:55 +08:00
pagedown
9f1c9529aa Allow completion for show_key kitten
Use the lowercase form of kitty.
2022-08-09 12:15:48 +08:00
Kovid Goyal
5bba1a0851 get_current_selection should return char* not const char* 2022-08-09 09:05:13 +05:30
Kovid Goyal
e9823eb40c Cleanup previous PR 2022-08-09 08:54:47 +05:30
Kovid Goyal
14fc3f6ac4 Merge branch 'macos-accessibility' of https://github.com/page-down/kitty 2022-08-09 08:52:44 +05:30
pagedown
74714f942a Implement macOS accessibility protocol to provide selected text
Allow "Speak selection" (Option+Esc) to work properly.
2022-08-09 11:02:12 +08:00
pagedown
0d116e6ef0 Use four spaces to indent 2022-08-08 22:31:55 +05:30
pagedown
06108d66b1 Replace tab with four spaces indent 2022-08-08 22:31:55 +05:30
Kovid Goyal
21eece4c6d Ensure no bytecode is written when running shell based tests 2022-08-08 17:50:59 +05:30
Kovid Goyal
4dd696e4e0 Add API to glfw to get the currently active text selection 2022-08-08 15:52:34 +05:30
Kovid Goyal
d04d4444af implement primary selection api on cocoa as stubs, can be useful for #5357 2022-08-06 12:59:15 +05:30
Kovid Goyal
a487a78200 Add type definitions for the crypto data types 2022-08-05 14:39:20 +05:30
Kovid Goyal
f06a72b418 OpenSSL 3.0 apparently has API to get rid of the tag length magic number. Lets hope it works 2022-08-05 14:28:56 +05:30
Kovid Goyal
3270c9a527 Get rid of various magic length constants 2022-08-05 14:17:42 +05:30
Kovid Goyal
a7b7fb560a Add tests for AES256GCM 2022-08-05 13:50:03 +05:30
Kovid Goyal
384eba6cd4 Wrap the OpenSSL API for AES 256 GCM encryption 2022-08-05 13:14:25 +05:30
Kovid Goyal
dc7e3ba1ec DRYer 2022-08-05 08:57:22 +05:30
Kovid Goyal
b1e0adcfdc ... 2022-08-05 08:14:29 +05:30
Kovid Goyal
2a5922ce92 Cleanup previous PR
The reason maxsplit is 1 is because some layout action in the future may need more
sophisticated args processing, for example, shlex.split() instead of
plain split(), or even a full command line parser.
2022-08-05 08:12:05 +05:30
Kovid Goyal
93694925ce Merge branch 'feature/toggle_bias' of https://github.com/mong8se/kitty 2022-08-05 08:11:35 +05:30
Steven Moazami
adfcbb004f Add layout_action to change bias on tall layout
Can specify 1 bias to toggle between that and 50%.

Can specify multiple biases to rotate through them with each call to the
layout_action.

Left a comment regarding working around either a possible bug or a
design decision.
2022-08-04 19:29:17 -04:00
Kovid Goyal
6595898b73 Merge branch 'patch-4' of https://github.com/ctrlcctrlv/kitty 2022-08-04 20:45:29 +05:30
Fredrick Brennan
81b33f1f6f Document how to build docs 2022-08-04 11:12:04 -04:00
Kovid Goyal
a1c4ffec20 Private raw key should be returned as a secret 2022-08-04 20:27:38 +05:30
Kovid Goyal
89854cca8b Test for secret derivation 2022-08-04 20:05:19 +05:30
Kovid Goyal
4fe5211ed7 Code to derive the shared secret with elliptic curve keys 2022-08-04 19:42:38 +05:30
Kovid Goyal
795b32efd7 Bash integration: Fix the inherit_errexit option being set by shell integration
Fixes #5349
2022-08-04 16:23:52 +05:30
Kovid Goyal
153064ef3a Fail if mlock fails 2022-08-04 11:16:36 +05:30
Kovid Goyal
183a31c884 mlock() the returned private key to prevent it from being saved to swap 2022-08-04 11:08:54 +05:30
Kovid Goyal
adf47bed89 Use an actual type for the EC key rather than a capsule 2022-08-04 11:01:14 +05:30
Kovid Goyal
cc297a8984 Merge branch 'patch-1' of https://github.com/TomFaulkner/kitty 2022-08-04 07:39:38 +05:30
Tom Faulkner
4ef17edace Fix doc typo: throught to throughout
Just a typo in the docs. Kitty is great, thanks for all the hard work.
2022-08-03 23:52:00 +00:00
Kovid Goyal
e56fa9d31f Try and get Homebrew installed OpenSSL to work 2022-08-03 23:17:47 +05:30
Kovid Goyal
791d4b30fb We need openssl installed via brew 2022-08-03 22:47:11 +05:30
Kovid Goyal
a9a9f1ac00 Add a mappable action to toggle the mirrored setting for the tall and fat layouts
Fixes #5344
2022-08-03 22:45:38 +05:30
Kovid Goyal
fd6bc55db6 Start work on implementing public key crypto
Will come in handy for various things in the future, so lets just setup
the API now. No new dependencies are needed since Python already depends
on OpenSSL.
2022-08-03 22:37:35 +05:30
Kovid Goyal
97d7329d14 A nicer fix for kitty @ ls | less
We rely on the fact that cfmakeraw() and less's code to put the tty in
raw state diverge. This is obv a hack but then so is kitty @ ls | less

This hack allows

kitty +kitten clipboard --get-clipboard > output

to work.
2022-08-02 18:33:53 +05:30
Kovid Goyal
609d42e2bc Ignore EAGAIN when doing tty io 2022-08-02 17:21:28 +05:30
Kovid Goyal
3463931dad Rewrite clipboard kitten to only change termios settings while it is actually reading from terminal 2022-08-02 17:14:27 +05:30
Kovid Goyal
f637bf2377 socket prewarm: Dont control the tty if STDOUT is not a tty
This is because we could be being piped to a program like less that does
want to control the tty itself
2022-08-02 14:09:34 +05:30
Kovid Goyal
2271eb5e60 Document KITTY_PREWARM_SOCKET_REAL_TTY 2022-08-02 08:38:07 +05:30
Kovid Goyal
a5cbb552f0 Allow prewarming of kitty @ commands 2022-08-01 19:47:28 +05:30
Kovid Goyal
e43ca5b031 Add an implementation using splice() for in-kernel tty copies
Sadly splice is currently not functional in Linux, so the implementation
is turned off
2022-08-01 19:16:51 +05:30
Kovid Goyal
cc7e668ad6 Cleanup editing of proc environ 2022-08-01 19:03:03 +05:30
Kovid Goyal
a01dbbdf04 Fix launcher not building universal 2022-08-01 19:03:03 +05:30
Kovid Goyal
e0ce0a67cc ensure setting KITTY_PREWARM_SOCKET_REAL_TTY does not clobber the environ 2022-08-01 19:03:03 +05:30
Kovid Goyal
0d83a8866b Make setting the real tty name more robust 2022-08-01 19:03:03 +05:30
Kovid Goyal
f7a7e39a36 prewarm wrapper should indicate it is active via the process environment 2022-08-01 19:03:03 +05:30
Kovid Goyal
67cb466ea9 ... 2022-08-01 19:03:03 +05:30
Kovid Goyal
376688ab9f Add a test for SIGTSTP via ctrl-z 2022-08-01 19:03:03 +05:30
Kovid Goyal
8668087d15 flush data when exiting on signal as well
should make the signal tests less flaky
2022-08-01 19:03:03 +05:30
Kovid Goyal
9b1c23987c Fix stdout line_buffering incorrect when parent kitty instance has its stdout redirected to a file 2022-08-01 19:03:03 +05:30
Kovid Goyal
784daa1a4b Update changelog for socket prewarm 2022-08-01 19:03:03 +05:30
Kovid Goyal
06f9b73a7b Workaround mypy bug 2022-08-01 19:03:03 +05:30
Kovid Goyal
62c0272df2 Get test.py working when prewarm socket is in operation 2022-08-01 19:03:03 +05:30
Kovid Goyal
7ce2b4c641 Indicate in kitty_run_data we are prewarmed 2022-08-01 19:03:03 +05:30
Kovid Goyal
08c2de541f Nicer establish_controlling_tty 2022-08-01 19:03:03 +05:30
Kovid Goyal
94551623ec Make JSON reading test a bit more robust 2022-08-01 19:03:02 +05:30
Kovid Goyal
cb0d23bae8 Use sub tests for the various prewarm things 2022-08-01 19:03:02 +05:30
Kovid Goyal
cb5157f2d1 Nicer implementation of eintr_retry that does not prevent type checking of wrapped functions arguments 2022-08-01 19:03:02 +05:30
Kovid Goyal
32dcbbb5e1 ... 2022-08-01 19:03:02 +05:30
Kovid Goyal
4eedf0d36c macOS needs SIGTTOU SIGTTIN explicitly ignored to allow the supervisor to use TIOCSWINSZ 2022-08-01 19:03:02 +05:30
Kovid Goyal
be458303c5 Debounce WINSZ events 2022-08-01 19:03:02 +05:30
Kovid Goyal
78542ede14 Separate test for SIGWINCH handling 2022-08-01 19:03:02 +05:30
Kovid Goyal
df8800b7ff tcsetpgrp can raise EINTR despite python claiming to auto retry 2022-08-01 19:03:02 +05:30
Kovid Goyal
9c30cd8891 Use a process supervisor for socket workers
This simplifies the code and also allows SIGTSTP to work as the worker
process is no longer in an orphaned process group.
2022-08-01 19:03:02 +05:30
Kovid Goyal
dda28efd66 Use the same signal to stop as stopped the child 2022-08-01 19:03:02 +05:30
Kovid Goyal
b78183972c Report child stop to wrapper process 2022-08-01 19:03:02 +05:30
Kovid Goyal
fc06196a3e Restore termios state when stopping 2022-08-01 19:03:02 +05:30
Kovid Goyal
2a1809a2d8 When exiting with a signal run cleanup 2022-08-01 19:03:02 +05:30
Kovid Goyal
ac5c312267 Work on handling child stop events 2022-08-01 19:03:02 +05:30
Kovid Goyal
8f3174038b Fix running of test suite inside kitty 2022-08-01 19:03:02 +05:30
Kovid Goyal
2d8113e0e0 Give up on signal delivery tests 2022-08-01 19:03:02 +05:30
Kovid Goyal
e881850bb4 ... 2022-08-01 19:03:02 +05:30
Kovid Goyal
4cbae1db89 ... 2022-08-01 19:03:02 +05:30
Kovid Goyal
97bce7be18 and again 2022-08-01 19:03:01 +05:30
Kovid Goyal
5d2a276172 ... 2022-08-01 19:03:01 +05:30
Kovid Goyal
762dfe8315 increase timeout since signal delivery on CI is flakey 2022-08-01 19:03:01 +05:30
Kovid Goyal
1c0d1ec8a9 wait for child events explicitly 2022-08-01 19:03:01 +05:30
Kovid Goyal
e650699217 py3.8 compat 2022-08-01 19:03:01 +05:30
Kovid Goyal
5ff2b5be1c Clear out any signals before ending test 2022-08-01 19:03:01 +05:30
Kovid Goyal
f1841d7c81 DRYer 2022-08-01 19:03:01 +05:30
Kovid Goyal
fd6231a778 Fix signal reading in prewarm wrapper 2022-08-01 19:03:01 +05:30
Kovid Goyal
751a52153d Restore python signal handlers properly after the test 2022-08-01 19:03:01 +05:30
Kovid Goyal
61b733bae9 Add a test for SIGCHLD on SIGTSTP 2022-08-01 19:03:01 +05:30
Kovid Goyal
624e96df9b wrapper process should exit with signal if prewarmed worker exits with signal 2022-08-01 19:03:01 +05:30
Kovid Goyal
a3f1a44d83 OK I give up I cant get signal delivery to work reliably 2022-08-01 19:03:01 +05:30
Kovid Goyal
ed1547938e When running tests ensure the signal mask is empty for processes run in the testing pty 2022-08-01 19:03:01 +05:30
Kovid Goyal
f96a13e9e4 mask handled signals when running signal handler 2022-08-01 19:03:01 +05:30
Kovid Goyal
7b70ed96b6 DRYer 2022-08-01 19:03:01 +05:30
Kovid Goyal
9379853d47 Get the SIGINT test working on macOS 2022-08-01 19:03:01 +05:30
Kovid Goyal
6ccfebd9e3 ... 2022-08-01 19:03:01 +05:30
Kovid Goyal
45186a17ca macOS doesnt allow TIOCSWINSZ from any process other than the process connected to the terminal or its parent
So send it over the socket to the zygote and have it resize the
terminal. Sigh.
2022-08-01 19:03:00 +05:30
Kovid Goyal
24bb4585af Allow easily skipping tests when updating on ox 2022-08-01 19:03:00 +05:30
Kovid Goyal
feb96f1be8 Use O_CLOEXEC for temp ctty fds 2022-08-01 19:03:00 +05:30
Kovid Goyal
b7d3d64975 Ignore error condition on master fd of testing pty 2022-08-01 19:03:00 +05:30
Kovid Goyal
6114b49630 Ensure pty is in utf8 2022-08-01 19:03:00 +05:30
Kovid Goyal
87d95caae0 Dont bother sending slave fd over the socket as it doesnt help on macOS anyway 2022-08-01 19:03:00 +05:30
Kovid Goyal
9535bc94ff Use both open and the ioctl to set the controlling terminal 2022-08-01 19:03:00 +05:30
Kovid Goyal
0841be7803 Test sigwinch handling 2022-08-01 19:03:00 +05:30
Kovid Goyal
6cec89181b dont abort when failing to write to a tty 2022-08-01 19:03:00 +05:30
Kovid Goyal
cb78e17594 dont break when socket is pre-closed 2022-08-01 19:03:00 +05:30
Kovid Goyal
285c399ae5 ... 2022-08-01 19:03:00 +05:30
Kovid Goyal
c9b14f6f78 Switch to using select() instead of poll() in prewarm wrapper
This is because poll() is broken on macOS with pty fds
2022-08-01 19:03:00 +05:30
Kovid Goyal
6a101c51d2 Close tty_fd in master on fork() rather than on close() 2022-08-01 19:03:00 +05:30
Kovid Goyal
8998970adc Make the socket prewarm test a bit more robust 2022-08-01 19:03:00 +05:30
Kovid Goyal
991fbacb99 Fix ttyfd passing 2022-08-01 19:03:00 +05:30
Kovid Goyal
72f3e8cd40 Avoid passing around pty paths, instead send the pty fd 2022-08-01 19:03:00 +05:30
Kovid Goyal
cf8113ea24 Even more flexible management of poll data 2022-08-01 19:03:00 +05:30
Kovid Goyal
5d1cf49fb6 Only set control msg metadata when actually sending a control msg 2022-08-01 19:03:00 +05:30
Kovid Goyal
90f3c0f9af Workaround macOS weirdness 2022-08-01 19:02:59 +05:30
Kovid Goyal
d02598688a Show full traceback for failures to fork socket child 2022-08-01 19:02:59 +05:30
Kovid Goyal
1991f1ccd7 Better handling of multiple optional to poll fds 2022-08-01 19:02:59 +05:30
Kovid Goyal
8fad8972d5 ... 2022-08-01 19:02:59 +05:30
Kovid Goyal
fc3e78e226 Also handle SIGQUIT 2022-08-01 19:02:59 +05:30
Kovid Goyal
15aace29a1 Restore python signal handlers in forked workers 2022-08-01 19:02:59 +05:30
Kovid Goyal
12a3a2d7fe Only set switch interval after prewarm fork 2022-08-01 19:02:59 +05:30
Kovid Goyal
7e26a340a3 Try to read from child pty even after zygote signals its death 2022-08-01 19:02:59 +05:30
Kovid Goyal
f0764c24d2 Retry read/write while there is space 2022-08-01 19:02:59 +05:30
Kovid Goyal
d080bf3b9c Forward termination signals 2022-08-01 19:02:59 +05:30
Kovid Goyal
51698dff07 ... 2022-08-01 19:02:59 +05:30
Kovid Goyal
4154926be7 Get the test to pass on macOS 2022-08-01 19:02:59 +05:30
Kovid Goyal
806ca2b224 Fix atexit handlers being called in forked children
In particular the atexit handler for random_unix_socket()
2022-08-01 19:02:59 +05:30
Kovid Goyal
92bbf08343 Fix socket connect call on non-linux 2022-08-01 19:02:59 +05:30
Kovid Goyal
dc84e3de67 Do not hang forever waiting for child death 2022-08-01 19:02:59 +05:30
Kovid Goyal
8011801549 re-init openssl PRNG when forking for prewarm 2022-08-01 19:02:59 +05:30
Kovid Goyal
dfec88ed15 Inherit full outside env 2022-08-01 19:02:59 +05:30
Kovid Goyal
5d3e2c7111 ... 2022-08-01 19:02:58 +05:30
Kovid Goyal
af1c48e0f7 Dont rely on having source of test modules available 2022-08-01 19:02:58 +05:30
Kovid Goyal
d4bc906c5c Fix launcher build with sanitize 2022-08-01 19:02:58 +05:30
Kovid Goyal
62fe467336 ... 2022-08-01 19:02:58 +05:30
Kovid Goyal
ef3e9d1c2e make various compilers happy 2022-08-01 19:02:58 +05:30
Kovid Goyal
09ddbbf600 Finish move of prewarm launcher into its own compilation unit 2022-08-01 19:02:58 +05:30
Kovid Goyal
4195c239c8 Start moving prewarm launcher into its own compilation unit 2022-08-01 19:02:58 +05:30
Kovid Goyal
a6c3c57d40 Test stdio redirection with socket prewarm 2022-08-01 19:02:58 +05:30
Kovid Goyal
de9263a117 Verify uid/gid of connection from a prewarm client 2022-08-01 19:02:58 +05:30
Kovid Goyal
7b7f1ecc54 Add basic tests for socket prewarm 2022-08-01 19:02:58 +05:30
Kovid Goyal
d1b028c27a Dont pass inherited KITTY_PREWARM_SOCKET 2022-08-01 19:02:58 +05:30
Kovid Goyal
055aae2382 Use correct exit codes for signals 2022-08-01 19:02:58 +05:30
Kovid Goyal
dbb084da7a Cleanup closing of socket child 2022-08-01 19:02:58 +05:30
Kovid Goyal
8332cd2f79 Avoid needing to call os.getpid() repeatedly 2022-08-01 19:02:58 +05:30
Kovid Goyal
4e29c0c16b Propagate SIGWINCH 2022-08-01 19:02:58 +05:30
Kovid Goyal
320d45a3f5 Only use prewarm socket if uid and gid match 2022-08-01 19:02:58 +05:30
Kovid Goyal
73795b5257 detect when socket child closes its tty 2022-08-01 19:02:58 +05:30
Kovid Goyal
16e59784c6 handle failures to send data over socket gracefully 2022-08-01 19:02:58 +05:30
Kovid Goyal
65a7ec3f85 move socket launch handling into its own function 2022-08-01 19:02:57 +05:30
Kovid Goyal
360ff35061 Better error logging from prewarm zygote 2022-08-01 19:02:57 +05:30
Kovid Goyal
5098792723 Make the tty pipes non-blocking 2022-08-01 19:02:57 +05:30
Kovid Goyal
a4883e6d41 Transfer data between ttys 2022-08-01 19:02:57 +05:30
Kovid Goyal
44c9d66dd4 Use a map for pid -> socketchild 2022-08-01 19:02:57 +05:30
Kovid Goyal
c7718d078c Fix parsing of child pid and exit code 2022-08-01 19:02:57 +05:30
Kovid Goyal
2525994db4 ... 2022-08-01 19:02:57 +05:30
Kovid Goyal
81e6afa9b3 Cleanup fd transmit 2022-08-01 19:02:57 +05:30
Kovid Goyal
d8f5ccf9e4 Make master tty raw and print error messages with more context 2022-08-01 19:02:57 +05:30
Kovid Goyal
774489c578 ... 2022-08-01 19:02:57 +05:30
Kovid Goyal
39bb0ecfcf more work on socket based prewarm 2022-08-01 19:02:57 +05:30
Kovid Goyal
b222ab1bf6 Start work on socket based prewarm 2022-08-01 19:02:57 +05:30
Kovid Goyal
7a31c7ff50 Start work on everywhere prewarm 2022-08-01 19:02:57 +05:30
Kovid Goyal
132f87d152 show_key: use a better representation of the space key when 2022-08-01 13:25:56 +05:30
Kovid Goyal
aedda4bf9b ... 2022-07-31 10:36:03 +05:30
Kovid Goyal
40bba70bfe Wayland IME: Avoid printing errors for compositors that pointlessly acknowledge previous IME commits rather than just the current one. Apparently kwin is one such. Fixes #5339 2022-07-31 10:22:40 +05:30
Kovid Goyal
8202247b27 DRYer 2022-07-29 12:51:36 +05:30
Kovid Goyal
e2117ee8a4 ssh kitten: Allow completion of ssh options between the destination and command
This contravenes the documented command line parsing behavior of ssh but
matches its actual implementation. Sigh.

Fixes #5322
2022-07-29 08:29:49 +05:30
Kovid Goyal
e3a4150fea Second draw attempt has single fade edge 2022-07-29 08:15:38 +05:30
Kovid Goyal
0ce2a23af3 Allow tab title templates to use the current max title length 2022-07-29 07:43:55 +05:30
Kovid Goyal
6b2337c9c0 Merge branch 'master' of https://github.com/newbee1905/kitty-1 2022-07-26 20:27:59 +05:30
newbee1905
54661b7fc4 reflector: replace unecessary while loop 2022-07-26 21:47:52 +07:00
Kovid Goyal
a1f895b781 Merge branch 'master' of https://github.com/nullchilly/kitty 2022-07-26 19:10:34 +05:30
nullchilly
199c271edc Fix modify_font underline_position 1 2022-07-26 20:08:04 +07:00
Kovid Goyal
9ac744ae63 DRYer 2022-07-26 16:10:43 +05:30
Kovid Goyal
93b05bcd1e Make the calculation of the bound for underline_position more precise
Fixes #5308
2022-07-26 16:07:01 +05:30
Kovid Goyal
546cdbefae Don't expose all Tab methods in title template
They can have side effects so prevent user from foot shot
2022-07-26 13:13:00 +05:30
Kovid Goyal
352c07987b Nicer fix for showing cwd in tab titles 2022-07-26 12:35:07 +05:30
Kovid Goyal
f6a1eb19d7 Only import ReferenceType when type checking 2022-07-26 11:06:19 +05:30
Kovid Goyal
a352804c14 Merge branch 'misc' of https://github.com/page-down/kitty 2022-07-26 11:04:01 +05:30
pagedown
28ae8c4d20 Expand ~ when resolving editor path and applying exe_search_path 2022-07-26 13:21:50 +08:00
pagedown
1eef584382 Replace tr with string built-in in fish integration 2022-07-26 13:21:36 +08:00
pagedown
4e1cd0590b Use builtin to call read in zsh integration and bash integration 2022-07-26 13:20:50 +08:00
pagedown
fa670e1f5d ... 2022-07-26 13:20:41 +08:00
Kovid Goyal
c7fa6f620a py3.8 compat 2022-07-26 08:39:33 +05:30
Kovid Goyal
04690c8c7c Dont incur the cost of checking the cwd of a process on every tabbar update unless actually needed 2022-07-26 08:19:14 +05:30
Kovid Goyal
4345ea6602 Remove debugging code I left in the last commit accidentally 2022-07-26 08:17:44 +05:30
Kovid Goyal
d39c212336 Merge branch 'add-cwd-TabBarData' of https://github.com/nxvxl/kitty 2022-07-26 08:08:14 +05:30
Kovid Goyal
54d2f06abe remote files kitten: Fix working with files whose names have characters that need to be quoted in shell scripts
Fixes #5313
2022-07-26 08:06:25 +05:30
noval
237bfc9a6e add cwd to TabBarData
this option add current working directory to the tab by using active windows child directory.
2022-07-26 09:33:55 +07:00
Kovid Goyal
29b3d49cd5 Note that the crossterm library has added support for the kitty keyboard protocol 2022-07-26 07:45:57 +05:30
Kovid Goyal
fe8892ec54 Update changelog for previous PR 2022-07-21 20:03:46 +05:30
Kovid Goyal
2d8dd7a53e Merge branch 'rc-scroll-window' of https://github.com/page-down/kitty 2022-07-21 20:03:05 +05:30
pagedown
b493599690 Remote control: Allow half-scrolling when scrolling window by page 2022-07-21 21:05:56 +08:00
Kovid Goyal
d9371dc265 ssh kitten: Better handling of exit on keyboard interrupt 2022-07-20 21:40:51 +05:30
Kovid Goyal
ef2a12fbdf Ignore sigint while draining the tty 2022-07-20 19:40:23 +05:30
Kovid Goyal
7215c6d6be ssh kitten: Allow pressing Ctrl-C to abort ssh before the connection is completed
Fixing this involved adding a new mode to kitty where it handles
ctrl-c/z/q by sending signals to the tty foreground process group
instead of delegating to the kernel to do that. Since the pipe may be
full we have no way of knowing when the kernel will get around to
reading the signal byte. So send the signal ourselves.

Fixes #5271
2022-07-20 19:11:14 +05:30
Kovid Goyal
bd9e1f58fe ssh kitten: Make discarding of garbage data after ssh fails more robust
We now roundtrip an UUID via the terminal and only exit after receiving
it back. This guarantees that any pending data in the pipe is discarded.
2022-07-20 13:28:51 +05:30
Kovid Goyal
79dec269e1 ... 2022-07-16 10:25:18 +05:30
Kovid Goyal
d6ffbf4f3c Rebuild before and after publishing if a branch change was needed
Sometimes branches break things
2022-07-16 10:18:05 +05:30
Kovid Goyal
32588939ae Deprecate the adjust_baseline adjust_line_height and adjust_column_width options in favor of modify_font
Unifies handling and allow using pt units for those adjustments.
Note that the behavior of percentage sizes for adjust baseline is
backwards incompatible. It now uses the baseline value as the base
rather than the cell height.
2022-07-15 15:29:42 +05:30
Kovid Goyal
a02e07bfe8 Add modify_fonts to the changelog
Fixes #5265
2022-07-15 12:29:08 +05:30
Kovid Goyal
03df0c3cca Actually implement modify_font 2022-07-15 12:27:42 +05:30
Kovid Goyal
1aa50b73a1 Allow pixel based adjustments as well 2022-07-15 11:45:43 +05:30
Kovid Goyal
c910f483bf Improve formatting of config diff for modify_font 2022-07-15 11:15:57 +05:30
Kovid Goyal
14f4a8d28e Make modify_font available to C code 2022-07-15 11:06:24 +05:30
Kovid Goyal
ee931a17b0 Start work on option to modify font characteristics
Implement parsing of the option
2022-07-15 08:54:53 +05:30
Kovid Goyal
0a2ba3fb66 Merge branch 'fix-macos-launch' of https://github.com/page-down/kitty 2022-07-14 16:45:08 +05:30
pagedown
512db660a1 macOS: Fix unable to open new tab/window when there is no OS window 2022-07-14 18:25:00 +08:00
Kovid Goyal
b0666c9180 test.py now needs kitty built 2022-07-13 20:00:54 +05:30
Kovid Goyal
57d3d09679 DRYer 2022-07-13 19:49:40 +05:30
Kovid Goyal
3a17f54bca Add a note about how to exclude directories in the copy command 2022-07-12 16:23:48 +05:30
Kovid Goyal
4c2800b294 mask handled signals when running the signal handler 2022-07-10 12:52:51 +05:30
Kovid Goyal
8358377ec3 Fix reading multiple signals from buffer on macOS 2022-07-10 12:07:54 +05:30
Kovid Goyal
3ab12c616c Merge branch 'patch-1' of https://github.com/kidonng/kitty 2022-07-09 14:45:48 +05:30
Kid
ef4e784121 Fix link formatting in docs 2022-07-09 16:00:51 +08:00
Kovid Goyal
1ead20a5b9 Add a GitHub icon to the docs footer 2022-07-08 20:36:32 +05:30
Kovid Goyal
31dfee8a95 Nicer error message for zsh versions before 5.1 2022-07-08 20:28:42 +05:30
Kovid Goyal
d6492264c7 Bash integration: Fix declare not creating global variables in .bashrc
Fixes #5254
2022-07-08 18:55:04 +05:30
Kovid Goyal
7281b9dbb1 Ensure local kitty is used when running the tests 2022-07-05 21:09:09 +05:30
Kovid Goyal
4b63ee036e Run the test suite using the kitty binary 2022-07-05 21:05:03 +05:30
Kovid Goyal
fb8eb69c20 ... 2022-07-03 20:51:59 +05:30
Kovid Goyal
4b1fa2609d Match behavior of who when getting num_users by ignoring zombie pids 2022-07-03 14:46:54 +05:30
Kovid Goyal
a8b756f040 ssh kitten: A new option :code:--symlink-strategy to control how symlinks are copied to the remote machine
Fixes #5249
2022-07-03 14:03:56 +05:30
Kovid Goyal
a94a0f3026 Fix fd leak in prewarm zygote 2022-07-03 13:32:09 +05:30
Kovid Goyal
71c902eaf8 Build the launcher with debug symbols when using --debug 2022-07-03 13:28:57 +05:30
Kovid Goyal
6e7af8ce2e Merge branch 'fix-last-cmd-output' of https://github.com/page-down/kitty 2022-07-02 10:18:16 +05:30
pagedown
6c80cd040c Fix missing last line when getting output of the running command 2022-07-02 12:33:58 +08:00
Kovid Goyal
4ed413eaa7 Switch to GA2 2022-06-30 17:00:14 +05:30
Kovid Goyal
86357d2c38 ... 2022-06-29 18:53:11 +05:30
Kovid Goyal
c0d4d01b88 ... 2022-06-29 18:41:39 +05:30
Kovid Goyal
b3fcb53625 ssh kitten: Allow ssh kitten to work from inside tmux, provided the tmux session inherits the correct KITTY env vars
Fixes #5227
2022-06-29 18:40:22 +05:30
Kovid Goyal
4f29dea8ef Utility function to detect when running inside tmux 2022-06-29 17:51:38 +05:30
Kovid Goyal
4f8ef05058 Linux: Update cursor position after all key presses not just pre-edit text changes
Fixes #5241
2022-06-29 11:37:35 +05:30
Kovid Goyal
7fc1735a21 swaps_disallowed is used only on wayland 2022-06-28 20:19:52 +05:30
Kovid Goyal
1e49038747 Fix edit-in-kitty not working with editors that use file replace to save changes 2022-06-28 11:51:03 +05:30
Kovid Goyal
295fbe42ad Merge branch 'misc' of https://github.com/page-down/kitty 2022-06-28 11:42:37 +05:30
Kovid Goyal
60d33f2847 Wayland: Reduce flicker at startup by not using render frames immediately after a resize
Fixes #5235
2022-06-28 11:29:57 +05:30
Kovid Goyal
cd369f633a Wayland: Ensure that opengl buffer swapping does not happen till the xdg surface is configured 2022-06-28 10:47:33 +05:30
pagedown
c3df6d2fe3 Remove executable perms from kitten files 2022-06-28 11:59:47 +08:00
Kovid Goyal
72dfa74b3e Avoid an extra buffer swap during startup
glfw should not be swapping buffers behind the clients back. Since we
control the client, we can ensure that the OpenGL VRAM is cleared before
the window is shown.

Also fixes the issue with the glfw wayland backend where the buffer was
being created before the surface was configured
2022-06-28 09:25:24 +05:30
pagedown
1411269187 Docs: Improve documentation for remote commands
Use text roles in the document to apply the style in the cli output.
Add more links.
Unify the text roles.
Use code blocks instead of quote blocks.
Use '+' to connect the shortcut key names.
2022-06-28 11:52:20 +08:00
pagedown
185d959f25 ssh kitten: Add MacPorts paths to the common locations for login shell 2022-06-28 11:43:19 +08:00
pagedown
1652d41992 Fix edit-in-kitty not working when option editor comes with arguments 2022-06-28 11:41:27 +08:00
pagedown
297dea881d Use the same fish completion function for commands 2022-06-28 11:35:11 +08:00
pagedown
01df828353 Refactor the fish implementation of edit-in-kitty
Clean up global variable and signal handling function before exit.
For commands allowing the use of valid functions or binary executables.
2022-06-28 11:31:42 +08:00
pagedown
617115d447 Docs: edit-in-kitty works with neovim 2022-06-28 11:22:52 +08:00
Kovid Goyal
31f9978599 Merge branch 'patch-1' of https://github.com/AnonymouX47/kitty 2022-06-27 15:54:23 +05:30
My Avatar ;D
dc068c16e8 Update projects using kitty graphics protocol
Add `term-image` to the list of projects using the kitty graphics protocol.
2022-06-27 10:35:39 +01:00
Kovid Goyal
89626a462f ... 2022-06-25 20:46:02 +05:30
Kovid Goyal
a043588b4a Update changelog for last PR 2022-06-25 16:50:46 +05:30
Kovid Goyal
2e08ee16c2 Merge branch 'fix-macos-jis-kbd' of https://github.com/page-down/kitty
Fixes #5232
2022-06-25 16:49:46 +05:30
pagedown
2cc506476b macOS: Fix JIS Eisu and Kana keys not working 2022-06-25 19:01:02 +08:00
Kovid Goyal
0a462ad706 Forgot one place to change over to kitty_run_data 2022-06-24 10:31:55 +05:30
Kovid Goyal
81c1bfe1c5 ... 2022-06-24 09:26:38 +05:30
Kovid Goyal
8ce80e39d9 kitty now needs python >= 3.8 2022-06-24 00:01:35 +05:30
Kovid Goyal
fa823a37ae Backport 6281f498c8 2022-06-23 13:00:28 +05:30
Kovid Goyal
17f67fbe28 Add a note that WezTerm implements the kitty keyboard protocol as well 2022-06-23 11:22:01 +05:30
Kovid Goyal
560b78bc35 Dont leak kitty_run_data on error 2022-06-23 08:59:31 +05:30
Kovid Goyal
f023f047ff Workaround for Python 3.11 breaking sys._xoptions
Apparently in Python-land its acceptable behavior to break backward
compatibility with documented interfaces on a whim. Bloody joke.
https://github.com/python/cpython/pull/28823

Fixes #5223
2022-06-23 08:44:34 +05:30
Kovid Goyal
5673359be2 Merge branch 'sam/modern-whiskers-icon' of https://github.com/samholmes/kitty 2022-06-22 04:11:41 +05:30
Samuel Holmes
666696d142 Add "modern whiskers" alternative icon to FAQ 2022-06-21 11:04:24 -07:00
Kovid Goyal
f95bc48f9b kitty @ set-colors: Fix changing inactive_tab_foreground not working
Fixes #5214
2022-06-19 20:20:58 +05:30
Kovid Goyal
8d18fc09fa Merge branch 'fix-rc-new-window' of https://github.com/page-down/kitty 2022-06-19 18:21:22 +05:30
Kovid Goyal
a3d42a90f2 Get rid of os.waitid() since its not present on macOS we cannot rely on it anyway 2022-06-19 18:11:23 +05:30
pagedown
1da5f2ecc6 Fix the rc command new-window does not open the shell by default 2022-06-19 20:25:12 +08:00
Kovid Goyal
d226e82f68 It is only possible to not have an OS Window on macOS 2022-06-19 09:39:40 +05:30
Kovid Goyal
60cc2cb26c Merge branch 'fix-rc-launch' of https://github.com/page-down/kitty 2022-06-19 09:38:30 +05:30
pagedown
1ac90cf464 Allow remote control to launch a new OS window when there is none 2022-06-19 11:51:58 +08:00
Kovid Goyal
d3ffaebd17 Ignore exceptions in kitten result processors 2022-06-18 08:20:01 +05:30
Kovid Goyal
bf01c549f5 Allow kittens to handle multiple results in a window 2022-06-18 08:18:25 +05:30
Kovid Goyal
6912d8c086 No need for entire screen object when scaling a scroll 2022-06-18 06:55:28 +05:30
Kovid Goyal
a89e1b5573 Fix horizontal wheel events not being reported to client programs when they grab the mouse
Fixes #2819
2022-06-18 06:47:42 +05:30
Kovid Goyal
3a9c6088b2 Add debug output for scroll events 2022-06-18 05:54:26 +05:30
Kovid Goyal
fba629f385 Merge branch 'globinclude-sorted' of https://github.com/amarshall/kitty 2022-06-18 04:59:25 +05:30
Andrew Marshall
90477825c2 Make globinclude sort files before loading
`Path.glob` gives no guarantee about the order results are returned in.
This means that if files included by `globinclude` override each other,
the resulting config was non-deterministic. Resolve this by sorting the
results from `glob` to give consistent, well-defined order.
2022-06-17 18:50:16 -04:00
Kovid Goyal
1e56d39777 Wakeup main loop when refreshing window as well as io loop 2022-06-17 19:33:43 +05:30
Kovid Goyal
2829971412 Merge branch 'expose-wakeup-main-loop' of https://github.com/sirno/kitty 2022-06-17 19:09:07 +05:30
Nicolas Ochsner
c147fda6ca Expose wakeup main loop in python api. 2022-06-17 15:26:16 +02:00
Kovid Goyal
a27dfd8b7c Increase the timeout for prewarm I/O on CI 2022-06-14 21:17:28 +05:30
Kovid Goyal
a7c65efc45 Ensure local kitty is used in tests even when another kitty is present in the system PATH
Fixes #5194
2022-06-14 21:08:58 +05:30
Kovid Goyal
646a524c8e Sort imports 2022-06-14 20:06:12 +05:30
Kovid Goyal
f8d01d2c4f Use the same parser for resize_window actions and session setting 2022-06-14 20:03:21 +05:30
Kovid Goyal
1d846f3744 Cleanup previous PR
Merge branch 'session-resize-window' of https://github.com/sirno/kitty
2022-06-14 19:59:01 +05:30
Nicolas Ochsner
6bbe58f876 Change to pass window specs. 2022-06-14 12:28:41 +02:00
Nicolas Ochsner
36719fb086 Cleanup. 2022-06-14 11:23:35 +02:00
Nicolas Ochsner
78fd7a8458 Enable resizing in session files. 2022-06-14 11:09:26 +02:00
Kovid Goyal
f5976d0d63 Remove unneeded code 2022-06-13 21:33:07 +05:30
Kovid Goyal
b313fc3fbe Forgot to also add SIGUSR1 handler 2022-06-13 21:09:32 +05:30
Kovid Goyal
cf667b8c47 Use a signal handler instead of a pipe for child death notification 2022-06-13 20:40:04 +05:30
Kovid Goyal
7e3bd8586f Dont use SIGTSTP and SIGCONT in the test as they are very flaky 2022-06-13 20:29:58 +05:30
Kovid Goyal
d5df301317 Finer grained polling 2022-06-13 19:41:40 +05:30
Kovid Goyal
628246c3da Workaround for python 3.8 that doesnt have the CLD_* constants 2022-06-13 19:22:37 +05:30
Kovid Goyal
d228acd30a Use a busy loop for signaled process 2022-06-13 19:11:29 +05:30
Kovid Goyal
18cd97d914 Skip SIGSTSTP test when CLD_STOPPED is not available 2022-06-13 19:05:49 +05:30
Kovid Goyal
5f13946bac Allow using our signal handlers in python event loops via an fd
pythons signal fd only return signal numbers not the full siginfo struct
2022-06-13 18:52:23 +05:30
Kovid Goyal
8fb24fbc1e poll() takes times in ms not seconds 2022-06-13 18:51:35 +05:30
Kovid Goyal
f0d4952055 Use an iterator 2022-06-13 08:14:51 +05:30
Kovid Goyal
7113580db2 macOS has no waitid
Le Sigh
2022-06-13 02:19:51 +05:30
Kovid Goyal
163c211219 Use waitid() rather than waitpid() to get full exit status 2022-06-13 00:19:56 +05:30
Kovid Goyal
6993157b3a ... 2022-06-13 00:15:07 +05:30
Kovid Goyal
e2efdf674d Reap prewarmed processes 2022-06-13 00:11:16 +05:30
Kovid Goyal
9fcb8e5b6e Close unneeded fds in forked children 2022-06-12 20:26:20 +05:30
Kovid Goyal
a1a637c7f1 Restore SIGUSR1 handling in prewarmed child 2022-06-12 18:59:55 +05:30
Kovid Goyal
4f87f3e9f4 ... 2022-06-12 18:15:23 +05:30
Kovid Goyal
da6faa656c Use a fork() without exec() to create prewarm process
This has the advantages:

1) Even first kitten use is fast
2) Computer has to do less work overall since prewarm process is itself prewarmed
2022-06-12 18:06:51 +05:30
Kovid Goyal
e1ad75e932 Graphics protocol: Make it explicit what is supposed to happen when two images with the same z-index overlap
Fixes #5187
2022-06-10 22:10:11 +05:30
Kovid Goyal
646bdbd002 Wayland: Fix a regression in the previous release that caused mouse cursor animation and keyboard repeat to stop working when switching seats
Fixes #5188
2022-06-10 21:38:30 +05:30
Kovid Goyal
9184de1997 ... 2022-06-10 18:44:23 +05:30
Kovid Goyal
eabc29ec4d Changelog entry for prewarming 2022-06-09 10:43:00 +05:30
Kovid Goyal
e338cdab31 Increase the timeout when talking to prewarm process 2022-06-09 07:01:42 +05:30
Kovid Goyal
7001d609fa Fix spurious warning from runpy module when prewarmed 2022-06-09 07:01:42 +05:30
Kovid Goyal
c8399ce3d2 clear signal handlers in prewarm controller 2022-06-09 07:01:42 +05:30
Kovid Goyal
3e1d701dce DRYer 2022-06-09 07:01:41 +05:30
Kovid Goyal
a385c39c2e Fix reading of dead prewarmed child pids 2022-06-09 07:01:41 +05:30
Kovid Goyal
5d1cf339a7 Simplify child death tracking
Re-use the existing fd instead of catching signals
2022-06-09 07:01:41 +05:30
Kovid Goyal
fafb8518e0 Fix compilation on platforms without SO_PASSCRED 2022-06-09 07:01:41 +05:30
Kovid Goyal
6807f4d4ea Report the correct cmdline for prewarmed processes 2022-06-09 07:01:41 +05:30
Kovid Goyal
0ed7b2f3c0 Manage fd lifecycles a bit better 2022-06-09 07:01:41 +05:30
Kovid Goyal
116128ebb5 Get prewarm working
Needed to wait in the control process for child to set its controlling
terminal so that closing the slave fd in kitty is safe.
2022-06-09 07:01:41 +05:30
Kovid Goyal
0c870c5fcd handle child death and config reload for prewarmed processes 2022-06-09 07:01:41 +05:30
Kovid Goyal
90bc3ab770 Function to create a randomly named UNIX domain socket 2022-06-09 07:01:41 +05:30
Kovid Goyal
0021b0c242 Prewarm all kittens 2022-06-09 07:01:41 +05:30
Kovid Goyal
6dc076f5d1 Complete move to prewarm.py 2022-06-09 06:54:05 +05:30
Kovid Goyal
2dd1201c3f Dont use a kitten for prewarm 2022-06-09 06:53:51 +05:30
Kovid Goyal
9be68966b4 Also detect ssh kitten run as an overlay 2022-06-08 18:53:54 +05:30
Kovid Goyal
47d482dca9 Clear signal handlers when running processes 2022-06-08 17:50:42 +05:30
Kovid Goyal
18dd13c872 Make init_loop_data a little safer to use 2022-06-08 15:10:52 +05:30
Kovid Goyal
c71bb877c3 Handle SIGHUP gradefully 2022-06-08 09:06:28 +05:30
Kovid Goyal
eee8106f9e Fix a regression that broke completion when using a kitty alias instead of having kitty on PATH 2022-06-08 07:36:09 +05:30
Kovid Goyal
80ad596d3d Yet another place where macos_colorspace was broken 2022-06-08 07:17:34 +05:30
Kovid Goyal
9dbafcc368 Remove unneccessary argument to connection_sharing_args() 2022-06-07 20:40:01 +05:30
Kovid Goyal
9f5f113840 ... 2022-06-07 13:05:07 +05:30
Kovid Goyal
6afbdbe94f Use correct kitty config in prewarmed process 2022-06-07 12:53:39 +05:30
Kovid Goyal
061a0c8cb6 Reset global options object in the tests 2022-06-07 10:58:03 +05:30
Kovid Goyal
ad128a3c29 version 0.25.2 2022-06-07 07:32:35 +05:30
Kovid Goyal
b71d2e04ca Clarify behavior of placement id when image id is zero 2022-06-07 07:22:12 +05:30
Kovid Goyal
cc3c7b0286 Fix waitpid() call on python 3.8 2022-06-06 21:22:04 +05:30
Kovid Goyal
bf6c90a69a Compare realpaths for cwd test 2022-06-06 20:46:49 +05:30
Kovid Goyal
4c9a75c1ba Remove unused code 2022-06-06 20:45:40 +05:30
Kovid Goyal
98f46f8bd7 Start work on prewarming
The prewarm process and its controller are implemented with some basic
tests.
2022-06-06 20:39:36 +05:30
Kovid Goyal
dec62b1929 Allow ignoring SHM close failures
Useful if we export the mmap beyond the lifetime of the shm object
2022-06-06 20:31:13 +05:30
Kovid Goyal
79f7954048 Cleanup previous PR 2022-06-06 17:19:52 +05:30
Kovid Goyal
fc217dafba Merge branch 'master' of https://github.com/suvayu/kitty 2022-06-06 16:55:08 +05:30
Kovid Goyal
a6aff817cf Prepare for prewarm testing 2022-06-06 15:59:34 +05:30
Suvayu Ali
38cb18fe92 diff kitten: tests for directory walking 2022-06-06 11:01:45 +02:00
Suvayu Ali
20b6a97159 Update in response to feedback
- one configuration option: ignore_paths
- use shlex to parse option to support whitespace and in-line comments
- change option type to Tuple[str, ...]
- remove ignored directories from dirnames to prevent scanning
2022-06-06 11:00:45 +02:00
Kovid Goyal
98f6e24106 Move block outside try/except as it doesnt need to be in there 2022-06-06 08:17:15 +05:30
Kovid Goyal
4ed6364b61 Fix compiler warning on 32bit builds 2022-06-06 07:19:52 +05:30
Kovid Goyal
cd7751681d hints kitten: Fix surrounding quotes/brackets and embedded carriage returns not being removed when using line number processing
Fixes #5170
2022-06-05 18:07:16 +05:30
Kovid Goyal
76531d2f7a Python wrapper function to establish controlling tty 2022-06-05 15:36:05 +05:30
Suvayu Ali
eea652f1d0 kittens/diff: move empty pattern check to dir tree walk 2022-06-05 10:11:21 +02:00
Kovid Goyal
f20f4762a8 Use builtin facility for removing cloexec 2022-06-05 12:33:34 +05:30
Kovid Goyal
c004fd1f4d Declare the set of handled signals in only one place 2022-06-05 08:01:26 +05:30
Kovid Goyal
f29039db29 Make the full signal info available in our signal handler 2022-06-05 07:22:38 +05:30
Suvayu Ali
fbf1ec43c7 diff kitten: add options to ignore paths when comparing directories
Tested locally & over SSH:

    $ kitty +kitten diff /local/path /local/path2
    $ kitty +kitten diff /local/path ssh:remote:/path
2022-06-05 00:11:30 +02:00
Kovid Goyal
a42200a430 Use the log_error function to log SIGUSR2 2022-06-04 15:38:56 +05:30
Kovid Goyal
ad576c333c Also restore signal handlers for SIGUSR1 and SIGUSR2 2022-06-04 15:15:39 +05:30
Kovid Goyal
5a0a980648 Make getting cmdline of a PID a bit more convenient 2022-06-04 15:07:08 +05:30
Kovid Goyal
b3578a4fa5 ... 2022-06-04 14:54:32 +05:30
Kovid Goyal
3c952b01d3 Fix reloading in all kitties skipping kitty processes started as kitty +open 2022-06-04 14:53:13 +05:30
Kovid Goyal
b1453a51f6 Better error message for kitty + 2022-06-04 14:47:13 +05:30
Kovid Goyal
2c3a7b5f41 Restore a couple more signal handlers that python nukes 2022-06-04 14:30:08 +05:30
Kovid Goyal
0df5a6c6c8 Utility function to test if PID is alive 2022-06-04 14:14:24 +05:30
Kovid Goyal
bf4dc6365a Add support for sigqueue() and also handle SIGUSR2
I anticipate using sigqueue() for simpler handling of SIGCHLD
notifications from the prewram process to the its parent.
2022-06-04 14:09:45 +05:30
Kovid Goyal
ce3322bf91 Remote control: Fix commands with asynchronous payloads not sending responses
Fixes #5165
2022-06-04 10:13:21 +05:30
Kovid Goyal
835cb31501 Fix incorrect dispatch of poll events when more than one peer is present 2022-06-04 09:26:57 +05:30
Kovid Goyal
762dd065f3 Nicer reverse loop 2022-06-04 09:06:35 +05:30
Kovid Goyal
7b91447d89 Use a full chekcout in CI when building docs
The :commit: docs role requires it
2022-06-04 08:00:00 +05:30
Kovid Goyal
1146c4ea3f Merge branch 'ignore-fig-osc' of https://github.com/grant0417/kitty 2022-06-04 07:44:17 +05:30
grant0417
729f7b8e03 Add custom message for Fig OSC 2022-06-03 18:57:53 -07:00
grant0417
d3ec632b9f Ignore Fig OSC codes 2022-06-03 17:07:44 -07:00
Kovid Goyal
cb01b5ee44 DRYer 2022-06-03 21:38:49 +05:30
Kovid Goyal
0828096e9e ... 2022-06-03 18:30:14 +05:30
Kovid Goyal
ebcbed290f Make loading of kitty options in kitten re-useable 2022-06-03 17:49:58 +05:30
Kovid Goyal
d6afe6f2cb Move entrypoints into their own module 2022-06-03 11:12:13 +05:30
Kovid Goyal
4daf70f636 ... 2022-06-03 11:08:41 +05:30
Kovid Goyal
2f3dd72c84 Weston: Fix client side decorations flickering on slow computers during window resize
Fixes #5162
2022-06-03 11:00:56 +05:30
Kovid Goyal
dca8c65376 Fix display of url open failures not working 2022-06-02 10:41:08 +05:30
Kovid Goyal
12d8175d9a Use inode/executable rather than application/executable 2022-06-02 10:33:56 +05:30
Kovid Goyal
609bcd68dd Fix #5161 2022-06-02 10:32:43 +05:30
Kovid Goyal
313136803c DRYer 2022-06-02 10:21:34 +05:30
Kovid Goyal
b937033411 macOS: Allow opening executables without a file extension with kitty as well
Fixes #5160
2022-06-02 09:25:30 +05:30
Kovid Goyal
55eeb9c11e Dont import kitty.complete in ssh.main 2022-06-02 08:08:33 +05:30
Kovid Goyal
8fbec2dfd5 remove unused arg 2022-06-02 08:07:53 +05:30
Kovid Goyal
c4521290b8 ... 2022-06-01 19:43:41 +05:30
Kovid Goyal
e12a9f3caf Iosevka: Fix incorrect rendering when there is a combining char that does not group with its neighbors
Fixes #5153
2022-06-01 12:00:53 +05:30
Kovid Goyal
56f8a06362 DRYer 2022-06-01 08:47:19 +05:30
Kovid Goyal
5c4abe749b Merge branch 'fontconfig-special-sources' of https://github.com/leungbk/kitty 2022-06-01 08:33:13 +05:30
Brian Leung
62c27b3db7 Add kitty/fontconfig.c to SPECIAL_SOURCES
Fixup of bec620a8d3.
2022-05-31 19:58:42 -07:00
Kovid Goyal
1283a2b7e5 ... 2022-06-01 08:21:23 +05:30
Kovid Goyal
bec620a8d3 Fix #5154 2022-06-01 08:19:11 +05:30
Kovid Goyal
6b0bb2e845 Sphinx v5 needs language to be not None 2022-06-01 06:47:06 +05:30
Kovid Goyal
135818f34b Note about __main__.py with +launch 2022-05-31 07:56:01 +05:30
Kovid Goyal
2a361d1de1 Update changelog for last PR 2022-05-31 07:46:00 +05:30
Kovid Goyal
761a941d43 Merge branch 'kovidgoyal-master' of https://github.com/jimbob3806/kitty 2022-05-31 07:41:40 +05:30
Kovid Goyal
c03630a487 ... 2022-05-31 07:26:04 +05:30
James Reid
0b79cbdb3b Add "user" tab to themes kitten
Add new tab named "user" to the built-in themes kitten - new tab
filters and displays only user-defined color themes, identified by
adding "is_user_defined" property to "Theme" class which defaults
to False, and is set True when a theme is fetched using the
"load_from_dir" method.
2022-05-30 19:25:09 +01:00
James Reid
1dc6b49e02 Remove hard coded tab string in ThemesHandler
Remove hard coded tab string and replace with self.tabs, which is
a reference to the same tab string defined in the __init__ of
ThemesHandler
2022-05-30 19:17:07 +01:00
Kovid Goyal
1962f8e5a0 Advertise edit-in-kitty a bit more 2022-05-30 15:27:23 +05:30
Kovid Goyal
cabfcbcb69 macOS: When pasting text and the clipboard has a filesystem path, paste the full path instead of the text, which is sometimes just the file name
Fixes #5142
2022-05-30 14:40:45 +05:30
Kovid Goyal
48bb43a2c4 fish: completion for edit-in-kitty clone-in-kitty
fish's wrapping facility does not preserve argv[0] so it cannot be used
unlike for zsh and bash
2022-05-30 10:50:19 +05:30
Kovid Goyal
af5e3e0c18 Add a reference to edit-in-kitty to the remote file kitten docs 2022-05-30 08:19:33 +05:30
Kovid Goyal
fb8398c2eb bash: completion for edit/clone-in-kitty 2022-05-30 08:16:51 +05:30
Kovid Goyal
eefd4bb3e3 zsh: Completion for edit-in-kitty and clone-in-kitty 2022-05-30 08:12:09 +05:30
Kovid Goyal
581c388838 ... 2022-05-29 15:02:37 +05:30
Kovid Goyal
7a63ea6480 Drop python 3.7 from CI 2022-05-29 14:54:51 +05:30
Kovid Goyal
65f1329635 Wayland: When the seat is closed remove any pending pointer animation and key repeat timers
Fixes #5145
2022-05-29 14:50:34 +05:30
Kovid Goyal
0df9a5d5c5 Fix compilation on Python 3.11
Python 3.11 deprecates the supposedly "stable API" PySys_AddXOption().
So switch to using PyConfig.xoptions instead. This means dropping
support for python 3.7 since PyConfig is not available there. So it
rolls.

Fixes #5143
2022-05-29 14:37:14 +05:30
Kovid Goyal
6405849a1b Bash integration clone test was accidentally running zsh
Fixes #5144
2022-05-29 08:46:06 +05:30
Kovid Goyal
e9340dfaaf Some more tests for last non empty command output 2022-05-28 15:22:17 +05:30
Kovid Goyal
0509855930 Allow getting the last non-empty command output easily via an action or remote control
Fixes #4973
2022-05-28 15:19:24 +05:30
Kovid Goyal
4c74462763 ssh kitten: Look in common locations for login shell if it is not in PATH 2022-05-28 11:29:09 +05:30
Kovid Goyal
7f69381221 Update changelog 2022-05-28 11:13:35 +05:30
Kovid Goyal
75942fb47e Implement edit-in-kitty for fish 2022-05-28 11:12:11 +05:30
Kovid Goyal
0893d7164a _run_kitten -> run_kitten_with_metadata 2022-05-28 11:00:25 +05:30
Kovid Goyal
27906ea853 Skip login shell detection when login shell is set to nologin 2022-05-28 08:09:30 +05:30
Kovid Goyal
8540ca3990 Workaround for nix package messing with kitty file permissions 2022-05-28 08:03:17 +05:30
Kovid Goyal
e82c5a63b5 Avoid unnecessary use of cat 2022-05-27 14:18:16 +05:30
Kovid Goyal
83602d7e53 Make chunked transmit code re-useable in fish integration script 2022-05-27 13:21:26 +05:30
Kovid Goyal
64e30e5299 Ignore permission errors when stating file to edit 2022-05-27 13:04:02 +05:30
Kovid Goyal
83ce23ff9f Use zsh's builtin stat instead of relying on the stat command 2022-05-27 12:50:52 +05:30
Kovid Goyal
c5e5ec618d Also trap SIGTERM to cleanup 2022-05-27 12:39:22 +05:30
Kovid Goyal
bd84ec03ce Implement edit-in-kitty for bash 2022-05-27 12:38:26 +05:30
Kovid Goyal
d71f18566e forgot to declare data local 2022-05-27 12:29:11 +05:30
Kovid Goyal
76e75d9f89 Ensure self.tdir exists in __del__ 2022-05-27 10:48:16 +05:30
Kovid Goyal
f5695ac4f4 Increase edit file size limit to 8MB 2022-05-27 10:45:36 +05:30
Kovid Goyal
b748cd21cf Allow opening files at a spedific line number with edit-in-kitty 2022-05-27 09:53:43 +05:30
Kovid Goyal
3a8bdf3b48 React instantly to editor window being closed 2022-05-27 09:15:16 +05:30
Kovid Goyal
196c6b07aa Merge branch 'fix-window-menu' of https://github.com/henryhchchc/kitty 2022-05-27 09:12:56 +05:30
Henry Chu
1978cc5b55 Fixed #5132 2022-05-27 11:15:16 +08:00
Kovid Goyal
ea47cee23f Document edit-in-kitty 2022-05-27 07:41:54 +05:30
Kovid Goyal
e6844ad6f2 ssh kitten: Run bash as a login shell
This fell through the cracks in the rewrite for automatic shell
integration. Fixes #5130
2022-05-26 21:24:32 +05:30
Kovid Goyal
02d5b3eafa Fix shebang 2022-05-26 21:21:36 +05:30
Kovid Goyal
151dacf17f Update changelog 2022-05-26 21:21:27 +05:30
Kovid Goyal
117d1b02be Start work on edit-in-kitty 2022-05-26 21:16:42 +05:30
Kovid Goyal
cb55878efd Fix #5129 2022-05-26 19:42:20 +05:30
Kovid Goyal
ea4751eae5 Move logic for handling chunked remote data into a separate function
Use the existing clipboard_max_size as the limit for remote data
2022-05-26 08:52:20 +05:30
Kovid Goyal
cc4f1c0a24 version 0.25.1 2022-05-26 07:59:25 +05:30
Kovid Goyal
3eb5320e29 Add tpix to list of programs that speak the graphics protocol 2022-05-25 12:27:38 +05:30
Kovid Goyal
4f63cff1a4 Make _run_kitten public API 2022-05-25 07:14:18 +05:30
Kovid Goyal
8381171c8d Forgot trailing newline 2022-05-24 06:54:53 +05:30
Kovid Goyal
1b2d54d97a Output a warning when libwayland-cursor returns incorrectly sized cursor images 2022-05-23 12:50:47 +05:30
Kovid Goyal
e7da874b82 GNOME: Workaround for GNOME's text input system going into an infinite loop if cursor position is updated in response to a done event
Fixes #5105
2022-05-23 10:36:58 +05:30
Kovid Goyal
ea8bed2a71 Fix #5113 2022-05-20 20:45:08 +05:30
Kovid Goyal
c747e681a2 Merge branch 'patch-1' of https://github.com/jack1142/kitty 2022-05-20 20:42:11 +05:30
Jakub Kuczys
a9a9ec80b5 Support the short pretty flag (-p) in hyperlinked_grep kitten 2022-05-20 10:57:42 +02:00
Kovid Goyal
eb84990f5a Fix #5110 2022-05-19 09:55:12 +05:30
Kovid Goyal
1938ba3108 Add changelog entry for previous PR 2022-05-18 20:04:09 +05:30
Kovid Goyal
0eee2db199 Merge branch 'add-option-select_by_word_characters_forward' of https://github.com/kgraefe/kitty 2022-05-18 20:02:11 +05:30
Kovid Goyal
bba1455e28 Dont import all of the ssh kitten just to detect commandlines 2022-05-18 15:58:06 +05:30
Konrad Gräfe
8c41cc8d3e Add option select_by_word_characters_forward
This adds an option to select separate characters for forward and
backward word extension on double click. If it is empty the old behavior
is preserved. This is the default.

If it is not empty, select_by_word_characters_forward will be used for
extending the selection in forward direction (right) and
select_by_word_characters will be used for extending in backward
direction (left).

Signed-off-by: Konrad Gräfe <kgraefe@paktolos.net>
2022-05-16 11:09:36 +02:00
Kovid Goyal
5efcb35cfb Only integrate with ssh kitten if shared connections are enabled for that host 2022-05-14 10:37:05 +05:30
Kovid Goyal
1b4cf1fea7 Remote file kitten: Integrate with the ssh kitten 2022-05-14 10:31:18 +05:30
Kovid Goyal
d3656bf7e9 Linux: Load libfontconfig at runtime to allow the binaries to work for running kittens on servers without FontConfig 2022-05-13 19:56:19 +05:30
Kovid Goyal
aaffec1cbc Better error message 2022-05-13 19:25:37 +05:30
Kovid Goyal
ed9391d4d6 Add a note explaining why fontconfig is not bundled 2022-05-13 17:45:16 +05:30
Kovid Goyal
58333f260b Fix spurious error print in test 2022-05-13 17:42:00 +05:30
Kovid Goyal
cf8ccabad9 Fix deleting images by row not calculating image bounds correctly
Fixes #5081
2022-05-13 09:51:25 +05:30
Kovid Goyal
600c595fdf Fix reloading of config not working when kitty.conf does not exist when kitty is launched
Fixes #5071
2022-05-08 20:57:23 +05:30
Kovid Goyal
2427d2d9da Workaround Apple's "hardening" breaking the platform module
Fix #5065
Fix #5051
2022-05-07 20:43:10 +05:30
Kovid Goyal
4ca70bfa26 ... 2022-05-04 13:21:17 +05:30
Kovid Goyal
4e8eb2f7f0 Merge branch 'rc-match' of https://github.com/page-down/kitty 2022-05-01 21:23:58 +05:30
pagedown
b6cf4bc78f ... 2022-05-01 23:27:33 +08:00
pagedown
622cd5531a Raise an exception when not in broadcast and no match for send-text
send-text still won't return an error code when there is no match,
since no_response is True by default.
2022-05-01 23:05:44 +08:00
pagedown
ec35b0cc7c Fix remote command --match=all returns empty 2022-05-01 23:05:22 +08:00
pagedown
0719c7f8bb DRYer: Use window matching function in remote commands 2022-05-01 23:04:50 +08:00
Kovid Goyal
bb7e4039e8 Merge branch 'rc-err' of https://github.com/page-down/kitty 2022-05-01 07:11:21 +05:30
pagedown
a0559e506b Show error message when remote command arguments are invalid 2022-04-30 22:01:58 +08:00
Kovid Goyal
4ce4176bbe cleanup previous PR 2022-04-30 15:03:27 +05:30
Kovid Goyal
99409f0a8b Merge branch 'docs' of https://github.com/page-down/kitty 2022-04-30 14:41:12 +05:30
pagedown
13303416b8 Docs: Improve the documentations
Add more text roles and links.
Fix typos.
Adjust the default shortcut order in overview.
Notes on the impact of kitty-open.desktop on the default open apps.
Document KITTY_DEVELOP_FROM in glossary.
Add Python type hints to the watcher example.
Mention clone-in-kitty in launch --copy-env.
Fix remote control ls example does not work, by escaping the backslash.
2022-04-30 17:07:36 +08:00
Kovid Goyal
9811d677e5 query terminal kitten: Return fast when run in non-kitty terminals 2022-04-30 14:25:39 +05:30
pagedown
b9fd039668 Docs: Document the env vars set by kitty for auto shell integration 2022-04-30 16:54:53 +08:00
pagedown
6c1f20bb27 Docs: Mention close_shared_ssh_connections in ssh kitten config docs 2022-04-30 16:54:46 +08:00
pagedown
2b58316c64 ... 2022-04-30 16:54:41 +08:00
Kovid Goyal
f2df629634 ... 2022-04-30 09:38:08 +05:30
Kovid Goyal
8f46505a50 Header to print stack traces in C 2022-04-30 09:28:05 +05:30
Kovid Goyal
c48bf4fd85 Output debug lines for when kitty sets the pointer in Wayland 2022-04-30 09:13:08 +05:30
Kovid Goyal
8c67f5aea8 Merge branch 'fix-gen-conf' of https://github.com/page-down/kitty 2022-04-30 07:35:15 +05:30
pagedown
76f84e32c4 Fix the generated sample kitty.conf containing invalid options 2022-04-30 02:23:33 +08:00
Kovid Goyal
4a7125ec92 ssh kitten: Suppress error prints about invalid items in kitty.conf
Fixes #4985
2022-04-29 20:39:32 +05:30
Kovid Goyal
92c3af6a92 Allow using --match=all in all rc commands 2022-04-29 17:17:07 +05:30
Kovid Goyal
443f36ebc7 Merge branch 'docs' of https://github.com/page-down/kitty 2022-04-29 07:11:40 +05:30
pagedown
17632dea3c Docs: Improve remote control command documentation
Improve the --match option description.
Add more text roles and links.
Fix typos.
2022-04-29 01:31:11 +08:00
pagedown
bb78dc5ccb Docs: Fix the help text of query_terminal and other minor tweaks
Use --match-tab in broadcast kitten example.
2022-04-29 01:30:45 +08:00
Kovid Goyal
2737cb7dd0 Fix #5026 2022-04-28 22:12:43 +05:30
Kovid Goyal
08b2ce444f Also dont apply umask when extracting bootstrap data 2022-04-28 17:28:40 +05:30
Kovid Goyal
289028b468 Prevent umask from interfering with tar file extraction
Fixes #5025
2022-04-28 17:21:34 +05:30
Kovid Goyal
2b3be147e6 Allow three combining chars per cell
Makes use of otherwise wasted padding in the CPUCell struct
2022-04-28 09:45:34 +05:30
Kovid Goyal
1a2d9c6fba Fix a couple of issues highlighted by updated mypy 2022-04-28 07:03:35 +05:30
Kovid Goyal
af15b0313a Ensure there are no duplicate watchers for send-text sessions 2022-04-27 22:17:09 +05:30
Kovid Goyal
b080296326 Remove unused code 2022-04-27 21:25:39 +05:30
Kovid Goyal
516e0e8bb3 broadcast kitten: Keep the ghost cursors in target windows as long as broadcast window has focus 2022-04-27 21:24:18 +05:30
Kovid Goyal
57e23bd4e3 Handle zero blink time correctly 2022-04-27 20:37:23 +05:30
Kovid Goyal
59534d620e Use cursor blink interval as TIMEOUT_FOR_SESSION 2022-04-27 20:31:16 +05:30
Kovid Goyal
068b7e8d63 remove unused adjust_line_height() function 2022-04-27 20:21:36 +05:30
Kovid Goyal
2c1edb9611 Merge branch 'docs' of https://github.com/page-down/kitty 2022-04-27 20:18:39 +05:30
pagedown
510022c3c1 Docs: Improve the documentation for kittens
Add more text roles and links.
Add an example that broadcasts only to other windows in the current tab.
Initial capitalization of the key names in the kbd text role.
Add Python type hints for custom kittens.
Note about hyperlink support for ls on macOS.
Add description text for show_key.
2022-04-27 16:14:54 +08:00
Kovid Goyal
627c79ffbb Show detailed traceback when using show_error() 2022-04-26 13:58:57 +05:30
Kovid Goyal
e80cd36237 Show traceback on stderr for action failures 2022-04-26 11:58:17 +05:30
Kovid Goyal
92ebada9a6 ... 2022-04-26 11:15:45 +05:30
Kovid Goyal
462ae3bb58 ... 2022-04-26 11:15:33 +05:30
Kovid Goyal
6d6d9cc26b macOS: Add the macos_colorspace option to control what color space colors are rendered in
Fixed #4686
2022-04-26 11:14:01 +05:30
Kovid Goyal
a36d5dcde1 GLFW API for changing colorspace of windows on cocoa 2022-04-26 10:56:34 +05:30
Kovid Goyal
f9f6f98527 Note that neovim is also getting support for the kitty keyboard protocol 2022-04-26 08:39:44 +05:30
Kovid Goyal
ee94114eb2 Fix #5016 2022-04-26 08:20:24 +05:30
Kovid Goyal
8e98fcf2f6 Merge branch 'docs' of https://github.com/page-down/kitty 2022-04-25 14:16:16 +05:30
pagedown
c4710bf9cb Docs: Add text to the ref text role and minor tweaks
The text will be used when generating the commented configuration file.
Use inline literal to quote codes with spaces, as the `code` text role
will be removed when the commented configuration is generated, making it
indistinguishable from normal text.
2022-04-25 15:36:57 +08:00
pagedown
97a568a405 Docs: Improve the FAQ
Add more text roles and links.
Document `PATH` in the glossary.
2022-04-25 15:36:51 +08:00
pagedown
7bace19aed clone-in-kitty: Skip more SSH env vars to use the correct values 2022-04-25 15:36:43 +08:00
pagedown
7282f1f684 Docs: Improve ssh kitten documentation
Add more text roles.
Put the env example at the end.
The alias syntax of fish and bash requires quotation marks.
Document `SSH_ASKPASS` in the glossary.
2022-04-25 15:36:37 +08:00
Kovid Goyal
9edb772a81 Merge branch 'fix-launch-cwd-oldest' of https://github.com/rafikdraoui/kitty 2022-04-24 22:04:05 +05:30
Rafik Draoui
d123b6c377 Fix launch --cwd=oldest 2022-04-24 13:19:22 -03:00
Kovid Goyal
c9ba3695d3 ... 2022-04-24 15:50:02 +05:30
Kovid Goyal
0ee970b418 --hold is not suitable for replay commands as it outputs to the terminal 2022-04-24 15:37:20 +05:30
Kovid Goyal
8239cb1b5a Merge branch 'docs' of https://github.com/page-down/kitty 2022-04-24 15:36:35 +05:30
pagedown
97caa073b0 Docs: Improvements to the configuration documentation
Slightly adjust and simplify the config option descriptions.
Add more text roles.
Initial capitalized key names.
Change some examples to better demonstrate configurations.
Fix listen_on description.
Also document cmd+c and cmd+v.
Fix doc text role links in commented out configuration file.
2022-04-24 17:32:49 +08:00
pagedown
45bbe17559 Docs: Minor improvements to the kitty cli help documentation
Add some text roles.
Use `kitty --hold`.
Use `appname` and `conf_name`.
`appname` is also applied to the system-wide configuration path.
2022-04-24 17:18:55 +08:00
pagedown
288d16f7be Docs: Minor tweaks to the help documentation of hints kitten 2022-04-24 17:18:45 +08:00
pagedown
ecb60b313e Docs: Improve clone-in-kitty documentation and fix LANG descriptions
Reduce duplicate `launch`.
Add links to python venv and conda.
Adjust the order of env vars, `.._CODE` takes precedence over `.._PATH`.
Add clone-in-kitty env vars to glossary.
Correct the description of the LANG env var.
2022-04-24 17:18:31 +08:00
Kovid Goyal
cf2a20e4ea Merge branch 'fix-f-string' of https://github.com/page-down/kitty 2022-04-24 08:03:51 +05:30
pagedown
bc4f40fea7 ... 2022-04-24 09:34:22 +08:00
Kovid Goyal
102097da5a DRYer 2022-04-23 12:51:02 +05:30
Kovid Goyal
0e3528df14 Merge branch 'feat-macos-open-website' of https://github.com/page-down/kitty 2022-04-23 12:49:21 +05:30
Kovid Goyal
214631c2dd Sort frozenset literals in generated options class definition 2022-04-23 11:23:21 +05:30
pagedown
e919857dfc macOS: Make the global menu shortcut to open kitty website configurable
This allows remapping the key combination shift+cmd+/
2022-04-23 13:22:27 +08:00
pagedown
a5bd1dcb08 Add a new mappable action open_url 2022-04-23 13:17:28 +08:00
Kovid Goyal
37cdaea9ed Also save command history before cloning in bash 2022-04-22 23:40:59 +05:30
Kovid Goyal
6bbaf5f1cf zsh cloning: save history so that it is up-to-date in cloned shell 2022-04-22 23:34:34 +05:30
Kovid Goyal
8808a252ae Merge branch 'docs' of https://github.com/page-down/kitty 2022-04-22 13:29:24 +05:30
pagedown
5f1376b9a0 ... 2022-04-22 15:02:23 +08:00
Kovid Goyal
efa873bf50 DRYer 2022-04-22 10:53:25 +05:30
Kovid Goyal
714461de76 Also ensure oldest cwd request type is honored by modify_argv 2022-04-22 08:40:18 +05:30
Kovid Goyal
b753cf6879 Forgot to implement at_prompt use of reported cwd in modify_argv 2022-04-22 08:25:46 +05:30
Kovid Goyal
27010d0446 Merge branch 'docs' of https://github.com/page-down/kitty 2022-04-21 15:24:18 +05:30
Kovid Goyal
bdc039fbf5 Fix docstring 2022-04-21 14:51:23 +05:30
pagedown
72f92f3174 Docs: Mention again that kitty.conf will be created if not present 2022-04-21 16:45:12 +08:00
Kovid Goyal
8fcd5e40d4 Proper fix for reporting button in drag events to children 2022-04-21 11:41:57 +05:30
Kovid Goyal
b76319b7e8 Update changelog 2022-04-21 11:34:18 +05:30
Kovid Goyal
feeb8f28c4 Fix #4993 2022-04-21 11:00:34 +05:30
Kovid Goyal
55b21b741e Fix a regression in the previous release that caused mouse move events to be incorrectly reported as drag events even when a button is not pressed
Fixes #4992

Will need to investigate a different fix for #4925. xterm does report
the button press that caused the drag to start with move events, so we
will have to track that to match its behavior as glfw does not track it
for us.
2022-04-21 07:53:37 +05:30
Kovid Goyal
6941884221 ... 2022-04-20 13:36:26 +05:30
Kovid Goyal
6174c2008f ... 2022-04-20 10:10:05 +05:30
Kovid Goyal
1a32e79470 ... 2022-04-19 21:14:34 +05:30
Kovid Goyal
dd032db89c Merge branch 'docs' of https://github.com/page-down/kitty 2022-04-19 21:07:03 +05:30
pagedown
f70e0e216c Docs: Show copy button for installation command snippets 2022-04-19 23:28:51 +08:00
Kovid Goyal
51362706d7 Fix closing a tab incorrectly storing the tab to its right in the active tab history 2022-04-19 17:44:01 +05:30
Kovid Goyal
b2c317ebc6 ... 2022-04-19 17:38:16 +05:30
Kovid Goyal
90acbd0dd5 Add a note about ssh kitten colors to FAQ 2022-04-19 15:21:05 +05:30
Kovid Goyal
402fac3edf ... 2022-04-19 10:53:18 +05:30
Kovid Goyal
c4c62c1505 When using --keep-focus ensure active history list is not affected
Fixes #4987
2022-04-18 20:23:15 +05:30
Kovid Goyal
b569c01b49 Fix #4986 2022-04-18 17:04:05 +05:30
Kovid Goyal
c0d9b6e979 Merge branch 'docs' of https://github.com/page-down/kitty 2022-04-18 12:41:05 +05:30
pagedown
b94afbba13 ... 2022-04-18 14:51:15 +08:00
Kovid Goyal
1994c17c75 Note on how clone-in-kitty works 2022-04-18 12:08:32 +05:30
Kovid Goyal
f88a4fe986 ... 2022-04-18 11:13:16 +05:30
Kovid Goyal
25616aaa7b Merge branch 'clone-in-kitty' of https://github.com/page-down/kitty 2022-04-18 10:57:55 +05:30
pagedown
19fdcec358 ... 2022-04-18 11:54:14 +08:00
pagedown
45eb4a0760 clone-in-kitty: Remove duplicate PATH entries in fish implementation 2022-04-18 11:46:29 +08:00
pagedown
9e026983e6 clone-in-kitty: Remove CONDA_PREFIX_* env vars 2022-04-18 11:42:22 +08:00
Kovid Goyal
be0a524e23 Yet another try to get zsh to de-dup $PATH 2022-04-18 07:40:37 +05:30
Kovid Goyal
339af1b4b2 Add more send_text examples 2022-04-17 22:48:03 +05:30
Kovid Goyal
31fda568e4 typeset -U both path and PATH 2022-04-17 21:27:08 +05:30
Kovid Goyal
3efbccc850 ... 2022-04-17 20:56:24 +05:30
Kovid Goyal
93c23f99cb conda activate now works under fish so use it 2022-04-17 20:55:53 +05:30
Kovid Goyal
6590d0690e Document venv and sourcing behavior of clone-in-kitty 2022-04-17 19:51:27 +05:30
Kovid Goyal
230a9f4678 Implement option to control clone sourcing strategies 2022-04-17 19:39:32 +05:30
Kovid Goyal
f2189b3e70 only pass VIRTUAL_ENV if it is currently active 2022-04-17 15:43:57 +05:30
Kovid Goyal
0ee5712e00 Start work on option to control sourcing strategies 2022-04-17 15:30:57 +05:30
Kovid Goyal
f9cad2c4ea Add a note about show__key limitations 2022-04-17 08:45:27 +05:30
Kovid Goyal
4372cf2893 ... 2022-04-17 08:43:23 +05:30
Kovid Goyal
34c18bacd8 Free up memory used to store copy of child env block 2022-04-17 08:35:55 +05:30
Kovid Goyal
3af11e92d6 Ensure the clone launch env var is not set accidentally 2022-04-17 08:29:47 +05:30
Kovid Goyal
74d5f2c259 Dont allow inappropriate types for cloning 2022-04-17 08:19:01 +05:30
Kovid Goyal
291f9e9a5e Make cloning safer
Now env vars are set after shell rc files are sourced. And the clone
request cannot specify the cmdline to execute.
2022-04-17 07:49:58 +05:30
Kovid Goyal
38e1d32065 Actually implement allow_cloning 2022-04-16 22:40:05 +05:30
Kovid Goyal
b45fedd794 Infrastructure for serializing env blocks 2022-04-16 22:16:20 +05:30
Kovid Goyal
df9b13fb74 Ask for confirmation before doing a clone by default 2022-04-16 20:04:26 +05:30
Kovid Goyal
53788c4c89 Get conda working with fish 2022-04-16 15:16:53 +05:30
Kovid Goyal
831043b773 Implement venv detection for fish 2022-04-16 14:45:02 +05:30
Kovid Goyal
1daf745d74 Add explicit support for python and conda venvs to clone-in-kitty
Still needs to be implemented for fish
2022-04-16 13:15:10 +05:30
Kovid Goyal
d6c5b40ead ... 2022-04-16 09:26:53 +05:30
Kovid Goyal
57ea524464 Merge branch 'clone-in-kitty' of https://github.com/page-down/kitty 2022-04-15 20:27:36 +05:30
pagedown
e19ce6cce6 clone-in-kitty: Skip some user-related environment variables 2022-04-15 22:47:57 +08:00
Kovid Goyal
8d4f6681e8 Merge branch 'clone-in-kitty' of https://github.com/page-down/kitty 2022-04-15 19:49:33 +05:30
pagedown
9c855a8377 Skip environment variables such as SSH_TTY when using clone-in-kitty 2022-04-15 19:43:40 +08:00
Kovid Goyal
716813e38a Proper fix for macOS argv[0] 2022-04-15 15:23:45 +05:30
Kovid Goyal
e5322cdc52 Fix clone-in-kitty --env not working over ssh 2022-04-15 15:20:38 +05:30
Kovid Goyal
b5701691c6 Dont clone prompt related env variables
These really shouldnt be exported but people often do
2022-04-15 15:18:43 +05:30
Kovid Goyal
aab9482e31 ... 2022-04-15 15:01:13 +05:30
Kovid Goyal
775584b5a5 Use literal quoting for env vars sent over ssh by clone 2022-04-15 14:34:21 +05:30
Kovid Goyal
25f022cc14 Ensure copy_env is False 2022-04-15 14:04:52 +05:30
Kovid Goyal
981ad88309 Allow nuking expandvars globally 2022-04-15 13:58:01 +05:30
Kovid Goyal
e71b9091a3 Dont rely on env -0 for bash either 2022-04-15 13:33:32 +05:30
Kovid Goyal
bde468594e ssh kitten: handle newlines in env vars 2022-04-15 12:49:35 +05:30
Kovid Goyal
0fcfe104e3 Handle argv[0] being buggered on macOS 2022-04-15 12:25:05 +05:30
Kovid Goyal
4cf54d2dfb Dont rely on env -0 in zsh
zsh outputs env vars in a nice one per line format using $'' encoding.
So exploit it
2022-04-15 12:17:59 +05:30
Kovid Goyal
b866c3e783 Add a zsh test for clone env serialization 2022-04-15 12:04:50 +05:30
Kovid Goyal
c15a31e725 Ensure colors are copied form the correct window when cloning
Also, encapsulate clone command into its own class to ease testing
2022-04-15 11:53:28 +05:30
Kovid Goyal
afaf866b15 Merge branch 'ksi-fish-clone-in-kitty' of https://github.com/page-down/kitty 2022-04-14 19:47:41 +05:30
pagedown
af6b1837cb Minor refactoring for fish clone-in-kitty and allow use without env -0
The builtin option from the latest version of fish is not used for now.
clone-in-kitty has been tested with fish 3.2.x.
BusyBox env does not support the -0 option.
2022-04-14 21:32:28 +08:00
Kovid Goyal
aab6f3e450 ... 2022-04-14 17:28:41 +05:30
Kovid Goyal
829ed0ec0d Fix #4964 2022-04-14 17:20:30 +05:30
Kovid Goyal
d9899cb489 Add missing item to changelog 2022-04-14 15:04:48 +05:30
Kovid Goyal
1a370ea9b6 Put the examples front and center 2022-04-14 07:59:32 +05:30
Kovid Goyal
cc07b1f79d Use 2048 chunk size in fish as well 2022-04-13 22:50:24 +05:30
Kovid Goyal
3ddea42660 ... 2022-04-13 22:45:36 +05:30
Kovid Goyal
236dbd95c9 ... 2022-04-13 22:34:23 +05:30
Kovid Goyal
6b078c4267 Implement clone-in-kitty for the fish shell 2022-04-13 22:33:21 +05:30
Kovid Goyal
1dec5f2e08 Help message for clone-in-kitty 2022-04-13 21:38:33 +05:30
Kovid Goyal
e5f70b7306 ... 2022-04-13 21:22:27 +05:30
Kovid Goyal
e2bb856e41 Document clone-in-kitty 2022-04-13 21:01:45 +05:30
Kovid Goyal
88d597f6b2 Dont define clone-in-kitty in POSIX mode
POSIX mode doesnt allow - in identifiers
2022-04-13 20:55:00 +05:30
Kovid Goyal
d0c0b01724 Get clone-in-kitty working for bash as well 2022-04-13 20:38:04 +05:30
Kovid Goyal
4b7c50518e Fix usage of chunk_num 2022-04-13 20:16:51 +05:30
Kovid Goyal
a1bfcd9fc5 Also transfer env vars when cloning over ssh kitten 2022-04-13 20:08:06 +05:30
Kovid Goyal
eb024fa40a ... 2022-04-13 15:51:00 +05:30
Kovid Goyal
122475ad4d Work on getting cloning working with the SSH kitten
Still need to do environment passing
2022-04-13 15:41:42 +05:30
Kovid Goyal
f7114bc1c5 ... 2022-04-13 15:35:06 +05:30
Kovid Goyal
feea6998f8 Allow using the cwd of the oldest as well as the newest foreground process for launch --cwd 2022-04-13 15:31:17 +05:30
Kovid Goyal
e187110611 Use $PWD instead of pwd -P as we want the exact same cwd not the resolved one when cloning 2022-04-13 15:13:58 +05:30
Kovid Goyal
c19e69855a Start work on a command to clone the current working env into a new kitty window 2022-04-13 15:02:22 +05:30
Kovid Goyal
7788f48dd5 Ensure IFS is correct when iterating over KITTY_SHELL_INTEGRATION 2022-04-12 23:03:05 +05:30
Kovid Goyal
073eecb6bb Also package kitty.termcap 2022-04-12 22:43:22 +05:30
Kovid Goyal
030e7e2db3 termcap should be generated in generate not compile 2022-04-12 22:41:19 +05:30
Kovid Goyal
aead3c1c35 Also generate a termcap database entry when building terminfo 2022-04-12 22:38:52 +05:30
Kovid Goyal
587f44ad4e A working implementation of cwd_of_process for FreeBSD 2022-04-12 22:06:46 +05:30
Kovid Goyal
c9ef4aa8c8 Sessions: Fix os_window_size and os_window_class not applying to the first OS Window
Fixes #4957
2022-04-12 21:38:29 +05:30
Kovid Goyal
aabadd8517 ... 2022-04-12 21:19:28 +05:30
Kovid Goyal
b8866371a3 avoid unneccessary session creation during startup 2022-04-12 21:18:18 +05:30
Kovid Goyal
0f3883af02 ... 2022-04-12 21:13:56 +05:30
Kovid Goyal
5876ce0845 Remove --target-group in favor of the new boolean search expressions with matching on window/tab state 2022-04-12 20:41:17 +05:30
Kovid Goyal
2c72c56e22 Add a couple more states to match against
So we can now select windows/tabs that are not active/focused but are in
the active/focused tab/os window.
2022-04-12 20:35:31 +05:30
Kovid Goyal
f15ce21da1 Markup the --match options help text a bit more 2022-04-12 20:20:29 +05:30
Kovid Goyal
b3fa7310cb Allow matching on window/tab state 2022-04-12 20:14:01 +05:30
Kovid Goyal
ade38870a0 Allow using boolean operators when matching windows or tabs 2022-04-12 19:55:20 +05:30
Kovid Goyal
11bc1b100c Handle <> inside :ref: on the CLI 2022-04-12 19:48:09 +05:30
Kovid Goyal
93a7b220c9 Fix parsing of quoted words 2022-04-12 19:31:56 +05:30
Kovid Goyal
8f92c594f2 Create a search query parser 2022-04-12 19:26:25 +05:30
Kovid Goyal
afebea8635 --tab-title=current should respect any override title set on the tab 2022-04-12 12:53:59 +05:30
Kovid Goyal
5d76cfb578 Remove output start mark from last command output 2022-04-12 08:55:07 +05:30
Kovid Goyal
f085f853bd unactive -> inactive 2022-04-12 06:35:29 +05:30
Kovid Goyal
4ac2312b2a Fix #4954 2022-04-12 06:33:35 +05:30
Kovid Goyal
c6dcbe6521 Dont check if running in kitty when updating
I dont actually know if it causes any problems and its fairly
inconvenient to use another terminal.
2022-04-11 22:07:36 +05:30
Kovid Goyal
49efbf0c6e Remove the code to generate installer.sh from installer.py 2022-04-11 21:35:59 +05:30
491 changed files with 76391 additions and 40754 deletions

2
.gitattributes vendored
View File

@@ -15,6 +15,8 @@ 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
tools/wcswidth/std.go linguist-generated=true
*.py text diff=python
*.m text diff=objc
*.go text diff=go

View File

@@ -30,8 +30,13 @@ def install_deps():
print('Installing kitty dependencies...')
sys.stdout.flush()
if is_macos:
items = (x.split()[1].strip('"') for x in open('Brewfile').readlines() if x.strip().startswith('brew '))
run('brew', 'install', 'fish', *items)
items = [x.split()[1].strip('"') for x in open('Brewfile').readlines() if x.strip().startswith('brew ')]
openssl = 'openssl'
items.remove('go') # already installed by ci.yml
import ssl
if ssl.OPENSSL_VERSION_INFO[0] == 1:
openssl += '@1.1'
run('brew', 'install', 'fish', openssl, *items)
else:
run('sudo apt-get update')
run('sudo apt-get install -y libgl1-mesa-dev libxi-dev libxrandr-dev libxinerama-dev ca-certificates'
@@ -59,7 +64,7 @@ def build_kitty():
def test_kitty():
run('./kitty/launcher/kitty +launch test.py')
run('./test.py')
def package_kitty():
@@ -125,6 +130,12 @@ def main():
package_kitty()
elif action == 'test':
test_kitty()
elif action == 'gofmt':
q = subprocess.check_output('gofmt -s -l tools'.split())
if q.strip():
q = '\n'.join(filter(lambda x: not x.rstrip().endswith('_generated.go'), q.decode().strip().splitlines())).strip()
if q:
raise SystemExit(q)
else:
raise SystemExit(f'Unknown action: {action}')

View File

@@ -5,6 +5,10 @@ env:
ASAN_OPTIONS: leak_check_at_exit=0
LC_ALL: en_US.UTF-8
LANG: en_US.UTF-8
GO_INSTALL_VERSION: ">=1.19.0"
permissions:
contents: read # to fetch code (actions/checkout)
jobs:
linux:
@@ -20,15 +24,15 @@ jobs:
cc: [gcc, clang]
include:
- python: a
pyver: 3.7
pyver: "3.8"
sanitize: 0
- python: b
pyver: 3.8
pyver: "3.11"
sanitize: 1
- python: c
pyver: 3.9
pyver: "3.9"
sanitize: 1
@@ -41,20 +45,26 @@ jobs:
cc: gcc
steps:
- name: Checkout source code
uses: actions/checkout@v3
with:
fetch-depth: 10
- name: Set up Python ${{ matrix.pyver }}
uses: actions/setup-python@v3
with:
python-version: ${{ matrix.pyver }}
- name: Checkout source code
uses: actions/checkout@v3
with:
fetch-depth: 10
- name: Build kitty
run: python .github/workflows/ci.py build
- name: Set up Python ${{ matrix.pyver }}
uses: actions/setup-python@v3
with:
python-version: ${{ matrix.pyver }}
- name: Test kitty
run: python .github/workflows/ci.py test
- name: Install Go
uses: actions/setup-go@v3
with:
go-version: ${{ env.GO_INSTALL_VERSION }}
- name: Build kitty
run: python .github/workflows/ci.py build
- name: Test kitty
run: python .github/workflows/ci.py test
linux-package:
name: Linux package
@@ -62,36 +72,53 @@ jobs:
env:
CFLAGS: -funsigned-char
steps:
- name: Checkout source code
uses: actions/checkout@v3
with:
fetch-depth: 10
- name: Checkout source code
uses: actions/checkout@v3
with:
fetch-depth: 0 # needed for :commit: docs role
- name: Test for trailing whitespace
run: if grep -Inr '\s$' kitty kitty_tests kittens docs *.py *.asciidoc *.rst .gitattributes .gitignore; then echo Trailing whitespace found, aborting.; exit 1; fi
- name: Test for trailing whitespace
run: if grep -Inr '\s$' kitty kitty_tests kittens docs *.py *.asciidoc *.rst *.go .gitattributes .gitignore; then echo Trailing whitespace found, aborting.; exit 1; fi
- name: Set up Python
uses: actions/setup-python@v3
with:
python-version: 3.8
- name: Set up Python
uses: actions/setup-python@v3
with:
python-version: "3.10"
- name: Install build-only deps
run: pip install -r docs/requirements.txt flake8 mypy types-requests types-docutils
- name: Install Go
uses: actions/setup-go@v3
with:
go-version: ${{ env.GO_INSTALL_VERSION }}
- name: Run pyflakes
run: python -m flake8 --count .
- name: Install build-only deps
run: python -m pip install -r docs/requirements.txt ruff mypy types-requests types-docutils
- name: Build kitty package
run: python .github/workflows/ci.py package
- name: Run ruff
run: ruff .
- name: Run mypy
run: python test.py mypy
- name: Run gofmt
run: go version && python .github/workflows/ci.py gofmt
- name: Build man page
run: make FAIL_WARN=1 man
- name: Build kitty package
run: python .github/workflows/ci.py package
- name: Build HTML docs
run: make FAIL_WARN=1 html
- name: Build kitty
run: python setup.py build --debug
- name: Build static kitty-tool
run: python setup.py build-static-binaries
- name: Run mypy
run: which python && python -m mypy --version && ./test.py mypy
- name: Run go vet
run: go version && go vet ./...
- name: Build man page
run: make FAIL_WARN=1 man
- name: Build HTML docs
run: make FAIL_WARN=1 html
bundle:
name: Bundle test (${{ matrix.os }})
@@ -102,31 +129,52 @@ jobs:
env:
KITTY_BUNDLE: 1
steps:
- name: Checkout source code
uses: actions/checkout@master
with:
fetch-depth: 10
- name: Checkout source code
uses: actions/checkout@master
with:
fetch-depth: 10
- name: Build kitty
run: which python3 && python3 .github/workflows/ci.py build
- name: Install Go
uses: actions/setup-go@v3
with:
go-version: ${{ env.GO_INSTALL_VERSION }}
- name: Test kitty
run: python3 .github/workflows/ci.py test
- name: Build kitty
run: which python3 && python3 .github/workflows/ci.py build
- name: Test kitty
run: python3 .github/workflows/ci.py test
brew:
name: macOS Brew
runs-on: macos-latest
steps:
- name: Checkout source code
uses: actions/checkout@master
with:
fetch-depth: 10
- name: Checkout source code
uses: actions/checkout@master
with:
fetch-depth: 0 # needed for :commit: docs role
- name: Build kitty
run: python3 .github/workflows/ci.py build
- name: Set up Python
uses: actions/setup-python@v3
with:
python-version: "3.10"
- name: Test kitty
run: python3 .github/workflows/ci.py test
- name: Install Go
uses: actions/setup-go@v3
with:
go-version: ${{ env.GO_INSTALL_VERSION }}
- name: Build kitty package
run: python3 .github/workflows/ci.py package
- name: Build kitty
run: python3 .github/workflows/ci.py build
- name: Test kitty
run: python3 .github/workflows/ci.py test
- name: Install deps for docs
run: python3 -m pip install -r docs/requirements.txt
- name: Builds docs
run: make FAIL_WARN=1 docs
- name: Build kitty package
run: python3 .github/workflows/ci.py package

View File

@@ -9,12 +9,25 @@ on:
schedule:
- cron: '0 22 * * 5'
permissions:
contents: read # to fetch code (actions/checkout)
jobs:
CodeQL-Build:
permissions:
contents: read # to fetch code (actions/checkout)
security-events: write # to upload SARIF results (github/codeql-action/analyze)
runs-on: ubuntu-latest
steps:
- name: Install Go
uses: actions/setup-go@v3
with:
go-version: ">=1.19.0"
- name: Checkout repository
uses: actions/checkout@v3
with:
@@ -24,7 +37,7 @@ jobs:
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v1
uses: github/codeql-action/init@v2
with:
languages: python, c
setup-python-dependencies: false

9
.gitignore vendored
View File

@@ -2,15 +2,17 @@
*.pyc
*.pyo
*_stub.pyi
*_generated.go
*_generated.h
/.dmypy.json
/tags
/build/
/linux-package/
/kitty.app/
/compile_commands.json
/link_commands.json
/glad/out/
/kitty/launcher/
/kitty/launcher/kitt*
/tools/cmd/at/*_generated.go
*_generated.go
/*.dSYM/
__pycache__/
/glfw/wayland-*-client-protocol.[ch]
@@ -18,5 +20,6 @@ __pycache__/
/docs/generated/
/.mypy_cache
.DS_Store
.cache
bypy/b
bypy/virtual-machines.conf

View File

@@ -5,3 +5,4 @@ brew "python"
brew "imagemagick"
brew "harfbuzz"
brew "sphinx-doc"
brew "go"

View File

@@ -7,6 +7,11 @@ When reporting a bug, provide full details of your environment, that means, at
a minimum, kitty version, OS and OS version, kitty config (ideally a minimal
config to reproduce the issue with).
Note that bugs and feature requests are often closed quickly as they are either
fixed or deemed wontfix/invalid. In my experience, this is the only scaleable way to
manage a bug tracker. Feel free to continue to post to a closed bug report
if you would like to discuss the issue further. Being closed does not mean you
will not get any more responses.
### Contributing code

View File

@@ -35,6 +35,12 @@ profile:
app:
python3 setup.py kitty.app $(VVAL)
linux-package: FORCE
rm -rf linux-package
python3 setup.py linux-package
FORCE:
man:
$(MAKE) -C docs man

View File

@@ -1,185 +1,7 @@
#!/usr/bin/env python3
# License: GPL v3 Copyright: 2015, Kovid Goyal <kovid at kovidgoyal.net>
import os
import sys
from typing import List
def icat(args: List[str]) -> None:
from kittens.runner import run_kitten as rk
sys.argv = args
rk('icat')
def list_fonts(args: List[str]) -> None:
from kitty.fonts.list import main as list_main
list_main(args)
def remote_control(args: List[str]) -> None:
from kitty.remote_control import main as rc_main
rc_main(args)
def runpy(args: List[str]) -> None:
if len(args) < 2:
raise SystemExit('Usage: kitty +runpy "some python code"')
sys.argv = ['kitty'] + args[2:]
exec(args[1])
def hold(args: List[str]) -> None:
import subprocess
ret = 1
try:
ret = subprocess.Popen(args[1:]).wait()
except KeyboardInterrupt:
pass
except FileNotFoundError:
print(f'Could not find {args[1]!r} to execute', file=sys.stderr)
except Exception as e:
print(e, file=sys.stderr)
from kitty.utils import hold_till_enter
hold_till_enter()
raise SystemExit(ret)
def complete(args: List[str]) -> None:
from kitty.complete import main as complete_main
complete_main(args[1:], entry_points, namespaced_entry_points)
def open_urls(args: List[str]) -> None:
setattr(sys, 'cmdline_args_for_open', True)
sys.argv = ['kitty'] + args[1:]
from kitty.main import main as kitty_main
kitty_main()
def launch(args: List[str]) -> None:
import runpy
sys.argv = 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(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__')
def shebang(args: List[str]) -> None:
script_path = args[1]
cmd = args[2:]
if cmd == ['__ext__']:
cmd = [os.path.splitext(script_path)[1][1:].lower()]
try:
f = open(script_path)
except FileNotFoundError:
raise SystemExit(f'The file {script_path} does not exist')
with f:
if f.read(2) == '#!':
line = f.readline().strip()
_plat = sys.platform.lower()
is_macos: bool = 'darwin' in _plat
if is_macos:
cmd = line.split(' ')
else:
cmd = line.split(' ', maxsplit=1)
os.execvp(cmd[0], cmd + [script_path])
def run_kitten(args: List[str]) -> None:
try:
kitten = args[1]
except IndexError:
from kittens.runner import list_kittens
list_kittens()
raise SystemExit(1)
sys.argv = args[1:]
from kittens.runner import run_kitten as rk
rk(kitten)
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:
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 = {
# These two are here for backwards compat
'icat': icat,
'list-fonts': list_fonts,
'@': remote_control,
'+': namespaced,
}
namespaced_entry_points = {k: v for k, v in entry_points.items() if k[0] not in '+@'}
namespaced_entry_points['hold'] = hold
namespaced_entry_points['complete'] = complete
namespaced_entry_points['runpy'] = runpy
namespaced_entry_points['launch'] = launch
namespaced_entry_points['open'] = open_urls
namespaced_entry_points['kitten'] = run_kitten
namespaced_entry_points['edit-config'] = edit_config_file
namespaced_entry_points['shebang'] = shebang
def setup_openssl_environment() -> None:
# Use our bundled CA certificates instead of the system ones, since
# many systems come with no certificates in a useable form or have various
# locations for the certificates.
d = os.path.dirname
ext_dir: str = getattr(sys, 'kitty_extensions_dir')
if 'darwin' in sys.platform.lower():
cert_file = os.path.join(d(d(d(ext_dir))), 'cacert.pem')
else:
cert_file = os.path.join(d(ext_dir), 'cacert.pem')
os.environ['SSL_CERT_FILE'] = cert_file
setattr(sys, 'kitty_ssl_env_var', 'SSL_CERT_FILE')
def main() -> None:
if getattr(sys, 'frozen', False) and getattr(sys, 'kitty_extensions_dir', ''):
setup_openssl_environment()
first_arg = '' if len(sys.argv) < 2 else sys.argv[1]
func = entry_points.get(first_arg)
if func is None:
if first_arg.startswith('@'):
remote_control(['@', first_arg[1:]] + sys.argv[2:])
elif first_arg.startswith('+'):
namespaced(['+', first_arg[1:]] + sys.argv[2:])
else:
from kitty.main import main as kitty_main
kitty_main()
else:
func(sys.argv[1:])
if __name__ == '__main__':
from kitty.entry_points import main
main()

View File

@@ -4,7 +4,6 @@
import glob
import os
import re
import shutil
import subprocess
import sys
@@ -13,11 +12,10 @@ import tempfile
def compile_terminfo(base):
with tempfile.TemporaryDirectory() as tdir:
proc = subprocess.run(['tic', '-x', f'-o{tdir}', 'terminfo/kitty.terminfo'], check=True, stderr=subprocess.PIPE)
regex = '^"terminfo/kitty.terminfo", line [0-9]+, col [0-9]+, terminal \'xterm-kitty\': older tic versions may treat the description field as an alias$'
for error in proc.stderr.decode('utf-8').splitlines():
if not re.match(regex, error):
print(error, file=sys.stderr)
proc = subprocess.run(['tic', '-x', f'-o{tdir}', 'terminfo/kitty.terminfo'], capture_output=True)
if proc.returncode != 0:
sys.stderr.buffer.write(proc.stderr)
raise SystemExit(proc.returncode)
tfiles = glob.glob(os.path.join(tdir, '*', 'xterm-kitty'))
if not tfiles:
raise SystemExit('tic failed to output the compiled kitty terminfo file')
@@ -40,6 +38,13 @@ def generate_terminfo():
with open('terminfo/kitty.terminfo', 'w') as f:
f.write(generate_terminfo())
proc = subprocess.run(['tic', '-CrT0', 'terminfo/kitty.terminfo'], capture_output=True)
if proc.returncode != 0:
sys.stderr.buffer.write(proc.stderr)
raise SystemExit(proc.returncode)
tcap = proc.stdout.decode('utf-8').splitlines()[-1]
with open('terminfo/kitty.termcap', 'w') as f:
f.write(tcap)
compile_terminfo(os.path.join(base, 'terminfo'))

View File

@@ -11,9 +11,8 @@ import sys
import tempfile
from contextlib import suppress
from bypy.constants import (
LIBDIR, PREFIX, PYTHON, SRC as KITTY_DIR, ismacos, worker_env
)
from bypy.constants import LIBDIR, PREFIX, PYTHON, ismacos, worker_env
from bypy.constants import SRC as KITTY_DIR
from bypy.utils import run_shell, walk
@@ -63,20 +62,31 @@ def build_frozen_launcher(extra_include_dirs):
def run_tests(kitty_exe):
with tempfile.TemporaryDirectory() as tdir:
env = {
uenv = {
'KITTY_CONFIG_DIRECTORY': os.path.join(tdir, 'conf'),
'KITTY_CACHE_DIRECTORY': os.path.join(tdir, 'cache')
}
[os.mkdir(x) for x in env.values()]
cmd = [kitty_exe, '+runpy', 'from kitty_tests.main import run_tests; run_tests()']
[os.mkdir(x) for x in uenv.values()]
env = os.environ.copy()
env.update(uenv)
cmd = [kitty_exe, '+runpy', 'from kitty_tests.main import run_tests; run_tests(report_env=True)']
print(*map(shlex.quote, cmd), flush=True)
if subprocess.call(cmd, env=env) != 0:
print('Checking of kitty build failed', file=sys.stderr)
if subprocess.call(cmd, env=env, cwd=build_frozen_launcher.writeable_src_dir) != 0:
print('Checking of kitty build failed, in directory:', build_frozen_launcher.writeable_src_dir, file=sys.stderr)
os.chdir(os.path.dirname(kitty_exe))
run_shell()
raise SystemExit('Checking of kitty build failed')
def build_frozen_tools(kitty_exe):
cmd = SETUP_CMD + ['--prefix', os.path.dirname(kitty_exe)] + ['build-frozen-tools']
if run(*cmd, cwd=build_frozen_launcher.writeable_src_dir) != 0:
print('Building of frozen kitten failed', file=sys.stderr)
os.chdir(KITTY_DIR)
run_shell()
raise SystemExit('Building of kitten launcher failed')
def sanitize_source_folder(path: str) -> None:
for q in walk(path):
if os.path.splitext(q)[1] not in ('.py', '.glsl', '.ttf', '.otf'):

View File

@@ -1,3 +1,3 @@
image 'https://cloud-images.ubuntu.com/releases/bionic/release/ubuntu-18.04-server-cloudimg-{}.img'
deps 'bison flex libxcursor-dev libxrandr-dev libxi-dev libxinerama-dev libgl1-mesa-dev libxcb-xkb-dev libfontconfig1-dev libdbus-1-dev'
deps 'bison flex libxcursor-dev libxrandr-dev libxi-dev libxinerama-dev libgl1-mesa-dev libx11-xcb-dev libxcb-xkb-dev libfontconfig1-dev libdbus-1-dev'

View File

@@ -10,12 +10,8 @@ import subprocess
import tarfile
import time
from bypy.constants import (
OUTPUT_DIR, PREFIX, is64bit, python_major_minor_version
)
from bypy.freeze import (
extract_extension_modules, freeze_python, path_to_freeze_dir
)
from bypy.constants import OUTPUT_DIR, PREFIX, is64bit, python_major_minor_version
from bypy.freeze import extract_extension_modules, freeze_python, path_to_freeze_dir
from bypy.utils import get_dll_path, mkdtemp, py_compile, walk
j = os.path.join
@@ -35,6 +31,9 @@ def binary_includes():
'expat', 'sqlite3', 'ffi', 'z', 'lzma', 'png16', 'lcms2', 'crypt',
'iconv', 'pcre', 'graphite2', 'glib-2.0', 'freetype', 'rsync',
'harfbuzz', 'xkbcommon', 'xkbcommon-x11',
# fontconfig is not bundled because in typical brain dead Linux
# distro fashion, different distros use different default config
# paths for fontconfig.
'ncursesw', 'readline', 'brotlicommon', 'brotlienc', 'brotlidec',
'wayland-client', 'wayland-cursor',
))) + (
@@ -140,6 +139,7 @@ def copy_python(env):
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', remove_pyc_files=True)
shutil.rmtree(env.py_dir)
def build_launcher(env):
@@ -216,7 +216,7 @@ def create_tarfile(env, compression_level='9'):
print('Compressing archive...')
ans = f'{dist.rpartition(".")[0]}.txz'
start_time = time.time()
subprocess.check_call(['xz', '--threads=0', '-f', f'-{compression_level}', dist])
subprocess.check_call(['xz', '--verbose', '--threads=0', '-f', f'-{compression_level}', dist])
secs = time.time() - start_time
print('Compressed in {} minutes {} seconds'.format(secs // 60, secs % 60))
os.rename(f'{dist}.xz', ans)
@@ -234,10 +234,12 @@ def main():
files = find_binaries(env)
fix_permissions(files)
add_ca_certs(env)
kitty_exe = os.path.join(env.base, 'bin', 'kitty')
iv['build_frozen_tools'](kitty_exe)
if not args.dont_strip:
strip_binaries(files)
if not args.skip_tests:
iv['run_tests'](os.path.join(env.base, 'bin', 'kitty'))
iv['run_tests'](kitty_exe)
create_tarfile(env, args.compression_level)

View File

@@ -1,4 +1,4 @@
# Requires installation of XCode 10.3 and Python 3 and
# Requires installation of XCode 10.3 and go 1.19 and Python 3 and
# python3 -m pip install certifi
vm_name 'macos-kitty'

View File

@@ -13,16 +13,9 @@ import tempfile
import zipfile
from bypy.constants import PREFIX, PYTHON, SW, python_major_minor_version
from bypy.freeze import (
extract_extension_modules, freeze_python, path_to_freeze_dir
)
from bypy.macos_sign import (
codesign, create_entitlements_file, make_certificate_useable, notarize_app,
verify_signature
)
from bypy.utils import (
current_dir, mkdtemp, py_compile, run_shell, timeit, walk
)
from bypy.freeze import extract_extension_modules, freeze_python, path_to_freeze_dir
from bypy.macos_sign import codesign, create_entitlements_file, make_certificate_useable, notarize_app, verify_signature
from bypy.utils import current_dir, mkdtemp, py_compile, run_shell, timeit, walk
iv = globals()['init_env']
kitty_constants = iv['kitty_constants']
@@ -113,6 +106,9 @@ def do_sign(app_dir):
codesign(fw)
items = set(os.listdir('.')) - fw
codesign(expand_dirs(items))
# Sign kitten
with current_dir('MacOS'):
codesign('kitten')
# Now sign the main app
codesign(app_dir)
@@ -171,6 +167,7 @@ class Freeze(object):
self.add_misc_libraries()
self.freeze_python()
self.add_ca_certs()
self.build_frozen_tools()
if not self.dont_strip:
self.strip_files()
if not self.skip_tests:
@@ -369,6 +366,7 @@ class Freeze(object):
iv['sanitize_source_folder'](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', remove_pyc_files=True)
shutil.rmtree(self.python_stdlib)
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'))
@@ -377,6 +375,10 @@ class Freeze(object):
if f.endswith('.so') or f.endswith('.dylib'):
self.fix_dependencies_in_lib(f)
@flush
def build_frozen_tools(self):
iv['build_frozen_tools'](join(self.contents_dir, 'MacOS', 'kitty'))
@flush
def add_site_packages(self):
print('\nAdding site-packages')

View File

@@ -1 +1 @@
to_vm_excludes '/build /dist /kitty/launcher/kitty /.build-cache /tags __pycache__ /*_commands.json *.so *.pyd *.pyc'
to_vm_excludes '/build /dist /kitty/launcher/kitty* /.build-cache /tags __pycache__ /*_commands.json *.so *.pyd *.pyc *_generated.go'

View File

@@ -2,8 +2,8 @@
{
"name": "zlib",
"unix": {
"filename": "zlib-1.2.11.tar.xz",
"hash": "sha256:4ff941449631ace0d4d203e3483be9dbc9da454084111f97ea0a2114e19bf066",
"filename": "zlib-1.2.13.tar.xz",
"hash": "sha256:d14c38e313afc35a9a8760dadf26042f51ea0f5d154b0630a31da0540107fb98",
"urls": ["https://zlib.net/{filename}"]
}
},

View File

@@ -21,10 +21,17 @@ kitty/options/parse.py
kitty/options/to-c-generated.h
kittens/diff/options/types.py
kittens/diff/options/parse.py
tools/wcswidth/std.go
'''
ignored = []
for line in subprocess.check_output(['git', 'status', '--ignored', '--porcelain']).decode().splitlines():
if line.startswith('!! '):
ignored.append(line[3:])
files_to_exclude += '\n'.join(ignored)
p = subprocess.Popen([
'cloc', '--exclude-list-file', '/dev/stdin', 'kitty', 'kittens'
'cloc', '--exclude-list-file', '/dev/stdin', 'kitty', 'kittens', 'tools',
], stdin=subprocess.PIPE)
p.communicate(files_to_exclude.encode('utf-8'))
raise SystemExit(p.wait())

View File

@@ -10,7 +10,7 @@
}
.sidebar-logo {
max-height: 128px;
height: 128px;
}
.major-features li {

View File

@@ -4,18 +4,14 @@
{{ 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']);
<!-- Global site tag (gtag.js) - Google Analytics -->
<script async src="https://www.googletagmanager.com/gtag/js?id={{ analytics_id }}"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
(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);
})();
gtag('config', '{{ analytics_id }}');
</script>
{% endif -%}

View File

@@ -1,12 +1,13 @@
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:
|kitty| is capable of running multiple programs organized into tabs and windows.
The top level of organization is the :term:`OS window <os_window>`. Each OS
window consists of one or more :term:`tabs <tab>`. Each tab consists of one or more
:term:`kitty windows <window>`. The kitty windows can be arranged in multiple
different :term:`layouts <layout>`, like windows are organized in a tiling
window manager. The keyboard controls (which are :ref:`all customizable
<conf-kitty-shortcuts>`) for tabs and windows are:
Scrolling
~~~~~~~~~~~~~~
@@ -26,6 +27,11 @@ Browse scrollback in less :sc:`show_scrollback`
Browse last cmd output :sc:`show_last_command_output` (see :ref:`shell_integration`)
========================= =======================
The scroll actions only take effect when the terminal is in the main screen.
When the alternate screen is active (for example when using a full screen
program like an editor) the key events are instead passed to program running in the
terminal.
Tabs
~~~~~~~~~~~
@@ -64,8 +70,9 @@ Focus specific window :sc:`first_window`, :sc:`second_window` ... :sc:`ten
(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)::
Additionally, you can define shortcuts in :file:`kitty.conf` to focus
neighboring windows and move windows around (similar to window movement in
:program:`vim`)::
map ctrl+left neighboring_window left
map shift+left move_window right
@@ -77,20 +84,20 @@ 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 (starting from
:ac:`nth_window` will focus the nth window for positive numbers (starting from
zero) and the previously active windows for negative numbers.
To switch to the nth OS window, you can define ``nth_os_window``. Only positive
numbers are accepted, starting from one.
To switch to the nth OS window, you can define :ac:`nth_os_window`. Only
positive numbers are accepted, starting from one.
.. _detach_window:
You can define shortcuts to detach the current window and
move it to another tab or another OS 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
# moves the window into a new tab
map ctrl+f3 detach_window new-tab
# moves the window into the previously active tab
map ctrl+f3 detach_window tab-prev
@@ -106,8 +113,8 @@ Similarly, you can detach the current tab, with::
# 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::
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
@@ -121,21 +128,22 @@ The full list of actions that can be mapped to key presses is available
================================== =======================
Action Shortcut
================================== =======================
Show this help :sc:`show_kitty_doc`
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`
Pass selection to program :sc:`pass_selection_to_program`
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)
Input Unicode character :sc:`input_unicode_character` (also :kbd:`⌃+⌘+space` on macOS)
Open URL in web browser :sc:`open_url`
Reset the terminal :sc:`reset_terminal` (also :kbd:`⌥+⌘+r` on macOS)
Edit :file:`kitty.conf` :sc:`edit_config_file` (also :kbd:`⌘+,` on macOS)
Reload :file:`kitty.conf` :sc:`reload_config_file` (also :kbd:`⌃+⌘+,` on macOS)
Debug :file:`kitty.conf` :sc:`debug_config` (also :kbd:`⌥+⌘+,` on macOS)
Pass current selection to program :sc:`pass_selection_to_program`
Edit |kitty| config file :sc:`edit_config_file` (also :kbd:`⌘+,` on macOS)
Open a |kitty| shell :sc:`kitty_shell`
Increase background opacity :sc:`increase_background_opacity`
Decrease background opacity :sc:`decrease_background_opacity`

View File

@@ -4,17 +4,14 @@ Install kitty
Binary install
----------------
.. |ins| replace:: curl -L :literal:`https://sw.kovidgoyal.net/kitty/installer.sh` | sh /dev/stdin
.. highlight:: sh
You can install pre-built binaries of |kitty| if you are on macOS or Linux using
the following simple command:
.. parsed-literal::
:class: pre
.. code-block:: sh
|ins|
_kitty_install_cmd
The binaries will be installed in the standard location for your OS,
@@ -24,7 +21,7 @@ simply re-run the command.
.. warning::
**Do not** copy the kitty binary out of the installation folder. If you want
to add it to your ``PATH`` create a symlink in :file:`~/.local/bin` or
to add it to your :envvar:`PATH`, create a symlink in :file:`~/.local/bin` or
:file:`/usr/bin` or wherever.
@@ -33,11 +30,12 @@ Manually installing
If something goes wrong or you simply do not want to run the installer, you can
manually download and install |kitty| from the `GitHub releases page
<https://github.com/kovidgoyal/kitty/releases>`_. If you are on macOS, download
the :file:`.dmg` and install as normal. If you are on Linux, download the tarball
and extract it into a directory. The |kitty| executable will be in the
<https://github.com/kovidgoyal/kitty/releases>`__. If you are on macOS, download
the :file:`.dmg` and install as normal. If you are on Linux, download the
tarball and extract it into a directory. The |kitty| executable will be in the
:file:`bin` sub-directory.
Desktop integration on Linux
--------------------------------
@@ -60,9 +58,19 @@ particular desktop, but it should work for most major desktop environments.
sed -i "s|Exec=kitty|Exec=/home/$USER/.local/kitty.app/bin/kitty|g" ~/.local/share/applications/kitty*.desktop
.. note::
If you use the venerable `stow <https://www.gnu.org/software/stow/>`_
In :file:`kitty-open.desktop`, kitty is registered to handle some supported
MIME types. This will cause kitty to take precedence on some systems where
the default apps are not explicitly set. For example, you expect to use
other GUI file managers to open dir paths when using commands such as
:program:`xdg-open`, you should configure the default opener for the MIME
type ``inode/directory``::
xdg-mime default org.kde.dolphin.desktop inode/directory
.. 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`)::
above for you (use with :code:`dest=~/.local/stow`)::
cd ~/.local/stow
stow -v kitty.app
@@ -75,44 +83,39 @@ Customizing the installation
* You can install the latest nightly kitty build with ``installer``:
.. parsed-literal::
:class: pre
.. code-block:: sh
|ins| \\
_kitty_install_cmd \
installer=nightly
If you want to install it in parallel to the released kitty specify a
different install locations with ``dest``:
.. parsed-literal::
:class: pre
.. code-block:: sh
|ins| \\
_kitty_install_cmd \
installer=nightly dest=/some/other/location
* You can specify a different install location, with ``dest``:
.. parsed-literal::
:class: pre
.. code-block:: sh
|ins| \\
_kitty_install_cmd \
dest=/some/other/location
* You can tell the installer not to launch |kitty| after installing it with
``launch=n``:
.. parsed-literal::
:class: pre
.. code-block:: sh
|ins| \\
_kitty_install_cmd \
launch=n
* You can use a previously downloaded dmg/tarball, with ``installer``:
.. parsed-literal::
:class: pre
.. code-block:: sh
|ins| \\
_kitty_install_cmd \
installer=/path/to/dmg or tarball

View File

@@ -7,21 +7,21 @@ Build from source
.. highlight:: sh
|kitty| is designed to run from source, for easy hack-ability. Make sure
the following dependencies are installed first.
|kitty| is designed to run from source, for easy hack-ability. Make sure the
following dependencies are installed first.
.. note::
If you just want to test the latest changes to kitty you dont need to build
If you just want to test the latest changes to kitty, you don't need to build
from source. Instead install the :ref:`latest nightly build <nightly>`.
.. note::
If you are making small changes only to the python parts of kitty, there is no need to
build kitty at all, instead, assuming you have installed the official kitty
binaries, you can simply set the KITTY_DEVELOP_FROM enviroment variable to
point to the directory into which you have checked out the kitty source
code. kitty will then load its python code from there. You should use a
version of the source that matches the binary version as closely as
possible, since the two are tightly coupled.
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 :envvar:`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
@@ -29,24 +29,28 @@ Dependencies
Run-time dependencies:
* ``python`` >= 3.6
* ``python`` >= 3.8
* ``harfbuzz`` >= 2.2.0
* ``zlib``
* ``libpng``
* ``liblcms2``
* ``librsync``
* ``openssl``
* ``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)
* ``ImageMagick`` (optional, needed to display uncommon image formats in the terminal)
* ``pygments`` (optional, needed for syntax highlighting in ``kitty +kitten diff``)
Build-time dependencies:
* ``gcc`` or ``clang``
* ``go >= 1.19`` (see :file:`go.mod` for go packages used during building)
* ``pkg-config``
* For building on Linux in addition to the above dependencies you might also need to install the following packages, if they are not already installed by your distro:
* For building on Linux in addition to the above dependencies you might also
need to install the following packages, if they are not already installed by
your distro:
- ``libdbus-1-dev``
- ``libxcursor-dev``
@@ -77,9 +81,12 @@ You can run |kitty|, as::
./kitty/launcher/kitty
If that works, you can create a symlink to the launcher in :file:`~/bin` or
some other directory on your PATH so that you can run |kitty| using
just ``kitty``.
If that works, you can create a symlink to the launcher in :file:`~/bin` or some
other directory on your PATH so that you can run |kitty| using just ``kitty``.
To have the kitty documentation available locally, run::
python3 -m pip install -r docs/requirements.txt && make docs
Building kitty.app on macOS from source
@@ -87,28 +94,30 @@ Building kitty.app on macOS from source
Run::
python3 -m pip install -r docs/requirements.txt && make docs
make app
Building the docs needs to be done only once.
This :file:`kitty.app` unlike the released one does not include its own copy of
python and the other dependencies. So if you ever un-install/upgrade those dependencies
you might have to rebuild the app.
Python and the other dependencies. So if you ever un-install/upgrade those
dependencies 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
`bypy framework <https://github.com/kovidgoyal/bypy>`_ however, that is
`bypy framework <https://github.com/kovidgoyal/bypy>`__ however, that is
designed to run on Linux and is not for the faint of heart.
.. note::
Apple disallows certain functionality, such as notifications for unsigned applications.
If you need this functionality, you can try signing the built kitty.app with
a self signed certificate, see for example, `here
<https://stackoverflow.com/questions/27474751/how-can-i-codesign-an-app-without-being-in-the-mac-developer-program/27474942>`_.
Apple disallows certain functionality, such as notifications for unsigned
applications. If you need this functionality, you can try signing the built
:file:`kitty.app` with a self signed certificate, see for example, `here
<https://stackoverflow.com/questions/27474751/how-can-i-codesign-an-app-without-being-in-the-mac-developer-program/27474942>`__.
.. note::
If you are facing issues with ``linker`` while building,
try with a ``brew`` installed python instead, see :iss:`289`
for more discussion.
If you are facing issues with ``linker`` while building, try with a ``brew``
installed Python instead, see :iss:`289` for more discussion.
Build and run from source with Nix
@@ -116,13 +125,14 @@ Build and run from source with Nix
On NixOS or any other Linux or macOS system with the Nix package manager
installed, execute `nix-shell
<https://nixos.org/guides/nix-pills/developing-with-nix-shell.html>`_ to create
<https://nixos.org/guides/nix-pills/developing-with-nix-shell.html>`__ to create
the correct environment to build kitty or use ``nix-shell --pure`` instead to
eliminate most of the influence of the outside system, e.g. globally installed
packages. ``nix-shell`` will automatically fetch all required dependencies and
make them available in the newly spawned shell.
Then proceed with ``make`` or ``make app`` according to the platform specific instructions above.
Then proceed with ``make`` or ``make app`` according to the platform specific
instructions above.
Debug builds
@@ -132,7 +142,8 @@ A basic debug build can be done with::
make debug
This includes debug info in the binary for better traces. To build with address sanitizer, use::
This includes debug info in the binary for better traces. To build with address
sanitizer, use::
make asan
@@ -144,46 +155,48 @@ Notes for Linux/macOS packagers
----------------------------------
The released |kitty| source code is available as a `tarball`_ from
`the GitHub releases page <https://github.com/kovidgoyal/kitty/releases>`_.
`the GitHub releases page <https://github.com/kovidgoyal/kitty/releases>`__.
While |kitty| does use python, it is not a traditional python package, so please
While |kitty| does use Python, it is not a traditional Python package, so please
do not install it in site-packages.
Instead run::
python3 setup.py linux-package
make linux-package
This will install |kitty| into the directory :file:`linux-package`. You can run |kitty|
with :file:`linux-package/bin/kitty`. All the files needed to run kitty will be in
:file:`linux-package/lib/kitty`. The terminfo file will be installed into
:file:`linux-package/share/terminfo`. Simply copy these files into :file:`/usr` to install
|kitty|. In other words, :file:`linux-package` is the staging area into which |kitty| is
installed. You can choose a different staging area, by passing the ``--prefix``
argument to :file:`setup.py`.
This will install |kitty| into the directory :file:`linux-package`. You can run
|kitty| with :file:`linux-package/bin/kitty`. All the files needed to run kitty
will be in :file:`linux-package/lib/kitty`. The terminfo file will be installed
into :file:`linux-package/share/terminfo`. Simply copy these files into
:file:`/usr` to install |kitty|. In other words, :file:`linux-package` is the
staging area into which |kitty| is installed. You can choose a different staging
area, by passing the ``--prefix`` argument to :file:`setup.py`.
You should probably split |kitty| into three packages:
:code:`kitty-terminfo`
installs the terminfo file
Installs the terminfo file
:code:`kitty-shell-integration`
installs the shell integration scripts (the contents of the
shell-integration directory in the kitty source code, probably to
Installs the shell integration scripts (the contents of the
shell-integration directory in the kitty source code), probably to
:file:`/usr/share/kitty/shell-integration`
:code:`kitty`
installs the main program
Installs the main program
This allows users to install the terminfo and shell integration files on
servers into which they ssh, without needing to install all of |kitty|.
servers into which they ssh, without needing to install all of |kitty|. The
shell integration files **must** still be present in
:file:`lib/kitty/shell-integration` when installing the kitty main package as
the kitty program expects to find them there.
.. 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 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``.
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
:file:`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
Homebrew or MacPorts as well.

View File

@@ -16,6 +16,7 @@ The :doc:`ssh kitten <kittens/ssh>` is redesigned with powerful new features:
* Automatic :ref:`shell_integration` on remote machines
* Easily :ref:`clone local shell/editor config <real_world_ssh_kitten_config>` on remote machines
* Easily :ref:`edit files in your local editor <edit_file>` on remote machines
* Automatic :opt:`re-use of existing connections <kitten-ssh.share_connections>` to avoid connection setup latency
@@ -34,6 +35,336 @@ mouse anywhere in the current command to move the cursor there. See
Detailed list of changes
-------------------------------------
0.27.0 [2023-01-31]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- A new statically compiled, standalone executable, ``kitten`` (written in Go)
that can be used on all UNIX-like servers for remote control (``kitten @``),
viewing images (``kitten icat``), manipulating the clipboard (``kitten clipboard``), etc.
- :doc:`clipboard kitten </kittens/clipboard>`: Allow copying arbitrary data types to/from the clipboard, not just plain text
- Speed up the ``kitty @`` executable by ~10x reducing the time for typical
remote control commands from ~50ms to ~5ms
- icat kitten: Speed up by using POSIX shared memory when possible to transfer
image data to the terminal. Also support common image formats
GIF/PNG/JPEG/WEBP/TIFF/BMP out of the box without needing ImageMagick.
- Option :opt:`show_hyperlink_targets` to show the target of terminal hyperlinks when hovering over them with the mouse (:pull:`5830`)
- Keyboard protocol: Remove ``CSI R`` from the allowed encodings of the :kbd:`F3` key as it conflicts with the *Cursor Position Report* escape code (:disc:`5813`)
- Allow using the cwd of the original process for :option:`launch --cwd` (:iss:`5672`)
- Session files: Expand environment variables (:disc:`5917`)
- Pass key events mapped to scroll actions to the program running in the terminal when the terminal is in alternate screen mode (:iss:`5839`)
- Implement :ref:`edit-in-kitty <edit_file>` using the new ``kitten`` static executable (:iss:`5546`, :iss:`5630`)
- Add an option :opt:`background_tint_gaps` to control background image tinting for window gaps (:iss:`5596`)
- A new option :opt:`undercurl_style` to control the rendering of undercurls (:pull:`5883`)
- Bash integration: Fix ``clone-in-kitty`` not working on bash >= 5.2 if an environment variable values contain newlines or other special characters (:iss:`5629`)
- A new :ac:`sleep` action useful in combine based mappings to make kitty sleep before executing the next action
- Wayland GNOME: Workaround for latest mutter release breaking full screen for semi-transparent kitty windows (:iss:`5677`)
- A new option :opt:`tab_title_max_length` to limit the length of tab (:iss:`5718`)
- When drawing the tab bar have the default left and right margins drawn in a color matching the neighboring tab (:iss:`5719`)
- When using the :code:`include` directive in :file:`kitty.conf` make the environment variable :envvar:`KITTY_OS` available for OS specific config
- Wayland: Fix signal handling not working with some GPU drivers (:iss:`4636`)
- Remote control: When matching windows allow using negative id numbers to match recently created windows (:iss:`5753`)
- ZSH Integration: Bind :kbd:`alt+left` and :kbd:`alt+right` to move by word if not already bound. This mimics the default bindings in Terminal.app (:iss:`5793`)
- macOS: Allow to customize :sc:`Hide <hide_macos_app>`, :sc:`Hide Others <hide_macos_other_apps>`, :sc:`Minimize <minimize_macos_window>`, and :sc:`Quit <quit>` global menu shortcuts. Note that :opt:`clear_all_shortcuts` will remove these shortcuts now (:iss:`948`)
- When a multi-key sequence does not match any action, send all key events to the child program (:pull:`5841`)
- broadcast kitten: Allow pressing a key to stop echoing of input into the broadcast window itself (:disc:`5868`)
- When reporting unused activity in a window, ignore activity that occurs soon after a window resize (:iss:`5881`)
- Fix using :opt:`cursor` = ``none`` not working on text that has reverse video (:iss:`5897`)
- Fix ssh kitten not working on FreeBSD (:iss:`5928`)
- macOS: Export kitty selected text to the system for use with services that accept it (patch by Sertaç Ö. Yıldız)
0.26.5 [2022-11-07]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- Splits layout: Add a new mappable action to move the active window to the screen edge (:iss:`5643`)
- ssh kitten: Allow using absolute paths for the location of transferred data (:iss:`5607`)
- Fix a regression in the previous release that caused a :opt:`resize_draw_strategy` of ``static`` to not work (:iss:`5601`)
- Wayland KDE: Fix abort when pasting into Firefox (:iss:`5603`)
- Wayland GNOME: Fix ghosting when using :opt:`background_tint` (:iss:`5605`)
- Fix cursor position at x=0 changing to x=1 on resize (:iss:`5635`)
- Wayland GNOME: Fix incorrect window size in some circumstances when switching between windows with window decorations disabled (:iss:`4802`)
- Wayland: Fix high CPU usage when using some input methods (:pull:`5369`)
- Remote control: When matching window by `state:focused` and no window currently has keyboard focus, match the window belonging to the OS window that was last focused (:iss:`5602`)
0.26.4 [2022-10-17]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- macOS: Allow changing the kitty icon by placing a custom icon in the kitty config folder (:pull:`5464`)
- Allow centering the :opt:`background_image` (:iss:`5525`)
- X11: Fix a regression in the previous release that caused pasting from GTK based applications to have extra newlines (:iss:`5528`)
- Tab bar: Improve empty space management when some tabs have short titles, allocate the saved space to the active tab (:iss:`5548`)
- Fix :opt:`background_tint` not applying to window margins and padding (:iss:`3933`)
- Wayland: Fix background image scaling using tiled mode on high DPI screens
- Wayland: Fix an abort when changing background colors with :opt:`wayland_titlebar_color` set to ``background`` (:iss:`5562`)
- Update to Unicode 15.0 (:pull:`5542`)
- GNOME Wayland: Fix a memory leak in gnome-shell when using client side decorations
0.26.3 [2022-09-22]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- Wayland: Mark windows in which a bell occurs as urgent on compositors that support the xdg-activation protocol
- Allow passing null bytes through the system clipboard (:iss:`5483`)
- ssh kitten: Fix :envvar:`KITTY_PUBLIC_KEY` not being encoded properly when transmitting (:iss:`5496`)
- Sessions: Allow controlling which OS Window is active via the ``focus_os_window`` directive
- Wayland: Fix for bug in NVIDIA drivers that prevents transparency working (:iss:`5479`)
- Wayland: Fix for a bug that could cause kitty to become non-responsive when
using multiple OS windows in a single instance on some compositors (:iss:`5495`)
- Wayland: Fix for a bug preventing kitty from starting on Hyprland when using a non-unit scale (:iss:`5467`)
- Wayland: Generate a XDG_ACTIVATION_TOKEN when opening URLs or running programs in the background via the launch action
- Fix a regression that caused kitty not to restore SIGPIPE after python nukes it when launching children. Affects bash which does not sanitize its signal mask. (:iss:`5500`)
- Fix a use-after-free when handling fake mouse clicks and the action causes windows to be removed/re-allocated (:iss:`5506`)
0.26.2 [2022-09-05]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- Allow creating :code:`overlay-main` windows, which are treated as the active window unlike normal overlays (:iss:`5392`)
- hints kitten: Allow using :doc:`launch` as the program to run, to open the result in a new kitty tab/window/etc. (:iss:`5462`)
- hyperlinked_grep kitten: Allow control over which parts of ``rg`` output are hyperlinked (:pull:`5428`)
- Fix regression in 0.26.0 that caused launching kitty without working STDIO handles to result in high CPU usage and prewarming failing (:iss:`5444`)
- :doc:`/launch`: Allow setting the margin and padding for newly created windows (:iss:`5463`)
- macOS: Fix regression in 0.26.0 that caused asking the user for a line of input such as for :ac:`set_tab_title` to not work (:iss:`5447`)
- hints kitten: hyperlink matching: Fix hints occasionally matching text on subsequent line as part of hyperlink (:pull:`5450`)
- Fix a regression in 0.26.0 that broke mapping of native keys whose key codes did not fit in 21 bits (:iss:`5452`)
- Wayland: Fix remembering window size not accurate when client side decorations are present
- Fix an issue where notification identifiers were not sanitized leading to
code execution if the user clicked on a notification popup from a malicious
source. Thanks to Carter Sande for discovering this vulnerability.
0.26.1 [2022-08-30]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- ssh kitten: Fix executable permission missing from kitty bootstrap script (:iss:`5438`)
- Fix a regression in 0.26.0 that caused kitty to no longer set the ``LANG`` environment variable on macOS (:iss:`5439`)
- Allow specifying a title when using the :ac:`set_tab_title` action (:iss:`5441`)
0.26.0 [2022-08-29]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- A new option :opt:`remote_control_password` to use fine grained permissions for what can be remote controlled (:disc:`5320`)
- Reduce startup latency by ~30 milliseconds when running kittens via key bindings inside kitty (:iss:`5159`)
- A new option :opt:`modify_font` to adjust various font metrics like underlines, cell sizes etc. (:pull:`5265`)
- A new shortcut :sc:`show_kitty_doc` to display the kitty docs in a browser
- Graphics protocol: Only delete temp files if they have the string
:code:`tty-graphics-protocol` in their file paths. This prevents deletion of arbitrary files in :file:`/tmp`.
- Deprecate the ``adjust_baseline``, ``adjust_line_height`` and ``adjust_column_width`` options in favor of :opt:`modify_font`
- Wayland: Fix a regression in the previous release that caused mouse cursor
animation and keyboard repeat to stop working when switching seats (:iss:`5188`)
- Allow resizing windows created in session files (:pull:`5196`)
- Fix horizontal wheel events not being reported to client programs when they grab the mouse (:iss:`2819`)
- macOS: Remote control: Fix unable to launch a new OS window or background process when there is no OS window (:iss:`5210`)
- macOS: Fix unable to open new tab or new window when there is no OS window (:iss:`5276`)
- kitty @ set-colors: Fix changing inactive_tab_foreground not working (:iss:`5214`)
- macOS: Fix a regression that caused switching keyboard input using Eisu and
Kana keys not working (:iss:`5232`)
- Add a mappable action to toggle the mirrored setting for the tall and fat
layouts (:pull:`5344`)
- Add a mappable action to switch between predefined bias values for the tall and fat
layouts (:pull:`5352`)
- Wayland: Reduce flicker at startup by not using render frames immediately after a resize (:iss:`5235`)
- Linux: Update cursor position after all key presses not just pre-edit text
changes (:iss:`5241`)
- ssh kitten: Allow ssh kitten to work from inside tmux, provided the tmux
session inherits the correct KITTY env vars (:iss:`5227`)
- ssh kitten: A new option :code:`--symlink-strategy` to control how symlinks
are copied to the remote machine (:iss:`5249`)
- ssh kitten: Allow pressing :kbd:`Ctrl+C` to abort ssh before the connection is
completed (:iss:`5271`)
- Bash integration: Fix declare not creating global variables in .bashrc (:iss:`5254`)
- Bash integration: Fix the inherit_errexit option being set by shell integration (:iss:`5349`)
- :command:`kitty @ scroll-window` allow scrolling by fractions of a screen
(:iss:`5294`)
- remote files kitten: Fix working with files whose names have characters that
need to be quoted in shell scripts (:iss:`5313`)
- Expand ~ in paths configured in :opt:`editor` and :opt:`exe_search_path` (:disc:`5298`)
- Allow showing the working directory of the active window in tab titles
(:pull:`5314`)
- ssh kitten: Allow completion of ssh options between the destination and command (:iss:`5322`)
- macOS: Fix speaking selected text not working (:iss:`5357`)
- Allow ignoring failure to close windows/tabs via rc commands (:disc:`5406`)
- Fix hyperlinks not present when fetching text from the history buffer
(:iss:`5427`)
0.25.2 [2022-06-07]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- A new command :command:`edit-in-kitty` to :ref:`edit_file`
- Allow getting the last non-empty command output easily via an action or
remote control (:pull:`4973`)
- Fix a bug that caused :opt:`macos_colorspace` to always be ``default`` regardless of its actual value (:iss:`5129`)
- diff kitten: A new option :opt:`kitten-diff.ignore_name` to exclude files and directories from being scanned (:pull:`5171`)
- ssh kitten: Fix bash not being executed as a login shell since kitty 0.25.0 (:iss:`5130`)
- macOS: When pasting text and the clipboard has a filesystem path, paste the
full path instead of the text, which is sometimes just the file name (:pull:`5142`)
- macOS: Allow opening executables without a file extension with kitty as well
(:iss:`5160`)
- Themes kitten: Add a tab to show user defined custom color themes separately
(:pull:`5150`)
- Iosevka: Fix incorrect rendering when there is a combining char that does not
group with its neighbors (:iss:`5153`)
- Weston: Fix client side decorations flickering on slow computers during
window resize (:iss:`5162`)
- Remote control: Fix commands with large or asynchronous payloads like
:command:`kitty @ set-backround-image`, :command:`kitty @ set-window-logo`
and :command:`kitty @ select-window` not working correctly
when using a socket (:iss:`5165`)
- hints kitten: Fix surrounding quotes/brackets and embedded carriage returns
not being removed when using line number processing (:iss:`5170`)
0.25.1 [2022-05-26]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- Shell integration: Add a command to :ref:`clone_shell`
- Remote control: Allow using :ref:`Boolean operators <search_syntax>` when constructing queries to match windows or tabs
- Sessions: Fix :code:`os_window_size` and :code:`os_window_class` not applying to the first OS Window (:iss:`4957`)
- Allow using the cwd of the oldest as well as the newest foreground process for :option:`launch --cwd` (:disc:`4869`)
- Bash integration: Fix the value of :opt:`shell_integration` not taking effect if the integration script is sourced in bashrc (:pull:`4964`)
- Fix a regression in the previous release that caused mouse move events to be incorrectly reported as drag events even when a button is not pressed (:iss:`4992`)
- remote file kitten: Integrate with the ssh kitten for improved performance
and robustness. Re-uses the control master connection of the ssh kitten to
avoid round-trip latency.
- Fix tab selection when closing a new tab not correct in some scenarios (:iss:`4987`)
- A new action :ac:`open_url` to open the specified URL (:pull:`5004`)
- A new option :opt:`select_by_word_characters_forward` that allows changing
which characters are considered part of a word to the right when double clicking to select
words (:pull:`5103`)
- macOS: Make the global menu shortcut to open kitty website configurable (:pull:`5004`)
- macOS: Add the :opt:`macos_colorspace` option to control what color space colors are rendered in (:iss:`4686`)
- Fix reloading of config not working when :file:`kitty.conf` does not exist when kitty is launched (:iss:`5071`)
- Fix deleting images by row not calculating image bounds correctly (:iss:`5081`)
- Increase the max number of combining chars per cell from two to three, without increasing memory usage.
- Linux: Load libfontconfig at runtime to allow the binaries to work for
running kittens on servers without FontConfig
- GNOME: Fix for high CPU usage caused by GNOME's text input subsystem going
into an infinite loop when IME cursor position is updated after a done event
(:iss:`5105`)
0.25.0 [2022-04-11]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -43,6 +374,10 @@ Detailed list of changes
- When pasting URLs at shell prompts automatically quote them. Also allow filtering pasted text and confirm pastes. See :opt:`paste_actions` for details. (:iss:`4873`)
- Change the default value of :opt:`confirm_os_window_close` to ask for confirmation when closing windows that are not sitting at shell prompts
- A new value :code:`last_reported` for :option:`launch --cwd` to use the current working directory last reported by the program running in the terminal
- macOS: When using Apple's less as the pager for viewing scrollback strip out OSC codes as it cant parse them (:iss:`4788`)
- diff kitten: Fix incorrect rendering in rare circumstances when scrolling after changing the context size (:iss:`4831`)
@@ -599,7 +934,7 @@ Detailed list of changes
0.21.2 [2021-06-28]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- A new :opt:`adjust_baseline` option to adjust the vertical alignment of text
- A new ``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
@@ -773,7 +1108,7 @@ Detailed list of changes
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
- 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
@@ -798,7 +1133,7 @@ Detailed list of changes
kitty window title bar
- Fix reading :option:`kitty --session` from ``STDIN`` not working when the
:option:`kitty --detach` option is used (:iss:`3523`)
:code:`kitty --detach` option is used (:iss:`3523`)
- Special case rendering of the few remaining Powerline box drawing chars
(:iss:`3535`)
@@ -1356,6 +1691,7 @@ Detailed list of changes
- Fix :option:`--title` not being applied at window creation time (:iss:`2570`)
0.17.2 [2020-03-29]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -1540,6 +1876,7 @@ Detailed list of changes
- When windows are semi-transparent and all contain graphics, correctly render
them. (:iss:`2310`)
0.15.1 [2019-12-21]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -1648,6 +1985,7 @@ Detailed list of changes
- Use selection foreground color for underlines as well (:iss:`1982`)
0.14.4 [2019-08-31]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -1941,7 +2279,7 @@ Detailed list of changes
- Allow the user to control the resize debounce time via
:opt:`resize_debounce_time`.
- Remote control: Make the :ref:`at_set-font-size` command more capable.
- Remote control: Make the :ref:`at-set-font-size` command more capable.
It can now increment font size and reset it. It also only acts on the
active top-level window, by default (:iss:`1581`)
@@ -1954,6 +2292,7 @@ Detailed list of changes
- Mouse selection: When extending by word, fix extending selection to non-word
characters not working well (:iss:`1616`)
0.13.3 [2019-01-19]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -2047,6 +2386,7 @@ Detailed list of changes
- Fix resizing window smaller and then restoring causing some wrapped lines to not
be properly unwrapped (:iss:`1206`)
0.13.0 [2018-12-05]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -2144,6 +2484,7 @@ Detailed list of changes
- Fix hover detection of URLs not working when hovering over the first colon
and slash characters in short URLs (:iss:`1201`)
0.12.3 [2018-09-29]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -2220,6 +2561,7 @@ Detailed list of changes
- Fix using :opt:`focus_follows_mouse` causing text selection with the
mouse to malfunction when using multiple kitty windows (:iss:`1002`)
0.12.1 [2018-09-08]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -2250,7 +2592,7 @@ Detailed list of changes
- Fix a regression in 0.12.0 that broke dynamic resizing of layouts (:iss:`860`)
- Wayland: Allow using the :option:`kitty --class` command line flag
- Wayland: Allow using the :code:`kitty --class` command line flag
to set the app id (:iss:`862`)
- Add completion of the kitty command for the fish shell (:pull:`829`)
@@ -2263,6 +2605,7 @@ Detailed list of changes
- macOS: Diff kitten: Fix syntax highlighting not working because of
a bug in the 0.12.0 macOS package
0.12.0 [2018-09-01]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -2293,7 +2636,7 @@ Detailed list of changes
window is not the active window (:iss:`729`)
- Remote control: Allow changing the current window layout with a new
:ref:`at_goto-layout` command (:iss:`845`)
:ref:`at-goto-layout` command (:iss:`845`)
- Remote control: Allow matching windows by the environment variables of their
child process as well
@@ -2773,6 +3116,7 @@ Detailed list of changes
- Fix a crash when getting the contents of the scrollback buffer as text
0.8.1 [2018-03-09]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -2850,6 +3194,7 @@ Detailed list of changes
- Browsing the scrollback buffer now happens in an overlay window instead of a
new window/tab.
0.7.1 [2018-01-31]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

160
docs/clipboard.rst Normal file
View File

@@ -0,0 +1,160 @@
Copying all data types to the clipboard
==============================================
There already exists an escape code to allow terminal programs to
read/write plain text data from the system clipboard, *OSC 52*.
kitty introduces a more advanced protocol that supports:
* Copy arbitrary data including images, rich text documents, etc.
* Allow terminals to ask the user for permission to access the clipboard and
report permission denied
The escape code is *OSC 5522*, an extension of *OSC 52*. The basic format
of the escape code is::
<OSC>5522;metadata;payload<ST>
Here, *metadata* is a colon separated list of key-value pairs and payload is
base64 encoded data. :code:`OSC` is :code:`<ESC>[`.
:code:`ST` is the string terminator, :code:`<ESC>\\`.
Reading data from the system clipboard
----------------------------------------
To read data from the system clipboard, the escape code is::
<OSC>5522;type=read;<base 64 encoded space separated list of mime types to read><ST>
For example, to read plain text and PNG data, the payload would be::
text/plain image/png
encoded as base64. To read from the primary selection instead of the
clipboard, add the key ``loc=primary`` to the metadata section.
To get the list of MIME types available on the clipboard the payload must be
just a period (``.``), encoded as base64.
The terminal emulator will reply with a sequence of escape codes of the form::
<OSC>5522;type=read:status=OK<ST>
<OSC>5522;type=read:status=DATA:mime=<base 64 encoded mime type>;<base64 encoded data><ST>
<OSC>5522;type=read:status=DATA:mime=<base 64 encoded mime type>;<base64 encoded data><ST>
.
.
.
<OSC>5522;type=read:status=DONE<ST>
Here, the ``status=DATA`` packets deliver the data (as base64 encoded bytes)
associated with each MIME type. The terminal emulator should chunk up the data
for an individual type. A recommended size for each chunk is 4096 bytes. All
the chunks for a given type must be transmitted sequentially and only once they
are done the chunks for the next type, if any, should be sent. The end of data
is indicated by a ``status=DONE`` packet.
If an error occurs, instead of the opening ``status=OK`` packet the terminal
must send a ``status=ERRORCODE`` packet. The error code must be one of:
``status=ENOSYS``
Sent if the requested clipboard type is not available. For example, primary
selection is not available on all systems and ``loc=primary`` was used.
``status=EPERM``
Sent if permission to read from the clipboard was denied by the system or
the user.
``status=EBUSY``
Sent if there is some temporary problem, such as multiple clients in a
multiplexer trying to access the clipboard simultaneously.
Terminals should ask the user for permission before allowing a read request.
However, if a read request only wishes to list the available data types on the
clipboard, it should be allowed without a permission prompt. This is so that
the user is not presented with a double permission prompt for reading the
available MIME types and then reading the actual data.
Writing data to the system clipboard
----------------------------------------
To write data to the system clipboard, the terminal programs sends the
following sequence of packets::
<OSC>5522;type=write<ST>
<OSC>5522;type=wdata:mime=<base64 encoded mime type>;<base 64 encoded chunk of data for this type><ST>
<OSC>5522;type=wdata:mime=<base64 encoded mime type>;<base 64 encoded chunk of data for this type><ST>
.
.
.
<OSC>5522;type=wdata<ST>
The final packet with no mime and no data indicates end of transmission. The
data for every MIME type should be split into chunks of no more than 4096
bytes. All the chunks for a given MIME type must be sent sequentially, before
sending chunks for the next MIME type. After the transmission is complete, the
terminal replies with a single packet indicating success::
<OSC>5522;type=write:status=DONE<ST>
If an error occurs the terminal can, at any time, send an error packet of the
form::
<OSC>5522;type=write:status=ERRORCODE<ST>
Here ``ERRORCODE`` must be one of:
``status=EIO``
An I/O error occurred while processing the data
``status=EINVAL``
One of the packets was invalid, usually because of invalid base64 encoding.
``status=ENOSYS``
The client asked to write to the primary selection with (``loc=primary``) and that is not
available on the system
``status=EPERM``
Sent if permission to write to the clipboard was denied by the system or
the user.
``status=EBUSY``
Sent if there is some temporary problem, such as multiple clients in a
multiplexer trying to access the clipboard simultaneously.
Once an error occurs, the terminal must ignore all further OSC 5522 write related packets until it
sees the start of a new write with a ``type=write`` packet.
The client can send to the primary selection instead of the clipboard by adding
``loc=primary`` to the initial ``type=write`` packet.
Finally, clients have the ability to *alias* MIME types when sending data to
the clipboard. To do that, the client must send a ``type=walias`` packet of the
form::
<OSC>5522;type=walias;mime=<base64 encoded target MIME type>;<base64 encoded, space separated list of aliases><ST>
The effect of an alias is that the system clipboard will make available all the
aliased MIME types, with the same data as was transmitted for the target MIME
type. This saves bandwidth, allowing the client to only transmit one copy of
the data, but create multiple references to it in the system clipboard. Alias
packets can be sent anytime after the initial write packet and before the end
of data packet.
Support for terminal multiplexers
------------------------------------
Since this protocol involves two way communication between the terminal
emulator and the client program, multiplexers need a way to know which window
to send responses from the terminal to. In order to make this possible, the
metadata portion of this escape code includes an optional ``id`` field. If
present the terminal emulator must send it back unchanged with every response.
Valid ids must include only characters from the set: ``[a-zA-Z0-9-_+.]``. Any
other characters must be stripped out from the id by the terminal emulator
before retransmitting it.
Note that when using a terminal multiplexer it is possible for two different
programs to tread on each others clipboard requests. This is fundamentally
unavoidable since the system clipboard is a single global shared resource.
However, there is an additional complication where responses form this protocol
could get lost if, for instance, multiple write requests are received
simultaneously. It is up to well designed multiplexers to ensure that only a
single request is in flight at a time. The multiplexer can abort requests by
sending back the ``EBUSY`` error code indicating some other window is trying
to access the clipboard.

View File

@@ -2,25 +2,25 @@ 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
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 themselves, then running the full screen application will
lose those 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.
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
.. 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
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.

View File

@@ -13,14 +13,12 @@ import subprocess
import sys
import time
from functools import partial
from typing import Any, Callable, Dict, Iterable, List, Optional, Tuple
from typing import Any, Callable, Dict, Iterable, List, Tuple
from docutils import nodes
from docutils.parsers.rst.roles import set_classes
from pygments.lexer import RegexLexer, bygroups # type: ignore
from pygments.token import ( # type: ignore
Comment, Keyword, Literal, Name, Number, String, Whitespace
)
from pygments.token import Comment, Keyword, Literal, Name, Number, String, Whitespace # type: ignore
from sphinx import addnodes, version_info
from sphinx.util.logging import getLogger
@@ -85,7 +83,7 @@ master_doc = 'index'
#
# This is also used if you do content translation via gettext catalogs.
# Usually you set "language" from the command line for these cases.
language: Optional[str] = None
language: str = 'en'
# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
@@ -104,6 +102,10 @@ rst_prolog = '''
'''.replace('VERSION', str_version)
smartquotes_action = 'qe' # educate quotes and ellipses but not dashes
string_replacements = {
'_kitty_install_cmd': 'curl -L https://sw.kovidgoyal.net/kitty/installer.sh | sh /dev/stdin',
}
# -- Options for HTML output -------------------------------------------------
@@ -116,10 +118,23 @@ 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.
#
github_icon_path = 'M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.013 8.013 0 0 0 16 8c0-4.42-3.58-8-8-8z' # noqa
html_theme_options: Dict[str, Any] = {
'sidebar_hide_name': True,
'navigation_with_keys': True,
'footer_icons': [
{
"name": "GitHub",
"url": "https://github.com/kovidgoyal/kitty",
"html": f"""
<svg stroke="currentColor" fill="currentColor" stroke-width="0" viewBox="0 0 16 16">
<path fill-rule="evenodd" d="{github_icon_path}"></path>
</svg>
""",
"class": "",
},
],
}
@@ -198,10 +213,10 @@ def commit_role(
# CLI docs {{{
def write_cli_docs(all_kitten_names: Iterable[str]) -> None:
from kitty.cli import option_spec_as_rst
from kitty.launch import options_spec as launch_options_spec
from kittens.ssh.copy import option_text
from kittens.ssh.options.definition import copy_message
from kitty.cli import option_spec_as_rst
from kitty.launch import options_spec as launch_options_spec
with open('generated/ssh-copy.rst', 'w') as f:
f.write(option_spec_as_rst(
appname='copy', ospec=option_text, heading_char='^',
@@ -232,12 +247,14 @@ if you specify a program-to-run you can use the special placeholder
from kitty.rc.base import cli_params_for
for cmd_name in sorted(all_command_names()):
func = command_for_name(cmd_name)
p(f'.. _at_{func.name}:\n')
p(f'.. _at-{func.name}:\n')
p('kitty @', func.name)
p('-' * 120)
p('.. program::', 'kitty @', func.name)
p('\n\n' + as_rst(*cli_params_for(func)))
from kittens.runner import get_kitten_cli_docs
from kitty.fast_data_types import wrapped_kitten_names
for kitten in all_kitten_names:
data = get_kitten_cli_docs(kitten)
if data:
@@ -246,7 +263,11 @@ if you specify a program-to-run you can use the special placeholder
p('.. program::', 'kitty +kitten', kitten)
p('\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}>`_.')
if kitten in wrapped_kitten_names():
scurl = f'https://github.com/kovidgoyal/kitty/tree/master/tools/cmd/{kitten}'
else:
scurl = f'https://github.com/kovidgoyal/kitty/tree/master/kittens/{kitten}'
p(f'\nThe source code for this kitten is `available on GitHub <{scurl}>`_.')
p('\nCommand Line Interface')
p('-' * 72)
p('\n\n' + option_spec_as_rst(
@@ -257,10 +278,8 @@ 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 (
RemoteCommand, all_command_names, command_for_name
)
field_pat = re.compile(r'\s*([a-zA-Z0-9_+]+)\s*:\s*(.+)')
from kitty.rc.base import RemoteCommand, all_command_names, command_for_name
field_pat = re.compile(r'\s*([^:]+?)\s*:\s*(.+)')
def format_cmd(p: Callable[..., None], name: str, cmd: RemoteCommand) -> None:
p(name)
@@ -272,7 +291,7 @@ def write_remote_control_protocol_docs() -> None: # {{{
if m is None:
p(line)
else:
fields.append((m.group(1), m.group(2)))
fields.append((m.group(1).split('/')[0], m.group(2)))
if fields:
p('\nFields are:\n')
for (name, desc) in fields:
@@ -300,8 +319,16 @@ def write_remote_control_protocol_docs() -> None: # {{{
# }}}
def replace_string(app: Any, docname: str, source: List[str]) -> None: # {{{
src = source[0]
for k, v in app.config.string_replacements.items():
src = src.replace(k, v)
source[0] = src
# }}}
# config file docs {{{
class ConfLexer(RegexLexer): # type: ignore
name = 'Conf'
aliases = ['conf']
@@ -516,6 +543,8 @@ def setup(app: Any) -> None:
write_cli_docs(kn)
write_remote_control_protocol_docs()
write_conf_docs(app, kn)
app.add_config_value('string_replacements', {}, True)
app.connect('source-read', replace_string)
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)

View File

@@ -3,13 +3,14 @@ kitty.conf
.. highlight:: conf
|kitty| is highly customizable, everything from keyboard shortcuts, to
rendering frames-per-second. See below for an overview of all customization
possibilities.
|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` (:kbd:`⌘+,` on macOS).
You can reload the config file within kitty by pressing
:sc:`reload_config_file` (:kbd:`⌃+⌘+,` on macOS) or sending kitty the ``SIGUSR1`` signal.
You can open the config file within kitty by pressing :sc:`edit_config_file`
(:kbd:`⌘+,` on macOS). A :file:`kitty.conf` with commented default
configurations and descriptions will be created if the file does not exist.
You can reload the config file within kitty by pressing :sc:`reload_config_file`
(:kbd:`⌃+⌘+,` on macOS) or sending kitty the ``SIGUSR1`` signal.
You can also display the current configuration by pressing :sc:`debug_config`
(:kbd:`⌥+⌘+,` on macOS).
@@ -17,20 +18,22 @@ You can also display the current configuration by pressing :sc:`debug_config`
|kitty| looks for a config file in the OS config directories (usually
:file:`~/.config/kitty/kitty.conf`) but you can pass a specific path via the
:option:`kitty --config` option or use the ``KITTY_CONFIG_DIRECTORY``
environment variable. See the :option:`kitty --config` option for full details.
:option:`kitty --config` option or use the :envvar:`KITTY_CONFIG_DIRECTORY`
environment variable. See :option:`kitty --config` for full details.
Comments can be added to the config file as lines starting with the ``#``
character. This works only if the ``#`` character is the first character
in the line.
character. This works only if the ``#`` character is the first character in the
line.
.. _include:
You can include secondary config files via the :code:`include` directive. If
You can include secondary config files via the :code:`include` directive. If
you use a relative path for :code:`include`, it is resolved with respect to the
location of the current config file. Note that environment variables are
expanded, so :code:`${USER}.conf` becomes :file:`name.conf` if
:code:`USER=name`. Also, you can use :code:`globinclude` to include files
:code:`USER=name`. A special environment variable :envvar:`KITTY_OS` is available,
to detect the operating system. It is ``linux``, ``macos`` or ``bsd``.
Also, you can use :code:`globinclude` to include files
matching a shell glob pattern and :code:`envinclude` to include configuration
from environment variables. For example::
@@ -42,7 +45,7 @@ from environment variables. For example::
.. note:: Syntax highlighting for :file:`kitty.conf` in vim is available via
`vim-kitty <https://github.com/fladson/vim-kitty>`_.
`vim-kitty <https://github.com/fladson/vim-kitty>`__.
.. include:: /generated/conf-kitty.rst
@@ -53,17 +56,17 @@ Sample 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>`.
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.
: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 :file:`kitty.conf`, then that will be used instead, delete it to
see the sample file.
All mappable actions

View File

@@ -3,19 +3,18 @@ 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
<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
:iss:`this discussion <160#issuecomment-346470545>`
and `this FAQ <https://invisible-island.net/ncurses/ncurses.faq.html#bce_mismatches>`_
(bce)* capability. See :iss:`this discussion <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::
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

View File

@@ -5,21 +5,20 @@ 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.
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 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:`<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
@@ -45,28 +44,28 @@ 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).
``[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). The size of the payload must be no
longer than ``2048`` bytes, *before being encoded*.
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
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.
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::
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>
@@ -87,9 +86,9 @@ 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.
the notification, however, given that some platforms, such as legacy versions
of macOS, don't allow displaying custom images on a notification, 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.
@@ -107,7 +106,7 @@ Key Value Default Description
``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,
``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
@@ -118,5 +117,6 @@ Key Value Default Description
.. note::
|kitty| also supports the legacy OSC 9 protocol developed by iTerm2 for
desktop notifications.
|kitty| also supports the `legacy OSC 9 protocol developed by iTerm2
<https://iterm2.com/documentation-escape-codes.html>`__ for desktop
notifications.

54
docs/extract-rst-targets.py Executable file
View File

@@ -0,0 +1,54 @@
#!/usr/bin/env python
# License: GPLv3 Copyright: 2022, Kovid Goyal <kovid at kovidgoyal.net>
import os
import re
from typing import Dict, Iterator
tgt_pat = re.compile(r'^.. _(\S+?):$', re.MULTILINE)
title_pat = re.compile('^(.+)\n[-=^#*]{5,}$', re.MULTILINE)
def find_explicit_targets(text: str) -> Iterator[str]:
for m in tgt_pat.finditer(text):
yield m.group(1)
def find_page_title(text: str) -> str:
for m in title_pat.finditer(text):
return m.group(1)
return ''
def main() -> Dict[str, Dict[str, str]]:
refs = {}
docs = {}
base = os.path.dirname(os.path.abspath(__file__))
for dirpath, dirnames, filenames in os.walk(base):
if 'generated' in dirnames:
dirnames.remove('generated')
for f in filenames:
if f.endswith('.rst'):
with open(os.path.join(dirpath, f)) as stream:
raw = stream.read()
href = os.path.relpath(stream.name, base).replace(os.sep, '/')
href = href.rpartition('.')[0] + '/'
docs[href.rstrip('/')] = find_page_title(raw)
first_line = raw.lstrip('\n').partition('\n')[0]
first_target_added = False
for explicit_target in find_explicit_targets(raw):
# Shorten the reference link to the top of the page.
# Note that anchor links should still be used in HTML docs
# to allow jumping within the same page.
if not first_target_added:
first_target_added = True
if first_line.startswith(f'.. _{explicit_target}:'):
refs[explicit_target] = href
continue
refs[explicit_target] = href + f'#{explicit_target.replace("_", "-")}'
return {'ref': refs, 'doc': docs}
if __name__ == '__main__':
import json
print(json.dumps(main(), indent=2))

View File

@@ -27,94 +27,145 @@ turned off for specific symbols using :opt:`narrow_symbols`.
Using a color theme with a background color does not work well in vim?
-----------------------------------------------------------------------
First make sure you have not changed the TERM environment variable, it should
be ``xterm-kitty``. vim uses *background color erase* even if the terminfo file
does not contain the ``bce`` capability. This is a bug in vim. You can work around
it by adding the following to your vimrc::
Sadly, vim has very poor out-of-the-box detection for modern terminal features.
Furthermore, it `recently broke detection even more <https://github.com/vim/vim/issues/11729>`__.
It kind of, but not really, supports terminfo, except it overrides it with its own hard-coded
values when it feels like it. Worst of all, it has no ability to detect modern
features not present in terminfo, at all, even security sensitive ones like
bracketed paste.
Thankfully, probably as a consequence of this lack of detection, vim allows users to
configure these low level details. So, to make vim work well with any modern
terminal, including kitty, add the following to your :file:`~/.vimrc`.
.. code-block:: vim
" Mouse support
set mouse=a
set ttymouse=sgr
set balloonevalterm
" Styled and colored underline support
let &t_AU = "\e[58:5:%dm"
let &t_8u = "\e[58:2:%lu:%lu:%lum"
let &t_Us = "\e[4:2m"
let &t_Cs = "\e[4:3m"
let &t_ds = "\e[4:4m"
let &t_Ds = "\e[4:5m"
let &t_Ce = "\e[4:0m"
" Strikethrough
let &t_Ts = "\e[9m"
let &t_Te = "\e[29m"
" Truecolor support
let &t_8f = "\e[38:2:%lu:%lu:%lum"
let &t_8b = "\e[48:2:%lu:%lu:%lum"
let &t_RF = "\e]10;?\e\\"
let &t_RB = "\e]11;?\e\\"
" Bracketed paste
let &t_BE = "\e[?2004h"
let &t_BD = "\e[?2004l"
let &t_PS = "\e[200~"
let &t_PE = "\e[201~"
" Cursor control
let &t_RC = "\e[?12$p"
let &t_SH = "\e[%d q"
let &t_RS = "\eP$q q\e\\"
let &t_SI = "\e[5 q"
let &t_SR = "\e[3 q"
let &t_EI = "\e[1 q"
let &t_VS = "\e[?12l"
" Focus tracking
let &t_fe = "\e[?1004h"
let &t_fd = "\e[?1004l"
execute "set <FocusGained>=\<Esc>[I"
execute "set <FocusLost>=\<Esc>[O"
" Window title
let &t_ST = "\e[22;2t"
let &t_RT = "\e[23;2t"
" vim hardcodes background color erase even if the terminfo file does
" not contain bce. This causes incorrect background rendering when
" using a color theme with a background color in terminals such as
" kitty that do not support background color erase.
let &t_ut=''
See :doc:`here <deccara>` for why |kitty| does not support background color erase.
These settings must be placed **before** setting the ``colorscheme``. It is
also important that the value of the vim ``term`` variable is not changed
after these settings.
I get errors about the terminal being unknown or opening the terminal failing or functional keys like arrow keys don't work?
-------------------------------------------------------------------------------------------------------------------------------
I get errors about the terminal being unknown or opening the terminal failing when SSHing into a different computer?
-----------------------------------------------------------------------------------------------------------------------
This happens because the |kitty| terminfo files are not available on the server.
You can ssh in using the following command which will automatically copy the
terminfo files to the server::
These issues all have the same root cause: the kitty terminfo files not being
available. The most common way this happens is SSHing into a computer that does
not have the kitty terminfo files. The simplest fix for that is running::
kitty +kitten ssh myserver
It will automatically copy over the terminfo files and also magically enable
:doc:`shell integration </shell-integration>` on the remote machine.
This :doc:`ssh kitten <kittens/ssh>` takes all the same command line arguments
as ssh, you can alias it to something small in your shell's rc files to avoid
having to type it each time::
as :program:`ssh`, you can alias it to something small in your shell's rc files
to avoid having to type it each time::
alias s="kitty +kitten ssh"
If the ssh kitten fails, use the following one-liner instead (it
is slower as it needs to ssh into the server twice, but will work with most
servers)::
If this does not work, see :ref:`manual_terminfo_copy` for alternative ways to
get the kitty terminfo files onto a remote computer.
infocmp -a xterm-kitty | ssh myserver tic -x -o \~/.terminfo /dev/stdin
The next most common reason for this is if you are running commands as root
using :program:`sudo` or :program:`su`. These programs often filter the
:envvar:`TERMINFO` environment variable which is what points to the kitty
terminfo files.
If you are behind a proxy (like Balabit) that prevents this, or ``tic`` comes
with macOS that does not support reading from STDIN, you must redirect the 1st
command to a file, copy that to the server and run ``tic`` manually. If you
connect to a server, embedded or Android system that doesn't have ``tic``, copy over
your local file terminfo to the other system as :file:`~/.terminfo/x/xterm-kitty`.
First, make sure the :envvar:`TERM` is set to ``xterm-kitty`` in the sudo
environment. By default, it should be automatically copied over.
Really, the correct solution for this is to convince the OpenSSH maintainers to
have ssh do this automatically, if possible, when connecting to a server, so that
all terminals work transparently.
If you are using a well maintained Linux distribution, it will have a
``kitty-terminfo`` package that you can simply install to make the kitty
terminfo files available system-wide. Then the problem will no longer occur.
If the server is running FreeBSD, or another system that relies on termcap
rather than terminfo, you will need to convert the terminfo file on your local
machine by running (on local machine with |kitty|)::
infocmp -C xterm-kitty
The output of this command is the termcap description, which should be appended
to :file:`/usr/share/misc/termcap` on the remote server. Then run the following
command to apply your change (on the server)::
cap_mkdb /usr/share/misc/termcap
Keys such as arrow keys, backspace, delete, home/end, etc. do not work when using su or sudo?
-------------------------------------------------------------------------------------------------
Make sure the TERM environment variable, is ``xterm-kitty``. And either the
TERMINFO environment variable points to a directory containing :file:`x/xterm-kitty`
or that file is under :file:`~/.terminfo/x/`.
For macOS, you may also need to put that file under :file:`~/.terminfo/78/`::
mkdir -p ~/.terminfo/{78,x}
ln -snf ../x/xterm-kitty ~/.terminfo/78/xterm-kitty
tic -x -o ~/.terminfo "$KITTY_INSTALLATION_DIR/terminfo/kitty.terminfo"
Note that ``sudo`` might remove TERMINFO. Then setting it at the shell prompt can
be too late, because command line editing may not be reinitialized. In that case
you can either ask ``sudo`` to set it or if that is not supported, insert an ``env``
command before starting the shell, or, if not possible, after sudo start another
Shell providing the right terminfo path::
sudo … TERMINFO=$HOME/.terminfo bash -i
sudo … env TERMINFO=$HOME/.terminfo bash -i
TERMINFO=/home/ORIGINALUSER/.terminfo exec bash -i
You can configure sudo to preserve TERMINFO by running ``sudo
visudo`` and adding the following line::
Alternately, you can configure :program:`sudo` to preserve :envvar:`TERMINFO`
by running ``sudo visudo`` and adding the following line::
Defaults env_keep += "TERM TERMINFO"
If none of these are suitable for you, you can run sudo as follows::
sudo TERMINFO="$TERMINFO" -s -H
This will start a new root shell with the correct :envvar:`TERMINFO` value from your
current environment copied over.
If you have double width characters in your prompt, you may also need to
explicitly set a UTF-8 locale, like::
export LANG=en_US.UTF-8 LC_ALL=en_US.UTF-8
I cannot use the key combination X in program Y?
-------------------------------------------------------
First, run::
kitty +kitten show_key -m kitty
Press the key combination X. If the kitten reports the key press
that means kitty is correctly sending the key press to terminal programs.
You need to report the issue to the developer of the terminal program. Most
likely they have not added support for :doc:`/keyboard-protocol`.
If the kitten does not report it, it means that the key is bound to some action
in kitty. You can unbind it in :file:`kitty.conf` with:
.. code-block:: conf
map X no_op
Here X is the keys you press on the keyboard. So for example
:kbd:`ctrl+shift+1`.
How do I change the colors in a running kitty instance?
------------------------------------------------------------
@@ -129,12 +180,15 @@ You can also define keyboard shortcuts to set colors, for example::
map f1 set_colors --configured /path/to/some/config/file/colors.conf
Or you can enable :doc:`remote control <remote-control>` for |kitty| and use :ref:`at_set-colors`.
The shortcut mapping technique has the same syntax as the remote control
command, for details, see :ref:`at_set-colors`.
Or you can enable :doc:`remote control <remote-control>` for |kitty| and use
:ref:`at-set-colors`. The shortcut mapping technique has the same syntax as the
remote control command, for details, see :ref:`at-set-colors`.
To change colors when SSHing into a remote host, use the :opt:`color_scheme
<kitten-ssh.color_scheme>` setting for the :doc:`ssh kitten <kittens/ssh>`.
Additionally, You can use the
`OSC terminal escape codes <https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h3-Operating-System-Commands>`_
`OSC terminal escape codes <https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h3-Operating-System-Commands>`__
to set colors. Examples of using OSC escape codes to set colors::
Change the default foreground color:
@@ -151,7 +205,7 @@ to set colors. Examples of using OSC escape codes to set colors::
printf '\x1b]4;n;green\x1b\\'
You can use various syntaxes/names for color specifications in the above
examples. See `XParseColor <https://linux.die.net/man/3/xparsecolor>`_
examples. See `XParseColor <https://linux.die.net/man/3/xparsecolor>`__
for full details.
If a ``?`` is given rather than a color specification, kitty will respond
@@ -164,14 +218,15 @@ How do I specify command line options for kitty on macOS?
Apple does not want you to use command line options with GUI applications. To
workaround that limitation, |kitty| will read command line options from the file
:file:`<kitty config dir>/macos-launch-services-cmdline` when it is launched
from the GUI, i.e. by clicking the |kitty| application icon or using ``open -a kitty``.
Note that this file is *only read* when running via the GUI.
from the GUI, i.e. by clicking the |kitty| application icon or using
``open -a kitty``. Note that this file is *only read* when running via the GUI.
You can, of course, also run |kitty| from a terminal with command line options, using:
:file:`/Applications/kitty.app/Contents/MacOS/kitty`.
You can, of course, also run |kitty| from a terminal with command line options,
using: :file:`/Applications/kitty.app/Contents/MacOS/kitty`.
And within |kitty| itself, you can always run |kitty| using just ``kitty`` as it
cleverly adds itself to the :envvar:`PATH`.
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?
-----------------------------------------------
@@ -179,10 +234,10 @@ 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.
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 :sc:`reset_terminal` to reset the terminal.
If you do want to cat unknown data, use ``cat -v``.
@@ -190,30 +245,36 @@ If you do want to cat unknown data, use ``cat -v``.
kitty is not able to use my favorite font?
---------------------------------------------
|kitty| achieves its stellar performance by caching alpha masks of each
rendered character on the GPU, and rendering them all in parallel. This means
it is a strictly character cell based display. As such it can use only
monospace fonts, since every cell in the grid has to be the same size.
Furthermore, it needs fonts to be freely resizable, so it does not support
bitmapped fonts.
|kitty| achieves its stellar performance by caching alpha masks of each rendered
character on the GPU, and rendering them all in parallel. This means it is a
strictly character cell based display. As such it can use only monospace fonts,
since every cell in the grid has to be the same size. Furthermore, it needs
fonts to be freely resizable, so it does not support bitmapped fonts.
.. note::
If you are trying to use a font patched with NERD font symbols, dont do that
as patching destroys fonts. There is no need, simply install the standalone
NERD font (the file :file:`NerdFontsSymbolsOnly.zip` from the `NERD font
releases page <https://github.com/ryanoasis/nerd-fonts/releases>`__). kitty
should pick up symbols from it automatically, and you can tell it to do so
explicitly in case it doesnt with the :opt:`symbol_map` directive::
If you are trying to use a font patched with `Nerd Fonts
<https://nerdfonts.com/>`__ symbols, don't do that as patching destroys
fonts. There is no need, simply install the standalone ``Symbols Nerd Font Mono``
(the file :file:`NerdFontsSymbolsOnly.zip` from the `Nerd Fonts releases page
<https://github.com/ryanoasis/nerd-fonts/releases>`__). kitty should pick up
symbols from it automatically, and you can tell it to do so explicitly in
case it doesn't with the :opt:`symbol_map` directive::
symbol_map U+23FB-U+23FE,U+2665,U+26A1,U+2B58,U+E000-U+E00A,U+E0A0-U+E0A3,U+E0B0-U+E0C8,U+E0CA,U+E0CC-U+E0D2,U+E0D4,U+E200-U+E2A9,U+E300-U+E3E3,U+E5FA-U+E62F,U+E700-U+E7C5,U+F000-U+F2E0,U+F300-U+F31C,U+F400-U+F4A9,U+F500-U+F8FF Symbols Nerd Font
# Nerd Fonts v2.2.2
symbol_map U+23FB-U+23FE,U+2665,U+26A1,U+2B58,U+E000-U+E00A,U+E0A0-U+E0A3,U+E0B0-U+E0C8,U+E0CA,U+E0CC-U+E0D2,U+E0D4,U+E200-U+E2A9,U+E300-U+E3E3,U+E5FA-U+E634,U+E700-U+E7C5,U+EA60-U+EBEB,U+F000-U+F2E0,U+F300-U+F32F,U+F400-U+F4A9,U+F500-U+F8FF Symbols Nerd Font Mono
Those Unicode symbols beyond the ``E000-F8FF`` Unicode private use area are
not included.
If your font is not listed in ``kitty +list-fonts`` it means that it is not
monospace or is a bitmapped font. On Linux you can list all monospace fonts with::
monospace or is a bitmapped font. On Linux you can list all monospace fonts
with::
fc-list : family spacing outline scalable | grep -e spacing=100 -e spacing=90 | grep -e outline=True | grep -e scalable=True
Note that the spacing property is calculated by fontconfig based on actual
glyph widths in the font. If for some reason fontconfig concludes your favorite
Note that the spacing property is calculated by fontconfig based on actual glyph
widths in the font. If for some reason fontconfig concludes your favorite
monospace font does not have ``spacing=100`` you can override it by using the
following :file:`~/.config/fontconfig/fonts.conf`::
@@ -273,13 +334,40 @@ homepage:
:target: https://github.com/igrmk/whiskers
:width: 256
On macOS you can change the icon by following the steps:
.. image:: https://github.com/samholmes/whiskers/raw/main/whiskers.png
:target: https://github.com/samholmes/whiskers
:width: 256
#. Find :file:`kitty.app` in the Applications folder, select it and press :kbd:`⌘+i`
On macOS you can put :file:`kitty.app.icns` or :file:`kitty.app.png` in the
:ref:`kitty configuration directory <confloc>`, and this icon will be applied
automatically at startup. Unfortunately, Apple's Dock does not change its
cached icon so the custom icon will revert when kitty is quit. Run the
following to force the Dock to update its cached icons:
.. code-block:: sh
rm /var/folders/*/*/*/com.apple.dock.iconcache; killall Dock
If you prefer not to keep a custom icon in the kitty config folder, you can
also set it with the following command:
.. code-block:: sh
# Set kitty.icns as the icon for currently running kitty
kitty +runpy 'from kitty.fast_data_types import cocoa_set_app_icon; import sys; cocoa_set_app_icon(*sys.argv[1:]); print("OK")' kitty.icns
# Set the icon for app bundle specified by the path
kitty +runpy 'from kitty.fast_data_types import cocoa_set_app_icon; import sys; cocoa_set_app_icon(*sys.argv[1:]); print("OK")' /path/to/icon.png /Applications/kitty.app
You can also change the icon manually by following the steps:
#. Find :file:`kitty.app` in the Applications folder, select it and press :kbd:`⌘+I`
#. Drag :file:`kitty.icns` onto the application icon in the kitty info pane
#. Delete the icon cache and restart Dock::
#. Delete the icon cache and restart Dock:
$ rm /var/folders/*/*/*/com.apple.dock.iconcache; killall Dock
.. code-block:: sh
rm /var/folders/*/*/*/com.apple.dock.iconcache; killall Dock
How do I map key presses in kitty to different keys in the terminal program?
@@ -295,7 +383,14 @@ the :sc:`send_text <send_text>` you can use the ``show_key`` kitten. Run::
kitty +kitten show_key
Then press the key you want to emulate.
Then press the key you want to emulate. Note that this kitten will only show
keys that actually reach the terminal program, in particular, keys mapped to
actions in kitty will not be shown. To check those first map them to
:ac:`no_op`. You can also start a kitty instance without any shortcuts to
interfere::
kitty -o clear_all_shortcuts=yes kitty +kitten show_key
How do I open a new window or tab with the same working directory as the current window?
--------------------------------------------------------------------------------------------
@@ -322,8 +417,8 @@ variables which kitty will now inherit.
You need to make sure that the environment variables you define in your shell's
rc files are either also defined system wide or via the :opt:`env` directive in
:file:`kitty.conf`. Common environment variables that cause issues are those
related to localization, such as ``LANG, LC_*`` and loading of configuration
files such as ``XDG_*, KITTY_CONFIG_DIRECTORY``.
related to localization, such as :envvar:`LANG`, ``LC_*`` and loading of
configuration files such as ``XDG_*``, :envvar:`KITTY_CONFIG_DIRECTORY`.
To see the environment variables that kitty sees, you can add the following
mapping to :file:`kitty.conf`::
@@ -340,40 +435,42 @@ sorts of places where they may or may not work.
I am using tmux and have a problem
--------------------------------------
First, terminal multiplexers are :iss:`a bad idea <391#issuecomment-638320745>`, do
not use them, if at all possible. kitty contains features that do all of what
First, terminal multiplexers are :iss:`a bad idea <391#issuecomment-638320745>`,
do not use them, if at all possible. kitty contains features that do all of what
tmux does, but better, with the exception of remote persistence (:iss:`391`).
If you still want to use tmux, read on.
Image display will not work, see `tmux issue
<https://github.com/tmux/tmux/issues/1391>`_.
<https://github.com/tmux/tmux/issues/1391>`__.
Using ancient versions of tmux such as 1.8 will
cause gibberish on screen when pressing keys (:iss:`3541`).
Using ancient versions of tmux such as 1.8 will cause gibberish on screen when
pressing keys (:iss:`3541`).
If you are using tmux with multiple terminals or you start it under one
terminal and then switch to another and these terminals have different TERM
variables, tmux will break. You will need to restart it as tmux does not
support multiple terminfo definitions.
If you are using tmux with multiple terminals or you start it under one terminal
and then switch to another and these terminals have different :envvar:`TERM`
variables, tmux will break. You will need to restart it as tmux does not support
multiple terminfo definitions.
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
version of tmux, etc.
:doc:`styled underlines </underlines>`, :doc:`desktop notifications
</desktop-notifications>`, :doc:`extended keyboard support
</keyboard-protocol>`, etc. they may or may not work, depending on the whims of
tmux's maintainer, your version of tmux, etc.
I opened and closed a lot of windows/tabs and top shows kitty's memory usage is very high?
-------------------------------------------------------------------------------------------
``top`` is not a good way to measure process memory usage. That is because on
modern systems, when allocating memory to a process, the C library functions
will typically allocate memory in large blocks, and give the process chunks of
these blocks. When the process frees a chunk, the C library will not
:program:`top` is not a good way to measure process memory usage. That is
because on modern systems, when allocating memory to a process, the C library
functions will typically allocate memory in large blocks, and give the process
chunks of these blocks. When the process frees a chunk, the C library will not
necessarily release the underlying block back to the OS. So even though the
application has released the memory, ``top`` will still claim the process is
using it.
application has released the memory, :program:`top` will still claim the process
is using it.
To check for memory leaks, instead use a tool like ``valgrind``. Run::
To check for memory leaks, instead use a tool like `Valgrind
<https://valgrind.org/>`__. Run::
PYTHONMALLOC=malloc valgrind --tool=massif kitty
@@ -386,18 +483,19 @@ that window, maybe run yes or find again. Then quit kitty and run::
You will see the allocations graph goes up when you opened the windows, then
goes back down when you closed them, indicating there were no memory leaks.
For those interested, you can get a similar profile out of ``valgrind`` as you get
with ``top`` by adding ``--pages-as-heap=yes`` then you will see that memory
allocated in malloc is not freed in free. This can be further refined if you
use `glibc`` as your C library by setting the environment variable
``MALLOC_MMAP_THRESHOLD_=64``. This will cause free to actually free memory
allocated in sizes of more than 64 bytes. With this set, memory usage will
climb high, then fall when closing windows, but not fall all the way back. The
remaining used memory can be investigated using valgrind again, and it will
For those interested, you can get a similar profile out of :program:`valgrind`
as you get with :program:`top` by adding ``--pages-as-heap=yes`` then you will
see that memory allocated in malloc is not freed in free. This can be further
refined if you use ``glibc`` as your C library by setting the environment
variable ``MALLOC_MMAP_THRESHOLD_=64``. This will cause free to actually free
memory allocated in sizes of more than 64 bytes. With this set, memory usage
will climb high, then fall when closing windows, but not fall all the way back.
The remaining used memory can be investigated using valgrind again, and it will
come from arenas in the GPU drivers and the per thread arenas glibc's malloc
maintains. These too allocate memory in large blocks and dont release it back
maintains. These too allocate memory in large blocks and don't release it back
to the OS immediately.
Why does kitty sometimes start slowly on my Linux system?
-------------------------------------------------------------------------------------------
@@ -421,4 +519,4 @@ The correct command will depend on your situation and hardware.
:file:`libEGL_mesa.so` and ignore :file:`libEGL_nvidia.so` also available on the
system, which will wake the NVIDIA card during device enumeration.
``MESA_LOADER_DRIVER_OVERRIDE`` also assures that Mesa won't offer any NVIDIA
card during enumeration, and will instead just use `/lib/dri/radeonsi_dri.so`.
card during enumeration, and will instead just use :file:`radeonsi_dri.so`.

View File

@@ -30,14 +30,20 @@ Glossary
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>`,
throughout 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.
</kittens/unicode_input>` etc. Normal overlays are meant for short
duration popups and so are not considered the :italic:`active window`
when determining the current working directory or getting input text for
kittens, launch commands, etc. To create an overlay considered as a
:italic:`main window` use the :code:`overlay-main` argument to
:doc:`launch`.
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.
hyperlink, based on the type of link and its URL. See also `Hyperlinks in terminal
emulators <https://gist.github.com/egmontkob/eb114294efbcd5adb1944c9f3cb5feda>`__.
.. _env_vars:
@@ -45,6 +51,7 @@ Environment variables
------------------------
Variables that influence kitty behavior
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.. envvar:: KITTY_CONFIG_DIRECTORY
@@ -65,9 +72,9 @@ Variables that influence kitty behavior
.. envvar:: VISUAL
The terminal editor (such as ``vi`` or ``nano``) kitty uses, when, for
instance, opening :file:`kitty.conf` in response to :sc:`edit_config_file`.
The terminal based text editor (such as :program:`vi` or :program:`nano`)
kitty uses, when, for instance, opening :file:`kitty.conf` in response to
:sc:`edit_config_file`.
.. envvar:: EDITOR
@@ -84,84 +91,129 @@ Variables that influence kitty behavior
is possible for the autodiscovery to fail; the default Wayland XKB mappings
are used in this case. See :pull:`3943` for details.
.. envvar:: SSH_ASKPASS
Specify the program for SSH to ask for passwords. When this is set, :doc:`ssh
kitten </kittens/ssh>` will use this environment variable by default. See
:opt:`askpass <kitten-ssh.askpass>` for details.
.. envvar:: KITTY_CLONE_SOURCE_CODE
Set this to some shell code that will be executed in the cloned window with
:code:`eval` when :ref:`clone-in-kitty <clone_shell>` is used.
.. envvar:: KITTY_CLONE_SOURCE_PATH
Set this to the path of a file that will be sourced in the cloned window when
:ref:`clone-in-kitty <clone_shell>` is used.
.. envvar:: KITTY_DEVELOP_FROM
Set this to the directory path of the kitty source code and its Python code
will be loaded from there. Only works with official binary builds.
.. envvar:: KITTY_RC_PASSWORD
Set this to a pass phrase to use the ``kitty @`` remote control command with
:opt:`remote_control_password`.
Variables that kitty sets when running child programs
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.. envvar:: LANG
This is set only on macOS, and only if the country and language from the
macOS user settings form a valid locale.
This is only set on macOS. If the country and language from the macOS user
settings form an invalid locale, it will be set to :code:`en_US.UTF-8`.
.. envvar:: PATH
kitty prepends itself to the PATH of its own environment to ensure the
functions calling :program:`kitty` will work properly.
.. envvar:: KITTY_WINDOW_ID
An integer that is the id for the kitty :term:`window` the program is running in.
Can be used with the :doc:`kitty remote control facility <remote-control>`.
.. envvar:: KITTY_PID
An integer that is the process id for the kitty process in which the program
is running. Allows programs to tell kitty to reload its config by sending it
the SIGUSR1 signal.
.. envvar:: KITTY_PUBLIC_KEY
A public key that programs can use to communicate securely with kitty using
the remote control protocol. The format is: :code:`protocol:key data`.
.. envvar:: WINDOWID
The id for the :term:`OS Window <os_window>` the program is running in. Only available
on platforms that have ids for their windows, such as X11 and macOS.
.. envvar:: TERM
The name of the terminal, defaults to ``xterm-kitty``. See :opt:`term`.
.. envvar:: TERMINFO
Path to a directory containing the kitty terminfo database.
.. envvar:: KITTY_INSTALLATION_DIR
Path to the kitty installation directory.
.. envvar:: COLORTERM
Set to the value ``truecolor`` to indicate that kitty supports 16 million
colors.
.. envvar:: KITTY_LISTEN_ON
Set when the :doc:`remote control <remote-control>` facility is enabled and
the a socket is used for control via :option:`kitty --listen-on` or :opt:`listen_on`.
Contains the path to the socket. Avoids needs to use :option:`kitty @ --to` when
Contains the path to the socket. Avoid the need 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.
kittens, so kittens can use them without needing to load :file:`kitty.conf`.
.. envvar:: KITTY_SHELL_INTEGRATION
Set when enabling :ref:`shell_integration`. It is automatically removed by
the shell integration scripts.
.. envvar:: ZDOTDIR
Set when enabling :ref:`shell_integration` with :program:`zsh`, allowing
:program:`zsh` to automatically load the integration script.
.. envvar:: XDG_DATA_DIRS
Set when enabling :ref:`shell_integration` with :program:`fish`, allowing
:program:`fish` to automatically load the integration script.
.. envvar:: ENV
Set when enabling :ref:`shell_integration` with :program:`bash`, allowing
:program:`bash` to automatically load the integration script.
.. envvar:: KITTY_OS
Set when using the include directive in kitty.conf. Can take values:
``linux``, ``macos``, ``bsd``.

View File

@@ -28,20 +28,22 @@ 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>`_
* `ranger <https://github.com/ranger/ranger>`_ - a terminal file manager, with image previews
* :doc:`kitty-diff <kittens/diff>` - a side-by-side terminal diff program with support for images
* `tpix <https://github.com/jesvedberg/tpix>`_ - a statically compiled binary that can be used to display images and easily installed on remote servers without root access
* `mpv <https://github.com/mpv-player/mpv/commit/874e28f4a41a916bb567a882063dd2589e9234e1>`_ - A video player that can play videos in the terminal
* `pixcat <https://github.com/mirukana/pixcat>`_ - a third party CLI and python library that wraps the graphics protocol
* `neofetch <https://github.com/dylanaraps/neofetch>`_ - A command line system
information tool
* `viu <https://github.com/atanunq/viu>`_ - a terminal image viewer
* `glkitty <https://github.com/michaeljclark/glkitty>`_ - C library to draw OpenGL shaders in the terminal with a glgears demo
* `ctx.graphics <https://ctx.graphics/>`_ - Library for drawing graphics
* `timg <https://github.com/hzeller/timg>`_ - a terminal image and video viewer
* `notcurses <https://github.com/dankamongmen/notcurses>`_ - C library for terminal graphics with bindings for C++, Rust and Python
* `rasterm <https://github.com/BourgeoisBear/rasterm>`_ - Go library to display images in the terminal
* `chafa <https://github.com/hpjansson/chafa>`_ - a terminal image viewer
* `hologram.nvim <https://github.com/edluffy/hologram.nvim>`_ - view images inside nvim
* `term-image <https://github.com/AnonymouX47/term-image>`_ - A Python library, CLI and TUI to display and browse images in the terminal
* `glkitty <https://github.com/michaeljclark/glkitty>`_ - C library to draw OpenGL shaders in the terminal with a glgears demo
Other terminals that have implemented the graphics protocol:
@@ -86,6 +88,17 @@ code to demonstrate its use
'number of rows: {} number of columns: {}'
'screen width: {} screen height: {}').format(*buf))
.. tab:: Go
.. code-block:: go
import "golang.org/x/sys/unix"
fd, err := unix.Open(fd, unix.O_NOCTTY|unix.O_CLOEXEC|unix.O_NDELAY|unix.O_RDWR, 0666)
sz, err := unix.IoctlGetWinsize(fd, unix.TIOCGWINSZ)
fmt.Println("rows: %v columns: %v width: %v height %v", sz.Row, sz.Col, sz.Xpixel, sz.Ypixel)
Note that some terminals return ``0`` for the width and height values. Such
terminals should be modified to return the correct values. Examples of
terminals that return correct values: ``kitty, xterm``
@@ -99,47 +112,71 @@ kitty.
A minimal example
------------------
Some minimal python code to display PNG images in kitty, using the most basic
Some minimal code to display PNG images in kitty, using the most basic
features of the graphics protocol:
.. code-block:: python
.. tab:: Bash
import sys
from base64 import standard_b64encode
.. code-block:: sh
#!/bin/bash
transmit_png() {
data=$(base64 "$1")
data="${data//[[:space:]]}"
builtin local pos=0
builtin local chunk_size=4096
while [ $pos -lt ${#data} ]; do
builtin printf "\e_G"
[ $pos = "0" ] && printf "a=T,f=100,"
builtin local chunk="${data:$pos:$chunk_size}"
pos=$(($pos+$chunk_size))
[ $pos -lt ${#data} ] && builtin printf "m=1"
[ ${#chunk} -gt 0 ] && builtin printf ";%s" "${chunk}"
builtin printf "\e\\"
done
}
transmit_png "$1"
.. tab:: Python
.. code-block:: python
#!/usr/bin/python
import sys
from base64 import standard_b64encode
def serialize_gr_command(**cmd):
payload = cmd.pop('payload', None)
cmd = ','.join(f'{k}={v}' for k, v in cmd.items())
ans = []
w = ans.append
w(b'\033_G'), w(cmd.encode('ascii'))
if payload:
w(b';')
w(payload)
w(b'\033\\')
return b''.join(ans)
def write_chunked(**cmd):
data = standard_b64encode(cmd.pop('data'))
while data:
chunk, data = data[:4096], data[4096:]
m = 1 if data else 0
sys.stdout.buffer.write(serialize_gr_command(payload=chunk, m=m,
**cmd))
sys.stdout.flush()
cmd.clear()
with open(sys.argv[-1], 'rb') as f:
write_chunked(a='T', f=100, data=f.read())
def serialize_gr_command(**cmd):
payload = cmd.pop('payload', None)
cmd = ','.join(f'{k}={v}' for k, v in cmd.items())
ans = []
w = ans.append
w(b'\033_G'), w(cmd.encode('ascii'))
if payload:
w(b';')
w(payload)
w(b'\033\\')
return b''.join(ans)
def write_chunked(**cmd):
data = standard_b64encode(cmd.pop('data'))
while data:
chunk, data = data[:4096], data[4096:]
m = 1 if data else 0
sys.stdout.buffer.write(serialize_gr_command(payload=chunk, m=m,
**cmd))
sys.stdout.flush()
cmd.clear()
with open(sys.argv[-1], 'rb') as f:
write_chunked(a='T', f=100, data=f.read())
Save this script as :file:`png.py`, then you can use it to display any PNG
Save this script as :file:`send-png`, then you can use it to display any PNG
file in kitty as::
python png.py file.png
chmod +x send-png
./send-png file.png
The graphics escape code
@@ -235,7 +272,8 @@ Value of `t` Meaning
the terminal emulator should only delete the file if it
is in a known temporary directory, such as :file:`/tmp`,
:file:`/dev/shm`, :file:`TMPDIR env var if present` and any platform
specific temporary directories.
specific temporary directories and the file has the
string :code:`tty-graphics-protocol` in its full file path.
``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
@@ -377,7 +415,9 @@ id. To do so add the ``p`` key with a number between ``1`` and ``4294967295``.
When you specify a placement id, it will be added to the acknowledgement code
above. Every placement is uniquely identified by the pair of the ``image id``
and the ``placement id``. If you specify a placement id for an image that does
not have an id, it will be ignored. An example response::
not have an id (i.e. has id=0), it will be ignored. In particular this means
there can exist multiple images with ``image id=0, placement id=0``.
An example response::
<ESC>_Gi=<image id>,p=<placement id>;OK<ESC>\
@@ -414,7 +454,9 @@ they are semi-transparent. You can specify z-index values using the ``z`` key.
Negative z-index values mean that the images will be drawn under the text. This
allows rendering of text on top of images. Negative z-index values below
INT32_MIN/2 (-1,073,741,824) will be drawn under cells with non-default background
colors.
colors. If two images with the same z-index overlap then the image with the
lower id is considered to have the lower z-index. If the images have the same
z-index and the same id, then the behavior is undefined.
.. note:: After placing an image on the screen the cursor must be moved to the
right by the number of cols in the image placement rectangle and down by the

View File

@@ -156,7 +156,6 @@ exec_kitty() {
}
main() {
[ -n "$KITTY_WINDOW_ID" ] && die "You should not try to update kitty from within kitty itself. For best results, quit all kitty instances and run this script from another terminal"
detect_os
parse_args "$@"
detect_network_tool

View File

@@ -4,8 +4,8 @@ Integrations with other 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.
:doc:`kittens/custom` and :doc:`kittens/icat` that allow it to be integrated
with other tools seamlessly.
Image and document viewers
@@ -30,19 +30,28 @@ Display markdown files nicely formatted with images in the terminal
`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_term_image:
`term-image <https://github.com/AnonymouX47/term-image>`__
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Tool to browse images in a terminal using kitty's graphics protocol.
.. _tool_koneko:
@@ -61,8 +70,8 @@ View images in the terminal, similar to kitty's icat.
`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:
@@ -71,13 +80,19 @@ knowledge base application that uses kitty's graphics protocol for images.
A text mode WWW browser that supports kitty's graphics protocol to display
images.
.. _tool_mpv:
`mpv <https://github.com/mpv-player/mpv/commit/874e28f4a41a916bb567a882063dd2589e9234e1>`_
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
A video player that can play videos in the terminal.
.. _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
@@ -87,7 +102,8 @@ System and data visualisation tools
`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:
@@ -105,16 +121,16 @@ Show images from Julia directly in kitty
`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
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:
A graphing and data visualization tool that can be made to display its output in
kitty with the following bash snippet:
.. code-block:: sh
@@ -171,26 +187,28 @@ 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
such a split windows, previews, REPLs etc.
|kitty| can be integrated into many different terminal based text 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:
@@ -202,7 +220,7 @@ Allows easily running tests in a terminal window
`hologram.nvim <https://github.com/edluffy/hologram.nvim>`_
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Terminal image viewer for nvim
Terminal image viewer for Neovim
Scrollback manipulation
@@ -228,21 +246,21 @@ Miscellaneous
`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
.. 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:

View File

@@ -35,8 +35,13 @@ inside the kitty terminal to report key events.
In addition to kitty, this protocol is also implemented in:
* The `foot terminal <https://codeberg.org/dnkl/foot/issues/319>`__
* The `WezTerm terminal <https://wezfurlong.org/wezterm/config/lua/config/enable_kitty_keyboard.html>`__
* The `notcurses library
<https://github.com/dankamongmen/notcurses/issues/2131>`__
* The `crossterm library
<https://github.com/crossterm-rs/crossterm/pull/688>`__
* The `Vim text editor <https://github.com/vim/vim/commit/63a2e360cca2c70ab0a85d14771d3259d4b3aafa>`__
* The `Neovim text editor <https://github.com/neovim/neovim/pull/18181>`__
* The `kakoune text editor <https://github.com/mawww/kakoune/issues/4103>`__
* The `dte text editor <https://gitlab.com/craigbarnes/dte/-/issues/138>`__
@@ -56,14 +61,14 @@ without too many changes, do the following:
that are easy to parse unambiguously.
#. 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.
to restore whatever the keyboard mode was before step 1.
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
text (``CSI`` is the bytes ``0x1b 0x5b``)::
CSI number ; modifiers [u~]
CSI 1; modifiers [ABCDEFHPQRS]
CSI 1; modifiers [ABCDEFHPQS]
0x0d - for the Enter key
0x7f or 0x08 - for Backspace
0x09 - for Tab
@@ -78,7 +83,7 @@ The second form is used for a few functional keys, such as the :kbd:`Home`,
:kbd:`End`, :kbd:`Arrow` keys and :kbd:`F1` ... :kbd:`F4`, they are enumerated in
the :ref:`functional` table below. Note that if no modifiers are present the
parameters are omitted entirely giving an escape code of the form ``CSI
[ABCDEFHPQRS]``.
[ABCDEFHPQS]``.
If you want support for more advanced features such as repeat and release
events, alternate keys for shortcut matching et cetera, these can be turned on
@@ -309,7 +314,7 @@ With this flag turned on, all key events that do not generate text are
represented in one of the following two forms::
CSI number; modifier u
CSI 1; modifier [~ABCDEFHPQRS]
CSI 1; modifier [~ABCDEFHPQS]
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
@@ -377,7 +382,7 @@ An application can query the terminal for support of this protocol by sending
the escape code querying for the :ref:`current progressive enhancement
<progressive_enhancement>` status
followed by request for the `primary device attributes
<https://vt100.net/docs/vt510-rm/DA1.html>`. If an answer for the device
<https://vt100.net/docs/vt510-rm/DA1.html>`__. If an answer for the device
attributes is received without getting back an answer for the progressive
enhancement the terminal does not support this protocol.
@@ -400,7 +405,7 @@ Legacy functional keys
These keys are encoded using three schemes::
CSI number ; modifier ~
CSI 1 ; modifier {ABCDEFHPQRS}
CSI 1 ; modifier {ABCDEFHPQS}
SS3 {ABCDEFHPQRS}
In the above, if there are no modifiers, the modifier parameter is omitted.
@@ -528,7 +533,7 @@ compatibility reasons.
"NUM_LOCK", "``57360 u``", "PRINT_SCREEN", "``57361 u``"
"PAUSE", "``57362 u``", "MENU", "``57363 u``"
"F1", "``1 P or 11 ~``", "F2", "``1 Q or 12 ~``"
"F3", "``1 R or 13 ~``", "F4", "``1 S or 14 ~``"
"F3", "``13 ~``", "F4", "``1 S or 14 ~``"
"F5", "``15 ~``", "F6", "``17 ~``"
"F7", "``18 ~``", "F8", "``19 ~``"
"F9", "``20 ~``", "F10", "``21 ~``"
@@ -577,8 +582,14 @@ compatibility reasons.
.. end functional key table
.. }}}
Note that the escape codes above of the form ``CSI 1 letter`` will omit the
``1`` if there are no modifiers, since ``1`` is the default value.
.. note::
The escape codes above of the form ``CSI 1 letter`` will omit the
``1`` if there are no modifiers, since ``1`` is the default value.
.. note::
The original version of this specification allowed F3 to be encoded as both
CSI R and CSI ~. However, CSI R conflicts with the Cursor Position Report,
so it was removed.
.. _ctrl_mapping:
@@ -671,3 +682,31 @@ specification.
* Handwaves that :kbd:`ctrl` *tends to* mask with ``0x1f``. In actual fact it
does this only for some keys. The action of :kbd:`ctrl` is not specified and
varies between terminals, historically because of different keyboard layouts.
Why xterm's modifyOtherKeys should not be used
---------------------------------------------------
* Does not support release events
* Does not fix the issue of :kbd:`Esc` key presses not being distinguishable from
escape codes.
* Does not fix the issue of some keypresses generating identical bytes and thus
being indistinguishable
* There is no robust way to query it or manage its state from a program running
in the terminal.
* No support for shifted keys.
* No support for alternate keyboard layouts.
* No support for modifiers beyond the basic four.
* No support for lock keys like Num lock and Caps lock.
* Is completely unspecified. The most discussion of it available anywhere is
`here <https://invisible-island.net/xterm/modified-keys.html>`__
And it contains no specification of what numbers to assign to what function
keys beyond running a Perl script on an X11 system!!

View File

@@ -3,18 +3,21 @@ 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).
The ``broadcast`` kitten can be used to type text simultaneously in all
:term:`kitty windows <window>` (or a subset as desired).
To use it, simply create a mapping in :file:`kitty.conf` such as::
map F1 launch --allow-remote-control kitty +kitten broadcast
map f1 launch --allow-remote-control kitty +kitten broadcast
Then press the :kbd:`F1` key and whatever you type in the newly created widow
Then press the :kbd:`F1` key and whatever you type in the newly created window
will be sent to all kitty windows.
You can use the options described below to control which windows
are selected.
You can use the options described below to control which windows are selected.
For example, only broadcast to other windows in the current tab::
map f1 launch --allow-remote-control kitty +kitten broadcast --match-tab state:focused
.. program:: kitty +kitten broadcast

View File

@@ -11,14 +11,46 @@ from the shell. It even works over SSH. Using it is as simple as::
echo hooray | kitty +kitten clipboard
All text received on :file:`stdin` is copied to the clipboard.
All text received on :file:`STDIN` is copied to the clipboard.
To get text from the clipboard you have to enable reading of the clipboard
in :opt:`clipboard_control` in :file:`kitty.conf`. Once you do that, you can
use::
To get text from the clipboard::
kitty +kitten clipboard --get-clipboard
The text will be written to :file:`STDOUT`. Note that by default kitty asks for
permission when a program attempts to read the clipboard. This can be
controlled via :opt:`clipboard_control`.
.. versionadded:: 0.27.0
Support for copying arbitrary data types
The clipboard kitten can be used to send/receive
more than just plain text from the system clipboard. You can transfer arbitrary
data types. Best illustrated with some examples::
# Copy an image to the clipboard:
kitty +kitten clipboard picture.png
# Copy an image and some text to the clipboard:
kitty +kitten clipboard picture.jpg text.txt
# Copy text from STDIN and an image to the clipboard:
echo hello | kitty +kitten clipboard picture.png /dev/stdin
# Copy any raster image available on the clipboard to a PNG file:
kitty +kitten clipboard -g picture.png
# Copy an image to a file and text to STDOUT:
kitty +kitten clipboard -g picture.png /dev/stdout
# List the formats available on the system clipboard
kitty +kitten clipboard -g -m . /dev/stdout
Normally, the kitten guesses MIME types based on the file names. To control the
MIME types precisely, use the :option:`--mime <kitty +kitten clipboard --mime>` option.
This kitten uses a new protocol developed by kitty to function, for details,
see :doc:`/clipboard`.
.. program:: kitty +kitten clipboard

View File

@@ -1,21 +1,20 @@
Custom kittens
=================
You can easily create your own kittens to extend kitty. They are just
terminal programs written in Python. When launching a kitten, kitty will
open an overlay window over the current window and optionally pass the
contents of the current window/scrollback to the kitten over its :file:`STDIN`.
The kitten can then perform whatever actions it likes, just as a normal
terminal program. After execution of the kitten is complete, it has access
to the running kitty instance so it can perform arbitrary actions
such as closing windows, pasting text, etc.
You can easily create your own kittens to extend kitty. They are just terminal
programs written in Python. When launching a kitten, kitty will open an overlay
window over the current window and optionally pass the contents of the current
window/scrollback to the kitten over its :file:`STDIN`. The kitten can then
perform whatever actions it likes, just as a normal terminal program. After
execution of the kitten is complete, it has access to the running kitty instance
so it can perform arbitrary actions such as closing windows, pasting text, etc.
Let's see a simple example of creating a kitten. It will ask the user for some
input and paste it into the terminal window.
Create a file in the kitty config folder, :file:`~/.config/kitty/mykitten.py`
(you might need to adjust the path to wherever the kitty config folder is on
your machine).
Create a file in the kitty config directory, :file:`~/.config/kitty/mykitten.py`
(you might need to adjust the path to wherever the :ref:`kitty config directory
<confloc>` is on your machine).
.. code-block:: python
@@ -43,11 +42,30 @@ Now in :file:`kitty.conf` add the lines::
map ctrl+k kitten mykitten.py
Start kitty and press :kbd:`ctrl+k` and you should see the kitten running.
The best way to develop your own kittens is to modify one of the built in
kittens. Look in the kittens sub-directory of the kitty source code for those.
Or see below for a list of :ref:`third-party kittens <external_kittens>`,
that other kitty users have created.
Start kitty and press :kbd:`Ctrl+K` and you should see the kitten running.
The best way to develop your own kittens is to modify one of the built-in
kittens. Look in the `kittens sub-directory
<https://github.com/kovidgoyal/kitty/tree/master/kittens>`__ of the kitty source
code for those. Or see below for a list of :ref:`third-party kittens
<external_kittens>`, that other kitty users have created.
kitty API to use with kittens
-------------------------------
Kittens have full access to internal kitty APIs. However these are neither
entirely stable nor documented. You can instead use the kitty
:doc:`Remote control API </remote-control>`. Simply call
:code:`boss.call_remote_control()`, with the same arguments you
would pass to ``kitty @``. For example:
.. code-block:: python
def handle_result(args: List[str], answer: str, target_window_id: int, boss: Boss) -> None:
# get the kitty window to which to send text
w = boss.window_id_map.get(target_window_id)
if w is not None:
boss.call_remote_control(w, ('send-text', 'hello world'))
Passing arguments to kittens
@@ -60,36 +78,40 @@ You can pass arguments to kittens by defining them in the map directive in
These will be available as the ``args`` parameter in the ``main()`` and
``handle_result()`` functions. Note also that the current working directory
of the kitten is set to the working directory of whatever program is
running in the active kitty window. The special argument ``@selection``
is replaced by the currently selected text in the active kitty window.
of the kitten is set to the working directory of whatever program is running in
the active kitty window. The special argument ``@selection`` is replaced by the
currently selected text in the active kitty window.
Passing the contents of the screen to the kitten
---------------------------------------------------
If you would like your kitten to have access to the contents of the screen
and/or the scrollback buffer, you just need to add an annotation to the ``handle_result()``
function, telling kitty what kind of input your kitten would like. For example:
and/or the scrollback buffer, you just need to add an annotation to the
``handle_result()`` function, telling kitty what kind of input your kitten would
like. For example:
.. code-block:: py
from typing import List
from kitty.boss import Boss
# in main, STDIN is for the kitten process and will contain
# the contents of the screen
def main(args):
def main(args: List[str]) -> str:
return sys.stdin.read()
# in handle_result, STDIN is for the kitty process itself, rather
# than the kitten process and should not be read from.
from kittens.tui.handler import result_handler
@result_handler(type_of_input='text')
def handle_result(args, stdin_data, target_window_id, boss):
def handle_result(args: List[str], stdin_data: str, target_window_id: int, boss: Boss) -> None:
pass
This will send the plain text of the active window to the kitten's
:file:`STDIN`. There are many other types of input you can ask for,
described in the table below:
:file:`STDIN`. There are many other types of input you can ask for, described in
the table below:
.. table:: Types of input to kittens
:align: left
@@ -121,31 +143,35 @@ and ``first_output`` gives the output of the first command currently on screen.
These can also be combined with ``screen`` and ``ansi`` for formatting.
.. note::
For the types based on the output of a command,
:ref:`shell_integration` is required.
For the types based on the output of a command, :ref:`shell_integration` is
required.
Using kittens to script kitty, without any terminal UI
-----------------------------------------------------------
If you would like your kitten to script kitty, without bothering to write a
terminal program, you can tell the kittens system to run the
``handle_result()`` function without first running the ``main()`` function.
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. This is
For example, here is a kitten that "zooms in/zooms out" the current terminal
window by switching to the stack layout or back to the previous layout. This is
equivalent to the builtin :ac:`toggle_layout` action.
Create a file in the kitty config folder, :file:`~/.config/kitty/zoom_toggle.py`
Create a Python file in the :ref:`kitty config directory <confloc>`,
:file:`~/.config/kitty/zoom_toggle.py`
.. code-block:: py
def main(args):
from typing import List
from kitty.boss import Boss
def main(args: List[str]) -> str:
pass
from kittens.tui.handler import result_handler
@result_handler(no_ui=True)
def handle_result(args, answer, target_window_id, boss):
def handle_result(args: List[str], answer: str, target_window_id: int, boss: Boss) -> None:
tab = boss.active_tab
if tab is not None:
if tab.current_layout.name == 'stack':
@@ -154,7 +180,7 @@ Create a file in the kitty config folder, :file:`~/.config/kitty/zoom_toggle.py`
tab.goto_layout('stack')
Now in kitty.conf add::
Now in :file:`kitty.conf` add::
map f11 kitten zoom_toggle.py
@@ -165,7 +191,7 @@ layout, by simply adding the line::
boss.toggle_fullscreen()
To the ``handle_result()`` function, above.
to the ``handle_result()`` function, above.
.. _send_mouse_event:
@@ -173,7 +199,7 @@ To the ``handle_result()`` function, above.
Sending mouse events
--------------------
If the program running in a window is receiving mouse events you can simulate
If the program running in a window is receiving mouse events, you can simulate
those using::
from kitty.fast_data_types import send_mouse_event
@@ -200,15 +226,15 @@ that type, and will return ``True`` if it sent the event, and ``False`` if not.
Debugging kittens
--------------------
The part of the kitten that runs in ``main()`` is just a normal program and
the output of print statements will be visible in the kitten window. Or
alternately, you can use::
The part of the kitten that runs in ``main()`` is just a normal program and the
output of print statements will be visible in the kitten window. Or alternately,
you can use::
from kittens.tui.loop import debug
debug('whatever')
The ``debug()`` function is just like ``print()`` except that the output
will appear in the ``STDOUT`` of the kitty process inside which the kitten is
The ``debug()`` function is just like ``print()`` except that the output will
appear in the ``STDOUT`` of the kitty process inside which the kitten is
running.
The ``handle_result()`` part of the kitten runs inside the kitty process.
@@ -216,12 +242,13 @@ 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.
configurable, you will need some boilerplate. Put the following files in the
directory of your kitten.
:file:`kitten_options_definition.py`
@@ -311,8 +338,9 @@ You can parse and read the options in your kitten using the following code:
opts.config_overrides = overrides
return opts
See the code for the builtin diff kitten for examples of creating more options
and keyboard shortcuts.
See `the code <https://github.com/kovidgoyal/kitty/tree/master/kittens/diff>`__
for the builtin :doc:`diff kitten </kittens/diff>` for examples of creating more
options and keyboard shortcuts.
.. _external_kittens:
@@ -320,7 +348,8 @@ Kittens created by kitty users
---------------------------------------------
`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.
`smart-scroll <https://github.com/yurikhan/kitty-smart-scroll>`_
Makes the kitty scroll bindings work in full screen applications

View File

@@ -12,8 +12,8 @@ Major Features
* Displays diffs side-by-side in the kitty terminal
* Does syntax highlighting of the displayed diffs, asynchronously, for maximum
speed
* Does syntax highlighting of the displayed diffs, asynchronously, for
maximum speed
* Displays images as well as text diffs, even over SSH
@@ -31,11 +31,11 @@ Major Features
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 <https://pygments.org/>`_ must be installed (note that pygments is
included in the official kitty binary builds).
Simply :ref:`install kitty <quickstart>`. You also need to have either the `git
<https://git-scm.com/>`__ program or the :program:`diff` program installed.
Additionally, for syntax highlighting to work, `pygments
<https://pygments.org/>`__ must be installed (note that pygments is included in
the official kitty binary builds).
Usage
@@ -45,9 +45,10 @@ In the kitty terminal, run::
kitty +kitten diff file1 file2
to see the diff between file1 and file2.
to see the diff between :file:`file1` and :file:`file2`.
Create an alias in your shell's startup file to shorten the command, for example:
Create an alias in your shell's startup file to shorten the command, for
example:
.. code-block:: sh
@@ -67,20 +68,20 @@ Keyboard controls
========================= ===========================
Action Shortcut
========================= ===========================
Quit :kbd:`q`, :kbd:`ctrl+c`, :kbd:`Esc`
Scroll line up :kbd:`k`, :kbd:`Up`
Scroll line down :kbd:`j`, :kbd:`Down`
Quit :kbd:`Q`, :kbd:`Ctrl+C`, :kbd:`Esc`
Scroll line up :kbd:`K`, :kbd:`Up`
Scroll line down :kbd:`J`, :kbd:`Down`
Scroll page up :kbd:`PgUp`
Scroll page down :kbd:`PgDn`
Scroll to top :kbd:`Home`
Scroll to bottom :kbd:`End`
Scroll to next page :kbd:`Space`, :kbd:`PgDn`
Scroll to previous page :kbd:`PgUp`
Scroll to next change :kbd:`n`
Scroll to previous change :kbd:`p`
Scroll to next change :kbd:`N`
Scroll to previous change :kbd:`P`
Increase lines of context :kbd:`+`
Decrease lines of context :kbd:`-`
All lines of context :kbd:`a`
All lines of context :kbd:`A`
Restore default context :kbd:`=`
Search forwards :kbd:`/`
Search backwards :kbd:`?`
@@ -93,7 +94,7 @@ Scroll to previous match :kbd:`<`, :kbd:`,`
Integrating with git
-----------------------
Add the following to `~/.gitconfig`:
Add the following to :file:`~/.gitconfig`:
.. code-block:: ini
@@ -119,24 +120,23 @@ 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
</protocol-extensions>`, such as the :doc:`kitty graphics protocol
</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).
</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).
And fundamentally, it's kitty only because I wrote it for myself, and I am
highly unlikely to use any other terminals :)
Configuration
------------------------
You can configure the colors used, keyboard shortcuts, the diff implementation,
the default lines of context, etc. by creating a :file:`diff.conf` file in
your :ref:`kitty config folder <confloc>`. See below for the supported
configuration directives.
the default lines of context, etc. by creating a :file:`diff.conf` file in your
:ref:`kitty config folder <confloc>`. See below for the supported configuration
directives.
.. include:: /generated/conf-kitten-diff.rst
@@ -145,7 +145,6 @@ configuration directives.
.. include:: /generated/cli-kitten-diff.rst
Sample diff.conf
-----------------

View File

@@ -1,9 +1,9 @@
Hints
==========
|kitty| has a *hints mode* to select and act on arbitrary text snippets currently
visible on the screen. For example, you can press :sc:`open_url`
to choose any URL visible on the screen and then open it using your system
|kitty| has a *hints mode* to select and act on arbitrary text snippets
currently visible on the screen. For example, you can press :sc:`open_url`
to choose any URL visible on the screen and then open it using your default web
browser.
.. figure:: ../screenshots/hints_mode.png
@@ -13,25 +13,29 @@ browser.
URL hints mode
Similarly, you can press :sc:`insert_selected_path` to
select anything that looks like a path or filename and then insert it into the
terminal, very useful for picking files from the output of a ``git`` or ``ls`` command and
adding them to the command line for the next command.
Similarly, you can press :sc:`insert_selected_path` to select anything that
looks like a path or filename and then insert it into the terminal, very useful
for picking files from the output of a :program:`git` or :program:`ls` command
and adding them to the command line for the next command.
You can also press :sc:`goto_file_line` to select anything that looks
like a path or filename followed by a colon and a line number and open
the file in vim at the specified line number. The patterns and editor
to be used can be modified using options passed to the kitten. For example::
You can also press :sc:`goto_file_line` to select anything that looks like a
path or filename followed by a colon and a line number and open the file in
:program:`vim` at the specified line number. The patterns and editor to be used
can be modified using options passed to the kitten. For example::
map ctrl+g kitten hints --type=linenum --linenum-action=tab nvim +{line} {path}
will open the selected file in a new tab inside neovim when you press
:kbd:`ctrl+g`.
will open the selected file in a new tab inside `Neovim <https://neovim.io/>`__
when you press :kbd:`Ctrl+G`.
Pressing :sc:`open_selected_hyperlink` will open hyperlinks, i.e. a URL
Pressing :sc:`open_selected_hyperlink` will open :term:`hyperlinks`, i.e. a URL
that has been marked as such by the program running in the terminal,
for example, by ``ls --hyperlink=auto``. You can also :doc:`customize what actions are
taken for different types of URLs <../open_actions>`.
for example, by ``ls --hyperlink=auto``. If :program:`ls` comes with your OS
does not support hyperlink, you may need to install `GNU Coreutils
<https://www.gnu.org/software/coreutils/>`__.
You can also :doc:`customize what actions are taken for different types of URLs
<../open_actions>`.
.. note:: If there are more hints than letters, hints will use multiple
letters. In this case, when you press the first letter, only hints
@@ -48,13 +52,12 @@ snippets. See :sc:`insert_selected_path <insert_selected_path>` for examples.
Completely customizing the matching and actions of the kitten
---------------------------------------------------------------
The hints kitten supports writing simple python scripts that can be used to
The hints kitten supports writing simple Python scripts that can be used to
completely customize how it finds matches and what happens when a match is
selected. This allows the hints kitten to provide the user interface, while
you can provide the logic for finding matches and performing actions on them.
This is best illustrated with an example. Create the file
:file:`custom-hints.py` in the kitty config directory with the following
contents:
selected. This allows the hints kitten to provide the user interface, while you
can provide the logic for finding matches and performing actions on them. This
is best illustrated with an example. Create the file :file:`custom-hints.py` in
the :ref:`kitty config directory <confloc>` with the following contents:
.. code-block:: python
@@ -98,9 +101,10 @@ look it up in the Google dictionary.
.. note::
To avoid having to specify the same command line options on every invocation,
you can use the :opt:`action_alias` option in :file:`kitty.conf`, creating aliases
that have common sets of options. For example::
To avoid having to specify the same command line options on every
invocation, you can use the :opt:`action_alias` option in
:file:`kitty.conf`, creating aliases that have common sets of options.
For example::
action_alias myhints kitten hints --alphabet qfjdkslaureitywovmcxzpq1234567890
map f1 myhints --customize-processing custom-hints.py

View File

@@ -1,11 +1,10 @@
Hyperlinked grep
=================
This kitten allows you to 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.
<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.
.. versionadded:: 0.19.0
@@ -18,68 +17,57 @@ following contents:
# by the hyperlink_grep kitten and nothing else so far.
protocol file
fragment_matches [0-9]+
action launch --type=overlay vim +${FRAGMENT} ${FILE_PATH}
action launch --type=overlay --cwd=current vim +${FRAGMENT} ${FILE_PATH}
# Open text files without fragments in the editor
protocol file
mime text/*
action launch --type=overlay ${EDITOR} ${FILE_PATH}
action launch --type=overlay --cwd=current ${EDITOR} ${FILE_PATH}
Now, run a search with::
kitty +kitten hyperlinked_grep something
Hold down the :kbd:`ctrl+shift` keys and click on any of the
result lines, to open the file in vim at the matching line. If
you use some editor other than vim, you should adjust the
:file:`open-actions.conf` file accordingly.
Hold down the :kbd:`Ctrl+Shift` keys and click on any of the result lines, to
open the file in :program:`vim` at the matching line. If you use some editor
other than :program:`vim`, you should adjust the :file:`open-actions.conf` file
accordingly.
Finally, add an alias to your shell's rc files to invoke the kitten as ``hg``::
Finally, add an alias to your shell's rc files to invoke the kitten as
:command:`hg`::
alias hg='kitty +kitten hyperlinked_grep'
alias hg="kitty +kitten hyperlinked_grep"
You can now run searches with::
hg some-search-term
If you want to enable completion, for the kitten, you can delegate completion
to rg. How to do that varies based on the shell:
.. tab:: zsh
Instead of using an alias create a simple wrapper script named
:file:`hg` somewhere in your ``PATH``:
.. code-block:: sh
#!/bin/sh
exec kitty +kitten hyperlinked_grep "$@"
Then, add the following to :file:`.zshrc`::
compdef _rg hg
.. tab:: fish
You can combine both the aliasing/wrapping and pointing fish
to rg's autocompletion with a fish "wrapper" function in your :file:`config.fish`:
.. code-block:: sh
function hg --wraps rg; kitty +kitten hyperlinked_grep $argv; end
To learn more about kitty's powerful framework for customizing URL click
actions, :doc:`see here </open_actions>`.
actions, see :doc:`here </open_actions>`.
By default, this kitten adds hyperlinks for several parts of ripgrep output:
the per-file header, match context lines, and match lines. You can control
which items are linked with a :code:`--kitten hyperlink` flag. For example,
:code:`--kitten hyperlink=matching_lines` will only add hyperlinks to the
match lines. :code:`--kitten hyperlink=file_headers,context_lines` will link
file headers and context lines but not match lines. :code:`--kitten
hyperlink=none` will cause the command line to be passed to directly to
:command:`rg` so no hyperlinking will be performed. :code:`--kitten hyperlink`
may be specified multiple times.
Hopefully, someday this functionality will make it into some `upstream grep
<https://github.com/BurntSushi/ripgrep/issues/665>`_
program directly removing the need for this kitten.
<https://github.com/BurntSushi/ripgrep/issues/665>`__ program directly removing
the need for this kitten.
.. note::
While you can pass any of ripgrep's comand line options to the kitten and
they will be forwarded to rg, do not use options that change the output
formatting as the kitten works by parsing the output from ripgrep.
they will be forwarded to :program:`rg`, do not use options that change the
output formatting as the kitten works by parsing the output from ripgrep.
The unsupported options are: :code:`--context-separator`,
:code:`--field-context-separator`, :code:`--field-match-separator`,
:code:`--json`, :code:`-I --no-filename`, :code:`-0 --null`,
:code:`--null-data`, :code:`--path-separator`. If you specify options via
configuration file, then any changes to the default output format will not be
supported, not just the ones listed.

View File

@@ -7,10 +7,11 @@ The ``icat`` kitten can be used to display arbitrary images in the |kitty|
terminal. Using it is as simple as::
kitty +kitten icat image.jpeg
kitten icat image.jpeg
It supports all image types supported by `ImageMagick
<https://www.imagemagick.org>`_. It even works over SSH. For details, see
the :doc:`kitty graphics protocol </graphics-protocol>`.
<https://www.imagemagick.org>`__. It even works over SSH. For details, see the
:doc:`kitty graphics protocol </graphics-protocol>`.
You might want to create an alias in your shell's configuration files::
@@ -20,14 +21,15 @@ Then you can simply use ``icat image.png`` to view images.
.. note::
`ImageMagick <https://www.imagemagick.org>`_ must be installed for ``icat`` to
work.
`ImageMagick <https://www.imagemagick.org>`__ must be installed for the
full range of image types. Without it only PNG/JPG/GIF/BMP/TIFF/WEBP are
supported.
.. note::
kitty's image display protocol may not work when used within a terminal
multiplexer such as ``screen`` or ``tmux``, depending on whether the
multiplexer has added support for it or not.
multiplexer such as :program:`screen` or :program:`tmux`, depending on
whether the multiplexer has added support for it or not.
.. program:: kitty +kitten icat
@@ -35,18 +37,18 @@ Then you can simply use ``icat image.png`` to view images.
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`, :option:`--silent` and :option:`--print-window-size`.
:option:`--detect-support` and :option:`--print-window-size`.
If you are trying to integrate icat into a complex program like a file
manager or editor, there are a few things to keep in mind. icat works by
communicating over the TTY device, it both writes to and reads from the TTY.
So it is imperative that while it is running the host program does not do
any TTY I/O. Any key presses or other input from the user on the TTY device
will be discarded. At a minimum, you should use the :option:`--silent` and
:option:`--transfer-mode` command line arguments. To be
really robust you should consider writing proper support for the
:doc:`../graphics-protocol` in the program instead. Nowadays there are many
libraries that have support for it.
If you are trying to integrate icat into a complex program like a file manager
or editor, there are a few things to keep in mind. icat works by communicating
over the TTY device, it both writes to and reads from the TTY. So it is
imperative that while it is running the host program does not do any TTY I/O.
Any key presses or other input from the user on the TTY device will be
discarded. At a minimum, you should use the :option:`--transfer-mode`
command line arguments. To be really robust you should
consider writing proper support for the :doc:`kitty graphics protocol
</graphics-protocol>` in the program instead. Nowadays there are many libraries
that have support for it.
.. include:: /generated/cli-kitten-icat.rst

View File

@@ -4,8 +4,8 @@ Draw a GPU accelerated dock panel on your desktop
.. highlight:: sh
You can use this kitten to draw a GPU accelerated panel on the edge
of your screen, that shows the output from an arbitrary terminal program.
You can use this kitten to draw a GPU accelerated panel on the edge of your
screen, that shows the output from an arbitrary terminal program.
It is useful for showing status information or notifications on your desktop
using terminal programs instead of GUI toolkits.
@@ -32,8 +32,8 @@ Using this kitten is simple, for example::
kitty +kitten panel sh -c 'printf "\n\n\nHello, world."; sleep 5s'
This will show ``Hello, world.`` at the top edge of your screen for five
seconds. Here the terminal program we are running is ``sh`` with a script to
print out ``Hello, world!``. You can make the terminal program as complex as
seconds. Here the terminal program we are running is :program:`sh` with a script
to print out ``Hello, world!``. You can make the terminal program as complex as
you like, as demonstrated in the screenshot above.

View File

@@ -1,18 +1,18 @@
Query terminal
=================
Used to query kitty from terminal programs about version, values of various
runtime options controlling its features, etc.
This kitten is used to query |kitty| from terminal programs about version, values
of various runtime options controlling its features, etc.
The querying is done using the (*semi*) standard XTGETTCAP escape sequence
pioneered by XTerm, so it works over SSH as well. The downside is that it
is slow, since it requires a roundtrip to the terminal emulator and back.
pioneered by xterm, so it works over SSH as well. The downside is that it is
slow, since it requires a roundtrip to the terminal emulator and back.
If you want to do some of the same querying in your terminal program without
depending on the kitten, you can do so, by processing the same escape codes.
Search `this page <https://invisible-island.net/xterm/ctlseqs/ctlseqs.html>`_
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.
Search `this page <https://invisible-island.net/xterm/ctlseqs/ctlseqs.html>`__
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.
.. include:: ../generated/cli-kitten-query_terminal.rst

View File

@@ -1,12 +1,12 @@
Remote files
==============
|kitty| has the ability to easily *Edit*, *Open* or *Download* files
from a computer into which you are SSHed. In your SSH session run::
|kitty| has the ability to easily *Edit*, *Open* or *Download* files from a
computer into which you are SSHed. In your SSH session run::
ls --hyperlink=auto
Then hold down :kbd:`ctrl+shift` and click the name of the file.
Then hold down :kbd:`Ctrl+Shift` and click the name of the file.
.. figure:: ../screenshots/remote_file.png
:alt: Remote file actions
@@ -19,23 +19,28 @@ Then hold down :kbd:`ctrl+shift` and click the name of the file.
to *Edit* it in which case kitty will download it and open it locally in your
:envvar:`EDITOR`. As you make changes to the file, they are automatically
transferred to the remote computer. Note that this happens without needing
to install *any* special software on the server, beyond ``ls`` that supports
hyperlinks.
to install *any* special software on the server, beyond :program:`ls` that
supports hyperlinks.
.. seealso:: See the :ref:`edit-in-kitty <edit_file>` command
.. seealso:: See the :doc:`transfer` kitten
.. versionadded:: 0.19.0
.. note::
Nested SSH sessions are not supported. The kitten will always try to copy
remote files from the first SSH host. This is because there is no way for
For best results, use this kitten with the :doc:`ssh kitten <./ssh>`.
Otherwise, nested SSH sessions are not supported. The kitten will always try to copy
remote files from the first SSH host. This is because, without the ssh
kitten, there is no way for
|kitty| to detect and follow a nested SSH session robustly. Use the
:doc:`transfer` kitten for such situations.
.. note::
If you have not setup automatic password-less SSH access, then, when
editing starts you will be asked to enter your password just once,
thereafter the SSH connection will be re-used.
If you have not setup automatic password-less SSH access, and are not using
the ssh kitten, then, when editing
starts you will be asked to enter your password just once, thereafter the SSH
connection will be re-used.
Similarly, you can choose to save the file to the local computer or download
and open it in its default file handler.

View File

@@ -15,28 +15,27 @@ Truly convenient SSH
Automatic shell integration, file transfer and reuse of connections
The ssh kitten allows you to login easily to remote hosts, and automatically
setup the environment there to be as comfortable as your local shell. You
can specify environment variables to set on the remote host and
files to copy there, making your remote experience just like your
local shell. Additionally, it automatically sets up :ref:`shell_integration` on
the remote host and copies the kitty terminfo database there.
setup the environment there to be as comfortable as your local shell. You can
specify environment variables to set on the remote host and files to copy there,
making your remote experience just like your local shell. Additionally, it
automatically sets up :ref:`shell_integration` on the remote host and copies the
kitty terminfo database there.
The ssh kitten is a thin wrapper around the traditional `ssh <https://man.openbsd.org/ssh>`__
command line program and supports all the same options and arguments and configuration.
In interactive usage scenarios it is a drop in replacement for ``ssh``. To try it
out, simply run:
In interactive usage scenarios it is a drop in replacement for :program:`ssh`.
To try it out, simply run:
.. code-block:: sh
kitty +kitten ssh some-hostname-to-connect-to
You should end up at a shell prompt on the remote host, with shell
integration enabled. If you like it you can add an alias to it in your shell's
rc files:
You should end up at a shell prompt on the remote host, with shell integration
enabled. If you like it you can add an alias to it in your shell's rc files:
.. code-block:: sh
alias s=kitty +kitten ssh
alias s="kitty +kitten ssh"
So now you can just type ``s hostname`` to connect.
@@ -44,13 +43,12 @@ If you define a mapping in :file:`kitty.conf` such as::
map f1 new_window_with_cwd
Then, pressing :kbd:`F1` will open a new window automatically logged
into the same host using the ssh kitten, at the same directory.
Then, pressing :kbd:`F1` will open a new window automatically logged into the
same host using the ssh kitten, at the same directory.
The ssh kitten can be configured using the :file:`~/.config/kitty/ssh.conf`
file where you can specify environment variables to set on the remote host
and files to copy from the local to the remote host. Let's see a
quick example:
The ssh kitten can be configured using the :file:`~/.config/kitty/ssh.conf` file
where you can specify environment variables to set on the remote host and files
to copy from the local to the remote host. Let's see a quick example:
.. code-block:: conf
@@ -80,8 +78,9 @@ Additionally, you can pass config options on the command line:
The :code:`--kitten` argument can be specified multiple times, with directives
from :file:`ssh.conf`. These are merged with :file:`ssh.conf` as if they were
appended to the end of that file. They apply only to the host being SSHed to
by this invocation, so any :opt:`hostname <kitten-ssh.hostname>` directives are ignored.
appended to the end of that file. They apply only to the host being SSHed to by
this invocation, so any :opt:`hostname <kitten-ssh.hostname>` directives are
ignored.
.. warning::
@@ -98,8 +97,8 @@ A real world example
Suppose you often SSH into a production server, and you would like to setup
your shell and editor there using your custom settings. However, other people
could SSH in as well and you don't want to clobber their settings. Here is how
this could be achieved using the ssh kitten with zsh and vim as the shell and
editor, respectively:
this could be achieved using the ssh kitten with :program:`zsh` and
:program:`vim` as the shell and editor, respectively:
.. code-block:: conf
@@ -125,23 +124,34 @@ How it works
The ssh kitten works by having SSH transmit and execute a POSIX sh (or
:opt:`optionally <kitten-ssh.interpreter>` Python) bootstrap script on the
remote host using an :opt:`interpreter <kitten-ssh.interpreter>`. This script
reads setup data over the tty device, which kitty sends as a base64 encoded
reads setup data over the TTY device, which kitty sends as a Base64 encoded
compressed tarball. The script extracts it and places the :opt:`files <kitten-ssh.copy>`
and sets the :opt:`environment variables <kitten-ssh.env>` before finally
launching the :opt:`login shell <kitten-ssh.login_shell>` with :opt:`shell
integration <kitten-ssh.shell_integration>` enabled. The data is requested by
the kitten over the TTY with a random one time password. kitty reads the request
and if the password matches a password pre-stored in shared memory on the
localhost by the kitten, the transmission is allowed. If your OpenSSH version is
>= 8.4 then the data is transmitted instantly without any roundtrip delay.
localhost by the kitten, the transmission is allowed. If your local
`OpenSSH <https://www.openssh.com/>`__ version is >= 8.4 then the data is
transmitted instantly without any roundtrip delay.
.. note::
When connecting to BSD hosts, it is possible the bootstrap script will
fail or run slowly, because the default shells are crippled in various ways.
When connecting to BSD hosts, it is possible the bootstrap script will fail
or run slowly, because the default shells are crippled in various ways.
Your best bet is to install Python on the remote, make sure the login shell
is something POSIX sh compliant, and use :code:`python` as the :opt:`interpreter
<kitten-ssh.interpreter>` in :file:`ssh.conf`.
is something POSIX sh compliant, and use :code:`python` as the
:opt:`interpreter <kitten-ssh.interpreter>` in :file:`ssh.conf`.
.. note::
This may or may not work when using terminal multiplexers, depending on
whether they passthrough the escape codes and if the values of the
environment variables :envvar:`KITTY_PID` and :envvar:`KITTY_WINDOW_ID` are
correct in the current session (they can be wrong when connecting to a tmux
session running in a different window) and the ssh kitten is run in the
currently active multiplexer window.
.. include:: /generated/conf-kitten-ssh.rst
@@ -152,3 +162,42 @@ The copy command
--------------------
.. include:: /generated/ssh-copy.rst
.. _manual_terminfo_copy:
Copying terminfo files manually
-------------------------------------
Sometimes, the ssh kitten can fail, or maybe you dont like to use it. In such
cases, the terminfo files can be copied over manually to a server with the
following one liner::
infocmp -a xterm-kitty | ssh myserver tic -x -o \~/.terminfo /dev/stdin
If you are behind a proxy (like Balabit) that prevents this, or you are SSHing
into macOS where the :program:`tic` does not support reading from :file:`STDIN`,
you must redirect the first command to a file, copy that to the server and run :program:`tic`
manually. If you connect to a server, embedded, or Android system that doesn't
have :program:`tic`, copy over your local file terminfo to the other system as
:file:`~/.terminfo/x/xterm-kitty`.
If the server is running a relatively modern Linux distribution and you have
root access to it, you could simply install the ``kitty-terminfo`` package on
the server to make the terminfo files available.
Really, the correct solution for this is to convince the OpenSSH maintainers to
have :program:`ssh` do this automatically, if possible, when connecting to a
server, so that all terminals work transparently.
If the server is running FreeBSD, or another system that relies on termcap
rather than terminfo, you will need to convert the terminfo file on your local
machine by running (on local machine with |kitty|)::
infocmp -CrT0 xterm-kitty
The output of this command is the termcap description, which should be appended
to :file:`/usr/share/misc/termcap` on the remote server. Then run the following
command to apply your change (on the server)::
cap_mkdb /usr/share/misc/termcap

View File

@@ -1,8 +1,8 @@
Changing kitty colors
========================
The themes kitten allows you to easily change color themes, from a collection
of almost two hundred pre-built themes available at `kitty-themes
The themes kitten allows you to easily change color themes, from a collection of
over two hundred pre-built themes available at `kitty-themes
<https://github.com/kovidgoyal/kitty-themes>`_. To use it, simply run::
kitty +kitten themes
@@ -12,9 +12,9 @@ of almost two hundred pre-built themes available at `kitty-themes
:alt: The themes kitten in action
:width: 600
The kitten allows you to pick a theme, with live previews of the colors. You
can choose between light and dark themes and search by theme name by just
typing a few characters from the name.
The kitten allows you to pick a theme, with live previews of the colors. You can
choose between light and dark themes and search by theme name by just typing a
few characters from the name.
The kitten maintains a list of recently used themes to allow quick switching.
@@ -24,14 +24,15 @@ If you want to restore the colors to default, you can do so by choosing the
.. versionadded:: 0.23.0
The themes kitten
How it works
----------------
A theme in kitty is just a :file:`.conf` file containing kitty settings.
When you select a theme, the kitten simply copies the :file:`.conf` file
to :file:`~/.config/kitty/current-theme.conf` and adds an include for
:file:`current-theme.conf` to :file:`kitty.conf`. It also comments out
any existing color settings in :file:`kitty.conf` so they do not interfere.
:file:`current-theme.conf` to :file:`kitty.conf`. It also comments out any
existing color settings in :file:`kitty.conf` so they do not interfere.
Once that's done, the kitten sends kitty a signal to make it reload its config.
@@ -39,9 +40,9 @@ Using your own themes
-----------------------
You can also create your own themes as :file:`.conf` files. Put them in the
:file:`themes` sub-directory of the kitty config directory, usually,
:file:`~/.config/kitty/themes` and the kitten will automatically add them to
the list of themes. You can use this to modify the builtin themes, by giving
:file:`themes` sub-directory of the :ref:`kitty config directory <confloc>`,
usually, :file:`~/.config/kitty/themes`. The kitten will automatically add them
to the list of themes. You can use this to modify the builtin themes, by giving
the conf file the name :file:`Some theme name.conf` to override the builtin
theme of that name. Note that after doing so you have to run the kitten and
choose that theme once for your changes to be applied.
@@ -52,13 +53,13 @@ Contributing new themes
If you wish to contribute a new theme to the kitty theme repository, start by
going to the `kitty-themes <https://github.com/kovidgoyal/kitty-themes>`__
repository. `Fork it
<https://docs.github.com/en/get-started/quickstart/fork-a-repo>`_, and use the
repository. `Fork it
<https://docs.github.com/en/get-started/quickstart/fork-a-repo>`__, and use the
file :download:`template.conf
<https://github.com/kovidgoyal/kitty-themes/raw/master/template.conf>` as a
template when creating your theme. Once you are satisfied with how it looks,
`submit a pull request
<https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request>`_
<https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request>`__
to have your theme merged into the `kitty-themes
<https://github.com/kovidgoyal/kitty-themes>`__ repository, which will make it
available in this kitten automatically.
@@ -67,12 +68,12 @@ available in this kitten automatically.
Changing the theme non-interactively
---------------------------------------
You can specify the theme name as an argument when invoking the kitten
to have it change to that theme instantly. For example::
You can specify the theme name as an argument when invoking the kitten to have
it change to that theme instantly. For example::
kitty +kitten themes --reload-in=all Dimmed Monokai
Will change the theme to ``Dimmed Monokai`` in all running kitty
instances. See below for more details on non-interactive operation.
Will change the theme to ``Dimmed Monokai`` in all running kitty instances. See
below for more details on non-interactive operation.
.. include:: ../generated/cli-kitten-themes.rst

View File

@@ -14,16 +14,16 @@ etc. Anywhere you have a terminal device, you can transfer files.
:alt: The transfer kitten at work
This kitten supports transferring entire directory trees, preserving soft and
hard links, file permissions, times, etc. It even supports the rsync_
protocol to transfer only changes to large files.
hard links, file permissions, times, etc. It even supports the rsync_ protocol
to transfer only changes to large files.
.. seealso:: See the :doc:`remote_file` kitten
.. note::
This kitten (which practically means kitty) must be installed on the other
machine as well. If that is not possible you can use the :doc:`remote_file`
kitten instead. Or write your own script to use the underlying :doc:`file transfer
protocol </file-transfer-protocol>`.
kitten instead. Or write your own script to use the underlying
:doc:`file transfer protocol </file-transfer-protocol>`.
.. versionadded:: 0.24.0
@@ -32,7 +32,8 @@ Basic usage
---------------
In what follows, the *local computer* is the computer running this kitten and
the *remote computer* is the computer connected to the other end of the TTY pipe.
the *remote computer* is the computer connected to the other end of the TTY
pipe.
To send a file from the local computer to the remote computer, simply run::
@@ -42,7 +43,7 @@ You will be prompted by kitty for confirmation on allowing the transfer, and if
you grant permission, the file will be copied.
Similarly, to get a file from the remote computer to the local computer, use
the :option:`kitty +kitten transfer --direction` option::
the :option:`--direction <kitty +kitten transfer --direction>` option::
kitty +kitten transfer --direction=receive /path/to/remote/file /path/to/destination/on/local/computer
@@ -58,25 +59,25 @@ the fact that you are copying multiple things) it is good practice to always
use a trailing slash when the destination is supposed to be a directory.
Also, when transferring multiple files/directories it is a good idea to
use the :option:`kitty +kitten transfer --confirm-paths` option which will give
you an opportunity to review and confirm the files that will be touched.
use the :option:`--confirm-paths <kitty +kitten transfer --confirm-paths>`
option which will give you an opportunity to review and confirm the files that
will be touched.
Avoiding the confirmation prompt
------------------------------------
Normally, when you start a file transfer kitty will prompt you for
confirmation. This is to ensure that hostile programs running on a remote
machine cannot read/write files on your computer without your permission.
If the remote machine is trusted and the connection between your computer
and the remote machine is secure, then you can disable the confirmation prompt
by:
Normally, when you start a file transfer kitty will prompt you for confirmation.
This is to ensure that hostile programs running on a remote machine cannot
read/write files on your computer without your permission. If the remote machine
is trusted and the connection between your computer and the remote machine is
secure, then you can disable the confirmation prompt by:
#. Setting the :opt:`file_transfer_confirmation_bypass` option to some
password.
#. Setting the :opt:`file_transfer_confirmation_bypass` option to some password.
#. When invoking the kitten use the :option:`kitty +kitten transfer --permissions-bypass`
to supply the password you set in step one.
#. When invoking the kitten use the :option:`--permissions-bypass
<kitty +kitten transfer --permissions-bypass>` to supply the password you set
in step one.
.. warning:: Using a password to bypass confirmation means any software running
on the remote machine could potentially learn that password and use it to
@@ -89,9 +90,10 @@ Delta transfers
-----------------------------------
This kitten has the ability to use the rsync_ protocol to only transfer the
differences between files. To turn it on use the :option:`kitty +kitten
transfer --transmit-deltas` option. Note that this will actually be slower when
transferring small files because of round trip overhead, so use with care.
differences between files. To turn it on use the :option:`--transmit-deltas
<kitty +kitten transfer --transmit-deltas>` option. Note that this will actually
be slower when transferring small files because of round trip overhead, so use
with care.
.. include:: ../generated/cli-kitten-transfer.rst

View File

@@ -1,27 +1,29 @@
Unicode input
================
You can input unicode characters by name, hex code, recently used and even an editable favorites list.
Press :sc:`input_unicode_character` to start the unicode input widget, shown below.
You can input Unicode characters by name, hex code, recently used and even an
editable favorites list. Press :sc:`input_unicode_character` to start the
unicode input kitten, shown below.
.. figure:: ../screenshots/unicode.png
:alt: A screenshot of the unicode input widget
:alt: A screenshot of the unicode input kitten
:align: center
:width: 100%
A screenshot of the unicode input widget
A screenshot of the unicode input kitten
In :guilabel:`Code` mode, you enter a unicode character by typing in the hex code for the
character and pressing enter, for example, type in ``2716`` and press enter to get
. You can also choose a character from the list of recently used characters by
typing a leading period and then the two character index and pressing Enter.
The up and down arrow keys can be used to choose the previous and next unicode
symbol respectively.
In :guilabel:`Code` mode, you enter a Unicode character by typing in the hex
code for the character and pressing :kbd:`Enter`. For example, type in ``2716``
and press :kbd:`Enter` to get ````. You can also choose a character from the
list of recently used characters by typing a leading period ``.`` and then the
two character index and pressing :kbd:`Enter`.
The :kbd:`Up` and :kbd:`Down` arrow keys can be used to choose the previous and
next Unicode symbol respectively.
In :guilabel:`Name` mode you instead type words from the character name and use
the arrow keys/tab to select the character from the displayed matches. You can
also type a space followed by a period and the index for the match if you don't
like to use arrow keys.
the :kbd:`ArrowKeys` / :kbd:`Tab` to select the character from the displayed
matches. You can also type a space followed by a period and the index for the
match if you don't like to use arrow keys.
You can switch between modes using either the keys :kbd:`F1` ... :kbd:`F4` or
:kbd:`Ctrl+1` ... :kbd:`Ctrl+4` or by pressing :kbd:`Ctrl+[` and :kbd:`Ctrl+]`

View File

@@ -20,8 +20,8 @@ Extend with 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.
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>`
@@ -33,8 +33,8 @@ Some prominent kittens:
images
:doc:`Unicode Input <kittens/unicode_input>`
Easily input arbitrary unicode characters in |kitty| by name or hex code.
:doc:`Unicode input <kittens/unicode_input>`
Easily input arbitrary Unicode characters in |kitty| by name or hex code.
:doc:`Hints <kittens/hints>`
@@ -48,29 +48,31 @@ Some prominent kittens:
:doc:`Transfer files <kittens/transfer>`
Transfer files and directories seamlessly and easily from remote machines over your existing
SSH sessions with a simple command.
Transfer files and directories seamlessly and easily from remote machines
over your existing SSH sessions with a simple command.
:doc:`Hyperlinked grep <kittens/hyperlinked_grep>`
Search your files using `ripgrep <https://github.com/BurntSushi/ripgrep>`_
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.
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>`.
Type in one :term:`kitty window <window>` and have it broadcast to all (or a
subset) of other :term:`kitty windows <window>`.
:doc:`SSH <kittens/ssh>`
SSH with automatic shell integration, connection re-use for low latency and easy cloning
of local shell and editor configuration to the remote machine.
SSH with automatic :ref:`shell integration <shell_integration>`, connection
re-use for low latency and easy cloning of local shell and editor
configuration to the remote host.
:doc:`Panel <kittens/panel>`
Draw a GPU accelerated dock panel on your desktop showing the output
from an arbitrary terminal program.
Draw a GPU accelerated dock panel on your desktop showing the output from an
arbitrary terminal program.
:doc:`Clipboard <kittens/clipboard>`

View File

@@ -5,22 +5,21 @@ The :command:`launch` command
|kitty| has a :code:`launch` action that can be used to run arbitrary programs
in new windows/tabs. It can be mapped to user defined shortcuts in kitty.conf.
It is very powerful and allows sending the contents of
the current window to the launched program, as well as many other options.
in new windows/tabs. It can be mapped to user defined shortcuts in
:file:`kitty.conf`. It is very powerful and allows sending the contents of the
current window to the launched program, as well as many other options.
In the simplest form, you can use it to open a new kitty window running the
shell, as shown below::
map f1 launch
To run a different program simply pass the command line as arguments to
launch::
To run a different program simply pass the command line as arguments to launch::
map f1 launch vim path/to/some/file
To open a new window with the same working directory as the currently
active window::
To open a new window with the same working directory as the currently active
window::
map f1 launch --cwd=current
@@ -30,9 +29,10 @@ To open the new window in a new tab::
To run multiple commands in a shell, use::
map f1 launch sh -c "ls && zsh"
map f1 launch sh -c "ls && exec zsh"
To pass the contents of the current screen and scrollback to the started process::
To pass the contents of the current screen and scrollback to the started
process::
map f1 launch --stdin-source=@screen_scrollback less
@@ -46,16 +46,16 @@ There are many more powerful options, refer to the complete list below.
map f1 launch_tab vim
map f2 launch_tab emacs
The :kbd:`F1` key will now open vim in a new tab with the current windows
working directory
The :kbd:`F1` key will now open :program:`vim` in a new tab with the current
windows working directory.
The piping environment
--------------------------
When using :option:`launch --stdin-source`, the program to which the data is
piped has a special environment variable declared, :envvar:`KITTY_PIPE_DATA` whose
contents are::
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}
@@ -73,33 +73,33 @@ the command line:
``@selection``
replaced by the currently selected text
Replaced by the currently selected text.
``@active-kitty-window-id``
replaced by the id of the currently active kitty window
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
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
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
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
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
Replaced by the current cursor y position with 1 being the topmost cell.
``@first-line-on-screen``
replaced by the first line on screen. Can be used for pager positioning.
Replaced by the first line on screen. Can be used for pager positioning.
``@last-line-on-screen``
replaced by the last line on screen. Can be used for pager positioning.
Replaced by the last line on screen. Can be used for pager positioning.
For example::
@@ -112,44 +112,51 @@ For example::
Watching launched windows
---------------------------
The :option:`launch --watcher` option allows you to specify python functions
The :option:`launch --watcher` option allows you to specify Python functions
that will be called at specific events, such as when the window is resized or
closed. Simply specify the path to a python module that specifies callback
closed. Simply specify the path to a Python module that specifies callback
functions for the events you are interested in, for example:
.. code-block:: python
def on_resize(boss, window, data):
from typing import Any, Dict
from kitty.boss import Boss
from kitty.window import Window
def on_resize(boss: Boss, window: Window, data: Dict[str, Any]) -> None:
# Here data will contain old_geometry and new_geometry
def on_focus_change(boss, window, data):
def on_focus_change(boss: Boss, window: Window, data: Dict[str, Any])-> None:
# Here data will contain focused
def on_close(boss, window, data):
def on_close(boss: Boss, window: Window, data: Dict[str, Any])-> None:
# called when window is closed, typically when the program running in
# it exits.
Every callback is passed a reference to the global ``Boss`` object as well as
the ``Window`` object the action is occurring on. The ``data`` object is
a dict that contains event dependent data. Some useful methods and attributes
for the ``Window`` object are: ``as_text(as_ans=False, add_history=False,
the ``Window`` object the action is occurring on. The ``data`` object is a dict
that contains event dependent data. Some useful methods and attributes for the
``Window`` object are: ``as_text(as_ans=False, add_history=False,
add_wrap_markers=False, alternate_screen=False)`` with which you can get the
contents of the window and its scrollback buffer. Similarly,
``window.child.pid`` is the PID of the processes that was launched
in the window and ``window.id`` is the internal kitty ``id`` of the
window.
in the window and ``window.id`` is the internal kitty ``id`` of the window.
Finding executables
-----------------------
When you specify a command to run as just a name rather than an absolute path,
it is searched for in the system-wide ``PATH`` environment variable. Note that
this **may not** be the value of ``PATH`` inside a shell, as shell startup scripts
often change the value of this variable. If it is not found there, then a
system specific list of default paths is searched. If it is still not found,
then your shell is run and the value of ``PATH`` inside the shell is used.
it is searched for in the system-wide :envvar:`PATH` environment variable. Note
that this **may not** be the value of :envvar:`PATH` inside a shell, as shell
startup scripts often change the value of this variable. If it is not found
there, then a system specific list of default paths is searched. If it is still
not found, then your shell is run and the value of :envvar:`PATH` inside the
shell is used.
See :opt:`exe_search_path` for details and how to control this.
Syntax reference

View File

@@ -10,7 +10,8 @@ other in arbitrary arrangements, based on *Layouts*, see below for examples:
:align: center
:width: 100%
Screenshot, showing vim, tig and git running in |kitty| with the 'Tall' layout
Screenshot, showing :program:`vim`, :program:`tig` and :program:`git`
running in |kitty| with the *Tall* layout
.. figure:: screenshots/splits.png
@@ -18,21 +19,22 @@ other in arbitrary arrangements, based on *Layouts*, see below for examples:
:align: center
:width: 100%
Screenshot, showing windows with arbitrary arrangement in the 'Splits'
Screenshot, showing windows with arbitrary arrangement in the *Splits*
layout
There are many different layouts available. They are all enabled by default,
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.
There are many different layouts available. They are all enabled by default, you
can switch layouts using :ac:`next_layout` (:sc:`next_layout` by default). 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.
The Stack Layout
------------------
This is the simplest layout it displays a single window using all available
space, other windows are hidden behind it. It has no options::
This is the simplest layout. It displays a single window using all available
space, other windows are hidden behind it. This layout has no options::
enabled_layouts stack
@@ -40,14 +42,14 @@ space, other windows are hidden behind it. It has no options::
The Tall Layout
------------------
Displays one (or optionally more) full height windows on the left half of the
Displays one (or optionally more) full-height windows on the left half of the
screen. Remaining windows are tiled vertically on the right half of the screen.
There are options to control how the screen is split horizontally ``bias``
(an integer between ``10`` and ``90``) and options to control how many
full-height windows there are ``full_size`` (a positive integer). The
``mirrored`` option when set to ``true`` will cause the short windows to be
on the left side of the screen instead of the right. The syntax
for the options is shown below::
``mirrored`` option when set to ``true`` will cause the full-height windows to
be on the right side of the screen instead of the left. The syntax
for the options is::
enabled_layouts tall:bias=50;full_size=1;mirrored=false
@@ -65,24 +67,32 @@ for the options is shown below::
│ │ │
└──────────────┴───────────────┘
In addition, you can map keys to increase or decrease the number of full size
windows, for example::
In addition, you can map keys to increase or decrease the number of full-height
windows, or toggle the mirrored setting, for example::
map ctrl+[ layout_action decrease_num_full_size_windows
map ctrl+] layout_action increase_num_full_size_windows
map ctrl+/ layout_action mirror toggle
map ctrl+y layout_action mirror true
map ctrl+n layout_action mirror false
You can also map a key to change the bias by providing a list of percentages
and it will rotate through the list as you press the key. If you only provide
one number it'll toggle between that percentage and 50, for example::
map ctrl+. layout_action bias 50 62 70
map ctrl+, layout_action bias 62
The Fat Layout
----------------
Displays one (or optionally more) full width windows on the top half of the
screen. Remaining windows are tiled horizontally on the bottom half of the screen.
There are options to control how the screen is split vertically ``bias``
Displays one (or optionally more) full-width windows on the top half of the
screen. Remaining windows are tiled horizontally on the bottom half of the
screen. There are options to control how the screen is split vertically ``bias``
(an integer between ``10`` and ``90``) and options to control how many
full-height windows there are ``full_size`` (a positive integer). The
``mirrored`` option when set to ``true`` will cause the narrow windows to be
on the top of the screen instead of the bottom. The syntax for the options is
shown below::
full-width windows there are ``full_size`` (a positive integer). The
``mirrored`` option when set to ``true`` will cause the full-width windows to be
on the bottom of the screen instead of the top. The syntax for the options is::
enabled_layouts fat:bias=50;full_size=1;mirrored=false
@@ -100,11 +110,15 @@ shown below::
└─────────┴──────────┴─────────┘
This layout also supports the same layout actions as the *Tall* layout, shown above.
The Grid Layout
--------------------
Display windows in a balanced grid with all windows the same size except the
last column if there are not enough windows to fill the grid. Has no options::
last column if there are not enough windows to fill the grid. This layout has no
options::
enabled_layouts grid
@@ -132,20 +146,20 @@ define a few extra key bindings in :file:`kitty.conf`::
# Create a new window splitting the space used by the existing one so that
# the two windows are placed one above the other
map F5 launch --location=hsplit
map f5 launch --location=hsplit
# Create a new window splitting the space used by the existing one so that
# the two windows are placed side by side
map F6 launch --location=vsplit
map f6 launch --location=vsplit
# Create a new window splitting the space used by the existing one so that
# the two windows are placed side by side if the existing window is wide or
# one above the other if the existing window is tall.
map F4 launch --location=split
map f4 launch --location=split
# Rotate the current split, chaging its split axis from vertical to
# horizontal or vice versa
map F7 layout_action rotate
map f7 layout_action rotate
# Move the active window in the indicated direction
map shift+up move_window up
@@ -153,22 +167,28 @@ define a few extra key bindings in :file:`kitty.conf`::
map shift+right move_window right
map shift+down move_window down
# Move the active window to the indicated screen edge
map ctrl+shift+up layout_action move_to_screen_edge top
map ctrl+shift+left layout_action move_to_screen_edge left
map ctrl+shift+right layout_action move_to_screen_edge right
map ctrl+shift+down layout_action move_to_screen_edge bottom
# Switch focus to the neighboring window in the indicated direction
map ctrl+left neighboring_window left
map ctrl+right neighboring_window right
map ctrl+up neighboring_window up
map ctrl+down neighboring_window down
Windows can be resized using :ref:`window_resizing`. You can swap the windows
Windows can be resized using :ref:`window_resizing`. You can swap the windows
in a split using the ``rotate`` action with an argument of ``180`` and rotate
and swap with an argument of ``270``.
This layout takes one option, ``split_axis`` that controls whether new windows
are placed into vertical or horizontal splits when a ``--location`` is not
specified. A value of ``horizontal`` (same as ``--location=vsplit``)
means when a new split is created the two windows will be placed side by side
and a value of ``vertical`` (same as ``--location=hsplit``) means the two
windows will be placed one on top of the other. By default::
are placed into vertical or horizontal splits when a :option:`--location <launch
--location>` is not specified. A value of ``horizontal`` (same as
``--location=vsplit``) means when a new split is created the two windows will be
placed side by side and a value of ``vertical`` (same as ``--location=hsplit``)
means the two windows will be placed one on top of the other. By default::
enabled_layouts splits:split_axis=horizontal
@@ -193,7 +213,7 @@ windows will be placed one on top of the other. By default::
The Horizontal Layout
------------------------
All windows are shown side by side. Has no options::
All windows are shown side by side. This layout has no options::
enabled_layouts horizontal
@@ -213,7 +233,7 @@ All windows are shown side by side. Has no options::
The Vertical Layout
-----------------------
All windows are shown one below the other. Has no options::
All windows are shown one below the other. This layout has no options::
enabled_layouts vertical
@@ -239,14 +259,14 @@ Resizing windows
You can resize windows inside layouts. Press :sc:`start_resizing_window` (also
:kbd:`⌘+r` on macOS) to enter resizing mode and follow the on-screen
instructions. In a given window layout only some operations may be possible
for a particular window. For example, in the Tall layout you can make the first
instructions. In a given window layout only some operations may be possible for
a particular window. For example, in the *Tall* layout you can make the first
window wider/narrower, but not taller/shorter. Note that what you are resizing
is actually not a window, but a row/column in the layout, all windows in that
row/column will be resized.
You can also define shortcuts in :file:`kitty.conf` to make the active window
wider, narrower, taller, or shorter by mapping to the ``resize_window``
wider, narrower, taller, or shorter by mapping to the :ac:`resize_window`
action, for example::
map ctrl+left resize_window narrower
@@ -256,22 +276,21 @@ action, for example::
# reset all windows in the tab to default sizes
map ctrl+home resize_window reset
The ``resize_window`` action has a second, optional argument to control
The :ac:`resize_window` action has a second optional argument to control
the resizing increment (a positive integer that defaults to 1).
Some layouts take options to control their behavior. For example, the ``fat``
and ``tall`` layouts accept the ``bias`` and ``full_size`` options to control
how the available space is split up.
To specify the option, in :opt:`kitty.conf <enabled_layouts>` use::
Some layouts take options to control their behavior. For example, the *Fat*
and *Tall* layouts accept the ``bias`` and ``full_size`` options to control
how the available space is split up. To specify the option, in :opt:`kitty.conf
<enabled_layouts>` use::
enabled_layouts tall:bias=70;full_size=2
This will have ``2`` instead of a single tall window, that occupy ``70%``
instead of ``50%`` of available width. ``bias`` can be any number between 10
and 90.
instead of ``50%`` of available width. ``bias`` can be any number between ``10``
and ``90``.
Writing a new layout only requires about two hundred lines of code, so if there
is some layout you want, take a look at one of the existing layouts in the
`layout <https://github.com/kovidgoyal/kitty/tree/master/kitty/layout>`_
`layout <https://github.com/kovidgoyal/kitty/tree/master/kitty/layout>`__
package and submit a pull request!

View File

@@ -9,12 +9,12 @@ 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`::
Suppose we want to be able to highlight the word :code:`ERROR` in the current
window. Add the following to :file:`kitty.conf`::
map f1 toggle_marker text 1 ERROR
Now when you press :kbd:`F1` all instances of the word :code:`ERROR` will be
Now when you press :kbd:`F1`, all instances of the word :code:`ERROR` will be
highlighted. To turn off the highlighting, press :kbd:`F1` again.
If you want to make it case-insensitive, use::
@@ -39,41 +39,40 @@ can control the colors used for these groups in :file:`kitty.conf` with::
.. note::
For performance reasons, matching is done per line only, and only when that line is
altered in any way. So you cannot match text that stretches across multiple
lines.
For performance reasons, matching is done per line only, and only when that
line is altered in any way. So you cannot match text that stretches across
multiple lines.
Creating markers dynamically
---------------------------------
If you want to create markers dynamically rather than pre-defining them in
:file:`kitty.conf` you can do so as follows::
:file:`kitty.conf`, you can do so as follows::
map f1 create_marker
map f2 remove_marker
Then pressing :kbd:`F1` will allow you to enter the marker definition and set
it and pressing :kbd:`F2` will remove the marker. ``create_marker`` accepts
the same syntax as ``toggle_marker`` above. Note that while creating
markers, the prompt has history so you can easily re-use previous marker
expressions.
Then pressing :kbd:`F1` will allow you to enter the marker definition and set it
and pressing :kbd:`F2` will remove the marker. :ac:`create_marker` accepts the
same syntax as :ac:`toggle_marker` above. Note that while creating markers, the
prompt has history so you can easily re-use previous marker expressions.
You can also use the facilities for :doc:`remote-control` to dynamically
add/remove markers.
You can also use the facilities for :doc:`remote-control` to dynamically add or
remove markers.
Scrolling to marks
--------------------
kitty has an action to scroll to the next line that contains a mark. You can
use it by mapping it to some shortcut in :file:`kitty.conf`::
kitty has a :ac:`scroll_to_mark` action to scroll to the next line that contains
a mark. You can use it by mapping it to some shortcut in :file:`kitty.conf`::
map ctrl+p scroll_to_mark prev
map ctrl+n scroll_to_mark next
Then pressing :kbd:`ctrl+p` will scroll to the first line in the scrollback
buffer above the current top line that contains a mark. Pressing :kbd:`ctrl+n`
Then pressing :kbd:`Ctrl+P` will scroll to the first line in the scrollback
buffer above the current top line that contains a mark. Pressing :kbd:`Ctrl+N`
will scroll to show the first line below the current last line that contains
a mark. If you wish to jump to a mark of a specific type, you can add that to
the mapping::
@@ -86,26 +85,26 @@ Which will scroll only to marks of type 1.
The full syntax for creating marks
-------------------------------------
The syntax of the :code:`toggle_marker` command is::
The syntax of the :ac:`toggle_marker` action is::
toggle_marker <marker-type> <specification>
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:
Arbitrary marker functions
-----------------------------
You can create your own marker functions. Create a python file named
:file:`mymarker.py` and in it create a :code:`marker` function. This
function receives the text of the line as input and must yield three numbers,
You can create your own marker functions. Create a Python file named
:file:`mymarker.py` and in it create a :code:`marker` function. This function
receives the text of the line as input and must yield three numbers,
the starting character position, the ending character position and the mark
group (1-3). For example:
@@ -122,6 +121,7 @@ Save this file somewhere and in :file:`kitty.conf`, use::
map f1 toggle_marker function /path/to/mymarker.py
If you save the file in the kitty config directory, you can use::
If you save the file in the :ref:`kitty config directory <confloc>`, you can
use::
map f1 toggle_marker function mymarker.py

View File

@@ -1,15 +1,14 @@
Scripting the mouse click
======================================================
|kitty| has support for `terminal hyperlinks
<https://gist.github.com/egmontkob/eb114294efbcd5adb1944c9f3cb5feda>`_. These
are generated by many terminal programs, such as ``ls``, ``gcc``, ``systemd``,
:ref:`tool_mdcat`, etc. You can customize exactly what happens when clicking on these
hyperlinks in |kitty|.
|kitty| has support for :term:`terminal hyperlinks <hyperlinks>`. These are
generated by many terminal programs, such as ``ls``, ``gcc``, ``systemd``,
: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
the file :file:`~/.config/kitty/open-actions.conf` with the following:
You can tell kitty to take arbitrarily many, complex actions when a link is
clicked. Let us illustrate with some examples, first. Create the file
:file:`~/.config/kitty/open-actions.conf` with the following:
.. code:: conf
@@ -22,6 +21,13 @@ Now, run ``ls --hyperlink=auto`` in kitty and click on the filename of an
image, holding down :kbd:`ctrl+shift`. It will be opened over the current
window. Press any key to close it.
.. note::
The :program:`ls` comes with macOS does not support hyperlink, you need to
install `GNU Coreutils <https://www.gnu.org/software/coreutils/>`__. If you
install it via `Homebrew <https://formulae.brew.sh/formula/coreutils>`__, it
will be :program:`gls`.
Each entry in :file:`open-actions.conf` consists of one or more
:ref:`matching_criteria`, such as ``protocol`` and ``mime`` and one or more
``action`` entries. In the example above kitty uses the :doc:`launch <launch>`
@@ -29,8 +35,8 @@ action which can be used to run external programs. Entries are separated by
blank lines.
Actions are very powerful, anything that you can map to a key combination in
`kitty.conf` can be used as an action. You can specify more than one action per
entry if you like, for example:
:file:`kitty.conf` can be used as an action. You can specify more than one
action per entry if you like, for example:
.. code:: conf
@@ -58,9 +64,20 @@ some special variables, documented below:
``FRAGMENT``
The fragment (unquoted), if any of the URL or the empty string.
``URL_PATH``
The path, query and fragment portions of the URL, without any
unquoting.
``EDITOR``
The terminal based text editor. The configured :opt:`editor` in
:file:`kitty.conf` is preferred.
``SHELL``
The path to the shell. The configured :opt:`shell` in :file:`kitty.conf` is
preferred, without arguments.
.. note::
You can use the :opt:`action_alias` option just as in kitty.conf to
You can use the :opt:`action_alias` option just as in :file:`kitty.conf` to
define aliases for frequently used actions.
@@ -77,7 +94,7 @@ lines. The various available criteria are:
``protocol``
A comma separated list of protocols, for example: ``http, https``. If
absent, there is no constraint on protocol
absent, there is no constraint on protocol.
``url``
A regular expression that must match against the entire (unquoted) URL
@@ -88,11 +105,13 @@ lines. The various available criteria are:
``mime``
A comma separated list of MIME types, for example: ``text/*, image/*,
application/pdf``. You can add MIME types to kitty by creating the
: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``. Note that the MIME type for directories is ``inode/directory``.
application/pdf``. You can add MIME types to kitty by creating a file named
:file:`mime.types` in the :ref:`kitty configuration directory <confloc>`.
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``. Note that the MIME type for directories is
``inode/directory``. MIME types are detected based on file extension, not
file contents.
``ext``
A comma separated list of file extensions, for example: ``jpeg, tar.gz``
@@ -116,9 +135,10 @@ URLs onto the kitty dock icon to open them with kitty. The default actions are:
These actions can also be executed from the command line by running::
open -a kitty.app file_or_url ... (on macOS only)
or
kitty +open file_or_url ...
kitty +open file_or_url another_url ...
# macOS only
open -a kitty.app file_or_url another_url ...
Since macOS lacks an official interface to set default URL scheme handlers,
kitty has a command you can use for it. The first argument for is the URL
@@ -133,36 +153,10 @@ defaults to kitty, if not specified. For example:
kitty +runpy 'from kitty.fast_data_types import cocoa_set_url_handler; import sys; cocoa_set_url_handler(*sys.argv[1:]); print("OK")' xyz someapp.bundle.identifier
You can customize these actions by creating a :file:`launch-actions.conf` file
in the kitty config directory, just like
the :file:`open-actions.conf` file above. For example:
in the :ref:`kitty config directory <confloc>`, just like the
:file:`open-actions.conf` file above. For example:
.. code:: conf
# Open script files based on their shebangs
protocol file
ext sh,command,tool
action launch --hold --type=os-window kitty +shebang $FILE_PATH {SHELL}
# Open shell specific script files
protocol file
ext fish,bash,zsh
action launch --hold --type=os-window kitty +shebang $FILE_PATH __ext__
# Open directories
protocol file
mime inode/directory
action launch --type=os-window --cwd $FILE_PATH
# Open text files without fragments in the editor
protocol file
mime text/*
action launch --type=os-window $EDITOR $FILE_PATH
# Open image files with icat
protocol file
mime image/*
action launch --type=os-window kitty +kitten icat --hold $FILE_PATH
# Open ssh URLs with ssh command
protocol ssh
action launch --type=os-window ssh $URL
.. literalinclude:: ../kitty/open_actions.py
:language: conf
:start-at: # Open script files
:end-before: '''.splitlines()))

View File

@@ -4,23 +4,22 @@ 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).
|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.
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.
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
@@ -28,10 +27,10 @@ relatively little effort.
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>`.
|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:
@@ -51,17 +50,26 @@ windows automatically, resizing and moving them as needed. You can create a new
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
* **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
* **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
* **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
particular layouts, and choose which layouts you want to enable, see
:ref:`conf-kitty-shortcuts.layout` for examples. The first layout listed in
:opt:`enabled_layouts` becomes the default layout.
@@ -77,11 +85,11 @@ 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
programs called :doc:`kittens <kittens_intro>`. These can be 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
: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
:doc:`viewing images <kittens/icat>` or :doc:`diffing files with image support
<kittens/diff>`.
You can :doc:`create your own kittens to scratch your own itches
@@ -101,9 +109,9 @@ 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.
change window layout, get text from one window and send text to another, etc.
The possibilities are endless. See the :doc:`tutorial <remote-control>` to get
started.
.. toctree::
:hidden:
@@ -117,10 +125,9 @@ 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:
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`. An example, showing all available commands:
.. code-block:: session
@@ -130,37 +137,46 @@ For example:
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
# 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)
# Create a new tab
# The part after new_tab is the optional tab title 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
enabled_layouts tall,stack
# Set the current layout
layout stack
launch zsh
# Create a new OS window
# Any definitions specified before the first new_os_window will apply to first 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
# Set new window size to 80x24 cells
os_window_size 80c 24c
# Set the --class for the new OS window
os_window_class mywindow
launch sh
# Make the current window the active (focused) window
# Resize the current window (see the resize_window action for details)
resize_window wider 2
# Make the current window the active (focused) window in its tab
focus
# Make the current OS Window the globally active window (not supported on Wayland)
focus_os_window
launch emacs
.. note::
The :doc:`launch <launch>` command when used in a session file
cannot create new OS windows, or tabs.
The :doc:`launch <launch>` command when used in a session file cannot create
new OS windows, or tabs.
.. note::
Environment variables of the for :code:`${NAME}` or :code:`$NAME` are
expanded in the session file, except in the *arguments* (not options) to the
launch command.
Creating tabs/windows
@@ -182,25 +198,25 @@ 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
* 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
* 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
* Selecting text automatically copies it to the primary clipboard (on platforms
with a primary clipboard).
* You can right click while holding :kbd:`ctrl+shift` to open the output
of the clicked on command in a pager (requires :ref:`shell_integration`)
* You can select text with kitty even when a terminal program has grabbed
the mouse by holding down the :kbd:`shift` key
* You can middle click to paste from the primary clipboard (on platforms with a
primary clipboard).
* You can right click while holding :kbd:`Ctrl+Shift` to open the output of the
clicked on command in a pager (requires :ref:`shell_integration`)
* You can select text with kitty even when a terminal program has grabbed the
mouse by holding down the :kbd:`Shift` key
All these actions can be customized in :file:`kitty.conf` as described
:ref:`here <conf-kitty-mouse.mousemap>`.
You can also customize what happens when clicking on :term:`hyperlinks` in kitty,
having it open files in your editor, download remote files, open things
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>`.
@@ -214,12 +230,11 @@ 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`.
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 comein 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:
@@ -228,29 +243,29 @@ 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.
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` shortcut, which will open the scrollback buffer in
your favorite pager program (which is :program:`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::
arbitrary, command running in a new :term:`window`, :term:`tab` or
:term:`overlay`. For example::
map f1 launch --stdin-source=@screen_scrollback --stdin-add-formatting less +G -R
Would open the scrollback buffer in a new :term:`window` when you press the :kbd:`F1`
key. See :sc:`show_scrollback <show_scrollback>` for details.
Would open the scrollback buffer in a new :term:`window` when you press the
:kbd:`F1` key. See :sc:`show_scrollback <show_scrollback>` for details.
If you want to use it with an editor such as vim to get more powerful features,
you can see tips for doing so, in :iss:`this thread <719>`.
If you want to use it with an editor such as :program:`vim` to get more powerful
features, you can see tips for doing so, in :iss:`this thread <719>`.
If you wish to store very large amounts of scrollback to view using the piping or
:sc:`show_scrollback <show_scrollback>` features, you can use the
If you wish to store very large amounts of scrollback to view using the piping
or :sc:`show_scrollback <show_scrollback>` features, you can use the
:opt:`scrollback_pager_history_size` option.
@@ -258,8 +273,8 @@ Integration with shells
---------------------------------
kitty has the ability to integrate closely within common shells, such as `zsh
<https://www.zsh.org/>`_, `fish <https://fishshell.com>`_ and `bash
<https://www.gnu.org/software/bash/>`_ to enable features such as jumping to
<https://www.zsh.org/>`__, `fish <https://fishshell.com>`__ and `bash
<https://www.gnu.org/software/bash/>`__ to enable features such as jumping to
previous prompts in the scrollback, viewing the output of the last command in
:program:`less`, using the mouse to move the cursor while editing prompts, etc.
See :doc:`shell-integration` for details.
@@ -274,17 +289,16 @@ See :doc:`shell-integration` for details.
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`::
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.
names are arbitrary strings, so you can define as many such buffers as you need.
Marks

View File

@@ -2,30 +2,31 @@ Performance
===================
The main goals for |kitty| performance are user perceived latency while typing
and "smoothness" while scrolling as well as CPU usage. |kitty| tries hard to find
an optimum balance for these. To that end it keeps a cache of each rendered
glyph in video RAM so that font rendering is not a bottleneck. Interaction
with child programs takes place in a separate thread from rendering, to improve
and "smoothness" while scrolling as well as CPU usage. |kitty| tries hard to
find an optimum balance for these. To that end it keeps a cache of each rendered
glyph in video RAM so that font rendering is not a bottleneck. Interaction with
child programs takes place in a separate thread from rendering, to improve
smoothness.
There are two parameters you can tune to adjust the performance. :opt:`repaint_delay`
and :opt:`input_delay`. These control the artificial delays introduced into the
render loop to reduce CPU usage. See :ref:`conf-kitty-performance` for details.
See also the :opt:`sync_to_monitor` option to further decrease latency at the cost
of some `tearing <https://en.wikipedia.org/wiki/Screen_tearing>`_ while scrolling.
There are two config options you can tune to adjust the performance,
:opt:`repaint_delay` and :opt:`input_delay`. These control the artificial delays
introduced into the render loop to reduce CPU usage. See
:ref:`conf-kitty-performance` for details. See also the :opt:`sync_to_monitor`
option to further decrease latency at the cost of some `screen tearing
<https://en.wikipedia.org/wiki/Screen_tearing>`__ while scrolling.
You can generate detailed per-function performance data using `gperftools
<https://github.com/gperftools/gperftools>`_. Build |kitty| with `make
profile`. Run kitty and perform the task you want to analyse, for example,
scrolling a large file with `less`. After you quit, function call statistics
will be printed to `stdout` and you can use tools like *kcachegrind* for more
detailed analysis.
You can generate detailed per-function performance data using
`gperftools <https://github.com/gperftools/gperftools>`__. Build |kitty| with
``make profile``. Run kitty and perform the task you want to analyse, for
example, scrolling a large file with :program:`less`. After you quit, function
call statistics will be printed to STDOUT and you can use tools like
*KCachegrind* for more detailed analysis.
Here are some CPU usage numbers for the task of scrolling a file continuously
in less. The CPU usage is for the terminal process and X together and is
measured using htop. The measurements are taken at the same font and window
size for all terminals on a ``Intel(R) Core(TM) i7-4820K CPU @ 3.70GHz`` CPU
with a ``Advanced Micro Devices, Inc. [AMD/ATI] Cape Verde XT [Radeon HD
Here are some CPU usage numbers for the task of scrolling a file continuously in
:program:`less`. The CPU usage is for the terminal process and X together and is
measured using :program:`htop`. The measurements are taken at the same font and
window size for all terminals on a ``Intel(R) Core(TM) i7-4820K CPU @ 3.70GHz``
CPU with a ``Advanced Micro Devices, Inc. [AMD/ATI] Cape Verde XT [Radeon HD
7770/8760 / R7 250X]`` GPU.
============== =========================
@@ -49,11 +50,11 @@ admittedly biased, eyes).
.. note::
Some people have asked why kitty does not perform better than terminal XXX in
the test of sinking large amounts of data, such as catting a large text
file. The answer is because this is not a goal for kitty. kitty
deliberately throttles input parsing and output rendering to minimize
resource usage while still being able to sink output faster than any real
world program can produce it. Reducing CPU usage, and hence battery drain
while achieving instant response times and smooth scrolling to a human eye
is a far more important goal.
Some people have asked why kitty does not perform better than terminal XXX
in the test of sinking large amounts of data, such as catting a large text
file. The answer is because this is not a goal for kitty. kitty deliberately
throttles input parsing and output rendering to minimize resource usage
while still being able to sink output faster than any real world program can
produce it. Reducing CPU usage, and hence battery drain while achieving
instant response times and smooth scrolling to a human eye is a far more
important goal.

View File

@@ -1,23 +1,24 @@
Terminal protocol extensions
===================================
|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.
|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.
The goal of these extensions is to be as small and unobtrusive as possible,
while filling in some gaps in the existing xterm protocol. In particular, one
of the goals of this specification is explicitly not to "re-imagine" the tty.
The tty should remain what it is -- a device for efficiently processing text
while filling in some gaps in the existing xterm protocol. In particular, one of
the goals of this specification is explicitly not to "re-imagine" the TTY. The
TTY should remain what it is -- a device for efficiently processing text
received as a simple byte stream. Another objective is to only move the minimum
possible amount of extra functionality into the terminal program itself. This
is to make it as easy to implement these protocol extensions as possible,
thereby hopefully encouraging their widespread adoption.
possible amount of extra functionality into the terminal program itself. This 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
<https://github.com/kovidgoyal/kitty/issues>`_ bug tracker.
If you wish to discuss these extensions, propose additions or changes to them,
please do so by opening issues in the `GitHub bug tracker
<https://github.com/kovidgoyal/kitty/issues>`__.
.. toctree::
@@ -31,3 +32,4 @@ please do so by opening issues in the `GitHub
unscroll
color-stack
deccara
clipboard

View File

@@ -9,9 +9,9 @@ Quickstart
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>`.
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.
@@ -25,4 +25,4 @@ and Linux.
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`.
For a tour of kitty's design and features, see the :doc:`overview`.

View File

@@ -7,34 +7,81 @@ form::
<ESC>P@kitty-cmd<JSON object><ESC>\
Where ``<ESC>`` is the byte ``0x1b``. The JSON object has the form::
Where ``<ESC>`` is the byte ``0x1b``. The JSON object has the form:
.. code-block:: json
{
"cmd": "command name",
"version": <kitty version>,
"no_response": <Optional Boolean>,
"payload": <Optional JSON object>,
"version": "<kitty version>",
"no_response": "<Optional Boolean>",
"kitty_window_id": "<Optional value of the KITTY_WINDOW_ID env var>",
"payload": "<Optional JSON object>"
}
The ``version`` above is an array of the form :code:`[0, 14, 2]`. If you are developing a
standalone client, use the kitty version that you are developing against. Using
a version greater than the version of the kitty instance you are talking to,
will cause a failure.
The ``version`` above is an array of the form :code:`[0, 14, 2]`. If you are
developing a standalone client, use the kitty version that you are developing
against. Using a version greater than the version of the kitty instance you are
talking to, will cause a failure.
Set ``no_response`` to ``true`` if you don't want a response from kitty.
The optional payload is a JSON object that is specific to the actual command being sent.
The fields in the object for every command are documented below.
The optional payload is a JSON object that is specific to the actual command
being sent. The fields in the object for every command are documented below.
As a quick example showing how easy to use this protocol is, we will implement
the ``@ ls`` command from the shell using only shell tools. First, run kitty
as::
the ``@ ls`` command from the shell using only shell tools.
First, run kitty as::
kitty -o allow_remote_control=socket-only --listen-on unix:/tmp/test
Now, in a different terminal, you can get the pretty printed ``@ ls`` output
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 .
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 .
There is also the statically compiled stand-alone executable ``kitten``
that can be used for this, available from the `kitty releases
<https://github.com/kovidgoyal/kitty/releases>`__ page::
kitten @ --help
.. _rc_crypto:
Encrypted communication
--------------------------
.. versionadded:: 0.26.0
When using the :opt:`remote_control_password` option communication to the
terminal is encrypted to keep the password secure. A public key is used from
the :envvar:`KITTY_PUBLIC_KEY` environment variable. Currently, only one
encryption protocol is supported. The protocol number is present in
:envvar:`KITTY_PUBLIC_KEY` as ``1``. The key data in this environment variable
is :rfc:`Base-85 <1924>` encoded. The algorithm used is `Elliptic Curve Diffie
Helman <https://en.wikipedia.org/wiki/Elliptic-curve_DiffieHellman>`__ with
the `X25519 curve <https://en.wikipedia.org/wiki/Curve25519>`__. A time based
nonce is used to minimise replay attacks. The original JSON command has the
fields: ``password`` and ``timestamp`` added. The timestamp is the number of
nanoseconds since the epoch, excluding leap seconds. Commands with a timestamp
more than 5 minutes from the current time are rejected. The command is then
encrypted using AES-256-GCM in authenticated encryption mode, with a symmetric
key that is derived from the ECDH key-pair by running the shared secret through
SHA-256 hashing, once. An IV of at least 96 bits of CSPRNG data is used. The
tag for authenticated encryption **must** be at least 128 bits long. The tag
**must** authenticate only the value of the ``encrypted`` field. A new command
is created and transmitted that contains the fields:
.. code-block:: json
{
"version": "<kitty version>",
"iv": "base85 encoded IV",
"tag": "base85 encoded AEAD tag",
"pubkey": "base85 encoded ECDH public key of sender",
"encrypted": "The original command encrypted and base85 encoded"
}
.. include:: generated/rc.rst

View File

@@ -4,9 +4,12 @@ Control kitty from scripts
.. highlight:: sh
|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.
windows, send arbitrary text input to any window, change the title of windows
and tabs, etc.
Let's walk through a few examples of controlling |kitty|.
Tutorial
------------
@@ -14,50 +17,52 @@ Start by running |kitty| as::
kitty -o allow_remote_control=yes -o enabled_layouts=tall
In order for control to work, :opt:`allow_remote_control` must be enabled in
:file:`kitty.conf`. Here we turn it on explicitly at the command line.
In order for control to work, :opt:`allow_remote_control` or
:opt:`remote_control_password` must be enabled in :file:`kitty.conf`. Here we
turn it on explicitly at the command line.
Now, in the new |kitty| window, enter the command::
kitty @ launch --title Output --keep-focus cat
This will open a new window, running the ``cat`` program that will appear next
to the current window.
This will open a new window, running the :program:`cat` program that will appear
next to the current window.
Let's send some text to this new window::
kitty @ send-text --match cmdline:cat Hello, World
This will make ``Hello, World`` show up in the window running the ``cat`` program.
The :option:`kitty @ send-text --match` option is very powerful, it allows selecting windows by their
titles, the command line of the program running in the window, the working
directory of the program running in the window, etc. See ``kitty @ send-text
--help`` for details.
This will make ``Hello, World`` show up in the window running the :program:`cat`
program. The :option:`kitty @ send-text --match` option is very powerful, it
allows selecting windows by their titles, the command line of the program
running in the window, the working directory of the program running in the
window, etc. See :ref:`kitty @ send-text --help <at-send-text>` for details.
More usefully, you can pipe the output of a command running in one window to
another window, for example::
ls | kitty @ send-text --match title:Output --stdin
ls | kitty @ send-text --match 'title:^Output' --stdin
This will show the output of ls in the output window instead of the current
window. You can use this technique to, for example, show the output of running
``make`` in your editor in a different window. The possibilities are endless.
This will show the output of :program:`ls` in the output window instead of the
current window. You can use this technique to, for example, show the output of
running :program:`make` in your editor in a different window. The possibilities
are endless.
You can even have things you type show up in a different window. Run::
kitty @ send-text --match title:Output --stdin
kitty @ send-text --match 'title:^Output' --stdin
And type some text, it will show up in the output window, instead of the current
window. Type ``Ctrl+D`` when you are ready to stop.
window. Type :kbd:`Ctrl+D` when you are ready to stop.
Now, let's open a new tab::
kitty @ launch --type=tab --tab-title "My Tab" --keep-focus bash
This will open a new tab running the bash shell with the title "My Tab".
We can change the title of the tab with::
We can change the title of the tab to "New Title" with::
kitty @ set-tab-title --match title:My New Title
kitty @ set-tab-title --match 'title:^My' New Title
Let's change the title of the current tab::
@@ -65,79 +70,196 @@ Let's change the title of the current tab::
Now lets switch to the newly opened tab::
kitty @ focus-tab --match title:New
kitty @ focus-tab --match 'title:^New'
Similarly, to focus the previously opened output window (which will also switch
back to the old tab, automatically)::
kitty @ focus-window --match title:Output
kitty @ focus-window --match 'title:^Output'
You can get a listing of available tabs and windows, by running::
kitty @ ls
This outputs a tree of data in JSON format. The top level of the tree is all
operating system kitty windows. Each OS window has an id and a list of tabs.
Each tab has its own id, a title and a list of windows. Each window has an id,
title, current working directory, process id (PID) and command-line of the
process running in the window. You can use this information with :option:`kitty @ focus-window --match`
to control individual windows.
:term:`OS windows <os_window>`. Each OS window has an id and a list of
:term:`tabs <tab>`. Each tab has its own id, a title and a list of :term:`kitty
windows <window>`. Each window has an id, title, current working directory,
process id (PID) and command-line of the process running in the window. You can
use this information with :option:`kitty @ focus-window --match` to control
individual windows.
As you can see, it is very easy to control |kitty| using the
``kitty @`` messaging system. This tutorial touches only the
surface of what is possible. See ``kitty @ --help`` for more details.
As you can see, it is very easy to control |kitty| using the ``kitty @``
messaging system. This tutorial touches only the surface of what is possible.
See ``kitty @ --help`` for more details.
Note that in the example's above, ``kitty @`` messaging works only when run inside a |kitty| window,
not anywhere. But, within a |kitty| window it even works over SSH. If you want to control
|kitty| from programs/scripts not running inside a |kitty| window, you have to implement a couple of
extra steps. First start |kitty| as::
In the example's above, ``kitty @`` messaging works only when run
inside a |kitty| window, not anywhere. But, within a |kitty| window it even
works over SSH. If you want to control |kitty| from programs/scripts not running
inside a |kitty| window, see the section on :ref:`using a socket for remote control <rc_via_socket>`
below.
Note that if all you want to do is run a single |kitty| "daemon" and have
subsequent |kitty| invocations appear as new top-level windows, you can use the
simpler :option:`kitty --single-instance` option, see ``kitty --help`` for that.
.. _rc_via_socket:
Remote control via a socket
--------------------------------
First, start |kitty| as::
kitty -o allow_remote_control=yes --listen-on unix:/tmp/mykitty
The :option:`kitty --listen-on` option tells |kitty| to listen for control messages at the
specified path. See ``kitty --help`` for details. Now you can control this
instance of |kitty| using the :option:`kitty @ --to` command line argument to ``kitty @``. For example::
The :option:`kitty --listen-on` option tells |kitty| to listen for control
messages at the specified UNIX-domain socket. See ``kitty --help`` for details.
Now you can control this instance of |kitty| using the :option:`kitty @ --to`
command line argument to ``kitty @``. For example::
kitty @ --to unix:/tmp/mykitty ls
Note that if all you want to do is run a single |kitty| "daemon" and have subsequent
|kitty| invocations appear as new top-level windows, you can use the simpler :option:`kitty --single-instance`
option, see ``kitty --help`` for that.
The builtin kitty shell
--------------------------
You can explore the |kitty| command language more easily using the builtin |kitty|
shell. Run ``kitty @`` with no arguments and you will be dropped into the |kitty|
shell with completion for |kitty| command names and options.
You can explore the |kitty| command language more easily using the builtin
|kitty| shell. Run ``kitty @`` with no arguments and you will be dropped into
the |kitty| shell with completion for |kitty| command names and options.
You can even open the |kitty| shell inside a running |kitty| using a simple
keyboard shortcut (:sc:`kitty_shell` by default).
.. note:: This has the added advantage that you don't need to use
``allow_remote_control`` to make it work.
:opt:`allow_remote_control` to make it work.
Allowing only some windows to control kitty
----------------------------------------------
If you do not want to allow all programs running in |kitty| to control it, you can selectively
enable remote control for only some |kitty| windows. Simply create a shortcut
such as::
If you do not want to allow all programs running in |kitty| to control it, you
can selectively enable remote control for only some |kitty| windows. Simply
create a shortcut such as::
map ctrl+k launch --allow-remote-control some_program
Then programs running in windows created with that shortcut can use ``kitty @``
to control kitty. Note that any program with the right level of permissions can
still write to the pipes of any other program on the same computer and
therefore can control |kitty|. It can, however, be useful to block programs
running on other computers (for example, over ssh) or as other users.
still write to the pipes of any other program on the same computer and therefore
can control |kitty|. It can, however, be useful to block programs running on
other computers (for example, over SSH) or as other users.
.. note:: You dont need ``allow_remote_control`` to make this work as it is
.. note:: You don't need :opt:`allow_remote_control` to make this work as it is
limited to only programs running in that specific window. Be careful with
what programs you run in such windows, since they can effectively control
kitty, as if you were running with ``allow_remote_control`` turned on.
kitty, as if you were running with :opt:`allow_remote_control` turned on.
You can further restrict what is allowed in these windows by using
:option:`kitty @ launch --remote-control-password`.
Fine grained permissions for remote control
----------------------------------------------
.. versionadded:: 0.26.0
The :opt:`allow_remote_control` option discussed so far is a blunt
instrument, granting the ability to any program running on your computer
or even on remote computers via SSH the ability to use remote control.
You can instead define remote control passwords that can be used to grant
different levels of control to different places. You can even write your
own script to decide which remote control requests are allowed. This is
done using the :opt:`remote_control_password` option in :file:`kitty.conf`.
Set :opt:`allow_remote_control` to :code:`password` to use this feature.
Let's see some examples:
.. code-block:: conf
remote_control_password "control colors" get-colors set-colors
Now, using this password, you can, in scripts run the command::
kitty @ --password="control colors" set-colors background=red
Any script with access to the password can now change colors in kitty using
remote control, but only that and nothing else. You can even supply the
password via the :envvar:`KITTY_RC_PASSWORD` environment variable, or the
file :file:`~/.config/kitty/rc-password` to avoid having to type it repeatedly.
See :option:`kitty @ --password-file` and :option:`kitty @ --password-env`.
The :opt:`remote_control_password` can be specified multiple times to create
different passwords with different capabilities. Run the following to get a
list of all action names::
kitty @ --help
You can even use glob patterns to match action names, for example:
.. code-block:: conf
remote_control_password "control colors" *-colors
If no action names are specified, all actions are allowed.
If ``kitty @`` is run with a password that is not present in
:file:`kitty.conf`, then kitty will interactively prompt the user to allow or
disallow the remote control request. The user can choose to allow or disallow
either just that request or all requests using that password. The user's
decision is remembered for the duration of that kitty instance.
.. note::
For password based authentication to work over SSH, you must pass the
:envvar:`KITTY_PUBLIC_KEY` environment variable to the remote host. The
:doc:`ssh kitten <kittens/ssh>` does this for you automatically. When
using a password, :ref:`rc_crypto` is used to ensure the password
is kept secure. This does mean that using password based authentication
is slower as the entire command is encrypted before transmission. This
can be noticeable when using a command like ``kitty @ set-background-image``
which transmits large amounts of image data. Also, the clock on the remote
system must match (within a few minutes) the clock on the local system.
kitty uses a time based nonce to minimise the potential for replay attacks.
.. _rc_custom_auth:
Customizing authorization with your own program
____________________________________________________________
If the ability to control access by action names is not fine grained enough,
you can define your own Python script to examine every remote control command
and allow/disallow it. To do so create a file in the kitty configuration
directory, :file:`~/.config/kitty/my_rc_auth.py` and add the following
to :file:`kitty.conf`:
.. code-block:: conf
remote_control_password "testing custom auth" my_rc_auth.py
:file:`my_rc_auth.py` should define a :code:`is_cmd_allowed` function
as shown below:
.. code-block:: py
def is_cmd_allowed(pcmd, window, from_socket, extra_data):
cmd_name = pcmd['cmd'] # the name of the command
cmd_payload = pcmd['payload'] # the arguments to the command
# examine the cmd_name and cmd_payload and return True to allow
# the command or False to disallow it. Return None to have no
# effect on the command.
# The command payload will vary from command to command, see
# the rc protocol docs for details. Below is an example of
# restricting the launch command to allow only running the
# default shell.
if cmd_name != 'launch':
return None
if cmd_payload.get('args') or cmd_payload.get('env') or cmd_payload.get('copy_cmdline') or cmd_payload.get('copy_env'):
return False
# prints in this function go to the parent kitty process STDOUT
print('Allowing launch command:', cmd_payload)
return True
.. _rc_mapping:
@@ -148,15 +270,21 @@ Mapping key presses to remote control commands
If you wish to trigger a remote control command easily with just a keypress,
you can map it in :file:`kitty.conf`. For example::
map F1 remote_control set-spacing margin=30
map f1 remote_control set-spacing margin=30
Then pressing the :kbd:`F1` key will set the active window margins to 30.
The syntax for what follows :code:`remote_control` is exactly the same
Then pressing the :kbd:`F1` key will set the active window margins to
:code:`30`. The syntax for what follows :ac:`remote_control` is exactly the same
as the syntax for what follows :code:`kitty @` above.
.. note:: You do not need ``allow_remote_control`` to use these mappings,
as they are not actual remote programs, but are simply a way to resuse
the remote control infrastructure via keybings.
If you wish to ignore errors from the command, prefix the command with an
``!``. For example, the following will not return an error when no windows
are matched::
map f1 remote_control !focus-window --match XXXXXX
.. note:: You do not need :opt:`allow_remote_control` to use these mappings,
as they are not actual remote programs, but are simply a way to resuse the
remote control infrastructure via keybings.
Broadcasting what you type to all kitty windows
@@ -166,17 +294,42 @@ As a simple illustration of the power of remote control, lets
have what we type sent to all open kitty windows. To do that define the
following mapping in :file:`kitty.conf`::
map F1 launch --allow-remote-control kitty +kitten broadcast
map f1 launch --allow-remote-control kitty +kitten broadcast
Now press, F1 and start typing, what you type will be sent to all windows,
Now press :kbd:`F1` and start typing, what you type will be sent to all windows,
live, as you type it.
The remote control protocol
-----------------------------------------------
If you wish to develop your own client to talk to |kitty|, you
can use the :doc:`protocol specification <rc_protocol>`.
If you wish to develop your own client to talk to |kitty|, you can use the
:doc:`remote control protocol specification <rc_protocol>`. Note that there
is a statically compiled, standalone executable, ``kitten`` available that
can be used as a remote control client on any UNIX like computer. This can be
downloaded and used directly from the `kitty releases
<https://github.com/kovidgoyal/kitty/releases>`__ page::
kitten @ --help
.. _search_syntax:
Matching windows and tabs
----------------------------
Many remote control operations operate on windows or tabs. To select these, the
:code:`--match` option is often used. This allows matching using various
sophisticated criteria such as title, ids, cmdlines, etc. These criteria are
expressions of the form :code:`field:query`. Where :italic:`field` is the field
against which to match and :italic:`query` is the expression to match. They can
be further combined using Boolean operators, best illustrated with some
examples::
title:"My special window" or id:43
title:bash and env:USER=kovid
not id:1
(id:2 or id:3) and title:something
.. toctree::
:hidden:

View File

@@ -4,8 +4,8 @@ Shell integration
-------------------
kitty has the ability to integrate closely within common shells, such as `zsh
<https://www.zsh.org/>`_, `fish <https://fishshell.com>`_ and `bash
<https://www.gnu.org/software/bash/>`_ to enable features such as jumping to
<https://www.zsh.org/>`__, `fish <https://fishshell.com>`__ and `bash
<https://www.gnu.org/software/bash/>`__ to enable features such as jumping to
previous prompts in the scrollback, viewing the output of the last command in
:program:`less`, using the mouse to move the cursor while editing prompts, etc.
@@ -22,7 +22,7 @@ Features
* Click with the mouse anywhere in the current command to move the cursor there
* Hold :kbd:`ctrl+shift` and right-click on any command output in the scrollback
* Hold :kbd:`Ctrl+Shift` and right-click on any command output in the scrollback
to view it in a pager
* The current working directory or the command being executed are automatically
@@ -30,20 +30,25 @@ Features
* The text cursor is changed to a bar when editing commands at the shell prompt
* :ref:`clone_shell` with all environment variables and the working directory
copied
* :ref:`Edit files in new kitty windows <edit_file>` even over SSH
* Glitch free window resizing even with complex prompts. Achieved by erasing
the prompt on resize and allowing the shell to redraw it cleanly.
* Sophisticated completion for the :program:`kitty` command in the shell.
* When confirming a quit command if a window is sitting at a shell prompt,
it is optionally, not counted (see :opt:`confirm_os_window_close`)
it is not counted (for details, see :opt:`confirm_os_window_close`)
Configuration
---------------
Shell integration is controlled by the :opt:`shell_integration` option. By
default, all shell integration is enabled. Individual features can be turned
default, all integration features are enabled. Individual features can be turned
off or it can be disabled entirely as well. The :opt:`shell_integration` option
takes a space separated list of keywords:
@@ -53,26 +58,28 @@ disabled
:ref:`manual integration <manual_shell_integration>`.
no-rc
Do not modify the shell's launch environment to enable integration. Useful if you prefer
to load the kitty shell integration code yourself, either as part of
:ref:`manually integration <manual_shell_integration>` or because you have
some other software that sets up shell integration.
This will still set the :envvar:`KITTY_SHELL_INTEGRATION` environment variable when kitty runs the shell.
Do not modify the shell's launch environment to enable integration. Useful
if you prefer to load the kitty shell integration code yourself, either as
part of :ref:`manually integration <manual_shell_integration>` or because
you have some other software that sets up shell integration.
This will still set the :envvar:`KITTY_SHELL_INTEGRATION` environment
variable when kitty runs the shell.
no-cursor
Turn off changing of the text cursor to a bar when editing text
Turn off changing of the text cursor to a bar when editing shell command
line.
no-title
Turn off setting the kitty window/tab title based on shell state.
Note that for the ``fish`` shell kitty relies on fish's native title
setting functionality instead.
Note that for the fish shell kitty relies on fish's native title setting
functionality instead.
no-cwd
Turn off reporting the current working directory. This is used to allow
:ac:`new_window_with_cwd` and similar to open windows logged
into remote machines using the :doc:`ssh kitten <kittens/ssh>`
automatically with the same working directory as the current window.
Note that for the ``fish`` shell this will not disable its built-in current
:ac:`new_window_with_cwd` and similar to open windows logged into remote
machines using the :doc:`ssh kitten <kittens/ssh>` automatically with the
same working directory as the current window.
Note that for the fish shell this will not disable its built-in current
working directory reporting.
no-prompt-mark
@@ -81,16 +88,16 @@ no-prompt-mark
no-complete
Turn off completion for the kitty command.
Note that for the ``fish`` shell this does not take effect, since fish
already comes with a kitty completion script.
Note that for the fish shell this does not take effect, since fish already
comes with a kitty completion script.
More ways to browse command output
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
You can add further key and mouse bindings to browse the output of commands
easily. For example to select the output of a command by right clicking the mouse
on the output, define the following in :file:`kitty.conf`:
easily. For example to select the output of a command by right clicking the
mouse on the output, define the following in :file:`kitty.conf`:
.. code:: conf
@@ -101,8 +108,8 @@ to be copied.
The feature to jump to previous prompts (
:sc:`scroll_to_previous_prompt` and :sc:`scroll_to_next_prompt`) and mouse
actions (:ac:`mouse_select_command_output` and :ac:`mouse_show_command_output`) can
be integrated with browsing command output as well. For example, define the
actions (:ac:`mouse_select_command_output` and :ac:`mouse_show_command_output`)
can be integrated with browsing command output as well. For example, define the
following mapping in :file:`kitty.conf`:
.. code:: conf
@@ -134,34 +141,34 @@ How it works
-----------------
At startup, kitty detects if the shell you have configured (either system wide
or in kitty.conf) is a supported shell. If so, kitty injects some shell specific
code into the shell, to enable shell integration. How it does so varies for
different shells.
or the :opt:`shell` option in :file:`kitty.conf`) is a supported shell. If so,
kitty injects some shell specific code into the shell, to enable shell
integration. How it does so varies for different shells.
.. tab:: zsh
For zsh, kitty sets the ``ZDOTDIR`` environment variable to make zsh load
kitty's :file:`.zshenv` which restores the original value of ``ZDOTDIR``
and sources the original :file:`.zshenv`. It then loads the shell integration code.
The remainder of zsh's startup process proceeds as normal.
For zsh, kitty sets the :envvar:`ZDOTDIR` environment variable to make zsh
load kitty's :file:`.zshenv` which restores the original value of
:envvar:`ZDOTDIR` and sources the original :file:`.zshenv`. It then loads
the shell integration code. The remainder of zsh's startup process proceeds
as normal.
.. tab:: fish
For fish, to make it automatically load the integration code provided by
kitty, the integration script directory path is prepended to the
``XDG_DATA_DIRS`` environment variable. This is only applied to the fish
process and will be cleaned up by the integration script after startup. No files
are added or modified.
:envvar:`XDG_DATA_DIRS` environment variable. This is only applied to the
fish process and will be cleaned up by the integration script after startup.
No files are added or modified.
.. tab:: bash
For bash, kitty starts bash in POSIX mode, using the environment variable
``ENV`` to load the shell integration script. This prevents bash from
:envvar:`ENV` to load the shell integration script. This prevents bash from
loading any startup files itself. The loading of the startup files is done
by the integration script, after disabling POSIX mode. From the
perspective of those scripts there should be no difference to running
vanilla bash.
by the integration script, after disabling POSIX mode. From the perspective
of those scripts there should be no difference to running vanilla bash.
Then, when launching the shell, kitty sets the environment variable
@@ -215,6 +222,76 @@ shell integration. Alternately, you can :ref:`setup shell integration manually
the remote server and editing the shell rc files there, as described below.
.. _clone_shell:
Clone the current shell into a new window
-----------------------------------------------
You can clone the current shell into a new kitty window by simply running the
:command:`clone-in-kitty` command, for example:
.. code-block:: sh
clone-in-kitty
clone-in-kitty --type=tab
clone-in-kitty --title "I am a clone"
This will open a new window running a new shell instance but with all
environment variables and the current working directory copied. This even works
over SSH when using :doc:`kittens/ssh`.
The :command:`clone-in-kitty` command takes almost all the same arguments as the
:doc:`launch <launch>` command, so you can open a new tab instead or a new OS
window, etc. Arguments of launch that can cause code execution or that don't
make sense when cloning are ignored. Most prominently, the following options are
ignored: :option:`--allow-remote-control <launch --allow-remote-control>`,
:option:`--copy-cmdline <launch --copy-cmdline>`, :option:`--copy-env <launch
--copy-env>`, :option:`--stdin-source <launch --stdin-source>`,
:option:`--marker <launch --marker>` and :option:`--watcher <launch --watcher>`.
:command:`clone-in-kitty` can be configured to source arbitrary code in the
cloned window using environment variables. It will automatically clone virtual
environments created by the :link:`Python venv module
<https://docs.python.org/3/library/venv.html>` or :link:`Conda
<https://conda.io/>`. In addition, setting the
env var :envvar:`KITTY_CLONE_SOURCE_CODE` to some shell code will cause that
code to be run in the cloned window with :code:`eval`. Similarly, setting
:envvar:`KITTY_CLONE_SOURCE_PATH` to the path of a file will cause that file to
be sourced in the cloned window. This can be controlled by
:opt:`clone_source_strategies`.
:command:`clone-in-kitty` works by asking the shell to serialize its internal
state (mainly CWD and env vars) and this state is transmitted to kitty and
restored by the shell integration scripts in the cloned window.
.. _edit_file:
Edit files in new kitty windows even over SSH
------------------------------------------------
.. code-block:: sh
edit-in-kitty myfile.txt
edit-in-kitty --type tab --title "Editing My File" myfile.txt
# open myfile.txt at line 75 (works with vim, neovim, emacs, nano, micro)
edit-in-kitty +75 myfile.txt
The :command:`edit-in-kitty` command allows you to seamlessly edit files
in your default :opt:`editor` in new kitty windows. This works even over
SSH (if you use the :doc:`ssh kitten <kittens/ssh>`), allowing you
to easily edit remote files in your local editor with all its bells and
whistles.
The :command:`edit-in-kitty` command takes almost all the same arguments as the
:doc:`launch <launch>` command, so you can open a new tab instead or a new OS
window, etc. Not all arguments are supported, see the discussion in the
:ref:`clone_shell` section above.
In order to avoid remote code execution, kitty will only execute the configured
editor and pass the file path to edit to it.
.. _manual_shell_integration:
Manual shell integration
@@ -276,9 +353,10 @@ to point to the location of the scripts.
Integration with other shells
-------------------------------
There exist third-party integrations to use these features for various other shells:
There exist third-party integrations to use these features for various other
shells:
* Jupyter console via a patch (:iss:`4475`)
* Jupyter console and IPython via a patch (:iss:`4475`)
* `xonsh <https://github.com/xonsh/xonsh/issues/4623>`__

View File

@@ -1,24 +1,25 @@
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>`_)
|kitty| supports colored and styled (wavy) underlines. This is of particular use
in terminal based text editors such as :program:`vim` and :program:`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
<ESC>[4:5m # this is a dashed underline
<ESC>[4m # this is a straight underline (for backwards compat)
<ESC>[24m # this is no underline (for backwards compat)
<ESC>[4:0m # no underline
<ESC>[4:1m # straight underline
<ESC>[4:2m # double underline
<ESC>[4:3m # curly underline
<ESC>[4:4m # dotted underline
<ESC>[4:5m # dashed underline
<ESC>[4m # straight underline (for backwards compat)
<ESC>[24m # 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)::
To set the underline color (this is reserved and as far as I can tell not
actually used for anything)::
<ESC>[58...m
@@ -29,8 +30,8 @@ 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.
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.
To detect support for this feature in a terminal emulator, query the terminfo
database for the ``Su`` boolean capability.

View File

@@ -4,10 +4,10 @@ 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
<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
@@ -22,17 +22,17 @@ 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/>`_
<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>`_.
<https://gitlab.freedesktop.org/terminal-wg/specifications/-/issues/30>`__.
.. versionadded:: 0.20.2
Also supported by the terminals:
* `mintty <https://github.com/mintty/mintty/releases/tag/3.5.2>`_
* `mintty <https://github.com/mintty/mintty/releases/tag/3.5.2>`__

View File

@@ -1,8 +1,9 @@
#!/usr/bin/env python
#!./kitty/launcher/kitty +launch
# License: GPLv3 Copyright: 2021, Kovid Goyal <kovid at kovidgoyal.net>
import re
import subprocess
from typing import List
from kitty.conf.generate import write_output
@@ -11,14 +12,25 @@ from kitty.conf.generate import write_output
def patch_color_list(path: str, colors: List[str], name: str, spc: str = ' ') -> None:
with open(path, 'r+') as f:
raw = f.read()
nraw = re.sub(
fr'(# {name}_COLORS_START).+?(\s+# {name}_COLORS_END)',
r'\1' + f'\n{spc}' + f'\n{spc}'.join(map(lambda x: f'{x!r},', sorted(colors))) + r'\2',
raw, flags=re.DOTALL | re.MULTILINE)
colors = sorted(colors)
if path.endswith('.go'):
spc = '\t'
nraw = re.sub(
fr'(// {name}_COLORS_START).+?(\s+// {name}_COLORS_END)',
r'\1' + f'\n{spc}' + f'\n{spc}'.join(map(lambda x: f'"{x}":true,', colors)) + r'\2',
raw, flags=re.DOTALL | re.MULTILINE)
else:
nraw = re.sub(
fr'(# {name}_COLORS_START).+?(\s+# {name}_COLORS_END)',
r'\1' + f'\n{spc}' + f'\n{spc}'.join(map(lambda x: f'{x!r},', colors)) + r'\2',
raw, flags=re.DOTALL | re.MULTILINE)
if nraw != raw:
f.seek(0)
f.truncate()
f.write(nraw)
f.flush()
if path.endswith('.go'):
subprocess.check_call(['gofmt', '-w', path])
def main() -> None:
@@ -34,6 +46,7 @@ def main() -> None:
elif opt.parser_func.__name__ in ('to_color', 'titlebar_color', 'macos_titlebar_color'):
all_colors.append(opt.name)
patch_color_list('kitty/rc/set_colors.py', nullable_colors, 'NULLABLE')
patch_color_list('tools/cmd/at/set_colors.go', nullable_colors, 'NULLABLE')
patch_color_list('kittens/themes/collection.py', all_colors, 'ALL', ' ' * 8)
from kittens.diff.options.definition import definition as kd

607
gen-go-code.py Executable file
View File

@@ -0,0 +1,607 @@
#!./kitty/launcher/kitty +launch
# License: GPLv3 Copyright: 2022, Kovid Goyal <kovid at kovidgoyal.net>
import io
import json
import os
import subprocess
import sys
from contextlib import contextmanager, suppress
from functools import lru_cache
from typing import Any, Dict, Iterator, List, Optional, Sequence, Set, Tuple, Union
import kitty.constants as kc
from kittens.tui.operations import Mode
from kittens.tui.spinners import spinners
from kitty.cli import (
CompletionSpec,
GoOption,
go_options_for_seq,
parse_option_spec,
serialize_as_go_string,
)
from kitty.guess_mime_type import text_mimes
from kitty.key_encoding import config_mod_map
from kitty.key_names import character_key_name_aliases, functional_key_name_aliases
from kitty.options.types import Options
from kitty.rc.base import RemoteCommand, all_command_names, command_for_name
from kitty.remote_control import global_options_spec
from kitty.rgb import color_names
changed: List[str] = []
# Utils {{{
def serialize_go_dict(x: Union[Dict[str, int], Dict[int, str], Dict[int, int], Dict[str, str]]) -> str:
ans = []
def s(x: Union[int, str]) -> str:
if isinstance(x, int):
return str(x)
return f'"{serialize_as_go_string(x)}"'
for k, v in x.items():
ans.append(f'{s(k)}: {s(v)}')
return '{' + ', '.join(ans) + '}'
def replace(template: str, **kw: str) -> str:
for k, v in kw.items():
template = template.replace(k, v)
return template
# }}}
# Completions {{{
@lru_cache
def kitten_cli_docs(kitten: str) -> Any:
from kittens.runner import get_kitten_cli_docs
return get_kitten_cli_docs(kitten)
@lru_cache
def go_options_for_kitten(kitten: str) -> Tuple[Sequence[GoOption], Optional[CompletionSpec]]:
kcd = kitten_cli_docs(kitten)
if kcd:
ospec = kcd['options']
return (tuple(go_options_for_seq(parse_option_spec(ospec())[0])), kcd.get('args_completion'))
return (), None
def generate_kittens_completion() -> None:
from kittens.runner import all_kitten_names, get_kitten_wrapper_of
for kitten in sorted(all_kitten_names()):
kn = 'kitten_' + kitten
print(f'{kn} := plus_kitten.AddSubCommand(&cli.Command{{Name:"{kitten}", Group: "Kittens"}})')
wof = get_kitten_wrapper_of(kitten)
if wof:
print(f'{kn}.ArgCompleter = cli.CompletionForWrapper("{serialize_as_go_string(wof)}")')
print(f'{kn}.OnlyArgsAllowed = true')
continue
gopts, ac = go_options_for_kitten(kitten)
if gopts or ac:
for opt in gopts:
print(opt.as_option(kn))
if ac is not None:
print(''.join(ac.as_go_code(kn + '.ArgCompleter', ' = ')))
else:
print(f'{kn}.HelpText = ""')
@lru_cache
def clone_safe_launch_opts() -> Sequence[GoOption]:
from kitty.launch import clone_safe_opts, options_spec
ans = []
allowed = clone_safe_opts()
for o in go_options_for_seq(parse_option_spec(options_spec())[0]):
if o.obj_dict['name'] in allowed:
ans.append(o)
return tuple(ans)
def completion_for_launch_wrappers(*names: str) -> None:
for o in clone_safe_launch_opts():
for name in names:
print(o.as_option(name))
def generate_completions_for_kitty() -> None:
from kitty.config import option_names_for_completion
print('package completion\n')
print('import "kitty/tools/cli"')
print('import "kitty/tools/cmd/tool"')
print('import "kitty/tools/cmd/at"')
conf_names = ', '.join((f'"{serialize_as_go_string(x)}"' for x in option_names_for_completion()))
print('var kitty_option_names_for_completion = []string{' + conf_names + '}')
print('func kitty(root *cli.Command) {')
# The kitty exe
print('k := root.AddSubCommand(&cli.Command{'
'Name:"kitty", SubCommandIsOptional: true, ArgCompleter: cli.CompleteExecutableFirstArg, SubCommandMustBeFirst: true })')
print('kt := root.AddSubCommand(&cli.Command{Name:"kitten", SubCommandMustBeFirst: true })')
print('tool.KittyToolEntryPoints(kt)')
for opt in go_options_for_seq(parse_option_spec()[0]):
print(opt.as_option('k'))
# kitty +
print('plus := k.AddSubCommand(&cli.Command{Name:"+", Group:"Entry points", ShortDescription: "Various special purpose tools and kittens"})')
# kitty +launch
print('plus_launch := plus.AddSubCommand(&cli.Command{'
'Name:"launch", Group:"Entry points", ShortDescription: "Launch Python scripts", ArgCompleter: complete_plus_launch})')
print('k.AddClone("", plus_launch).Name = "+launch"')
# kitty +list-fonts
print('plus_list_fonts := plus.AddSubCommand(&cli.Command{'
'Name:"list-fonts", Group:"Entry points", ShortDescription: "List all available monospaced fonts"})')
print('k.AddClone("", plus_list_fonts).Name = "+list-fonts"')
# kitty +runpy
print('plus_runpy := plus.AddSubCommand(&cli.Command{'
'Name: "runpy", Group:"Entry points", ArgCompleter: complete_plus_runpy, ShortDescription: "Run Python code"})')
print('k.AddClone("", plus_runpy).Name = "+runpy"')
# kitty +open
print('plus_open := plus.AddSubCommand(&cli.Command{'
'Name:"open", Group:"Entry points", ArgCompleter: complete_plus_open, ShortDescription: "Open files and URLs"})')
print('for _, og := range k.OptionGroups { plus_open.OptionGroups = append(plus_open.OptionGroups, og.Clone(plus_open)) }')
print('k.AddClone("", plus_open).Name = "+open"')
# kitty +kitten
print('plus_kitten := plus.AddSubCommand(&cli.Command{Name:"kitten", Group:"Kittens", SubCommandMustBeFirst: true})')
generate_kittens_completion()
print('k.AddClone("", plus_kitten).Name = "+kitten"')
# @
print('at.EntryPoint(k)')
# clone-in-kitty, edit-in-kitty
print('cik := root.AddSubCommand(&cli.Command{Name:"clone-in-kitty"})')
completion_for_launch_wrappers('cik')
print('}')
print('func init() {')
print('cli.RegisterExeForCompletion(kitty)')
print('}')
# }}}
# rc command wrappers {{{
json_field_types: Dict[str, str] = {
'bool': 'bool', 'str': 'escaped_string', 'list.str': '[]escaped_string', 'dict.str': 'map[escaped_string]escaped_string', 'float': 'float64', 'int': 'int',
'scroll_amount': 'any', 'spacing': 'any', 'colors': 'any',
}
def go_field_type(json_field_type: str) -> str:
q = json_field_types.get(json_field_type)
if q:
return q
if json_field_type.startswith('choices.'):
return 'string'
if '.' in json_field_type:
p, r = json_field_type.split('.', 1)
p = {'list': '[]', 'dict': 'map[string]'}[p]
return p + go_field_type(r)
raise TypeError(f'Unknown JSON field type: {json_field_type}')
class JSONField:
def __init__(self, line: str) -> None:
field_def = line.split(':', 1)[0]
self.required = False
self.field, self.field_type = field_def.split('/', 1)
if self.field.endswith('+'):
self.required = True
self.field = self.field[:-1]
self.struct_field_name = self.field[0].upper() + self.field[1:]
def go_declaration(self) -> str:
return self.struct_field_name + ' ' + go_field_type(self.field_type) + f'`json:"{self.field},omitempty"`'
def go_code_for_remote_command(name: str, cmd: RemoteCommand, template: str) -> str:
template = '\n' + template[len('//go:build exclude'):]
NO_RESPONSE_BASE = 'false'
af: List[str] = []
a = af.append
af.extend(cmd.args.as_go_completion_code('ans'))
od: List[str] = []
option_map: Dict[str, GoOption] = {}
for o in rc_command_options(name):
option_map[o.go_var_name] = o
a(o.as_option('ans'))
if o.go_var_name in ('NoResponse', 'ResponseTimeout'):
continue
od.append(o.struct_declaration())
jd: List[str] = []
json_fields = []
field_types: Dict[str, str] = {}
for line in cmd.protocol_spec.splitlines():
line = line.strip()
if ':' not in line:
continue
f = JSONField(line)
json_fields.append(f)
field_types[f.field] = f.field_type
jd.append(f.go_declaration())
jc: List[str] = []
handled_fields: Set[str] = set()
jc.extend(cmd.args.as_go_code(name, field_types, handled_fields))
unhandled = {}
used_options = set()
for field in json_fields:
oq = (cmd.field_to_option_map or {}).get(field.field, field.field)
oq = ''.join(x.capitalize() for x in oq.split('_'))
if oq in option_map:
o = option_map[oq]
used_options.add(oq)
if field.field_type == 'str':
jc.append(f'payload.{field.struct_field_name} = escaped_string(options_{name}.{o.go_var_name})')
elif field.field_type == 'list.str':
jc.append(f'payload.{field.struct_field_name} = escape_list_of_strings(options_{name}.{o.go_var_name})')
elif field.field_type == 'dict.str':
jc.append(f'payload.{field.struct_field_name} = escape_dict_of_strings(options_{name}.{o.go_var_name})')
else:
jc.append(f'payload.{field.struct_field_name} = options_{name}.{o.go_var_name}')
elif field.field in handled_fields:
pass
else:
unhandled[field.field] = field
for x in tuple(unhandled):
if x == 'match_window' and 'Match' in option_map and 'Match' not in used_options:
used_options.add('Match')
o = option_map['Match']
field = unhandled[x]
if field.field_type == 'str':
jc.append(f'payload.{field.struct_field_name} = escaped_string(options_{name}.{o.go_var_name})')
else:
jc.append(f'payload.{field.struct_field_name} = options_{name}.{o.go_var_name}')
del unhandled[x]
if unhandled:
raise SystemExit(f'Cant map fields: {", ".join(unhandled)} for cmd: {name}')
if name != 'send_text':
unused_options = set(option_map) - used_options - {'NoResponse', 'ResponseTimeout'}
if unused_options:
raise SystemExit(f'Unused options: {", ".join(unused_options)} for command: {name}')
argspec = cmd.args.spec
if argspec:
argspec = ' ' + argspec
ans = replace(
template,
CMD_NAME=name, __FILE__=__file__, CLI_NAME=name.replace('_', '-'),
SHORT_DESC=serialize_as_go_string(cmd.short_desc),
LONG_DESC=serialize_as_go_string(cmd.desc.strip()),
IS_ASYNC='true' if cmd.is_asynchronous else 'false',
NO_RESPONSE_BASE=NO_RESPONSE_BASE, ADD_FLAGS_CODE='\n'.join(af),
WAIT_TIMEOUT=str(cmd.response_timeout),
OPTIONS_DECLARATION_CODE='\n'.join(od),
JSON_DECLARATION_CODE='\n'.join(jd),
JSON_INIT_CODE='\n'.join(jc), ARGSPEC=argspec,
STRING_RESPONSE_IS_ERROR='true' if cmd.string_return_is_error else 'false',
STREAM_WANTED='true' if cmd.reads_streaming_data else 'false',
)
return ans
# }}}
# kittens {{{
@lru_cache
def wrapped_kittens() -> Sequence[str]:
with open('shell-integration/ssh/kitty') as f:
for line in f:
if line.startswith(' wrapped_kittens="'):
val = line.strip().partition('"')[2][:-1]
return tuple(sorted(filter(None, val.split())))
raise Exception('Failed to read wrapped kittens from kitty wrapper script')
def kitten_clis() -> None:
for kitten in wrapped_kittens():
with replace_if_needed(f'tools/cmd/{kitten}/cli_generated.go'):
od = []
kcd = kitten_cli_docs(kitten)
has_underscore = '_' in kitten
print(f'package {kitten}')
print('import "kitty/tools/cli"')
print('func create_cmd(root *cli.Command, run_func func(*cli.Command, *Options, []string)(int, error)) {')
print('ans := root.AddSubCommand(&cli.Command{')
print(f'Name: "{kitten}",')
print(f'ShortDescription: "{serialize_as_go_string(kcd["short_desc"])}",')
if kcd['usage']:
print(f'Usage: "[options] {serialize_as_go_string(kcd["usage"])}",')
print(f'HelpText: "{serialize_as_go_string(kcd["help_text"])}",')
print('Run: func(cmd *cli.Command, args []string) (int, error) {')
print('opts := Options{}')
print('err := cmd.GetOptionValues(&opts)')
print('if err != nil { return 1, err }')
print('return run_func(cmd, &opts, args)},')
if has_underscore:
print('Hidden: true,')
print('})')
gopts, ac = go_options_for_kitten(kitten)
for opt in gopts:
print(opt.as_option('ans'))
od.append(opt.struct_declaration())
if ac is not None:
print(''.join(ac.as_go_code('ans.ArgCompleter', ' = ')))
if has_underscore:
print("clone := root.AddClone(ans.Group, ans)")
print('clone.Hidden = false')
print(f'clone.Name = "{serialize_as_go_string(kitten.replace("_", "-"))}"')
print('}')
print('type Options struct {')
print('\n'.join(od))
print('}')
# }}}
# Constants {{{
def generate_spinners() -> str:
ans = ['package tui', 'import "time"', 'func NewSpinner(name string) *Spinner {', 'var ans *Spinner', 'switch name {']
a = ans.append
for name, spinner in spinners.items():
a(f'case "{serialize_as_go_string(name)}":')
a('ans = &Spinner{')
a(f'Name: "{serialize_as_go_string(name)}",')
a(f'interval: {spinner["interval"]},')
frames = ', '.join(f'"{serialize_as_go_string(x)}"' for x in spinner['frames'])
a(f'frames: []string{{{frames}}},')
a('}')
a('}')
a('if ans != nil {')
a('ans.interval *= time.Millisecond')
a('ans.current_frame = -1')
a('ans.last_change_at = time.Now().Add(-ans.interval)')
a('}')
a('return ans}')
return '\n'.join(ans)
def generate_color_names() -> str:
return 'package style\n\nvar ColorNames = map[string]RGBA{' + '\n'.join(
f'\t"{name}": RGBA{{ Red:{val.red}, Green:{val.green}, Blue:{val.blue} }},'
for name, val in color_names.items()
) + '\n}' + '\n\nvar ColorTable = [256]uint32{' + ', '.join(
f'{x}' for x in Options.color_table) + '}\n'
def load_ref_map() -> Dict[str, Dict[str, str]]:
with open('kitty/docs_ref_map_generated.h') as f:
raw = f.read()
raw = raw.split('{', 1)[1].split('}', 1)[0]
data = json.loads(bytes(bytearray(json.loads(f'[{raw}]'))))
return data # type: ignore
def generate_constants() -> str:
ref_map = load_ref_map()
dp = ", ".join(map(lambda x: f'"{serialize_as_go_string(x)}"', kc.default_pager_for_help))
return f'''\
package kitty
type VersionType struct {{
Major, Minor, Patch int
}}
const VersionString string = "{kc.str_version}"
const WebsiteBaseURL string = "{kc.website_base_url}"
const VCSRevision string = ""
const RC_ENCRYPTION_PROTOCOL_VERSION string = "{kc.RC_ENCRYPTION_PROTOCOL_VERSION}"
const IsFrozenBuild bool = false
const IsStandaloneBuild bool = false
const HandleTermiosSignals = {Mode.HANDLE_TERMIOS_SIGNALS.value[0]}
var Version VersionType = VersionType{{Major: {kc.version.major}, Minor: {kc.version.minor}, Patch: {kc.version.patch},}}
var DefaultPager []string = []string{{ {dp} }}
var FunctionalKeyNameAliases = map[string]string{serialize_go_dict(functional_key_name_aliases)}
var CharacterKeyNameAliases = map[string]string{serialize_go_dict(character_key_name_aliases)}
var ConfigModMap = map[string]uint16{serialize_go_dict(config_mod_map)}
var RefMap = map[string]string{serialize_go_dict(ref_map['ref'])}
var DocTitleMap = map[string]string{serialize_go_dict(ref_map['doc'])}
''' # }}}
# Boilerplate {{{
@contextmanager
def replace_if_needed(path: str, show_diff: bool = False) -> Iterator[io.StringIO]:
buf = io.StringIO()
origb = sys.stdout
sys.stdout = buf
try:
yield buf
finally:
sys.stdout = origb
orig = ''
with suppress(FileNotFoundError), open(path, 'r') as f:
orig = f.read()
new = buf.getvalue()
new = f'// Code generated by {os.path.basename(__file__)}; DO NOT EDIT.\n\n' + new
if orig != new:
changed.append(path)
if show_diff:
with open(path + '.new', 'w') as f:
f.write(new)
subprocess.run(['diff', '-Naurp', path, f.name], stdout=open('/dev/tty', 'w'))
os.remove(f.name)
with open(path, 'w') as f:
f.write(new)
@lru_cache(maxsize=256)
def rc_command_options(name: str) -> Tuple[GoOption, ...]:
cmd = command_for_name(name)
return tuple(go_options_for_seq(parse_option_spec(cmd.options_spec or '\n\n')[0]))
def update_at_commands() -> None:
with open('tools/cmd/at/template.go') as f:
template = f.read()
for name in all_command_names():
cmd = command_for_name(name)
code = go_code_for_remote_command(name, cmd, template)
dest = f'tools/cmd/at/cmd_{name}_generated.go'
with replace_if_needed(dest) as f:
f.write(code)
struct_def = []
opt_def = []
for o in go_options_for_seq(parse_option_spec(global_options_spec())[0]):
struct_def.append(o.struct_declaration())
opt_def.append(o.as_option(depth=1, group="Global options"))
sdef = '\n'.join(struct_def)
odef = '\n'.join(opt_def)
code = f'''
package at
import "kitty/tools/cli"
type rc_global_options struct {{
{sdef}
}}
var rc_global_opts rc_global_options
func add_rc_global_opts(cmd *cli.Command) {{
{odef}
}}
'''
with replace_if_needed('tools/cmd/at/global_opts_generated.go') as f:
f.write(code)
def update_completion() -> None:
with replace_if_needed('tools/cmd/completion/kitty_generated.go'):
generate_completions_for_kitty()
with replace_if_needed('tools/cmd/edit_in_kitty/launch_generated.go'):
print('package edit_in_kitty')
print('import "kitty/tools/cli"')
print('func AddCloneSafeOpts(cmd *cli.Command) {')
completion_for_launch_wrappers('cmd')
print(''.join(CompletionSpec.from_string('type:file mime:text/* group:"Text files"').as_go_code('cmd.ArgCompleter', ' = ')))
print('}')
def define_enum(package_name: str, type_name: str, items: str, underlying_type: str = 'uint') -> str:
actions = []
for x in items.splitlines():
x = x.strip()
if x:
actions.append(x)
ans = [f'package {package_name}', 'import "strconv"', f'type {type_name} {underlying_type}', 'const (']
stringer = [f'func (ac {type_name}) String() string ''{', 'switch(ac) {']
for i, ac in enumerate(actions):
stringer.append(f'case {ac}: return "{ac}"')
if i == 0:
ac = ac + f' {type_name} = iota'
ans.append(ac)
ans.append(')')
stringer.append('}\nreturn strconv.Itoa(int(ac)) }')
return '\n'.join(ans + stringer)
def generate_readline_actions() -> str:
return define_enum('readline', 'Action', '''\
ActionNil
ActionBackspace
ActionDelete
ActionMoveToStartOfLine
ActionMoveToEndOfLine
ActionMoveToStartOfDocument
ActionMoveToEndOfDocument
ActionMoveToEndOfWord
ActionMoveToStartOfWord
ActionCursorLeft
ActionCursorRight
ActionEndInput
ActionAcceptInput
ActionCursorUp
ActionHistoryPreviousOrCursorUp
ActionCursorDown
ActionHistoryNextOrCursorDown
ActionHistoryNext
ActionHistoryPrevious
ActionHistoryFirst
ActionHistoryLast
ActionHistoryIncrementalSearchBackwards
ActionHistoryIncrementalSearchForwards
ActionTerminateHistorySearchAndApply
ActionTerminateHistorySearchAndRestore
ActionClearScreen
ActionAddText
ActionAbortCurrentLine
ActionStartKillActions
ActionKillToEndOfLine
ActionKillToStartOfLine
ActionKillNextWord
ActionKillPreviousWord
ActionKillPreviousSpaceDelimitedWord
ActionEndKillActions
ActionYank
ActionPopYank
ActionNumericArgumentDigit0
ActionNumericArgumentDigit1
ActionNumericArgumentDigit2
ActionNumericArgumentDigit3
ActionNumericArgumentDigit4
ActionNumericArgumentDigit5
ActionNumericArgumentDigit6
ActionNumericArgumentDigit7
ActionNumericArgumentDigit8
ActionNumericArgumentDigit9
ActionNumericArgumentDigitMinus
ActionCompleteForward
ActionCompleteBackward
''')
def generate_mimetypes() -> str:
import mimetypes
if not mimetypes.inited:
mimetypes.init()
ans = ['package utils', 'import "sync"', 'var only_once sync.Once', 'var builtin_types_map map[string]string',
'func set_builtins() {', 'builtin_types_map = map[string]string{',]
for k, v in mimetypes.types_map.items():
ans.append(f' "{serialize_as_go_string(k)}": "{serialize_as_go_string(v)}",')
ans.append('}}')
return '\n'.join(ans)
def generate_textual_mimetypes() -> str:
ans = ['package utils', 'var KnownTextualMimes = map[string]bool{',]
for k in text_mimes:
ans.append(f' "{serialize_as_go_string(k)}": true,')
ans.append('}')
return '\n'.join(ans)
def main() -> None:
with replace_if_needed('constants_generated.go') as f:
f.write(generate_constants())
with replace_if_needed('tools/utils/style/color-names_generated.go') as f:
f.write(generate_color_names())
with replace_if_needed('tools/tui/readline/actions_generated.go') as f:
f.write(generate_readline_actions())
with replace_if_needed('tools/tui/spinners_generated.go') as f:
f.write(generate_spinners())
with replace_if_needed('tools/utils/mimetypes_generated.go') as f:
f.write(generate_mimetypes())
with replace_if_needed('tools/utils/mimetypes_textual_generated.go') as f:
f.write(generate_textual_mimetypes())
update_completion()
update_at_commands()
kitten_clis()
print(json.dumps(changed, indent=2))
if __name__ == '__main__':
main() # }}}

View File

@@ -2,8 +2,8 @@
# License: GPLv3 Copyright: 2021, Kovid Goyal <kovid at kovidgoyal.net>
import string
from typing import Dict, List, Any
from pprint import pformat
from typing import Any, Dict, List, Union
functional_key_defs = '''# {{{
# kitty XKB macVK macU
@@ -130,7 +130,7 @@ functional_encoding_overrides = {
}
different_trailer_functionals = {
'up': 'A', 'down': 'B', 'right': 'C', 'left': 'D', 'kp_begin': 'E', 'end': 'F', 'home': 'H',
'f1': 'P', 'f2': 'Q', 'f3': 'R', 'f4': 'S', 'enter': 'u', 'tab': 'u',
'f1': 'P', 'f2': 'Q', 'f3': '~', 'f4': 'S', 'enter': 'u', 'tab': 'u',
'backspace': 'u', 'escape': 'u'
}
@@ -248,6 +248,19 @@ def serialize_dict(x: Dict[Any, Any]) -> str:
return pformat(x, indent=4).replace('{', '{\n ', 1)
def serialize_go_dict(x: Union[Dict[str, int], Dict[int, str], Dict[int, int]]) -> str:
ans = []
def s(x: Union[int, str]) -> str:
if isinstance(x, int):
return str(x)
return f'"{x}"'
for k, v in x.items():
ans.append(f'{s(k)}: {s(v)}')
return '{' + ', '.join(ans) + '}'
def generate_glfw_header() -> None:
lines = [
'typedef enum {',
@@ -309,14 +322,20 @@ def generate_functional_table() -> None:
patch_file('kitty/key_encoding.c', 'special numbers', '\n'.join(enc_lines))
code_to_name = {v: k.upper() for k, v in name_to_code.items()}
csi_map = {v: name_to_code[k] for k, v in functional_encoding_overrides.items()}
letter_trailer_codes = {
v: functional_encoding_overrides.get(k, name_to_code.get(k))
letter_trailer_codes: Dict[str, int] = {
v: functional_encoding_overrides.get(k, name_to_code.get(k, 0))
for k, v in different_trailer_functionals.items() if v in 'ABCDEHFPQRSZ'}
text = f'functional_key_number_to_name_map = {serialize_dict(code_to_name)}'
text += f'\ncsi_number_to_functional_number_map = {serialize_dict(csi_map)}'
text += f'\nletter_trailer_to_csi_number_map = {letter_trailer_codes!r}'
text += f'\ntilde_trailers = {tilde_trailers!r}'
patch_file('kitty/key_encoding.py', 'csi mapping', text, start_marker='# ', end_marker='')
text = f'var functional_key_number_to_name_map = map[int]string{serialize_go_dict(code_to_name)}\n'
text += f'\nvar csi_number_to_functional_number_map = map[int]int{serialize_go_dict(csi_map)}\n'
text += f'\nvar letter_trailer_to_csi_number_map = map[string]int{serialize_go_dict(letter_trailer_codes)}\n'
tt = ', '.join(f'{x}: true' for x in tilde_trailers)
text += '\nvar tilde_trailers = map[int]bool{' + f'{tt}' + '}\n'
patch_file('tools/tui/loop/key-encoding.go', 'csi mapping', text, start_marker='// ', end_marker='')
def generate_legacy_text_key_maps() -> None:

View File

@@ -3,17 +3,26 @@
import os
import re
import subprocess
import sys
from collections import defaultdict
from contextlib import contextmanager
from datetime import date
from functools import partial
from functools import lru_cache, partial
from html.entities import html5
from itertools import groupby
from operator import itemgetter
from typing import (
Callable, DefaultDict, Dict, FrozenSet, Generator, Iterable, List,
Optional, Set, Tuple, Union
Callable,
DefaultDict,
Dict,
FrozenSet,
Generator,
Iterable,
List,
Optional,
Set,
Tuple,
Union,
)
from urllib.request import urlopen
@@ -44,6 +53,15 @@ def get_data(fname: str, folder: str = 'UCD') -> Iterable[str]:
yield line
@lru_cache(maxsize=2)
def unicode_version() -> Tuple[int, int, int]:
for line in get_data("ReadMe.txt"):
m = re.search(r'Version\s+(\d+)\.(\d+)\.(\d+)', line)
if m is not None:
return int(m.group(1)), int(m.group(2)), int(m.group(3))
raise ValueError('Could not find Unicode Version')
# Map of class names to set of codepoints in class
class_maps: Dict[str, Set[int]] = {}
all_symbols: Set[int] = set()
@@ -254,9 +272,13 @@ def get_ranges(items: List[int]) -> Generator[Union[int, Tuple[int, int]], None,
yield a, b
def write_case(spec: Union[Tuple[int, ...], int], p: Callable[..., None]) -> None:
def write_case(spec: Union[Tuple[int, ...], int], p: Callable[..., None], for_go: bool = False) -> None:
if isinstance(spec, tuple):
p('\t\tcase 0x{:x} ... 0x{:x}:'.format(*spec))
if for_go:
v = ', '.join(f'0x{x:x}' for x in range(spec[0], spec[1] + 1))
p(f'\t\tcase {v}:')
else:
p('\t\tcase 0x{:x} ... 0x{:x}:'.format(*spec))
else:
p(f'\t\tcase 0x{spec:x}:')
@@ -265,8 +287,8 @@ def write_case(spec: Union[Tuple[int, ...], int], p: Callable[..., None]) -> Non
def create_header(path: str, include_data_types: bool = True) -> Generator[Callable[..., None], None, None]:
with open(path, 'w') as f:
p = partial(print, file=f)
p('// unicode data, built from the unicode standard on:', date.today())
p('// see gen-wcwidth.py')
p('// Unicode data, built from the Unicode Standard', '.'.join(map(str, unicode_version())))
p(f'// Code generated by {os.path.basename(__file__)}, DO NOT EDIT.', end='\n\n')
if path.endswith('.h'):
p('#pragma once')
if include_data_types:
@@ -476,7 +498,7 @@ def gen_names() -> None:
# The trie
p('typedef struct { uint32_t children_offset; uint32_t match_offset; } word_trie;\n')
all_trie_nodes: List['TrieNode'] = [] # noqa
all_trie_nodes: List['TrieNode'] = []
class TrieNode:
@@ -524,45 +546,69 @@ def gen_names() -> None:
def gen_wcwidth() -> None:
seen: Set[int] = set()
non_printing = class_maps['Cc'] | class_maps['Cf'] | class_maps['Cs']
def add(p: Callable[..., None], comment: str, chars_: Union[Set[int], FrozenSet[int]], ret: int) -> None:
def add(p: Callable[..., None], comment: str, chars_: Union[Set[int], FrozenSet[int]], ret: int, for_go: bool = False) -> None:
chars = chars_ - seen
seen.update(chars)
p(f'\t\t// {comment} ({len(chars)} codepoints)' + ' {{' '{')
for spec in get_ranges(list(chars)):
write_case(spec, p)
write_case(spec, p, for_go)
p(f'\t\t\treturn {ret};')
p('\t\t// }}}\n')
with create_header('kitty/wcwidth-std.h') as p:
p('static inline int\nwcwidth_std(int32_t code) {')
p('\tif (LIKELY(0x20 <= code && code <= 0x7e)) return 1;')
p('\tswitch(code) {')
def add_all(p: Callable[..., None], for_go: bool = False) -> None:
seen.clear()
add(p, 'Flags', flag_codepoints, 2, for_go)
add(p, 'Marks', marks | {0}, 0, for_go)
add(p, 'Non-printing characters', non_printing, -1, for_go)
add(p, 'Private use', class_maps['Co'], -3, for_go)
add(p, 'Text Presentation', narrow_emoji, 1, for_go)
add(p, 'East Asian ambiguous width', ambiguous, -2, for_go)
add(p, 'East Asian double width', doublewidth, 2, for_go)
add(p, 'Emoji Presentation', wide_emoji, 2, for_go)
non_printing = class_maps['Cc'] | class_maps['Cf'] | class_maps['Cs']
add(p, 'Flags', flag_codepoints, 2)
add(p, 'Marks', marks | {0}, 0)
add(p, 'Non-printing characters', non_printing, -1)
add(p, 'Private use', class_maps['Co'], -3)
add(p, 'Text Presentation', narrow_emoji, 1)
add(p, 'East Asian ambiguous width', ambiguous, -2)
add(p, 'East Asian double width', doublewidth, 2)
add(p, 'Emoji Presentation', wide_emoji, 2)
add(p, 'Not assigned in the unicode character database', not_assigned, -4, for_go)
add(p, 'Not assigned in the unicode character database', not_assigned, -4)
p('\t\tdefault: return 1;')
p('\t\tdefault:\n\t\t\treturn 1;')
p('\t}')
p('\treturn 1;\n}')
if for_go:
p('\t}')
else:
p('\treturn 1;\n}')
with create_header('kitty/wcwidth-std.h') as p, open('tools/wcswidth/std.go', 'w') as gof:
gop = partial(print, file=gof)
gop('package wcswidth\n\n')
gop('func Runewidth(code rune) int {')
p('static inline int\nwcwidth_std(int32_t code) {')
p('\tif (LIKELY(0x20 <= code && code <= 0x7e)) { return 1; }')
p('\tswitch(code) {')
gop('\tswitch(code) {')
add_all(p)
add_all(gop, True)
p('static inline bool\nis_emoji_presentation_base(uint32_t code) {')
gop('func IsEmojiPresentationBase(code rune) bool {')
p('\tswitch(code) {')
gop('\tswitch(code) {')
for spec in get_ranges(list(emoji_presentation_bases)):
write_case(spec, p)
write_case(spec, gop, for_go=True)
p('\t\t\treturn true;')
gop('\t\t\treturn true;')
p('\t\tdefault: return false;')
p('\t}')
p('\treturn 1;\n}')
gop('\t\tdefault:\n\t\t\treturn false')
gop('\t}')
p('\treturn true;\n}')
gop('\n}')
uv = unicode_version()
p(f'#define UNICODE_MAJOR_VERSION {uv[0]}')
p(f'#define UNICODE_MINOR_VERSION {uv[1]}')
p(f'#define UNICODE_PATCH_VERSION {uv[2]}')
gop('var UnicodeDatabaseVersion [3]int = [3]int{' f'{uv[0]}, {uv[1]}, {uv[2]}' + '}')
subprocess.check_call(['gofmt', '-w', '-s', gof.name])
parse_ucd()

View File

@@ -8,7 +8,6 @@ import shlex
import shutil
import subprocess
cmdline = (
'glad --out-path {dest} --api gl:core=3.3 '
' --extensions GL_ARB_texture_storage,GL_ARB_copy_image,GL_ARB_multisample,GL_ARB_robustness,GL_KHR_debug '

View File

@@ -770,6 +770,11 @@ is_useful_apple_global_shortcut(int sc) {
}
}
static bool
is_apple_jis_layout_function_key(NSEvent *event) {
return [event keyCode] == 0x66 /* kVK_JIS_Eisu */ || [event keyCode] == 0x68 /* kVK_JIS_Kana */;
}
GLFWAPI GLFWapplicationshouldhandlereopenfun glfwSetApplicationShouldHandleReopen(GLFWapplicationshouldhandlereopenfun callback) {
GLFWapplicationshouldhandlereopenfun previous = handle_reopen_callback;
handle_reopen_callback = callback;
@@ -837,6 +842,14 @@ int _glfwPlatformInit(void)
last_keydown_shortcut_event.timestamp = [event timestamp];
return event;
}
// check for JIS keyboard layout function keys
if (is_apple_jis_layout_function_key(event)) {
debug_key("keyDown triggerred JIS layout function key ignoring\n");
last_keydown_shortcut_event.virtual_key_code = [event keyCode];
last_keydown_shortcut_event.input_source_switch_modifiers = 0;
last_keydown_shortcut_event.timestamp = [event timestamp];
return event;
}
}
last_keydown_shortcut_event.virtual_key_code = 0xffff;
NSWindow *kw = [NSApp keyWindow];
@@ -979,8 +992,6 @@ void _glfwPlatformTerminate(void)
_glfw.ns.appleSettings = nil;
}
free(_glfw.ns.clipboardString);
_glfwTerminateNSGL();
if (global_shortcuts != nil) { [global_shortcuts release]; global_shortcuts = nil; }

View File

@@ -183,7 +183,6 @@ typedef struct _GLFWlibraryNS
char keyName[64];
char text[256];
char* clipboardString;
CGPoint cascadePoint;
// Where to place the cursor when re-enabled
double restoreCursorPosX, restoreCursorPosY;

View File

@@ -29,6 +29,9 @@
#include "internal.h"
#include "../kitty/monotonic.h"
#include <Availability.h>
#import <CoreServices/CoreServices.h>
#import <UniformTypeIdentifiers/UniformTypeIdentifiers.h>
#include <float.h>
#include <string.h>
@@ -1540,6 +1543,95 @@ void _glfwPlatformUpdateIMEState(_GLFWwindow *w, const GLFWIMEUpdateEvent *ev) {
debug_key("\n\tdoCommandBySelector: (%s)\n", [NSStringFromSelector(selector) UTF8String]);
}
- (BOOL)isAccessibilityElement
{
return YES;
}
- (BOOL)isAccessibilitySelectorAllowed:(SEL)selector
{
if (selector == @selector(accessibilityRole) || selector == @selector(accessibilitySelectedText)) return YES;
return NO;
}
#if (TARGET_OS_OSX && __MAC_OS_X_VERSION_MIN_REQUIRED >= 101400)
- (NSAccessibilityRole)accessibilityRole
{
return NSAccessibilityTextAreaRole;
}
#endif
- (NSString *)accessibilitySelectedText
{
NSString *text = nil;
if (_glfw.callbacks.get_current_selection) {
char *s = _glfw.callbacks.get_current_selection();
if (s) {
text = [NSString stringWithUTF8String:s];
free(s);
}
}
return text;
}
// <https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/SysServices/Articles/using.html>
// Support services receiving "public.utf8-plain-text" and "NSStringPboardType"
- (id)validRequestorForSendType:(NSString *)sendType returnType:(NSString *)returnType
{
if ([sendType isEqual:NSPasteboardTypeString] || [sendType isEqual:@"NSStringPboardType"]) {
return self;
}
return nil;
}
// Selected text as input to be sent to Services
- (BOOL)writeSelectionToPasteboard:(NSPasteboard *)pboard types:(NSArray *)types
{
NSString *text = [self accessibilitySelectedText];
if (text && [text length] > 0) {
if ([types containsObject:NSPasteboardTypeString] == YES) {
[pboard declareTypes:@[NSPasteboardTypeString] owner:self];
return [pboard setString:text forType:NSPasteboardTypeString];
} else if ([types containsObject:@"NSStringPboardType"] == YES) {
[pboard declareTypes:@[@"NSStringPboardType"] owner:self];
return [pboard setString:text forType:NSPasteboardTypeString];
}
}
return NO;
}
// Service output to be handled
- (BOOL)readSelectionFromPasteboard:(NSPasteboard *)pboard
{
NSString* text = nil;
NSArray *types = [pboard types];
if ([types containsObject:NSPasteboardTypeString] == YES) {
text = [pboard stringForType:NSPasteboardTypeString]; // public.utf8-plain-text
} else if ([types containsObject:@"NSStringPboardType"] == YES) {
text = [pboard stringForType:@"NSStringPboardType"]; // for older services (need re-encode?)
} else {
return NO;
}
if (text && [text length] > 0) {
// Terminal.app inserts the output, do the same
const char *utf8 = polymorphic_string_as_utf8(text);
if ([self hasMarkedText]) {
[self unmarkText];
debug_key("Clearing pre-edit because insertText called from readSelectionFromPasteboard\n");
GLFWkeyevent glfw_keyevent = {.ime_state = GLFW_IME_PREEDIT_CHANGED};
_glfwInputKeyboard(window, &glfw_keyevent);
}
debug_key("Sending text received in readSelectionFromPasteboard as key event\n");
GLFWkeyevent glfw_keyevent = {.text=utf8};
_glfwInputKeyboard(window, &glfw_keyevent);
return YES;
}
return NO;
}
@end
// }}}
@@ -1731,7 +1823,11 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window,
if (!createNativeWindow(window, wndconfig, fbconfig))
return false;
[window->ns.object setColorSpace:[NSColorSpace sRGBColorSpace]];
switch((GlfwCocoaColorSpaces)wndconfig->ns.color_space) {
case SRGB_COLORSPACE: [window->ns.object setColorSpace:[NSColorSpace sRGBColorSpace]]; break;
case DISPLAY_P3_COLORSPACE: [window->ns.object setColorSpace:[NSColorSpace displayP3ColorSpace]]; break;
case DEFAULT_COLORSPACE: break;
}
if (ctxconfig->client != GLFW_NO_API)
{
@@ -2468,38 +2564,150 @@ bool _glfwPlatformToggleFullscreen(_GLFWwindow* w, unsigned int flags) {
return made_fullscreen;
}
void _glfwPlatformSetClipboardString(const char* string)
{
NSPasteboard* pasteboard = [NSPasteboard generalPasteboard];
[pasteboard declareTypes:@[NSPasteboardTypeString] owner:nil];
[pasteboard setString:@(string) forType:NSPasteboardTypeString];
// Clipboard {{{
#define UTI_ROUNDTRIP_PREFIX @"uti-is-typical-apple-nih."
static NSString*
mime_to_uti(const char *mime) {
if (strcmp(mime, "text/plain") == 0) return NSPasteboardTypeString;
if (@available(macOS 11.0, *)) {
UTType *t = [UTType typeWithMIMEType:@(mime)]; // auto-released
if (t != nil && !t.dynamic) return t.identifier;
}
return [NSString stringWithFormat:@"%@%s", UTI_ROUNDTRIP_PREFIX, mime]; // auto-released
}
const char* _glfwPlatformGetClipboardString(void)
{
NSPasteboard* pasteboard = [NSPasteboard generalPasteboard];
if (![[pasteboard types] containsObject:NSPasteboardTypeString])
{
_glfwInputError(GLFW_FORMAT_UNAVAILABLE,
"Cocoa: Failed to retrieve string from pasteboard");
return NULL;
static const char*
uti_to_mime(NSString *uti) {
if ([uti isEqualToString:NSPasteboardTypeString]) return "text/plain";
if ([uti hasPrefix:UTI_ROUNDTRIP_PREFIX]) return [[uti substringFromIndex:[UTI_ROUNDTRIP_PREFIX length]] UTF8String];
if (@available(macOS 11.0, *)) {
UTType *t = [UTType typeWithIdentifier:uti]; // auto-released
if (t.preferredMIMEType != nil) return [t.preferredMIMEType UTF8String];
}
NSString* object = [pasteboard stringForType:NSPasteboardTypeString];
if (!object)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"Cocoa: Failed to retrieve object from pasteboard");
return NULL;
}
free(_glfw.ns.clipboardString);
_glfw.ns.clipboardString = _glfw_strdup([object UTF8String]);
return _glfw.ns.clipboardString;
return "";
}
static void
list_clipboard_mimetypes(GLFWclipboardwritedatafun write_data, void *object) {
#define w(x) { if (ok) ok = write_data(object, x, strlen(x)); }
NSPasteboard* pasteboard = [NSPasteboard generalPasteboard];
NSDictionary* options = @{NSPasteboardURLReadingFileURLsOnlyKey:@YES};
BOOL has_file_urls = [pasteboard canReadObjectForClasses:@[[NSURL class]] options:options];
BOOL has_strings = [pasteboard canReadObjectForClasses:@[[NSString class]] options:nil];
/* NSLog(@"has_file_urls: %d has_strings: %d", has_file_urls, has_strings); */
bool ok = true;
if (has_strings) w("text/plain");
if (has_file_urls) w("text/local-path-list");
for (NSPasteboardItem * item in pasteboard.pasteboardItems) {
for (NSPasteboardType type in item.types) {
/* NSLog(@"%@", type); */
const char *mime = uti_to_mime(type);
if (mime && mime[0] && ![@(mime) hasPrefix:@"text/plain"]) {
/* NSLog(@"ut: %@ mt: %@ tags: %@", ut, ut.preferredMIMEType, ut.tags); */
w(mime);
}
}
}
#undef w
}
static void
get_text_plain(GLFWclipboardwritedatafun write_data, void *object) {
NSPasteboard* pasteboard = [NSPasteboard generalPasteboard];
NSDictionary* options = @{NSPasteboardURLReadingFileURLsOnlyKey:@YES};
NSArray* objs = [pasteboard readObjectsForClasses:@[[NSURL class], [NSString class]] options:options];
bool found = false;
if (objs) {
const NSUInteger count = [objs count];
if (count) {
NSMutableData *path_list = [NSMutableData dataWithCapacity:4096]; // auto-released
NSMutableData *text_list = [NSMutableData dataWithCapacity:4096]; // auto-released
for (NSUInteger i = 0; i < count; i++) {
id obj = objs[i];
if ([obj isKindOfClass:[NSURL class]]) {
NSURL *url = (NSURL*)obj;
if (url.fileURL && url.fileSystemRepresentation) {
if ([path_list length] > 0) [path_list appendBytes:"\n" length:1];
[path_list appendBytes:url.fileSystemRepresentation length:strlen(url.fileSystemRepresentation)];
}
} else if ([obj isKindOfClass:[NSString class]]) {
if ([text_list length] > 0) [text_list appendBytes:"\n" length:1];
[text_list appendData:[obj dataUsingEncoding:NSUTF8StringEncoding]];
}
}
const NSMutableData *text = nil;
if (path_list.length > 0) text = path_list;
else if (text_list.length > 0) text = text_list;
if (text) {
found = true;
write_data(object, text.mutableBytes, text.length);
}
}
}
if (!found) _glfwInputError(GLFW_PLATFORM_ERROR, "Cocoa: Failed to retrieve text/plain from pasteboard");
}
void
_glfwPlatformGetClipboard(GLFWClipboardType clipboard_type, const char* mime_type, GLFWclipboardwritedatafun write_data, void *object) {
if (clipboard_type != GLFW_CLIPBOARD) return;
if (mime_type == NULL) {
list_clipboard_mimetypes(write_data, object);
return;
}
if (strcmp(mime_type, "text/plain") == 0) {
get_text_plain(write_data, object);
return;
}
NSPasteboard* pasteboard = [NSPasteboard generalPasteboard];
/* NSLog(@"mime: %s uti: %@", mime_type, mime_to_uti(mime_type)); */
NSPasteboardType t = [pasteboard availableTypeFromArray:@[mime_to_uti(mime_type)]];
/* NSLog(@"available type: %@", t); */
if (t != nil) {
NSData *data = [pasteboard dataForType:t]; // auto-released
/* NSLog(@"data: %@", data); */
if (data != nil && data.length > 0) {
write_data(object, data.bytes, data.length);
}
}
}
static NSMutableData*
get_clipboard_data(const _GLFWClipboardData *cd, const char *mime) {
NSMutableData *ans = [NSMutableData dataWithCapacity:8192];
if (ans == nil) return nil;
GLFWDataChunk chunk = cd->get_data(mime, NULL, cd->ctype);
void *iter = chunk.iter;
if (!iter) return ans;
while (true) {
chunk = cd->get_data(mime, iter, cd->ctype);
if (!chunk.sz) break;
[ans appendBytes:chunk.data length:chunk.sz];
if (chunk.free) chunk.free((void*)chunk.free_data);
}
cd->get_data(NULL, iter, cd->ctype);
return ans;
}
void
_glfwPlatformSetClipboard(GLFWClipboardType t) {
if (t != GLFW_CLIPBOARD) return;
NSPasteboard* pasteboard = [NSPasteboard generalPasteboard];
NSMutableArray<NSPasteboardType> *ptypes = [NSMutableArray arrayWithCapacity:_glfw.clipboard.num_mime_types]; // auto-released
for (size_t i = 0; i < _glfw.clipboard.num_mime_types; i++) {
[ptypes addObject:mime_to_uti(_glfw.clipboard.mime_types[i])];
}
[pasteboard declareTypes:ptypes owner:nil];
for (size_t i = 0; i < _glfw.clipboard.num_mime_types; i++) {
NSMutableData *data = get_clipboard_data(&_glfw.clipboard, _glfw.clipboard.mime_types[i]); // auto-released
/* NSLog(@"putting data: %@ for: %s with UTI: %@", data, _glfw.clipboard.mime_types[i], ptypes[i]); */
if (data != nil) [pasteboard setData:data forType:ptypes[i]];
}
}
// }}}
EGLenum _glfwPlatformGetEGLPlatform(EGLint** attribs)
{
if (_glfw.egl.ANGLE_platform_angle)

12
glfw/context.c vendored
View File

@@ -396,15 +396,6 @@ bool _glfwRefreshContextAttribs(_GLFWwindow* window,
window->context.release = GLFW_RELEASE_BEHAVIOR_FLUSH;
}
// Clearing the front buffer to black to avoid garbage pixels left over from
// previous uses of our bit of VRAM
{
PFNGLCLEARPROC glClear = (PFNGLCLEARPROC)
window->context.getProcAddress("glClear");
glClear(GL_COLOR_BUFFER_BIT);
window->context.swapBuffers(window);
}
glfwMakeContextCurrent((GLFWwindow*) previous);
return true;
}
@@ -487,6 +478,9 @@ GLFWAPI void glfwSwapBuffers(GLFWwindow* handle)
}
window->context.swapBuffers(window);
#ifdef _GLFW_WAYLAND
_glfwWaylandAfterBufferSwap(window);
#endif
}
GLFWAPI void glfwSwapInterval(int interval)

8
glfw/egl_context.c vendored
View File

@@ -326,6 +326,7 @@ bool _glfwInitEGL(void)
glfw_dlsym(_glfw.egl.SwapBuffers, _glfw.egl.handle, "eglSwapBuffers");
glfw_dlsym(_glfw.egl.SwapInterval, _glfw.egl.handle, "eglSwapInterval");
glfw_dlsym(_glfw.egl.QueryString, _glfw.egl.handle, "eglQueryString");
glfw_dlsym(_glfw.egl.QuerySurface, _glfw.egl.handle, "eglQuerySurface");
glfw_dlsym(_glfw.egl.GetProcAddress, _glfw.egl.handle, "eglGetProcAddress");
if (!_glfw.egl.GetConfigAttrib ||
@@ -428,6 +429,8 @@ bool _glfwInitEGL(void)
extensionSupportedEGL("EGL_KHR_get_all_proc_addresses");
_glfw.egl.KHR_context_flush_control =
extensionSupportedEGL("EGL_KHR_context_flush_control");
_glfw.egl.EXT_present_opaque =
extensionSupportedEGL("EGL_EXT_present_opaque");
return true;
}
@@ -598,6 +601,11 @@ bool _glfwCreateContextEGL(_GLFWwindow* window,
if (_glfw.egl.KHR_gl_colorspace)
setAttrib(EGL_GL_COLORSPACE_KHR, EGL_GL_COLORSPACE_SRGB_KHR);
}
// Disabled because it prevents transparency from working on NVIDIA drivers under Wayland
// https://github.com/kovidgoyal/kitty/issues/5479
// We anyway dont use the alpha bits for anything.
/* if (_glfw.egl.EXT_present_opaque) */
/* setAttrib(EGL_PRESENT_OPAQUE_EXT, !fbconfig->transparent); */
setAttrib(EGL_NONE, EGL_NONE);

12
glfw/egl_context.h vendored
View File

@@ -132,6 +132,7 @@ typedef EGLBoolean (EGLAPIENTRY * PFN_eglMakeCurrent)(EGLDisplay,EGLSurface,EGLS
typedef EGLBoolean (EGLAPIENTRY * PFN_eglSwapBuffers)(EGLDisplay,EGLSurface);
typedef EGLBoolean (EGLAPIENTRY * PFN_eglSwapInterval)(EGLDisplay,EGLint);
typedef const char* (EGLAPIENTRY * PFN_eglQueryString)(EGLDisplay,EGLint);
typedef const char* (EGLAPIENTRY * PFN_eglQuerySurface)(EGLDisplay,EGLSurface,EGLint,EGLint*);
typedef GLFWglproc (EGLAPIENTRY * PFN_eglGetProcAddress)(const char*);
#define eglGetConfigAttrib _glfw.egl.GetConfigAttrib
#define eglGetConfigs _glfw.egl.GetConfigs
@@ -149,6 +150,7 @@ typedef GLFWglproc (EGLAPIENTRY * PFN_eglGetProcAddress)(const char*);
#define eglSwapBuffers _glfw.egl.SwapBuffers
#define eglSwapInterval _glfw.egl.SwapInterval
#define eglQueryString _glfw.egl.QueryString
#define eglQuerySurface _glfw.egl.QuerySurface
#define eglGetProcAddress _glfw.egl.GetProcAddress
typedef EGLDisplay (EGLAPIENTRY * PFNEGLGETPLATFORMDISPLAYEXTPROC)(EGLenum,void*,const EGLint*);
@@ -160,11 +162,11 @@ typedef EGLSurface (EGLAPIENTRY * PFNEGLCREATEPLATFORMWINDOWSURFACEEXTPROC)(EGLD
//
typedef struct _GLFWcontextEGL
{
EGLConfig config;
EGLContext handle;
EGLSurface surface;
EGLConfig config;
EGLContext handle;
EGLSurface surface;
void* client;
void* client;
} _GLFWcontextEGL;
@@ -186,6 +188,7 @@ typedef struct _GLFWlibraryEGL
bool EXT_platform_base;
bool EXT_platform_x11;
bool EXT_platform_wayland;
bool EXT_present_opaque;
bool ANGLE_platform_angle;
bool ANGLE_platform_angle_opengl;
bool ANGLE_platform_angle_d3d;
@@ -210,6 +213,7 @@ typedef struct _GLFWlibraryEGL
PFN_eglSwapBuffers SwapBuffers;
PFN_eglSwapInterval SwapInterval;
PFN_eglQueryString QueryString;
PFN_eglQuerySurface QuerySurface;
PFN_eglGetProcAddress GetProcAddress;
PFNEGLGETPLATFORMDISPLAYEXTPROC GetPlatformDisplayEXT;

View File

@@ -14,6 +14,10 @@ is_openbsd = 'openbsd' in _plat
base = os.path.dirname(os.path.abspath(__file__))
def null_func() -> None:
return None
class CompileKey(NamedTuple):
src: str
dest: str
@@ -23,7 +27,7 @@ class Command(NamedTuple):
desc: str
cmd: Sequence[str]
is_newer_func: Callable[[], bool]
on_success: Callable[[], None] = lambda: None
on_success: Callable[[], None] = null_func
key: Optional[CompileKey] = None
keyfile: Optional[str] = None
@@ -111,7 +115,7 @@ def init_env(
elif module == 'cocoa':
ans.cppflags.append('-DGL_SILENCE_DEPRECATION')
for f_ in 'Cocoa IOKit CoreFoundation CoreVideo'.split():
for f_ in 'Cocoa IOKit CoreFoundation CoreVideo UniformTypeIdentifiers'.split():
ans.ldpaths.extend(('-framework', f_))
elif module == 'wayland':
@@ -172,6 +176,8 @@ class Arg:
while self.name.startswith('*'):
self.name = self.name[1:]
self.type = self.type + '*'
if '[' in self.name:
self.type += '[' + self.name.partition('[')[-1]
def __repr__(self) -> str:
return f'Arg({self.type}, {self.name})'
@@ -245,11 +251,15 @@ 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)
void glfwWaylandActivateWindow(GLFWwindow *handle, const char *activation_token)
void glfwWaylandRunWithActivationToken(GLFWwindow *handle, GLFWactivationcallback cb, void *cb_data)
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)
int glfwSetX11LaunchCommand(GLFWwindow *handle, char **argv, int argc)
void glfwSetX11WindowAsDock(int32_t x11_window_id)
void glfwSetX11WindowStrut(int32_t x11_window_id, uint32_t dimensions[12])
'''.splitlines():
if line:
functions.append(Function(line.strip(), check_fail=False))

90
glfw/glfw3.h vendored
View File

@@ -512,6 +512,7 @@ typedef enum {
* GLFW_LOCK_KEY_MODS input mode is set.
*/
#define GLFW_MOD_NUM_LOCK 0x0080
#define GLFW_MOD_LAST GLFW_MOD_NUM_LOCK
#define GLFW_LOCK_MASK (GLFW_MOD_NUM_LOCK | GLFW_MOD_CAPS_LOCK)
/*! @} */
@@ -1024,6 +1025,16 @@ typedef enum GLFWMouseButton {
* [window hint](@ref GLFW_COCOA_GRAPHICS_SWITCHING_hint).
*/
#define GLFW_COCOA_GRAPHICS_SWITCHING 0x00023003
/*! @brief macOS specific
* [window hint](@ref GLFW_COCOA_COLOR_SPACE_hint).
*/
#define GLFW_COCOA_COLOR_SPACE 0x00023004
typedef enum {
DEFAULT_COLORSPACE = 0,
SRGB_COLORSPACE = 1,
DISPLAY_P3_COLORSPACE = 2,
} GlfwCocoaColorSpaces;
/*! @brief X11 specific
* [window hint](@ref GLFW_X11_CLASS_NAME_hint).
*/
@@ -1206,7 +1217,8 @@ typedef enum {
typedef enum {
GLFW_IME_NONE,
GLFW_IME_PREEDIT_CHANGED,
GLFW_IME_COMMIT_TEXT
GLFW_IME_COMMIT_TEXT,
GLFW_IME_WAYLAND_DONE_EVENT,
} GLFWIMEState;
typedef enum {
@@ -1704,7 +1716,21 @@ typedef void (* GLFWjoystickfun)(int,int);
typedef void (* GLFWuserdatafun)(unsigned long long, void*);
typedef void (* GLFWtickcallback)(void*);
typedef void (* GLFWactivationcallback)(GLFWwindow *window, const char *token, void *data);
typedef bool (* GLFWdrawtextfun)(GLFWwindow *window, const char *text, uint32_t fg, uint32_t bg, uint8_t *output_buf, size_t width, size_t height, float x_offset, float y_offset, size_t right_margin);
typedef char* (* GLFWcurrentselectionfun)(void);
typedef void (* GLFWclipboarddatafreefun)(void* data);
typedef struct GLFWDataChunk {
const char *data;
size_t sz;
GLFWclipboarddatafreefun free;
void *iter, *free_data;
} GLFWDataChunk;
typedef enum {
GLFW_CLIPBOARD, GLFW_PRIMARY_SELECTION
} GLFWClipboardType;
typedef GLFWDataChunk (* GLFWclipboarditerfun)(const char *mime_type, void *iter, GLFWClipboardType ctype);
typedef bool (* GLFWclipboardwritedatafun)(void *object, const char *data, size_t sz);
/*! @brief Video mode type.
*
@@ -1862,6 +1888,7 @@ GLFWAPI unsigned long long glfwAddTimer(monotonic_t interval, bool repeats, GLFW
GLFWAPI void glfwUpdateTimer(unsigned long long timer_id, monotonic_t interval, bool enabled);
GLFWAPI void glfwRemoveTimer(unsigned long long);
GLFWAPI GLFWdrawtextfun glfwSetDrawTextFunction(GLFWdrawtextfun function);
GLFWAPI GLFWcurrentselectionfun glfwSetCurrentSelectionCallback(GLFWcurrentselectionfun callback);
/*! @brief Terminates the GLFW library.
*
@@ -2757,6 +2784,7 @@ GLFWAPI void glfwWindowHintString(int hint, const char* value);
GLFWAPI GLFWwindow* glfwCreateWindow(int width, int height, const char* title, GLFWmonitor* monitor, GLFWwindow* share);
GLFWAPI bool glfwToggleFullscreen(GLFWwindow *window, unsigned int flags);
GLFWAPI bool glfwIsFullscreen(GLFWwindow *window, unsigned int flags);
GLFWAPI bool glfwAreSwapsAllowed(const GLFWwindow* window);
/*! @brief Destroys the specified window and its context.
*
@@ -5205,64 +5233,8 @@ GLFWAPI const char* glfwGetGamepadName(int jid);
*/
GLFWAPI int glfwGetGamepadState(int jid, GLFWgamepadstate* state);
/*! @brief Sets the clipboard to the specified string.
*
* This function sets the system clipboard to the specified, UTF-8 encoded
* string.
*
* @param[in] window Deprecated. Any valid window or `NULL`.
* @param[in] string A UTF-8 encoded string.
*
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
* GLFW_PLATFORM_ERROR.
*
* @remark @wayland Clipboard is currently unimplemented.
*
* @pointer_lifetime The specified string is copied before this function
* returns.
*
* @thread_safety This function must only be called from the main thread.
*
* @sa @ref clipboard
* @sa @ref glfwGetClipboardString
*
* @since Added in version 3.0.
*
* @ingroup input
*/
GLFWAPI void glfwSetClipboardString(GLFWwindow* window, const char* string);
/*! @brief Returns the contents of the clipboard as a string.
*
* This function returns the contents of the system clipboard, if it contains
* or is convertible to a UTF-8 encoded string. If the clipboard is empty or
* if its contents cannot be converted, `NULL` is returned and a @ref
* GLFW_FORMAT_UNAVAILABLE error is generated.
*
* @param[in] window Deprecated. Any valid window or `NULL`.
* @return The contents of the clipboard as a UTF-8 encoded string, or `NULL`
* if an [error](@ref error_handling) occurred.
*
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
* GLFW_PLATFORM_ERROR.
*
* @remark @wayland Clipboard is currently unimplemented.
*
* @pointer_lifetime The returned string is allocated and freed by GLFW. You
* should not free it yourself. It is valid until the next call to @ref
* glfwGetClipboardString or @ref glfwSetClipboardString, or until the library
* is terminated.
*
* @thread_safety This function must only be called from the main thread.
*
* @sa @ref clipboard
* @sa @ref glfwSetClipboardString
*
* @since Added in version 3.0.
*
* @ingroup input
*/
GLFWAPI const char* glfwGetClipboardString(GLFWwindow* window);
GLFWAPI void glfwSetClipboardDataTypes(GLFWClipboardType clipboard_type, const char* const *mime_types, size_t num_mime_types, GLFWclipboarditerfun get_iter);
GLFWAPI void glfwGetClipboard(GLFWClipboardType clipboard_type, const char* mime_type, GLFWclipboardwritedatafun write_data, void *object);
/*! @brief Returns the GLFW time.
*

4
glfw/ibus_glfw.c vendored
View File

@@ -383,12 +383,12 @@ input_context_created(DBusMessage *msg, const char* errmsg, void *data) {
enum Capabilities caps = IBUS_CAP_FOCUS | IBUS_CAP_PREEDIT_TEXT;
if (!glfw_dbus_call_method_no_reply(ibus->conn, IBUS_SERVICE, ibus->input_ctx_path, IBUS_INPUT_INTERFACE, "SetCapabilities", DBUS_TYPE_UINT32, &caps, DBUS_TYPE_INVALID)) return;
ibus->ok = true;
glfw_ibus_set_focused(ibus, false);
glfw_ibus_set_focused(ibus, _glfwFocusedWindow() != NULL);
glfw_ibus_set_cursor_geometry(ibus, 0, 0, 0, 0);
debug("Connected to IBUS daemon for IME input management\n");
}
bool
static bool
setup_connection(_GLFWIBUSData *ibus) {
const char *client_name = "GLFW_Application";
const char *address_file_name = get_ibus_address_file_name();

9
glfw/init.c vendored
View File

@@ -68,6 +68,8 @@ static void terminate(void)
int i;
memset(&_glfw.callbacks, 0, sizeof(_glfw.callbacks));
_glfw_free_clipboard_data(&_glfw.clipboard);
_glfw_free_clipboard_data(&_glfw.primary);
while (_glfw.windowListHead)
glfwDestroyWindow((GLFWwindow*) _glfw.windowListHead);
@@ -386,3 +388,10 @@ GLFWAPI GLFWdrawtextfun glfwSetDrawTextFunction(GLFWdrawtextfun cbfun)
_GLFW_SWAP_POINTERS(_glfw.callbacks.draw_text, cbfun);
return cbfun;
}
GLFWAPI GLFWcurrentselectionfun glfwSetCurrentSelectionCallback(GLFWcurrentselectionfun cbfun)
{
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
_GLFW_SWAP_POINTERS(_glfw.callbacks.get_current_selection, cbfun);
return cbfun;
}

51
glfw/input.c vendored
View File

@@ -1526,36 +1526,41 @@ GLFWAPI int glfwGetGamepadState(int jid, GLFWgamepadstate* state)
return true;
}
GLFWAPI void glfwSetClipboardString(GLFWwindow* handle UNUSED, const char* string)
{
assert(string != NULL);
void _glfw_free_clipboard_data(_GLFWClipboardData *cd) {
if (cd->mime_types) {
for (size_t i = 0; i < cd->num_mime_types; i++) free((void*)cd->mime_types[i]);
free((void*)cd->mime_types);
}
memset(cd, 0, sizeof(cd[0]));
}
GLFWAPI void glfwGetClipboard(GLFWClipboardType clipboard_type, const char* mime_type, GLFWclipboardwritedatafun write_data, void *object) {
_GLFW_REQUIRE_INIT();
_glfwPlatformSetClipboardString(string);
_glfwPlatformGetClipboard(clipboard_type, mime_type, write_data, object);
}
GLFWAPI const char* glfwGetClipboardString(GLFWwindow* handle UNUSED)
{
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
return _glfwPlatformGetClipboardString();
}
#if defined(_GLFW_X11) || defined(_GLFW_WAYLAND)
GLFWAPI void glfwSetPrimarySelectionString(GLFWwindow* handle UNUSED, const char* string)
{
assert(string != NULL);
GLFWAPI void glfwSetClipboardDataTypes(GLFWClipboardType clipboard_type, const char* const *mime_types, size_t num_mime_types, GLFWclipboarditerfun get_data) {
assert(mime_types != NULL);
assert(get_data != NULL);
_GLFW_REQUIRE_INIT();
_glfwPlatformSetPrimarySelectionString(string);
_GLFWClipboardData *cd = NULL;
switch(clipboard_type) {
case GLFW_CLIPBOARD: cd = &_glfw.clipboard; break;
case GLFW_PRIMARY_SELECTION: cd = &_glfw.primary; break;
}
_glfw_free_clipboard_data(cd);
cd->get_data = get_data;
cd->mime_types = calloc(num_mime_types, sizeof(char*));
cd->num_mime_types = 0;
cd->ctype = clipboard_type;
for (size_t i = 0; i < num_mime_types; i++) {
if (mime_types[i]) {
cd->mime_types[cd->num_mime_types++] = _glfw_strdup(mime_types[i]);
}
}
_glfwPlatformSetClipboard(clipboard_type);
}
GLFWAPI const char* glfwGetPrimarySelectionString(GLFWwindow* handle UNUSED)
{
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
return _glfwPlatformGetPrimarySelectionString();
}
#endif
GLFWAPI monotonic_t glfwGetTime(void)
{
_GLFW_REQUIRE_INIT_OR_RETURN(0);

31
glfw/internal.h vendored
View File

@@ -34,6 +34,9 @@
#endif
#define arraysz(x) (sizeof(x)/sizeof(x[0]))
#define MAX(x, y) __extension__ ({ \
__typeof__ (x) a = (x); __typeof__ (y) b = (y); \
a > b ? a : b;})
#if defined(GLFW_INCLUDE_GLCOREARB) || \
defined(GLFW_INCLUDE_ES1) || \
@@ -52,6 +55,8 @@
#define GLFW_INCLUDE_NONE
#include "glfw3.h"
#define EGL_PRESENT_OPAQUE_EXT 0x31df
#define _GLFW_INSERT_FIRST 0
#define _GLFW_INSERT_LAST 1
@@ -307,6 +312,7 @@ struct _GLFWwndconfig
bool scaleToMonitor;
struct {
bool retina;
int color_space;
char frameName[256];
} ns;
struct {
@@ -438,6 +444,11 @@ struct _GLFWwindow
bool rawMouseMotion;
_GLFWcontext context;
#ifdef _GLFW_WAYLAND
bool swaps_disallowed;
#else
const bool swaps_disallowed;
#endif
struct {
GLFWwindowposfun pos;
@@ -553,6 +564,13 @@ struct _GLFWmutex
_GLFW_PLATFORM_MUTEX_STATE;
};
typedef struct _GLFWClipboardData {
const char** mime_types;
size_t num_mime_types;
GLFWclipboarditerfun get_data;
GLFWClipboardType ctype;
} _GLFWClipboardData;
// Library global data
//
struct _GLFWlibrary
@@ -567,6 +585,8 @@ struct _GLFWlibrary
int refreshRate;
} hints;
_GLFWClipboardData primary, clipboard;
_GLFWerror* errorListHead;
_GLFWcursor* cursorListHead;
_GLFWwindow* windowListHead;
@@ -613,6 +633,7 @@ struct _GLFWlibrary
GLFWjoystickfun joystick;
GLFWapplicationclosefun application_close;
GLFWdrawtextfun draw_text;
GLFWcurrentselectionfun get_current_selection;
} callbacks;
@@ -665,12 +686,8 @@ void _glfwPlatformGetVideoMode(_GLFWmonitor* monitor, GLFWvidmode* mode);
bool _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp);
void _glfwPlatformSetGammaRamp(_GLFWmonitor* monitor, const GLFWgammaramp* ramp);
void _glfwPlatformSetClipboardString(const char* string);
const char* _glfwPlatformGetClipboardString(void);
#if defined(_GLFW_X11) || defined(_GLFW_WAYLAND)
void _glfwPlatformSetPrimarySelectionString(const char* string);
const char* _glfwPlatformGetPrimarySelectionString(void);
#endif
void _glfwPlatformSetClipboard(GLFWClipboardType t);
void _glfwPlatformGetClipboard(GLFWClipboardType clipboard_type, const char* mime_type, GLFWclipboardwritedatafun write_data, void *object);
bool _glfwPlatformInitJoysticks(void);
void _glfwPlatformTerminateJoysticks(void);
@@ -846,3 +863,5 @@ void _glfwPlatformUpdateTimer(unsigned long long timer_id, monotonic_t interval,
void _glfwPlatformRemoveTimer(unsigned long long timer_id);
char* _glfw_strdup(const char* source);
void _glfw_free_clipboard_data(_GLFWClipboardData *cd);

View File

@@ -83,8 +83,8 @@ process_settings_dict(DBusMessageIter *array_iter, void(process_setting)(const c
HANDLER(process_desktop_settings)
cursor_theme_changed = false;
DBusMessageIter root, array, item, settings;
dbus_message_iter_init(msg, &root);
DBusMessageIter root, array, item, settings;
dbus_message_iter_init(msg, &root);
#define die(...) { _glfwInputError(GLFW_PLATFORM_ERROR, __VA_ARGS__); return; }
if (dbus_message_iter_get_arg_type(&root) != DBUS_TYPE_ARRAY) die("Reply to request for desktop settings is not an array");
dbus_message_iter_recurse(&root, &array);

View File

@@ -77,7 +77,8 @@
"unstable/idle-inhibit/idle-inhibit-unstable-v1.xml",
"unstable/xdg-decoration/xdg-decoration-unstable-v1.xml",
"unstable/primary-selection/primary-selection-unstable-v1.xml",
"unstable/text-input/text-input-unstable-v3.xml"
"unstable/text-input/text-input-unstable-v3.xml",
"staging/xdg-activation/xdg-activation-v1.xml"
],
"sources": [
"wl_init.c",

11
glfw/window.c vendored
View File

@@ -71,7 +71,7 @@ void _glfwInputWindowFocus(_GLFWwindow* window, bool focused)
_glfw.focusedWindowId = window->id;
}
_GLFWwindow* _glfwFocusedWindow() {
_GLFWwindow* _glfwFocusedWindow(void) {
if (_glfw.focusedWindowId) {
_GLFWwindow *w = _glfw.windowListHead;
while (w) {
@@ -332,6 +332,8 @@ void glfwDefaultWindowHints(void)
// The default is to use full Retina resolution framebuffers
_glfw.hints.window.ns.retina = true;
// use the default colorspace assigned by the system
_glfw.hints.window.ns.color_space = 0;
}
GLFWAPI void glfwWindowHint(int hint, int value)
@@ -412,6 +414,9 @@ GLFWAPI void glfwWindowHint(int hint, int value)
case GLFW_COCOA_RETINA_FRAMEBUFFER:
_glfw.hints.window.ns.retina = value ? true : false;
return;
case GLFW_COCOA_COLOR_SPACE:
_glfw.hints.window.ns.color_space = value;
return;
case GLFW_COCOA_GRAPHICS_SWITCHING:
_glfw.hints.context.nsgl.offline = value ? true : false;
return;
@@ -1062,6 +1067,10 @@ GLFWAPI bool glfwIsFullscreen(GLFWwindow* wh, unsigned int flags) {
return _glfwPlatformIsFullscreen((_GLFWwindow*)wh, flags);
}
GLFWAPI bool glfwAreSwapsAllowed(const GLFWwindow* wh) {
return !(((_GLFWwindow*)wh)->swaps_disallowed);
}
GLFWAPI void glfwSetWindowUserPointer(GLFWwindow* handle, void* pointer)
{
_GLFWwindow* window = (_GLFWwindow*) handle;

View File

@@ -31,13 +31,13 @@ static void
build_blur_kernel(kernel_type *blur_kernel, const size_t size, kernel_type sigma) {
// 1D Normalized Gaussian
const kernel_type half = size / (kernel_type)2;
kernel_type sum = 0;
for (size_t i = 0; i < size; i++) {
kernel_type f = (i - half);
blur_kernel[i] = (kernel_type)exp(- f * f / sigma);
sum += blur_kernel[i];
}
for (size_t i = 0; i < size; i++) blur_kernel[i] /= sum;
kernel_type sum = 0;
for (size_t i = 0; i < size; i++) {
kernel_type f = (i - half);
blur_kernel[i] = (kernel_type)exp(- f * f / sigma);
sum += blur_kernel[i];
}
for (size_t i = 0; i < size; i++) blur_kernel[i] /= sum;
}
static void
@@ -102,13 +102,34 @@ init_buffer_pair(_GLFWWaylandBufferPair *pair, size_t width, size_t height, unsi
return 2 * pair->size_in_bytes;
}
static bool
window_has_buffer(_GLFWwindow *window, struct wl_buffer *q) {
#define Q(which) if (decs.which.buffer.a == q) { decs.which.buffer.a_needs_to_be_destroyed = false; return true; } if (decs.which.buffer.b == q) { decs.which.buffer.b_needs_to_be_destroyed = false; return true; }
Q(left); Q(top); Q(right); Q(bottom);
#undef Q
return false;
}
static void
alloc_buffer_pair(_GLFWWaylandBufferPair *pair, struct wl_shm_pool *pool, uint8_t *data, size_t *offset) {
buffer_release_event(void *data, struct wl_buffer *buffer) {
wl_buffer_destroy(buffer);
_GLFWwindow *window = _glfwWindowForId((uintptr_t)data);
if (window && window_has_buffer(window, buffer)) decs.buffer_destroyed = true;
}
static struct wl_buffer_listener handle_buffer_events = {.release = buffer_release_event};
static void
alloc_buffer_pair(uintptr_t window_id, _GLFWWaylandBufferPair *pair, struct wl_shm_pool *pool, uint8_t *data, size_t *offset) {
pair->data.a = data + *offset;
pair->a = wl_shm_pool_create_buffer(pool, *offset, pair->width, pair->height, pair->stride, WL_SHM_FORMAT_ARGB8888);
pair->a_needs_to_be_destroyed = true;
wl_buffer_add_listener(pair->a, &handle_buffer_events, (void*)window_id);
*offset += pair->size_in_bytes;
pair->data.b = data + *offset;
pair->b = wl_shm_pool_create_buffer(pool, *offset, pair->width, pair->height, pair->stride, WL_SHM_FORMAT_ARGB8888);
pair->b_needs_to_be_destroyed = true;
wl_buffer_add_listener(pair->b, &handle_buffer_events, (void*)window_id);
*offset += pair->size_in_bytes;
pair->front = pair->a; pair->back = pair->b;
pair->data.front = pair->data.a; pair->data.back = pair->data.b;
@@ -287,7 +308,7 @@ create_shm_buffers(_GLFWwindow* window) {
struct wl_shm_pool* pool = wl_shm_create_pool(_glfw.wl.shm, fd, decs.mapping.size);
close(fd);
size_t offset = 0;
#define a(which) alloc_buffer_pair(&decs.which.buffer, pool, decs.mapping.data, &offset)
#define a(which) alloc_buffer_pair(window->id, &decs.which.buffer, pool, decs.mapping.data, &offset)
a(top); a(left); a(bottom); a(right);
#undef a
wl_shm_pool_destroy(pool);
@@ -313,8 +334,8 @@ free_csd_surfaces(_GLFWwindow *window) {
static void
free_csd_buffers(_GLFWwindow *window) {
#define d(which) { \
if (decs.which.buffer.a) wl_buffer_destroy(decs.which.buffer.a); \
if (decs.which.buffer.b) wl_buffer_destroy(decs.which.buffer.b); \
if (decs.which.buffer.a_needs_to_be_destroyed && decs.which.buffer.a) wl_buffer_destroy(decs.which.buffer.a); \
if (decs.which.buffer.b_needs_to_be_destroyed && decs.which.buffer.b) wl_buffer_destroy(decs.which.buffer.b); \
memset(&decs.which.buffer, 0, sizeof(_GLFWWaylandBufferPair)); \
}
d(left); d(top); d(right); d(bottom);
@@ -337,9 +358,10 @@ create_csd_surfaces(_GLFWwindow *window, _GLFWWaylandCSDEdge *s) {
}
#define damage_csd(which, xbuffer) \
wl_surface_attach(decs.which.surface, xbuffer, 0, 0); \
wl_surface_attach(decs.which.surface, (xbuffer), 0, 0); \
wl_surface_damage(decs.which.surface, 0, 0, decs.which.buffer.width, decs.which.buffer.height); \
wl_surface_commit(decs.which.surface)
wl_surface_commit(decs.which.surface); \
if (decs.which.buffer.a == (xbuffer)) { decs.which.buffer.a_needs_to_be_destroyed = false; } else { decs.which.buffer.b_needs_to_be_destroyed = false; }
bool
ensure_csd_resources(_GLFWwindow *window) {
@@ -352,12 +374,14 @@ ensure_csd_resources(_GLFWwindow *window) {
decs.for_window_state.scale != window->wl.scale ||
!decs.mapping.data
);
const bool needs_update = focus_changed || size_changed || !decs.left.surface;
debug("CSD: old.size: %dx%d new.size: %dx%d needs_update: %d size_changed: %d\n", decs.for_window_state.width, decs.for_window_state.height, window->wl.width, window->wl.height, needs_update, size_changed);
const bool needs_update = focus_changed || size_changed || !decs.left.surface || decs.buffer_destroyed;
debug("CSD: old.size: %dx%d new.size: %dx%d needs_update: %d size_changed: %d buffer_destroyed: %d\n",
decs.for_window_state.width, decs.for_window_state.height, window->wl.width, window->wl.height, needs_update, size_changed, decs.buffer_destroyed);
if (!needs_update) return false;
if (size_changed) {
if (size_changed || decs.buffer_destroyed) {
free_csd_buffers(window);
if (!create_shm_buffers(window)) return false;
decs.buffer_destroyed = false;
}
int32_t x, y, scale = window->wl.scale < 1 ? 1 : window->wl.scale;
@@ -432,8 +456,5 @@ set_titlebar_color(_GLFWwindow *window, uint32_t color, bool use_system_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);
}
change_csd_title(window);
}

41
glfw/wl_init.c vendored
View File

@@ -99,7 +99,7 @@ static void pointerHandleEnter(void* data UNUSED,
return;
}
window->wl.decorations.focus = focus;
_glfw.wl.serial = serial;
_glfw.wl.serial = serial; _glfw.wl.input_serial = serial;
_glfw.wl.pointerFocus = window;
window->wl.hovered = true;
@@ -143,10 +143,19 @@ static void setCursor(GLFWCursorShape shape, _GLFWwindow* window)
if (!image)
return;
if (image->width % scale || image->height % scale) {
static uint32_t warned_width = 0, warned_height = 0;
if (warned_width != image->width || warned_height != image->height) {
_glfwInputError(GLFW_PLATFORM_ERROR, "WARNING: Cursor image size: %dx%d is not a multiple of window scale: %d. This will"
" cause some compositors such as GNOME to crash. See https://github.com/kovidgoyal/kitty/issues/4878", image->width, image->height, scale);
warned_width = image->width; warned_height = image->height;
}
}
buffer = wl_cursor_image_get_buffer(image);
if (!buffer)
return;
debug("Calling wl_pointer_set_cursor in setCursor with surface: %p\n", (void*)surface);
wl_pointer_set_cursor(_glfw.wl.pointer, _glfw.wl.serial,
surface,
image->hotspot_x / scale,
@@ -302,7 +311,7 @@ static void pointerHandleButton(void* data UNUSED,
if (window->wl.decorations.focus != CENTRAL_WINDOW)
return;
_glfw.wl.serial = serial;
_glfw.wl.serial = serial; _glfw.wl.input_serial = serial;
/* Makes left, right and middle 0, 1 and 2. Overall order follows evdev
* codes. */
@@ -454,7 +463,7 @@ static void keyboardHandleEnter(void* data UNUSED,
return;
}
_glfw.wl.serial = serial;
_glfw.wl.serial = serial; _glfw.wl.input_serial = serial;
_glfw.wl.keyboardFocusId = window->id;
_glfwInputWindowFocus(window, true);
uint32_t* key;
@@ -507,7 +516,7 @@ static void keyboardHandleKey(void* data UNUSED,
return;
int action = state == WL_KEYBOARD_KEY_STATE_PRESSED ? GLFW_PRESS : GLFW_RELEASE;
_glfw.wl.serial = serial;
_glfw.wl.serial = serial; _glfw.wl.input_serial = serial;
glfw_xkb_handle_key_event(window, &_glfw.wl.xkb, key, action);
if (action == GLFW_PRESS && _glfw.wl.keyboardRepeatRate > 0 && glfw_xkb_should_repeat(&_glfw.wl.xkb, key))
@@ -530,7 +539,7 @@ static void keyboardHandleModifiers(void* data UNUSED,
uint32_t modsLocked,
uint32_t group)
{
_glfw.wl.serial = serial;
_glfw.wl.serial = serial; _glfw.wl.input_serial = serial;
glfw_xkb_update_modifiers(&_glfw.wl.xkb, modsDepressed, modsLatched, modsLocked, 0, 0, group);
}
@@ -568,6 +577,7 @@ static void seatHandleCapabilities(void* data UNUSED,
{
wl_pointer_destroy(_glfw.wl.pointer);
_glfw.wl.pointer = NULL;
if (_glfw.wl.cursorAnimationTimer) toggleTimer(&_glfw.wl.eventLoopData, _glfw.wl.cursorAnimationTimer, 0);
}
if ((caps & WL_SEAT_CAPABILITY_KEYBOARD) && !_glfw.wl.keyboard)
@@ -579,6 +589,8 @@ static void seatHandleCapabilities(void* data UNUSED,
{
wl_keyboard_destroy(_glfw.wl.keyboard);
_glfw.wl.keyboard = NULL;
_glfw.wl.keyboardFocusId = 0;
if (_glfw.wl.keyRepeatInfo.keyRepeatTimer) toggleTimer(&_glfw.wl.eventLoopData, _glfw.wl.keyRepeatInfo.keyRepeatTimer, 0);
}
}
@@ -707,6 +719,9 @@ static void registryHandleGlobal(void* data UNUSED,
_glfwSetupWaylandPrimarySelectionDevice();
}
}
else if (strstr(interface, "xdg_activation_v1") != 0) {
_glfw.wl.xdg_activation_v1 = wl_registry_bind(registry, name, &xdg_activation_v1_interface, 1);
}
}
@@ -870,6 +885,14 @@ int _glfwPlatformInit(void)
void _glfwPlatformTerminate(void)
{
if (_glfw.wl.activation_requests.array) {
for (size_t i=0; i < _glfw.wl.activation_requests.sz; i++) {
glfw_wl_xdg_activation_request *r = _glfw.wl.activation_requests.array + i;
if (r->callback) r->callback(NULL, NULL, r->callback_data);
xdg_activation_token_v1_destroy(r->token);
}
free(_glfw.wl.activation_requests.array);
}
_glfwTerminateEGL();
if (_glfw.wl.egl.handle)
{
@@ -914,6 +937,8 @@ void _glfwPlatformTerminate(void)
zwp_idle_inhibit_manager_v1_destroy(_glfw.wl.idleInhibitManager);
if (_glfw.wl.dataSourceForClipboard)
wl_data_source_destroy(_glfw.wl.dataSourceForClipboard);
if (_glfw.wl.dataSourceForPrimarySelection)
zwp_primary_selection_source_v1_destroy(_glfw.wl.dataSourceForPrimarySelection);
for (size_t doi=0; doi < arraysz(_glfw.wl.dataOffers); doi++) {
if (_glfw.wl.dataOffers[doi].id) {
destroy_data_offer(&_glfw.wl.dataOffers[doi]);
@@ -927,6 +952,8 @@ void _glfwPlatformTerminate(void)
zwp_primary_selection_device_v1_destroy(_glfw.wl.primarySelectionDevice);
if (_glfw.wl.primarySelectionDeviceManager)
zwp_primary_selection_device_manager_v1_destroy(_glfw.wl.primarySelectionDeviceManager);
if (_glfw.wl.xdg_activation_v1)
xdg_activation_v1_destroy(_glfw.wl.xdg_activation_v1);
if (_glfw.wl.registry)
wl_registry_destroy(_glfw.wl.registry);
if (_glfw.wl.display)
@@ -935,10 +962,6 @@ void _glfwPlatformTerminate(void)
wl_display_disconnect(_glfw.wl.display);
}
finalizePollData(&_glfw.wl.eventLoopData);
free(_glfw.wl.clipboardString); _glfw.wl.clipboardString = NULL;
free(_glfw.wl.primarySelectionString); _glfw.wl.primarySelectionString = NULL;
free(_glfw.wl.pasteString); _glfw.wl.pasteString = NULL;
}
const char* _glfwPlatformGetVersionString(void)

38
glfw/wl_platform.h vendored
View File

@@ -58,7 +58,9 @@ typedef VkBool32 (APIENTRY *PFN_vkGetPhysicalDeviceWaylandPresentationSupportKHR
#include "wayland-pointer-constraints-unstable-v1-client-protocol.h"
#include "wayland-idle-inhibit-unstable-v1-client-protocol.h"
#include "wayland-primary-selection-unstable-v1-client-protocol.h"
#include "wayland-primary-selection-unstable-v1-client-protocol.h"
#include "wl_text_input.h"
#include "wayland-xdg-activation-v1-client-protocol.h"
#define _glfw_dlopen(name) dlopen(name, RTLD_LAZY | RTLD_LOCAL)
#define _glfw_dlclose(handle) dlclose(handle)
@@ -102,6 +104,7 @@ typedef struct _GLFWWaylandBufferPair {
struct { uint8_t *a, *b, *front, *back; } data;
bool has_pending_update;
size_t size_in_bytes, width, height, stride;
bool a_needs_to_be_destroyed, b_needs_to_be_destroyed;
} _GLFWWaylandBufferPair;
typedef struct _GLFWWaylandCSDEdge {
@@ -116,14 +119,22 @@ typedef enum WaylandWindowState {
TOPLEVEL_STATE_NONE = 0,
TOPLEVEL_STATE_MAXIMIZED = 1,
TOPLEVEL_STATE_FULLSCREEN = 2,
TOPLEVEL_STATE_RESIZING = 4,
TOPLEVEL_STATE_ACTIVATED = 8,
TOPLEVEL_STATE_TILED_LEFT = 16,
TOPLEVEL_STATE_TILED_RIGHT = 32,
TOPLEVEL_STATE_TILED_TOP = 64,
TOPLEVEL_STATE_TILED_BOTTOM = 128,
TOPLEVEL_STATE_RESIZING = 4,
TOPLEVEL_STATE_ACTIVATED = 8,
TOPLEVEL_STATE_TILED_LEFT = 16,
TOPLEVEL_STATE_TILED_RIGHT = 32,
TOPLEVEL_STATE_TILED_TOP = 64,
TOPLEVEL_STATE_TILED_BOTTOM = 128,
} WaylandWindowState;
typedef struct glfw_wl_xdg_activation_request {
GLFWid window_id;
GLFWactivationcallback callback;
void *callback_data;
uintptr_t request_id;
void *token;
} glfw_wl_xdg_activation_request;
static const WaylandWindowState TOPLEVEL_STATE_DOCKED = TOPLEVEL_STATE_MAXIMIZED | TOPLEVEL_STATE_FULLSCREEN | TOPLEVEL_STATE_TILED_TOP | TOPLEVEL_STATE_TILED_LEFT | TOPLEVEL_STATE_TILED_RIGHT | TOPLEVEL_STATE_TILED_BOTTOM;
@@ -141,6 +152,7 @@ typedef struct _GLFWwindowWayland
bool hovered;
bool transparent;
struct wl_surface* surface;
bool waiting_for_swap_to_commit;
struct wl_egl_window* native;
struct wl_callback* callback;
@@ -172,7 +184,7 @@ typedef struct _GLFWwindowWayland
struct zwp_idle_inhibitor_v1* idleInhibitor;
struct {
bool serverSide;
bool serverSide, buffer_destroyed;
_GLFWdecorationSideWayland focus;
_GLFWWaylandCSDEdge top, left, right, bottom;
@@ -276,13 +288,14 @@ typedef struct _GLFWlibraryWayland
struct zwp_primary_selection_device_manager_v1* primarySelectionDeviceManager;
struct zwp_primary_selection_device_v1* primarySelectionDevice;
struct zwp_primary_selection_source_v1* dataSourceForPrimarySelection;
struct xdg_activation_v1* xdg_activation_v1;
int compositorVersion;
int seatVersion;
struct wl_surface* cursorSurface;
GLFWCursorShape cursorPreviousShape;
uint32_t serial;
uint32_t serial, input_serial;
int32_t keyboardRepeatRate;
monotonic_t keyboardRepeatDelay;
@@ -316,12 +329,14 @@ typedef struct _GLFWlibraryWayland
PFN_wl_egl_window_resize window_resize;
} egl;
struct {
glfw_wl_xdg_activation_request *array;
size_t capacity, sz;
} activation_requests;
EventLoopData eventLoopData;
char* pasteString;
char* clipboardString;
size_t dataOffersCounter;
_GLFWWaylandDataOffer dataOffers[8];
char* primarySelectionString;
} _GLFWlibraryWayland;
// Wayland-specific per-monitor data
@@ -355,6 +370,7 @@ typedef struct _GLFWcursorWayland
void _glfwAddOutputWayland(uint32_t name, uint32_t version);
void _glfwWaylandAfterBufferSwap(_GLFWwindow *window);
void _glfwSetupWaylandDataDevice(void);
void _glfwSetupWaylandPrimarySelectionDevice(void);
void animateCursorImage(id_type timer_id, void *data);

41
glfw/wl_text_input.c vendored
View File

@@ -9,12 +9,15 @@
#include "internal.h"
#include "wayland-text-input-unstable-v3-client-protocol.h"
#include <stdlib.h>
#include <string.h>
#define debug(...) if (_glfw.hints.init.debugKeyboard) printf(__VA_ARGS__);
static struct zwp_text_input_v3* text_input;
static struct zwp_text_input_manager_v3* text_input_manager;
static char *pending_pre_edit = NULL;
static char *current_pre_edit = NULL;
static char *pending_commit = NULL;
static int last_cursor_left = 0, last_cursor_top = 0, last_cursor_width = 0, last_cursor_height = 0;
uint32_t commit_serial = 0;
static void commit(void) {
@@ -84,18 +87,26 @@ text_input_delete_surrounding_text(
}
static void
text_input_done(void *data UNUSED, struct zwp_text_input_v3 *txt_input UNUSED, uint32_t serial UNUSED) {
text_input_done(void *data UNUSED, struct zwp_text_input_v3 *txt_input UNUSED, uint32_t serial) {
debug("text-input: done event: serial: %u current_commit_serial: %u\n", serial, commit_serial);
if (serial != commit_serial) {
_glfwInputError(GLFW_PLATFORM_ERROR, "Wayland: text_input_done serial mismatch, expected=%u got=%u\n", commit_serial, serial);
if (serial > commit_serial) _glfwInputError(GLFW_PLATFORM_ERROR, "Wayland: text_input_done serial mismatch, expected=%u got=%u\n", commit_serial, serial);
return;
}
if (pending_pre_edit) {
send_text(pending_pre_edit, GLFW_IME_PREEDIT_CHANGED);
if ((pending_pre_edit == NULL && current_pre_edit == NULL) ||
(pending_pre_edit && current_pre_edit && strcmp(pending_pre_edit, current_pre_edit) == 0)) {
free(pending_pre_edit); pending_pre_edit = NULL;
} else {
// Clear pre-edit text
send_text(NULL, GLFW_IME_PREEDIT_CHANGED);
free(current_pre_edit);
current_pre_edit = pending_pre_edit;
pending_pre_edit = NULL;
if (current_pre_edit) {
send_text(current_pre_edit, GLFW_IME_PREEDIT_CHANGED);
} else {
// Clear pre-edit text
send_text(NULL, GLFW_IME_WAYLAND_DONE_EVENT);
}
}
if (pending_commit) {
send_text(pending_commit, GLFW_IME_COMMIT_TEXT);
@@ -133,6 +144,7 @@ _glfwWaylandDestroyTextInput(void) {
if (text_input_manager) zwp_text_input_manager_v3_destroy(text_input_manager);
text_input = NULL; text_input_manager = NULL;
free(pending_pre_edit); pending_pre_edit = NULL;
free(current_pre_edit); current_pre_edit = NULL;
free(pending_commit); pending_commit = NULL;
}
@@ -146,10 +158,11 @@ _glfwPlatformUpdateIMEState(_GLFWwindow *w, const GLFWIMEUpdateEvent *ev) {
zwp_text_input_v3_enable(text_input);
zwp_text_input_v3_set_content_type(text_input, ZWP_TEXT_INPUT_V3_CONTENT_HINT_NONE, ZWP_TEXT_INPUT_V3_CONTENT_PURPOSE_TERMINAL);
} else {
if (pending_pre_edit) {
free(pending_pre_edit); pending_pre_edit = NULL;
if (current_pre_edit) {
// Clear pre-edit text
send_text(NULL, GLFW_IME_PREEDIT_CHANGED);
free(pending_pre_edit); pending_pre_edit = NULL;
free(current_pre_edit); current_pre_edit = NULL;
}
if (pending_commit) {
free(pending_commit); pending_commit = NULL;
@@ -161,9 +174,15 @@ _glfwPlatformUpdateIMEState(_GLFWwindow *w, const GLFWIMEUpdateEvent *ev) {
case GLFW_IME_UPDATE_CURSOR_POSITION: {
const int scale = w->wl.scale;
const int left = ev->cursor.left / scale, top = ev->cursor.top / scale, width = ev->cursor.width / scale, height = ev->cursor.height / scale;
debug("\ntext-input: updating cursor position: left=%d top=%d width=%d height=%d\n", left, top, width, height);
zwp_text_input_v3_set_cursor_rectangle(text_input, left, top, width, height);
commit();
if (left != last_cursor_left || top != last_cursor_top || width != last_cursor_width || height != last_cursor_height) {
last_cursor_left = left;
last_cursor_top = top;
last_cursor_width = width;
last_cursor_height = height;
debug("\ntext-input: updating cursor position: left=%d top=%d width=%d height=%d\n", left, top, width, height);
zwp_text_input_v3_set_cursor_rectangle(text_input, left, top, width, height);
commit();
}
}
break;
}

552
glfw/wl_window.c vendored
View File

@@ -44,6 +44,59 @@
#define debug(...) if (_glfw.hints.init.debugRendering) fprintf(stderr, __VA_ARGS__);
static void
activation_token_done(void *data, struct xdg_activation_token_v1 *xdg_token, const char *token) {
for (size_t i = 0; i < _glfw.wl.activation_requests.sz; i++) {
glfw_wl_xdg_activation_request *r = _glfw.wl.activation_requests.array + i;
if (r->request_id == (uintptr_t)data) {
_GLFWwindow *window = _glfwWindowForId(r->window_id);
if (r->callback) r->callback((GLFWwindow*)window, token, r->callback_data);
remove_i_from_array(_glfw.wl.activation_requests.array, i, _glfw.wl.activation_requests.sz);
break;
}
}
xdg_activation_token_v1_destroy(xdg_token);
}
static const struct
xdg_activation_token_v1_listener activation_token_listener = {
.done = &activation_token_done,
};
static bool
get_activation_token(
_GLFWwindow *window, uint32_t serial, GLFWactivationcallback cb, void *cb_data
) {
#define fail(msg) { _glfwInputError(GLFW_PLATFORM_ERROR, msg); if (cb) cb((GLFWwindow*)window, NULL, cb_data); return false; }
if (_glfw.wl.xdg_activation_v1 == NULL) fail("Wayland: activation requests not supported by this Wayland compositor");
struct xdg_activation_token_v1 *token = xdg_activation_v1_get_activation_token(_glfw.wl.xdg_activation_v1);
if (token == NULL) fail("Wayland: failed to create activation request token");
if (_glfw.wl.activation_requests.capacity < _glfw.wl.activation_requests.sz + 1) {
_glfw.wl.activation_requests.capacity = MAX(64u, _glfw.wl.activation_requests.capacity * 2);
_glfw.wl.activation_requests.array = realloc(_glfw.wl.activation_requests.array, _glfw.wl.activation_requests.capacity * sizeof(_glfw.wl.activation_requests.array[0]));
if (!_glfw.wl.activation_requests.array) {
_glfw.wl.activation_requests.capacity = 0;
fail("Wayland: Out of memory while allocation activation request");
}
}
glfw_wl_xdg_activation_request *r = _glfw.wl.activation_requests.array + _glfw.wl.activation_requests.sz++;
memset(r, 0, sizeof(*r));
static uintptr_t rq = 0;
r->window_id = window->id;
r->callback = cb; r->callback_data = cb_data;
r->request_id = ++rq; r->token = token;
if (serial != 0)
xdg_activation_token_v1_set_serial(token, serial, _glfw.wl.seat);
xdg_activation_token_v1_set_surface(token, window->wl.surface);
xdg_activation_token_v1_add_listener(token, &activation_token_listener, (void*)r->request_id);
xdg_activation_token_v1_commit(token);
return true;
#undef fail
}
static struct wl_buffer* createShmBuffer(const GLFWimage* image, bool is_opaque, bool init_data)
{
struct wl_shm_pool* pool;
@@ -147,6 +200,7 @@ setCursorImage(_GLFWwindow* window, bool on_theme_change) {
cursorWayland->yhot = image->hotspot_y;
}
debug("Calling wl_pointer_set_cursor in setCursorImage with surface: %p\n", (void*)surface);
wl_pointer_set_cursor(_glfw.wl.pointer, _glfw.wl.serial,
surface,
cursorWayland->xhot / scale,
@@ -197,8 +251,17 @@ static bool checkScaleChange(_GLFWwindow* window)
return false;
}
static void
commit_window_surface_if_safe(_GLFWwindow *window) {
// we only commit if the buffer attached to the surface is the correct size,
// which means that at least one frame is drawn after resizeFramebuffer()
if (!window->wl.waiting_for_swap_to_commit) {
wl_surface_commit(window->wl.surface);
}
}
// Makes the surface considered as XRGB instead of ARGB.
static void setOpaqueRegion(_GLFWwindow* window)
static void setOpaqueRegion(_GLFWwindow* window, bool commit_surface)
{
struct wl_region* region;
@@ -208,7 +271,7 @@ static void setOpaqueRegion(_GLFWwindow* window)
wl_region_add(region, 0, 0, window->wl.width, window->wl.height);
wl_surface_set_opaque_region(window->wl.surface, region);
wl_surface_commit(window->wl.surface);
if (commit_surface) commit_window_surface_if_safe(window);
wl_region_destroy(region);
}
@@ -220,10 +283,21 @@ resizeFramebuffer(_GLFWwindow* window) {
int scaledHeight = window->wl.height * scale;
debug("Resizing framebuffer to: %dx%d at scale: %d\n", window->wl.width, window->wl.height, scale);
wl_egl_window_resize(window->wl.native, scaledWidth, scaledHeight, 0, 0);
if (!window->wl.transparent) setOpaqueRegion(window);
if (!window->wl.transparent) setOpaqueRegion(window, false);
window->wl.waiting_for_swap_to_commit = true;
_glfwInputFramebufferSize(window, scaledWidth, scaledHeight);
}
void
_glfwWaylandAfterBufferSwap(_GLFWwindow* window) {
if (window->wl.waiting_for_swap_to_commit) {
debug("Waiting for swap to commit: swap has happened\n");
window->wl.waiting_for_swap_to_commit = false;
// this is not really needed, since I think eglSwapBuffers() calls wl_surface_commit()
// but lets be safe. See https://gitlab.freedesktop.org/mesa/mesa/-/blob/main/src/egl/drivers/dri2/platform_wayland.c#L1510
wl_surface_commit(window->wl.surface);
}
}
static const char*
clipboard_mime(void) {
@@ -367,9 +441,22 @@ static bool createSurface(_GLFWwindow* window,
wl_surface_set_user_data(window->wl.surface, window);
window->wl.native = wl_egl_window_create(window->wl.surface,
wndconfig->width,
wndconfig->height);
// If we already have been notified of the primary monitor scale, assume
// the window will be created on it and so avoid a rescale roundtrip in the common
// case of the window being shown on the primary monitor or all monitors having the same scale.
// If you change this also change get_window_content_scale() in the kitty code.
GLFWmonitor* monitor = glfwGetPrimaryMonitor();
float xscale = 1.0, yscale = 1.0;
int scale = 1;
if (monitor) {
glfwGetMonitorContentScale(monitor, &xscale, &yscale);
// see wl_monitor.c xscale is always == yscale
if (xscale <= 0.0001 || xscale != xscale || xscale >= 24) xscale = 1.0;
if (xscale > 1) scale = (int)xscale;
}
debug("Creating window at size: %dx%d and scale %d\n", wndconfig->width, wndconfig->height, scale);
window->wl.native = wl_egl_window_create(window->wl.surface, wndconfig->width * scale, wndconfig->height * scale);
if (!window->wl.native)
return false;
@@ -377,11 +464,13 @@ static bool createSurface(_GLFWwindow* window,
window->wl.height = wndconfig->height;
window->wl.user_requested_content_size.width = wndconfig->width;
window->wl.user_requested_content_size.height = wndconfig->height;
window->wl.scale = 1;
window->wl.scale = scale;
if (!window->wl.transparent)
setOpaqueRegion(window);
setOpaqueRegion(window, false);
wl_surface_set_buffer_scale(window->wl.surface, scale);
return true;
}
@@ -487,6 +576,15 @@ static void xdgSurfaceHandleConfigure(void* data,
struct xdg_surface* surface,
uint32_t serial)
{
// The poorly documented pattern Wayland requires is:
// 1) ack the configure,
// 2) set the window geometry
// 3) attach a new buffer of the correct size to the surface
// 4) only then commit the surface.
// buffer is attached only by eglSwapBuffers,
// so we set a flag to not commit the surface till the next swapbuffers. Note that
// wl_egl_window_resize() does not actually resize the buffer until the next draw call
// or buffer state query.
_GLFWwindow* window = data;
xdg_surface_ack_configure(surface, serial);
if (window->wl.pending_state & PENDING_STATE_TOPLEVEL) {
@@ -494,12 +592,9 @@ static void xdgSurfaceHandleConfigure(void* data,
int width = window->wl.pending.width;
int height = window->wl.pending.height;
if (!window->wl.surface_configured_once) {
window->swaps_disallowed = false;
window->wl.waiting_for_swap_to_commit = true;
window->wl.surface_configured_once = true;
if (!width && !height && !new_states && !window->wl.decorations.serverSide && getenv("XAUTHORITY") && strstr(getenv("XAUTHORITY"), "mutter")) {
// https://github.com/kovidgoyal/kitty/issues/4802
debug("Ignoring first empty surface configure event on mutter.\n");
return;
}
}
if (new_states != window->wl.current.toplevel_states ||
@@ -522,12 +617,11 @@ static void xdgSurfaceHandleConfigure(void* data,
window->wl.current.decoration_mode = mode;
}
bool resized = false;
if (window->wl.pending_state) {
int width = window->wl.pending.width, height = window->wl.pending.height;
set_csd_window_geometry(window, &width, &height);
resized = dispatchChangesAfterConfigure(window, width, height);
if (window->wl.decorations.serverSide) {
bool resized = dispatchChangesAfterConfigure(window, width, height);
if (window->wl.decorations.serverSide || window->monitor || window->wl.current.toplevel_states & TOPLEVEL_STATE_FULLSCREEN) {
free_csd_surfaces(window);
} else {
ensure_csd_resources(window);
@@ -536,10 +630,7 @@ static void xdgSurfaceHandleConfigure(void* data,
}
inform_compositor_of_window_geometry(window, "configure");
// if a resize happened there will be a commit at the next render frame so
// dont commit here, GNOME doesnt like it and its not really needed anyway
if (!resized) wl_surface_commit(window->wl.surface);
commit_window_surface_if_safe(window);
window->wl.pending_state = 0;
}
@@ -783,6 +874,7 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window,
initialize_csd_metrics(window);
window->wl.transparent = fbconfig->transparent;
strncpy(window->wl.appId, wndconfig->wl.appId, sizeof(window->wl.appId));
window->swaps_disallowed = true;
if (!createSurface(window, wndconfig))
return false;
@@ -938,7 +1030,7 @@ void _glfwPlatformSetWindowSize(_GLFWwindow* window, int width, int height)
window->wl.width = w; window->wl.height = h;
resizeFramebuffer(window);
ensure_csd_resources(window);
wl_surface_commit(window->wl.surface);
commit_window_surface_if_safe(window);
inform_compositor_of_window_geometry(window, "SetWindowSize");
}
}
@@ -955,7 +1047,7 @@ void _glfwPlatformSetWindowSizeLimits(_GLFWwindow* window,
maxwidth = maxheight = 0;
xdg_toplevel_set_min_size(window->wl.xdg.toplevel, minwidth, minheight);
xdg_toplevel_set_max_size(window->wl.xdg.toplevel, maxwidth, maxheight);
wl_surface_commit(window->wl.surface);
commit_window_surface_if_safe(window);
}
}
@@ -992,7 +1084,7 @@ void _glfwPlatformGetWindowFrameSize(_GLFWwindow* window,
if (window->decorated && !window->monitor && !window->wl.decorations.serverSide)
{
if (top)
*top = window->wl.decorations.metrics.top;
*top = window->wl.decorations.metrics.top - window->wl.decorations.metrics.visible_titlebar_height;
if (left)
*left = window->wl.decorations.metrics.width;
if (right)
@@ -1061,38 +1153,51 @@ void _glfwPlatformHideWindow(_GLFWwindow* window)
xdg_surface_destroy(window->wl.xdg.surface);
window->wl.xdg.toplevel = NULL;
window->wl.xdg.surface = NULL;
window->wl.surface_configured_once = false;
window->swaps_disallowed = true;
}
window->wl.visible = false;
}
void _glfwPlatformRequestWindowAttention(_GLFWwindow* window UNUSED)
{
// TODO
static bool notified = false;
if (!notified) {
_glfwInputError(GLFW_FEATURE_UNIMPLEMENTED,
"Wayland: Window attention request not implemented yet");
notified = true;
static void
request_attention(GLFWwindow *window, const char *token, void *data UNUSED) {
if (window && token && token[0]) xdg_activation_v1_activate(_glfw.wl.xdg_activation_v1, token, ((_GLFWwindow*)window)->wl.surface);
}
static bool
has_activation_in_flight(_GLFWwindow* window, GLFWactivationcallback callback) {
for (size_t i = 0; i < _glfw.wl.activation_requests.sz; i++) {
glfw_wl_xdg_activation_request *r = _glfw.wl.activation_requests.array + i;
if (r->window_id == window->id && r->callback == callback) return true;
}
return false;
}
void _glfwPlatformRequestWindowAttention(_GLFWwindow* window) {
if (!has_activation_in_flight(window, request_attention)) get_activation_token(window, 0, request_attention, NULL);
}
int _glfwPlatformWindowBell(_GLFWwindow* window UNUSED)
{
// TODO: Use an actual Wayland API to implement this when one becomes available
static char tty[L_ctermid + 1];
int fd = open(ctermid(tty), O_WRONLY | O_CLOEXEC);
if (fd > -1) {
int ret = write(fd, "\x07", 1) == 1 ? true : false;
close(fd);
return ret;
}
return false;
}
static void
focus_window(GLFWwindow *window, const char *token, void *data UNUSED) {
if (!window) return;
if (token && token[0]) xdg_activation_v1_activate(_glfw.wl.xdg_activation_v1, token, ((_GLFWwindow*)window)->wl.surface);
else {
_glfwInputError(GLFW_PLATFORM_ERROR, "Wayland: Window focus request via xdg-activation protocol was denied by the compositor. Use a better compositor.");
}
}
void _glfwPlatformFocusWindow(_GLFWwindow* window UNUSED)
{
_glfwInputError(GLFW_FEATURE_UNAVAILABLE,
"Wayland: The platform does not support setting the input focus");
// Attempt to focus the window by using the activation protocol, whether it works
// is entirely compositor dependent and as we all know Wayland and its ecosystem is
// the product of morons.
if (_glfw.wl.input_serial && !has_activation_in_flight(window, focus_window)) get_activation_token(window, _glfw.wl.input_serial, focus_window, NULL);
}
void _glfwPlatformSetWindowMonitor(_GLFWwindow* window,
@@ -1177,7 +1282,7 @@ void _glfwPlatformSetWindowMousePassthrough(_GLFWwindow* window, bool enabled)
}
else
wl_surface_set_input_region(window->wl.surface, 0);
wl_surface_commit(window->wl.surface);
commit_window_surface_if_safe(window);
}
float _glfwPlatformGetWindowOpacity(_GLFWwindow* window UNUSED)
@@ -1241,7 +1346,7 @@ void _glfwPlatformSetCursorPos(_GLFWwindow* window, double x, double y)
zwp_locked_pointer_v1_set_cursor_position_hint(
window->wl.pointerLock.lockedPointer,
wl_fixed_from_double(x), wl_fixed_from_double(y));
wl_surface_commit(window->wl.surface);
commit_window_surface_if_safe(window);
}
}
@@ -1397,6 +1502,7 @@ static void lockPointer(_GLFWwindow* window)
window->wl.pointerLock.relativePointer = relativePointer;
window->wl.pointerLock.lockedPointer = lockedPointer;
debug("Calling wl_pointer_set_cursor in lockPointer with surface: %p\n", NULL);
wl_pointer_set_cursor(_glfw.wl.pointer, _glfw.wl.serial,
NULL, 0, 0);
}
@@ -1433,57 +1539,73 @@ void _glfwPlatformSetCursor(_GLFWwindow* window, _GLFWcursor* cursor)
}
else if (window->cursorMode == GLFW_CURSOR_HIDDEN)
{
debug("Calling wl_pointer_set_cursor in _glfwPlatformSetCursor with surface: %p\n", NULL);
wl_pointer_set_cursor(_glfw.wl.pointer, _glfw.wl.serial, NULL, 0, 0);
}
}
static void send_text(char *text, int fd)
{
if (text) {
size_t len = strlen(text), pos = 0;
monotonic_t start = glfwGetTime();
while (pos < len && glfwGetTime() - start < s_to_monotonic_t(2ll)) {
ssize_t ret = write(fd, text + pos, len - pos);
if (ret < 0) {
if (errno == EAGAIN || errno == EINTR) continue;
_glfwInputError(GLFW_PLATFORM_ERROR,
"Wayland: Could not copy writing to destination fd failed with error: %s", strerror(errno));
break;
}
if (ret > 0) {
start = glfwGetTime();
pos += ret;
}
static bool
write_all(int fd, const char *data, size_t sz) {
monotonic_t start = glfwGetTime();
size_t pos = 0;
while (pos < sz && glfwGetTime() - start < s_to_monotonic_t(2ll)) {
ssize_t ret = write(fd, data + pos, sz - pos);
if (ret < 0) {
if (errno == EAGAIN || errno == EINTR) continue;
_glfwInputError(GLFW_PLATFORM_ERROR,
"Wayland: Could not copy writing to destination fd failed with error: %s", strerror(errno));
return false;
}
if (ret > 0) {
start = glfwGetTime();
pos += ret;
}
}
return pos >= sz;
}
static void
send_clipboard_data(const _GLFWClipboardData *cd, const char *mime, int fd) {
if (strcmp(mime, "text/plain;charset=utf-8") == 0 || strcmp(mime, "UTF8_STRING") == 0 || strcmp(mime, "TEXT") == 0 || strcmp(mime, "STRING") == 0) mime = "text/plain";
GLFWDataChunk chunk = cd->get_data(mime, NULL, cd->ctype);
void *iter = chunk.iter;
if (!iter) return;
bool keep_going = true;
while (keep_going) {
chunk = cd->get_data(mime, iter, cd->ctype);
if (!chunk.sz) break;
if (!write_all(fd, chunk.data, chunk.sz)) keep_going = false;
if (chunk.free) chunk.free((void*)chunk.free_data);
}
cd->get_data(NULL, iter, cd->ctype);
}
static void _glfwSendClipboardText(void *data UNUSED, struct wl_data_source *data_source UNUSED, const char *mime_type, int fd) {
send_clipboard_data(&_glfw.clipboard, mime_type, fd);
close(fd);
}
static void _glfwSendClipboardText(void *data UNUSED, struct wl_data_source *data_source UNUSED, const char *mime_type UNUSED, int fd) {
send_text(_glfw.wl.clipboardString, fd);
}
static void _glfwSendPrimarySelectionText(void *data UNUSED, struct zwp_primary_selection_source_v1 *primary_selection_source UNUSED,
const char *mime_type UNUSED, int fd) {
send_text(_glfw.wl.primarySelectionString, fd);
const char *mime_type, int fd) {
send_clipboard_data(&_glfw.primary, mime_type, fd);
close(fd);
}
static char* read_offer_string(int data_pipe, size_t *data_sz) {
static void
read_offer(int data_pipe, GLFWclipboardwritedatafun write_data, void *object) {
wl_display_flush(_glfw.wl.display);
size_t capacity = 0;
char *buf = NULL;
*data_sz = 0;
struct pollfd fds;
fds.fd = data_pipe;
fds.events = POLLIN;
monotonic_t start = glfwGetTime();
#define bail(...) { \
_glfwInputError(GLFW_PLATFORM_ERROR, __VA_ARGS__); \
free(buf); buf = NULL; \
close(data_pipe); \
return NULL; \
return; \
}
char buf[8192];
while (glfwGetTime() - start < s_to_monotonic_t(2ll)) {
int ret = poll(&fds, 1, 2000);
if (ret == -1) {
@@ -1493,34 +1615,65 @@ static char* read_offer_string(int data_pipe, size_t *data_sz) {
if (!ret) {
bail("Wayland: Failed to read clipboard data from pipe (timed out)");
}
if (capacity <= *data_sz || capacity - *data_sz <= 64) {
capacity += 4096;
buf = realloc(buf, capacity);
if (!buf) {
bail("Wayland: Failed to allocate memory to read clipboard data");
}
}
ret = read(data_pipe, buf + *data_sz, capacity - *data_sz - 1);
ret = read(data_pipe, buf, sizeof(buf));
if (ret == -1) {
if (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK) continue;
bail("Wayland: Failed to read clipboard data from pipe with error: %s", strerror(errno));
}
if (ret == 0) { close(data_pipe); buf[*data_sz] = 0; return buf; }
*data_sz += ret;
if (ret == 0) { close(data_pipe); return; }
if (!write_data(object, buf, ret)) bail("Wayland: call to write_data() failed with data from data offer");
start = glfwGetTime();
}
bail("Wayland: Failed to read clipboard data from pipe (timed out)");
#undef bail
}
static char* read_primary_selection_offer(struct zwp_primary_selection_offer_v1 *primary_selection_offer, const char *mime) {
typedef struct chunked_writer {
char *buf; size_t sz, cap;
} chunked_writer;
static bool
write_chunk(void *object, const char *data, size_t sz) {
chunked_writer *cw = object;
if (cw->cap < cw->sz + sz) {
cw->cap = MAX(cw->cap * 2, cw->sz + 8*sz);
cw->buf = realloc(cw->buf, cw->cap * sizeof(cw->buf[0]));
}
memcpy(cw->buf + cw->sz, data, sz);
cw->sz += sz;
return true;
}
static char*
read_offer_string(int data_pipe, size_t *sz) {
chunked_writer cw = {0};
read_offer(data_pipe, write_chunk, &cw);
if (cw.buf) {
*sz = cw.sz;
return cw.buf;
}
*sz = 0;
return NULL;
}
static void
read_clipboard_data_offer(struct wl_data_offer *data_offer, const char *mime, GLFWclipboardwritedatafun write_data, void *object) {
int pipefd[2];
if (pipe2(pipefd, O_CLOEXEC) != 0) return NULL;
if (pipe2(pipefd, O_CLOEXEC) != 0) return;
wl_data_offer_receive(data_offer, mime, pipefd[1]);
close(pipefd[1]);
read_offer(pipefd[0], write_data, object);
}
static void
read_primary_selection_offer(struct zwp_primary_selection_offer_v1 *primary_selection_offer, const char *mime, GLFWclipboardwritedatafun write_data, void *object) {
int pipefd[2];
if (pipe2(pipefd, O_CLOEXEC) != 0) return;
zwp_primary_selection_offer_v1_receive(primary_selection_offer, mime, pipefd[1]);
close(pipefd[1]);
size_t sz = 0;
return read_offer_string(pipefd[0], &sz);
read_offer(pipefd[0], write_data, object);
}
static char* read_data_offer(struct wl_data_offer *data_offer, const char *mime, size_t *sz) {
@@ -1532,24 +1685,33 @@ static char* read_data_offer(struct wl_data_offer *data_offer, const char *mime,
}
static void data_source_canceled(void *data UNUSED, struct wl_data_source *wl_data_source) {
if (_glfw.wl.dataSourceForClipboard == wl_data_source)
if (_glfw.wl.dataSourceForClipboard == wl_data_source) {
_glfw.wl.dataSourceForClipboard = NULL;
_glfw_free_clipboard_data(&_glfw.clipboard);
}
wl_data_source_destroy(wl_data_source);
}
static void primary_selection_source_canceled(void *data UNUSED, struct zwp_primary_selection_source_v1 *primary_selection_source) {
if (_glfw.wl.dataSourceForPrimarySelection == primary_selection_source)
if (_glfw.wl.dataSourceForPrimarySelection == primary_selection_source) {
_glfw.wl.dataSourceForPrimarySelection = NULL;
_glfw_free_clipboard_data(&_glfw.primary);
}
zwp_primary_selection_source_v1_destroy(primary_selection_source);
}
static void data_source_target(void *data UNUSED, struct wl_data_source *wl_data_source UNUSED, const char* mime UNUSED) {
// KWin aborts if we don't define these even though they are not used for copy/paste
static void dummy_data_source_target(void* data UNUSED, struct wl_data_source* wl_data_source UNUSED, const char* mime_type UNUSED) {
}
static void dummy_data_source_action(void* data UNUSED, struct wl_data_source* wl_data_source UNUSED, uint dnd_action UNUSED) {
}
static const struct wl_data_source_listener data_source_listener = {
.send = _glfwSendClipboardText,
.cancelled = data_source_canceled,
.target = data_source_target,
.target = dummy_data_source_target,
.action = dummy_data_source_action,
};
static const struct zwp_primary_selection_source_v1_listener primary_selection_source_listener = {
@@ -1826,30 +1988,69 @@ static bool _glfwEnsureDataDevice(void) {
return true;
}
void _glfwPlatformSetClipboardString(const char* string)
{
if (!_glfwEnsureDataDevice()) return;
free(_glfw.wl.clipboardString);
_glfw.wl.clipboardString = _glfw_strdup(string);
if (_glfw.wl.dataSourceForClipboard)
wl_data_source_destroy(_glfw.wl.dataSourceForClipboard);
_glfw.wl.dataSourceForClipboard = wl_data_device_manager_create_data_source(_glfw.wl.dataDeviceManager);
if (!_glfw.wl.dataSourceForClipboard)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"Wayland: Cannot copy failed to create data source");
return;
typedef void(*add_offer_func)(void*, const char *mime);
void
_glfwPlatformSetClipboard(GLFWClipboardType t) {
_GLFWClipboardData *cd = NULL;
void *data_source;
add_offer_func f;
if (t == GLFW_CLIPBOARD) {
if (!_glfwEnsureDataDevice()) return;
cd = &_glfw.clipboard;
f = (add_offer_func)wl_data_source_offer;
if (_glfw.wl.dataSourceForClipboard) wl_data_source_destroy(_glfw.wl.dataSourceForClipboard);
_glfw.wl.dataSourceForClipboard = wl_data_device_manager_create_data_source(_glfw.wl.dataDeviceManager);
if (!_glfw.wl.dataSourceForClipboard)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"Wayland: Cannot copy failed to create data source");
return;
}
wl_data_source_add_listener(_glfw.wl.dataSourceForClipboard, &data_source_listener, NULL);
data_source = _glfw.wl.dataSourceForClipboard;
} else {
if (!_glfw.wl.primarySelectionDevice) {
static bool warned_about_primary_selection_device = false;
if (!warned_about_primary_selection_device) {
_glfwInputError(GLFW_PLATFORM_ERROR,
"Wayland: Cannot copy no primary selection device available");
warned_about_primary_selection_device = true;
}
return;
}
cd = &_glfw.primary;
f = (add_offer_func)zwp_primary_selection_source_v1_offer;
if (_glfw.wl.dataSourceForPrimarySelection) zwp_primary_selection_source_v1_destroy(_glfw.wl.dataSourceForPrimarySelection);
_glfw.wl.dataSourceForPrimarySelection = zwp_primary_selection_device_manager_v1_create_source(_glfw.wl.primarySelectionDeviceManager);
if (!_glfw.wl.dataSourceForPrimarySelection)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"Wayland: Cannot copy failed to create primary selection source");
return;
}
zwp_primary_selection_source_v1_add_listener(_glfw.wl.dataSourceForPrimarySelection, &primary_selection_source_listener, NULL);
data_source = _glfw.wl.dataSourceForPrimarySelection;
}
f(data_source, clipboard_mime());
for (size_t i = 0; i < cd->num_mime_types; i++) {
if (strcmp(cd->mime_types[i], "text/plain") == 0) {
f(data_source, "TEXT");
f(data_source, "STRING");
f(data_source, "UTF8_STRING");
f(data_source, "text/plain;charset=utf-8");
}
f(data_source, cd->mime_types[i]);
}
wl_data_source_add_listener(_glfw.wl.dataSourceForClipboard, &data_source_listener, NULL);
wl_data_source_offer(_glfw.wl.dataSourceForClipboard, clipboard_mime());
wl_data_source_offer(_glfw.wl.dataSourceForClipboard, "text/plain");
wl_data_source_offer(_glfw.wl.dataSourceForClipboard, "text/plain;charset=utf-8");
wl_data_source_offer(_glfw.wl.dataSourceForClipboard, "TEXT");
wl_data_source_offer(_glfw.wl.dataSourceForClipboard, "STRING");
wl_data_source_offer(_glfw.wl.dataSourceForClipboard, "UTF8_STRING");
struct wl_callback *callback = wl_display_sync(_glfw.wl.display);
static const struct wl_callback_listener clipboard_copy_callback_listener = {.done = clipboard_copy_callback_done};
wl_callback_add_listener(callback, &clipboard_copy_callback_listener, _glfw.wl.dataSourceForClipboard);
if (t == GLFW_CLIPBOARD) {
static const struct wl_callback_listener clipboard_copy_callback_listener = {.done = clipboard_copy_callback_done};
wl_callback_add_listener(callback, &clipboard_copy_callback_listener, _glfw.wl.dataSourceForClipboard);
} else {
static const struct wl_callback_listener primary_selection_copy_callback_listener = {.done = primary_selection_copy_callback_done};
wl_callback_add_listener(callback, &primary_selection_copy_callback_listener, _glfw.wl.dataSourceForPrimarySelection);
}
}
static bool
@@ -1867,81 +2068,47 @@ plain_text_mime_for_offer(const _GLFWWaylandDataOffer *d) {
A("text/plain");
A("UTF8_STRING");
A("STRING");
A("TEXT");
#undef A
return NULL;
}
const char* _glfwPlatformGetClipboardString(void)
{
void
_glfwPlatformGetClipboard(GLFWClipboardType clipboard_type, const char* mime_type, GLFWclipboardwritedatafun write_data, void *object) {
_GLFWWaylandOfferType offer_type = clipboard_type == GLFW_PRIMARY_SELECTION ? PRIMARY_SELECTION : CLIPBOARD;
for (size_t i = 0; i < arraysz(_glfw.wl.dataOffers); i++) {
_GLFWWaylandDataOffer *d = _glfw.wl.dataOffers + i;
if (d->id && d->offer_type == CLIPBOARD) {
if (d->is_self_offer) return _glfw.wl.clipboardString;
const char *mime = plain_text_mime_for_offer(d);
if (mime) {
free(_glfw.wl.pasteString);
size_t sz = 0;
_glfw.wl.pasteString = read_data_offer(d->id, mime, &sz);
return _glfw.wl.pasteString;
if (d->id && d->offer_type == offer_type) {
if (d->is_self_offer) {
write_data(object, NULL, 1);
return;
}
}
}
return NULL;
}
void _glfwPlatformSetPrimarySelectionString(const char* string)
{
if (!_glfw.wl.primarySelectionDevice) {
static bool warned_about_primary_selection_device = false;
if (!warned_about_primary_selection_device) {
_glfwInputError(GLFW_PLATFORM_ERROR,
"Wayland: Cannot copy no primary selection device available");
warned_about_primary_selection_device = true;
}
return;
}
if (_glfw.wl.primarySelectionString == string) return;
free(_glfw.wl.primarySelectionString);
_glfw.wl.primarySelectionString = _glfw_strdup(string);
if (_glfw.wl.dataSourceForPrimarySelection)
zwp_primary_selection_source_v1_destroy(_glfw.wl.dataSourceForPrimarySelection);
_glfw.wl.dataSourceForPrimarySelection = zwp_primary_selection_device_manager_v1_create_source(_glfw.wl.primarySelectionDeviceManager);
if (!_glfw.wl.dataSourceForPrimarySelection)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"Wayland: Cannot copy failed to create primary selection source");
return;
}
zwp_primary_selection_source_v1_add_listener(_glfw.wl.dataSourceForPrimarySelection, &primary_selection_source_listener, NULL);
zwp_primary_selection_source_v1_offer(_glfw.wl.dataSourceForPrimarySelection, clipboard_mime());
zwp_primary_selection_source_v1_offer(_glfw.wl.dataSourceForPrimarySelection, "text/plain");
zwp_primary_selection_source_v1_offer(_glfw.wl.dataSourceForPrimarySelection, "text/plain;charset=utf-8");
zwp_primary_selection_source_v1_offer(_glfw.wl.dataSourceForPrimarySelection, "TEXT");
zwp_primary_selection_source_v1_offer(_glfw.wl.dataSourceForPrimarySelection, "STRING");
zwp_primary_selection_source_v1_offer(_glfw.wl.dataSourceForPrimarySelection, "UTF8_STRING");
struct wl_callback *callback = wl_display_sync(_glfw.wl.display);
static const struct wl_callback_listener primary_selection_copy_callback_listener = {.done = primary_selection_copy_callback_done};
wl_callback_add_listener(callback, &primary_selection_copy_callback_listener, _glfw.wl.dataSourceForPrimarySelection);
}
const char* _glfwPlatformGetPrimarySelectionString(void)
{
if (_glfw.wl.dataSourceForPrimarySelection != NULL) return _glfw.wl.primarySelectionString;
for (size_t i = 0; i < arraysz(_glfw.wl.dataOffers); i++) {
_GLFWWaylandDataOffer *d = _glfw.wl.dataOffers + i;
if (d->id && d->is_primary && d->offer_type == PRIMARY_SELECTION) {
if (d->is_self_offer) return _glfw.wl.primarySelectionString;
const char *mime = plain_text_mime_for_offer(d);
if (mime) {
free(_glfw.wl.pasteString);
_glfw.wl.pasteString = read_primary_selection_offer(d->id, mime);
return _glfw.wl.pasteString;
if (mime_type == NULL) {
bool ok = true;
for (size_t o = 0; o < d->mimes_count; o++) {
const char *q = d->mimes[o];
if (strchr(d->mimes[0], '/')) {
if (strcmp(q, clipboard_mime()) == 0) continue;
if (strcmp(q, "text/plain;charset=utf-8") == 0) q = "text/plain";
} else {
if (strcmp(q, "UTF8_STRING") == 0 || strcmp(q, "STRING") == 0 || strcmp(q, "TEXT") == 0) q = "text/plain";
}
if (ok) ok = write_data(object, q, strlen(q));
}
return;
}
if (strcmp(mime_type, "text/plain") == 0) {
mime_type = plain_text_mime_for_offer(d);
if (!mime_type) return;
}
if (d->is_primary) {
read_primary_selection_offer(d->id, mime_type, write_data, object);
} else {
read_clipboard_data_offer(d->id, mime_type, write_data, object);
}
break;
}
}
return NULL;
}
EGLenum _glfwPlatformGetEGLPlatform(EGLint** attribs UNUSED)
@@ -2063,6 +2230,18 @@ GLFWAPI struct wl_surface* glfwGetWaylandWindow(GLFWwindow* handle)
return window->wl.surface;
}
GLFWAPI void glfwWaylandActivateWindow(GLFWwindow* handle, const char *activation_token) {
_GLFWwindow* window = (_GLFWwindow*) handle;
_GLFW_REQUIRE_INIT();
if (activation_token && activation_token[0]) xdg_activation_v1_activate(_glfw.wl.xdg_activation_v1, activation_token, window->wl.surface);
}
GLFWAPI void glfwWaylandRunWithActivationToken(GLFWwindow *handle, GLFWactivationcallback cb, void *cb_data) {
_GLFWwindow* window = (_GLFWwindow*) handle;
_GLFW_REQUIRE_INIT();
get_activation_token(window, _glfw.wl.input_serial, cb, cb_data);
}
GLFWAPI int glfwGetNativeKeyForName(const char* keyName, bool caseSensitive) {
return glfw_xkb_keysym_from_name(keyName, caseSensitive);
}
@@ -2071,12 +2250,19 @@ GLFWAPI void glfwRequestWaylandFrameEvent(GLFWwindow *handle, unsigned long long
_GLFWwindow* window = (_GLFWwindow*) handle;
static const struct wl_callback_listener frame_listener = { .done = frame_handle_redraw };
if (window->wl.frameCallbackData.current_wl_callback) wl_callback_destroy(window->wl.frameCallbackData.current_wl_callback);
window->wl.frameCallbackData.id = id;
window->wl.frameCallbackData.callback = callback;
window->wl.frameCallbackData.current_wl_callback = wl_surface_frame(window->wl.surface);
if (window->wl.frameCallbackData.current_wl_callback) {
wl_callback_add_listener(window->wl.frameCallbackData.current_wl_callback, &frame_listener, window);
wl_surface_commit(window->wl.surface);
if (window->wl.waiting_for_swap_to_commit) {
callback(id);
window->wl.frameCallbackData.id = 0;
window->wl.frameCallbackData.callback = NULL;
window->wl.frameCallbackData.current_wl_callback = NULL;
} else {
window->wl.frameCallbackData.id = id;
window->wl.frameCallbackData.callback = callback;
window->wl.frameCallbackData.current_wl_callback = wl_surface_frame(window->wl.surface);
if (window->wl.frameCallbackData.current_wl_callback) {
wl_callback_add_listener(window->wl.frameCallbackData.current_wl_callback, &frame_listener, window);
commit_window_surface_if_safe(window);
}
}
}

14
glfw/x11_init.c vendored
View File

@@ -137,6 +137,8 @@ static void detectEWMH(void)
getAtomIfSupported(supportedAtoms, atomCount, "_NET_WM_WINDOW_TYPE");
_glfw.x11.NET_WM_WINDOW_TYPE_NORMAL =
getAtomIfSupported(supportedAtoms, atomCount, "_NET_WM_WINDOW_TYPE_NORMAL");
_glfw.x11.NET_WM_WINDOW_TYPE_DOCK =
getAtomIfSupported(supportedAtoms, atomCount, "_NET_WM_WINDOW_TYPE_DOCK");
_glfw.x11.NET_WORKAREA =
getAtomIfSupported(supportedAtoms, atomCount, "_NET_WORKAREA");
_glfw.x11.NET_CURRENT_DESKTOP =
@@ -147,6 +149,8 @@ static void detectEWMH(void)
getAtomIfSupported(supportedAtoms, atomCount, "_NET_FRAME_EXTENTS");
_glfw.x11.NET_REQUEST_FRAME_EXTENTS =
getAtomIfSupported(supportedAtoms, atomCount, "_NET_REQUEST_FRAME_EXTENTS");
_glfw.x11.NET_WM_STRUT_PARTIAL =
getAtomIfSupported(supportedAtoms, atomCount, "_NET_WM_STRUT_PARTIAL");
XFree(supportedAtoms);
}
@@ -680,8 +684,14 @@ void _glfwPlatformTerminate(void)
glfw_xkb_release(&_glfw.x11.xkb);
glfw_dbus_terminate(&_glfw.x11.dbus);
free(_glfw.x11.primarySelectionString);
free(_glfw.x11.clipboardString);
if (_glfw.x11.mime_atoms.array) {
for (size_t i = 0; i < _glfw.x11.mime_atoms.sz; i++) {
free((void*)_glfw.x11.mime_atoms.array[i].mime);
}
free(_glfw.x11.mime_atoms.array);
}
if (_glfw.x11.clipboard_atoms.array) { free(_glfw.x11.clipboard_atoms.array); }
if (_glfw.x11.primary_atoms.array) { free(_glfw.x11.primary_atoms.array); }
if (_glfw.x11.display)
{

18
glfw/x11_platform.h vendored
View File

@@ -207,6 +207,16 @@ typedef struct _GLFWwindowX11
} _GLFWwindowX11;
typedef struct MimeAtom {
Atom atom;
const char* mime;
} MimeAtom;
typedef struct AtomArray {
MimeAtom *array;
size_t sz, capacity;
} AtomArray;
// X11-specific global data
//
typedef struct _GLFWlibraryX11
@@ -225,10 +235,6 @@ typedef struct _GLFWlibraryX11
XContext context;
// Most recent error code received by X error handler
int errorCode;
// Primary selection string (while the primary selection is owned)
char* primarySelectionString;
// Clipboard string (while the selection is owned)
char* clipboardString;
// Where to place the cursor when re-enabled
double restoreCursorPosX, restoreCursorPosY;
// The window whose disabled cursor mode is active
@@ -247,6 +253,7 @@ typedef struct _GLFWlibraryX11
Atom NET_WM_PING;
Atom NET_WM_WINDOW_TYPE;
Atom NET_WM_WINDOW_TYPE_NORMAL;
Atom NET_WM_WINDOW_TYPE_DOCK;
Atom NET_WM_STATE;
Atom NET_WM_STATE_ABOVE;
Atom NET_WM_STATE_FULLSCREEN;
@@ -262,6 +269,7 @@ typedef struct _GLFWlibraryX11
Atom NET_ACTIVE_WINDOW;
Atom NET_FRAME_EXTENTS;
Atom NET_REQUEST_FRAME_EXTENTS;
Atom NET_WM_STRUT_PARTIAL;
Atom MOTIF_WM_HINTS;
// Xdnd (drag and drop) atoms
@@ -291,6 +299,8 @@ typedef struct _GLFWlibraryX11
// XRM database atom
Atom RESOURCE_MANAGER;
// Atoms for MIME types
AtomArray mime_atoms, clipboard_atoms, primary_atoms;
struct {
bool available;

374
glfw/x11_window.c vendored
View File

@@ -716,19 +716,60 @@ static bool createNativeWindow(_GLFWwindow* window,
return true;
}
static size_t
get_clipboard_data(const _GLFWClipboardData *cd, const char *mime, char **data) {
*data = NULL;
GLFWDataChunk chunk = cd->get_data(mime, NULL, cd->ctype);
char *buf = NULL;
size_t sz = 0, cap = 0;
void *iter = chunk.iter;
if (!iter) return 0;
while (true) {
chunk = cd->get_data(mime, iter, cd->ctype);
if (!chunk.sz) break;
if (cap < sz + chunk.sz) {
cap = MAX(cap * 2, sz + 4 * chunk.sz);
buf = realloc(buf, cap * sizeof(buf[0]));
}
memcpy(buf + sz, chunk.data, chunk.sz);
sz += chunk.sz;
if (chunk.free) chunk.free((void*)chunk.free_data);
}
*data = buf;
cd->get_data(NULL, iter, cd->ctype);
return sz;
}
static void
get_atom_names(const Atom *atoms, int count, char **atom_names) {
_glfwGrabErrorHandlerX11();
XGetAtomNames(_glfw.x11.display, (Atom*)atoms, count, atom_names);
_glfwReleaseErrorHandlerX11();
if (_glfw.x11.errorCode != Success) {
for (int i = 0; i < count; i++) {
_glfwGrabErrorHandlerX11();
atom_names[i] = XGetAtomName(_glfw.x11.display, atoms[i]);
_glfwReleaseErrorHandlerX11();
if (_glfw.x11.errorCode != Success) atom_names[i] = NULL;
}
}
}
// Set the specified property to the selection converted to the requested target
//
static Atom writeTargetToProperty(const XSelectionRequestEvent* request)
{
int i;
char* selectionString = NULL;
const Atom formats[] = { _glfw.x11.UTF8_STRING, XA_STRING };
const int formatCount = sizeof(formats) / sizeof(formats[0]);
const AtomArray *aa;
const _GLFWClipboardData *cd;
if (request->selection == _glfw.x11.PRIMARY)
selectionString = _glfw.x11.primarySelectionString;
else
selectionString = _glfw.x11.clipboardString;
if (request->selection == _glfw.x11.PRIMARY) {
aa = &_glfw.x11.primary_atoms;
cd = &_glfw.primary;
} else {
aa = &_glfw.x11.clipboard_atoms;
cd = &_glfw.clipboard;
}
if (request->property == None)
{
@@ -741,11 +782,10 @@ static Atom writeTargetToProperty(const XSelectionRequestEvent* request)
{
// The list of supported targets was requested
const Atom targets[] = { _glfw.x11.TARGETS,
_glfw.x11.MULTIPLE,
_glfw.x11.UTF8_STRING,
XA_STRING };
Atom *targets = calloc(aa->sz + 2, sizeof(Atom));
targets[0] = _glfw.x11.TARGETS;
targets[1] = _glfw.x11.MULTIPLE;
for (size_t i = 0; i < aa->sz; i++) targets[i+2] = aa->array[i].atom;
XChangeProperty(_glfw.x11.display,
request->requestor,
request->property,
@@ -753,8 +793,8 @@ static Atom writeTargetToProperty(const XSelectionRequestEvent* request)
32,
PropModeReplace,
(unsigned char*) targets,
sizeof(targets) / sizeof(targets[0]));
aa->sz + 2);
free(targets);
return request->property;
}
@@ -763,7 +803,7 @@ static Atom writeTargetToProperty(const XSelectionRequestEvent* request)
// Multiple conversions were requested
Atom* targets;
unsigned long i, count;
size_t i, j, count;
count = _glfwGetWindowPropertyX11(request->requestor,
request->property,
@@ -772,24 +812,25 @@ static Atom writeTargetToProperty(const XSelectionRequestEvent* request)
for (i = 0; i < count; i += 2)
{
int j;
for (j = 0; j < formatCount; j++)
for (j = 0; j < aa->sz; j++)
{
if (targets[i] == formats[j])
if (targets[i] == aa->array[j].atom)
break;
}
if (j < formatCount)
if (j < aa->sz)
{
if (selectionString) XChangeProperty(_glfw.x11.display,
char *data = NULL; size_t sz = get_clipboard_data(cd, aa->array[j].mime, &data);
if (data) XChangeProperty(_glfw.x11.display,
request->requestor,
targets[i + 1],
targets[i],
8,
PropModeReplace,
(unsigned char *) selectionString,
strlen(selectionString));
(unsigned char *) data,
sz);
free(data);
}
else
targets[i + 1] = None;
@@ -828,20 +869,22 @@ static Atom writeTargetToProperty(const XSelectionRequestEvent* request)
// Conversion to a data target was requested
for (i = 0; i < formatCount; i++)
for (size_t i = 0; i < aa->sz; i++)
{
if (request->target == formats[i])
if (request->target == aa->array[i].atom)
{
// The requested target is one we support
if (selectionString) XChangeProperty(_glfw.x11.display,
char *data = NULL; size_t sz = get_clipboard_data(cd, aa->array[i].mime, &data);
if (data) XChangeProperty(_glfw.x11.display,
request->requestor,
request->property,
request->target,
8,
PropModeReplace,
(unsigned char *) selectionString,
strlen(selectionString));
(unsigned char *) data,
sz);
free(data);
return request->property;
}
@@ -856,13 +899,11 @@ static void handleSelectionClear(XEvent* event)
{
if (event->xselectionclear.selection == _glfw.x11.PRIMARY)
{
free(_glfw.x11.primarySelectionString);
_glfw.x11.primarySelectionString = NULL;
_glfw_free_clipboard_data(&_glfw.primary);
}
else
{
free(_glfw.x11.clipboardString);
_glfw.x11.clipboardString = NULL;
_glfw_free_clipboard_data(&_glfw.clipboard);
}
}
@@ -881,34 +922,21 @@ static void handleSelectionRequest(XEvent* event)
XSendEvent(_glfw.x11.display, request->requestor, False, 0, &reply);
}
static const char* getSelectionString(Atom selection)
static void
getSelectionString(Atom selection, Atom *targets, size_t num_targets, GLFWclipboardwritedatafun write_data, void *object, bool report_not_found)
{
char** selectionString = NULL;
const Atom targets[] = { _glfw.x11.UTF8_STRING, XA_STRING };
const size_t targetCount = sizeof(targets) / sizeof(targets[0]);
if (selection == _glfw.x11.PRIMARY)
selectionString = &_glfw.x11.primarySelectionString;
else
selectionString = &_glfw.x11.clipboardString;
if (XGetSelectionOwner(_glfw.x11.display, selection) ==
_glfw.x11.helperWindowHandle)
{
// Instead of doing a large number of X round-trips just to put this
// string into a window property and then read it back, just return it
return *selectionString;
#define XFREE(x) { if (x) XFree(x); x = NULL; }
if (XGetSelectionOwner(_glfw.x11.display, selection) == _glfw.x11.helperWindowHandle) {
write_data(object, NULL, 1);
return;
}
free(*selectionString);
*selectionString = NULL;
for (size_t i = 0; i < targetCount; i++)
bool found = false;
for (size_t i = 0; !found && i < num_targets; i++)
{
char* data;
Atom actualType;
int actualFormat;
unsigned long itemCount, bytesAfter;
char* data = NULL;
Atom actualType = None;
int actualFormat = 0;
unsigned long itemCount = 0, bytesAfter = 0;
monotonic_t start = glfwGetTime();
XEvent notification, dummy;
@@ -925,8 +953,7 @@ static const char* getSelectionString(Atom selection)
&notification))
{
monotonic_t time = glfwGetTime();
if (time - start > s_to_monotonic_t(2ll))
return "";
if (time - start > s_to_monotonic_t(2ll)) return;
waitForX11Event(s_to_monotonic_t(2ll) - (time - start));
}
@@ -953,9 +980,6 @@ static const char* getSelectionString(Atom selection)
if (actualType == _glfw.x11.INCR)
{
size_t size = 1;
char* string = NULL;
for (;;)
{
start = glfwGetTime();
@@ -966,13 +990,12 @@ static const char* getSelectionString(Atom selection)
{
monotonic_t time = glfwGetTime();
if (time - start > s_to_monotonic_t(2ll)) {
free(string);
return "";
return;
}
waitForX11Event(s_to_monotonic_t(2ll) - (time - start));
}
XFree(data);
XFREE(data);
XGetWindowProperty(_glfw.x11.display,
notification.xselection.requestor,
notification.xselection.property,
@@ -988,47 +1011,41 @@ static const char* getSelectionString(Atom selection)
if (itemCount)
{
size += itemCount;
string = realloc(string, size);
string[size - itemCount - 1] = '\0';
strcat(string, data);
}
if (!itemCount)
{
if (targets[i] == XA_STRING)
{
*selectionString = convertLatin1toUTF8(string);
free(string);
const char *string = data;
if (targets[i] == XA_STRING) {
string = convertLatin1toUTF8(data);
itemCount = strlen(string);
}
else
*selectionString = string;
bool ok = write_data(object, string, itemCount);
if (string != data) free((void*)string);
if (!ok) { XFREE(data); break; }
} else { found = true; break; }
break;
}
}
}
else if (actualType == targets[i])
{
if (targets[i] == XA_STRING)
*selectionString = convertLatin1toUTF8(data);
else
*selectionString = _glfw_strdup(data);
if (targets[i] == XA_STRING) {
const char *string = convertLatin1toUTF8(data);
write_data(object, string, strlen(string)); free((void*)string);
} else write_data(object, data, itemCount);
found = true;
}
else if (actualType == XA_ATOM && targets[i] == _glfw.x11.TARGETS) {
found = true;
write_data(object, data, sizeof(Atom) * itemCount);
}
XFree(data);
XFREE(data);
if (*selectionString)
break;
}
if (!*selectionString)
if (!found && report_not_found)
{
_glfwInputError(GLFW_FORMAT_UNAVAILABLE,
"X11: Failed to convert selection to string");
"X11: Failed to convert selection to data from clipboard");
}
return *selectionString;
#undef XFREE
}
// Make the specified window and its video mode active on its monitor
@@ -1098,21 +1115,6 @@ static void onConfigChange(void)
}
}
static void
get_atom_names(Atom *atoms, int count, char **atom_names) {
_glfwGrabErrorHandlerX11();
XGetAtomNames(_glfw.x11.display, atoms, count, atom_names);
_glfwReleaseErrorHandlerX11();
if (_glfw.x11.errorCode != Success) {
for (int i = 0; i < count; i++) {
_glfwGrabErrorHandlerX11();
atom_names[i] = XGetAtomName(_glfw.x11.display, atoms[i]);
_glfwReleaseErrorHandlerX11();
if (_glfw.x11.errorCode != Success) atom_names[i] = NULL;
}
}
}
// Process the specified X event
//
static void processEvent(XEvent *event)
@@ -2849,51 +2851,120 @@ void _glfwPlatformSetCursor(_GLFWwindow* window, _GLFWcursor* cursor UNUSED)
}
}
void _glfwPlatformSetClipboardString(const char* string)
{
char* copy = _glfw_strdup(string);
free(_glfw.x11.clipboardString);
_glfw.x11.clipboardString = copy;
static MimeAtom atom_for_mime(const char *mime) {
for (size_t i = 0; i < _glfw.x11.mime_atoms.sz; i++) {
MimeAtom ma = _glfw.x11.mime_atoms.array[i];
if (strcmp(ma.mime, mime) == 0) {
return ma;
}
}
MimeAtom ma = {.mime=_glfw_strdup(mime), .atom=XInternAtom(_glfw.x11.display, mime, 0)};
if (_glfw.x11.mime_atoms.capacity < _glfw.x11.mime_atoms.sz + 1) {
_glfw.x11.mime_atoms.capacity += 32;
_glfw.x11.mime_atoms.array = realloc(_glfw.x11.mime_atoms.array, _glfw.x11.mime_atoms.capacity * sizeof(_glfw.x11.mime_atoms.array[0]));
}
_glfw.x11.mime_atoms.array[_glfw.x11.mime_atoms.sz++] = ma;
return ma;
}
XSetSelectionOwner(_glfw.x11.display,
_glfw.x11.CLIPBOARD,
_glfw.x11.helperWindowHandle,
CurrentTime);
if (XGetSelectionOwner(_glfw.x11.display, _glfw.x11.CLIPBOARD) !=
_glfw.x11.helperWindowHandle)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"X11: Failed to become owner of clipboard selection");
void _glfwPlatformSetClipboard(GLFWClipboardType t) {
Atom which = None;
_GLFWClipboardData *cd = NULL;
AtomArray *aa = NULL;
switch (t) {
case GLFW_CLIPBOARD: which = _glfw.x11.CLIPBOARD; cd = &_glfw.clipboard; aa = &_glfw.x11.clipboard_atoms; break;
case GLFW_PRIMARY_SELECTION: which = _glfw.x11.PRIMARY; cd = &_glfw.primary; aa = &_glfw.x11.primary_atoms; break;
}
XSetSelectionOwner(_glfw.x11.display, which, _glfw.x11.helperWindowHandle, CurrentTime);
if (XGetSelectionOwner(_glfw.x11.display, which) != _glfw.x11.helperWindowHandle) {
_glfwInputError(GLFW_PLATFORM_ERROR, "X11: Failed to become owner of clipboard selection");
}
if (aa->capacity < cd->num_mime_types + 32) {
aa->capacity = cd->num_mime_types + 32;
aa->array = reallocarray(aa->array, aa->capacity, sizeof(aa->array[0]));
}
aa->sz = 0;
for (size_t i = 0; i < cd->num_mime_types; i++) {
MimeAtom *a = aa->array + aa->sz++;
*a = atom_for_mime(cd->mime_types[i]);
if (strcmp(cd->mime_types[i], "text/plain") == 0) {
a = aa->array + aa->sz++;
a->atom = _glfw.x11.UTF8_STRING;
a->mime = "text/plain";
}
}
}
const char* _glfwPlatformGetClipboardString(void)
{
return getSelectionString(_glfw.x11.CLIPBOARD);
typedef struct chunked_writer {
char *buf; size_t sz, cap;
bool is_self_offer;
} chunked_writer;
static bool
write_chunk(void *object, const char *data, size_t sz) {
chunked_writer *cw = object;
if (data) {
if (cw->cap < cw->sz + sz) {
cw->cap = MAX(cw->cap * 2, cw->sz + 8*sz);
cw->buf = realloc(cw->buf, cw->cap * sizeof(cw->buf[0]));
}
memcpy(cw->buf + cw->sz, data, sz);
cw->sz += sz;
} else if (sz == 1) cw->is_self_offer = true;
return true;
}
void _glfwPlatformSetPrimarySelectionString(const char* string)
{
free(_glfw.x11.primarySelectionString);
_glfw.x11.primarySelectionString = _glfw_strdup(string);
XSetSelectionOwner(_glfw.x11.display,
_glfw.x11.PRIMARY,
_glfw.x11.helperWindowHandle,
CurrentTime);
if (XGetSelectionOwner(_glfw.x11.display, _glfw.x11.PRIMARY) !=
_glfw.x11.helperWindowHandle)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"X11: Failed to become owner of primary selection");
static void
get_available_mime_types(Atom which_clipboard, GLFWclipboardwritedatafun write_data, void *object) {
chunked_writer cw = {0};
getSelectionString(which_clipboard, &_glfw.x11.TARGETS, 1, write_chunk, &cw, false);
if (cw.is_self_offer) {
write_data(object, NULL, 1);
return;
}
size_t count = 0;
bool ok = true;
if (cw.buf) {
Atom *atoms = (Atom*)cw.buf;
count = cw.sz / sizeof(Atom);
char **names = calloc(count, sizeof(char*));
get_atom_names(atoms, count, names);
for (size_t i = 0; i < count; i++) {
if (strchr(names[i], '/')) {
if (ok) ok = write_data(object, names[i], strlen(names[i]));
} else {
if (atoms[i] == _glfw.x11.UTF8_STRING || atoms[i] == XA_STRING) {
if (ok) ok = write_data(object, "text/plain", strlen("text/plain"));
}
}
XFree(names[i]);
}
free(cw.buf);
free(names);
}
}
const char* _glfwPlatformGetPrimarySelectionString(void)
{
return getSelectionString(_glfw.x11.PRIMARY);
void
_glfwPlatformGetClipboard(GLFWClipboardType clipboard_type, const char* mime_type, GLFWclipboardwritedatafun write_data, void *object) {
Atom atoms[4], which = clipboard_type == GLFW_PRIMARY_SELECTION ? _glfw.x11.PRIMARY : _glfw.x11.CLIPBOARD;
if (mime_type == NULL) {
get_available_mime_types(which, write_data, object);
return;
}
size_t count = 0;
if (strcmp(mime_type, "text/plain") == 0) {
// UTF8_STRING is what xclip uses by default, and there are people out there that expect to be able to paste from it with a single read operation. See https://github.com/kovidgoyal/kitty/issues/5842
// Also ancient versions of GNOME use DOS line endings even for text/plain;charset=utf-8. See https://github.com/kovidgoyal/kitty/issues/5528#issuecomment-1325348218
atoms[count++] = _glfw.x11.UTF8_STRING;
// we need to do this because GTK/GNOME is moronic they convert text/plain to DOS line endings, see
// https://gitlab.gnome.org/GNOME/gtk/-/issues/2307
atoms[count++] = atom_for_mime("text/plain;charset=utf-8").atom;
atoms[count++] = atom_for_mime("text/plain").atom;
atoms[count++] = XA_STRING;
} else {
atoms[count++] = atom_for_mime(mime_type).atom;
}
getSelectionString(which, atoms, count, write_data, object, true);
}
EGLenum _glfwPlatformGetEGLPlatform(EGLint** attribs)
@@ -3134,3 +3205,18 @@ GLFWAPI int glfwSetX11LaunchCommand(GLFWwindow *handle, char **argv, int argc)
_GLFWwindow* window = (_GLFWwindow*) handle;
return XSetCommand(_glfw.x11.display, window->x11.handle, argv, argc);
}
GLFWAPI void glfwSetX11WindowAsDock(int32_t x11_window_id) {
_GLFW_REQUIRE_INIT();
Atom type = _glfw.x11.NET_WM_WINDOW_TYPE_DOCK;
XChangeProperty(_glfw.x11.display, x11_window_id,
_glfw.x11.NET_WM_WINDOW_TYPE, XA_ATOM, 32,
PropModeReplace, (unsigned char*) &type, 1);
}
GLFWAPI void glfwSetX11WindowStrut(int32_t x11_window_id, uint32_t dimensions[12]) {
_GLFW_REQUIRE_INIT();
XChangeProperty(_glfw.x11.display, x11_window_id,
_glfw.x11.NET_WM_STRUT_PARTIAL, XA_CARDINAL, 32,
PropModeReplace, (unsigned char*) dimensions, 12);
}

18
go.mod Normal file
View File

@@ -0,0 +1,18 @@
module kitty
go 1.19
require (
github.com/ALTree/bigfloat v0.0.0-20220102081255-38c8b72a9924
github.com/disintegration/imaging v1.6.2
github.com/google/go-cmp v0.5.8
github.com/google/uuid v1.3.0
github.com/jamesruan/go-rfc1924 v0.0.0-20170108144916-2767ca7c638f
github.com/seancfoley/ipaddress-go v1.2.1
golang.org/x/crypto v0.0.0-20220924013350-4ba4fb4dd9e7
golang.org/x/exp v0.0.0-20220921164117-439092de6870
golang.org/x/image v0.2.0
golang.org/x/sys v0.0.0-20220919091848-fb04ddd9f9c8
)
require github.com/seancfoley/bintree v1.1.0 // indirect

47
go.sum Normal file
View File

@@ -0,0 +1,47 @@
github.com/ALTree/bigfloat v0.0.0-20220102081255-38c8b72a9924 h1:DG4UyTVIujioxwJc8Zj8Nabz1L1wTgQ/xNBSQDfdP3I=
github.com/ALTree/bigfloat v0.0.0-20220102081255-38c8b72a9924/go.mod h1:+NaH2gLeY6RPBPPQf4aRotPPStg+eXc8f9ZaE4vRfD4=
github.com/disintegration/imaging v1.6.2 h1:w1LecBlG2Lnp8B3jk5zSuNqd7b4DXhcjwek1ei82L+c=
github.com/disintegration/imaging v1.6.2/go.mod h1:44/5580QXChDfwIclfc/PCwrr44amcmDAg8hxG0Ewe4=
github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg=
github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/jamesruan/go-rfc1924 v0.0.0-20170108144916-2767ca7c638f h1:Ko4+g6K16vSyUrtd/pPXuQnWsiHe5BYptEtTxfwYwCc=
github.com/jamesruan/go-rfc1924 v0.0.0-20170108144916-2767ca7c638f/go.mod h1:eHzfhOKbTGJEGPSdMHzU6jft192tHHt2Bu2vIZArvC0=
github.com/seancfoley/bintree v1.1.0 h1:6J0rj9hLNLIcWSsfYdZ4ZHkMHokaK/PHkak8qyBO/mc=
github.com/seancfoley/bintree v1.1.0/go.mod h1:CtE6qO6/n9H3V2CAGEC0lpaYr6/OijhNaMG/dt7P70c=
github.com/seancfoley/ipaddress-go v1.2.1 h1:yEZxnyC6NQEDDPflyQm4KkWozffx1vHWsx+knKBr/n0=
github.com/seancfoley/ipaddress-go v1.2.1/go.mod h1:/UEVHyrBg1ASVap2ffdY2cq5UMYIX9f3QW3uWSVqpbo=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.0.0-20220924013350-4ba4fb4dd9e7 h1:WJywXQVIb56P2kAvXeMGTIgQ1ZHQxR60+F9dLsodECc=
golang.org/x/crypto v0.0.0-20220924013350-4ba4fb4dd9e7/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/exp v0.0.0-20220921164117-439092de6870 h1:j8b6j9gzSigH28O5SjSpQSSh9lFd6f5D/q0aHjNTulc=
golang.org/x/exp v0.0.0-20220921164117-439092de6870/go.mod h1:cyybsKvd6eL0RnXn6p/Grxp8F5bW7iYuBgsNCOHpMYE=
golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/image v0.2.0 h1:/DcQ0w3VHKCC5p0/P2B0JpAZ9Z++V2KOo2fyU89CXBQ=
golang.org/x/image v0.2.0/go.mod h1:la7oBXb9w3YFjBqaAwtynVioc1ZvOnNteUNrifGNmAI=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220919091848-fb04ddd9f9c8 h1:h+EGohizhe9XlX18rfpa8k8RAc5XyaeamM+0VHRd4lc=
golang.org/x/sys v0.0.0-20220919091848-fb04ddd9f9c8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=

View File

@@ -2,25 +2,35 @@
# License: GPL v3 Copyright: 2018, Kovid Goyal <kovid at kovidgoyal.net>
import os
import re
import sys
from contextlib import suppress
from typing import (
TYPE_CHECKING, Callable, Dict, List, NamedTuple, Optional, Tuple
TYPE_CHECKING,
Callable,
Dict,
Iterator,
List,
NamedTuple,
Optional,
Tuple,
)
from kitty.cli import parse_args
from kitty.cli_stub import AskCLIOptions
from kitty.constants import cache_dir
from kitty.fast_data_types import truncate_point_for_length, wcswidth
from kitty.types import run_once
from kitty.typing import BossType, KeyEventType, TypedDict
from kitty.utils import ScreenSize
from ..tui.handler import Handler, result_handler
from ..tui.loop import Loop, MouseEvent
from ..tui.loop import Loop, MouseEvent, debug
from ..tui.operations import MouseTracking, alternate_screen, styled
if TYPE_CHECKING:
import readline
debug
else:
readline = None
@@ -92,22 +102,31 @@ be used for completions and via the browse history readline bindings.
--choice -c
type=list
dest=choices
A choice for the choices type. Every choice has the syntax: letter:text Where
letter is the accelerator key and text is the corresponding text. There can be
an optional color specification after the letter to indicate what color it should
be.
For example: y:Yes and n;red:No
A choice for the choices type. Can be specified multiple times. Every choice has
the syntax: ``letter[;color]:text``. Where :italic:`letter` is the accelerator key
and :italic:`text` is the corresponding text. There can be an optional color
specification after the letter to indicate what color it should be.
For example: :code:`y:Yes` and :code:`n;red:No`
--default -d
A default choice or text. If unspecified, it is "y" for :code:`yesno`, the first choice
for :code:`choices` and empty for others. The default choice is selected when the user
presses the Enter key.
A default choice or text. If unspecified, it is :code:`y` for the type
:code:`yesno`, the first choice for :code:`choices` and empty for others types.
The default choice is selected when the user presses the :kbd:`Enter` key.
--prompt -p
default="> "
The prompt to use when inputting a line of text or a password.
--unhide-key
default=u
The key to be pressed to unhide hidden text
--hidden-text-placeholder
The text in the message to be replaced by hidden text. The hidden text is read via STDIN.
'''
@@ -147,14 +166,17 @@ def extra_for(width: int, screen_width: int) -> int:
class Password(Handler):
def __init__(self, cli_opts: AskCLIOptions, prompt: str) -> None:
def __init__(self, cli_opts: AskCLIOptions, prompt: str, is_password: bool = True, initial_text: str = '') -> None:
self.cli_opts = cli_opts
self.prompt = prompt
self.initial_text = initial_text
from kittens.tui.line_edit import LineEdit
self.line_edit = LineEdit(is_password=True)
self.line_edit = LineEdit(is_password=is_password)
def initialize(self) -> None:
self.cmd.set_cursor_shape('beam')
if self.initial_text:
self.line_edit.on_text(self.initial_text, True)
self.draw_screen()
@Handler.atomic_update
@@ -194,10 +216,11 @@ class Password(Handler):
return ''
class Choose(Handler):
class Choose(Handler): # {{{
mouse_tracking = MouseTracking.buttons_only
def __init__(self, cli_opts: AskCLIOptions) -> None:
self.prefix_style_pat = re.compile(r'(?:\x1b\[[^m]*?m)+')
self.cli_opts = cli_opts
self.choices: Dict[str, Choice] = {}
self.clickable_ranges: Dict[str, List[Range]] = {}
@@ -219,6 +242,18 @@ class Choose(Handler):
self.response_on_accept = cli_opts.default or ''
if cli_opts.type in ('yesno', 'choices') and self.response_on_accept not in self.allowed:
self.response_on_accept = 'y' if cli_opts.type == 'yesno' else tuple(self.choices.keys())[0]
self.message = cli_opts.message
self.hidden_text_start_pos = self.hidden_text_end_pos = -1
self.hidden_text = ''
self.replacement_text = t = f'Press {styled(self.cli_opts.unhide_key, fg="green")} or click to show'
self.replacement_range = Range(-1, -1, -1)
if self.message and self.cli_opts.hidden_text_placeholder:
self.hidden_text_start_pos = self.message.find(self.cli_opts.hidden_text_placeholder)
if self.hidden_text_start_pos > -1:
self.hidden_text = sys.stdin.read().rstrip()
self.hidden_text_end_pos = self.hidden_text_start_pos + len(t)
suffix = self.message[self.hidden_text_start_pos + len(self.cli_opts.hidden_text_placeholder):]
self.message = self.message[:self.hidden_text_start_pos] + t + suffix
def initialize(self) -> None:
self.cmd.set_cursor_visible(False)
@@ -227,24 +262,35 @@ class Choose(Handler):
def finalize(self) -> None:
self.cmd.set_cursor_visible(True)
def draw_long_text(self, text: str) -> int:
y = 0
def draw_long_text(self, text: str) -> Iterator[str]:
if not text:
yield ''
return
width = self.screen_size.cols - 2
m = self.prefix_style_pat.match(text)
prefix = m.group() if m else ''
while text:
t, text = truncate_at_space(text, width)
t = t.strip()
self.print(' ' * extra_for(wcswidth(t), width), styled(t, bold=True), sep='')
y += 1
return y
yield ' ' * extra_for(wcswidth(t), width) + styled(prefix + t, bold=True)
@Handler.atomic_update
def draw_screen(self) -> None:
self.cmd.clear_screen()
y = max(0, self.screen_size.rows // 2 - 2)
msg_lines: List[str] = []
if self.message:
for line in self.message.splitlines():
msg_lines.extend(self.draw_long_text(line))
y = self.screen_size.rows - len(msg_lines)
y = max(0, (y // 2) - 2)
self.print(end='\r\n'*y)
if self.cli_opts.message:
for line in self.cli_opts.message.splitlines():
y += self.draw_long_text(line)
for line in msg_lines:
if self.replacement_text in line:
idx = line.find(self.replacement_text)
x = wcswidth(line[:idx])
self.replacement_range = Range(x, x + wcswidth(self.replacement_text), y)
self.print(line)
y += 1
if self.screen_size.rows > 2:
self.print()
y += 1
@@ -259,7 +305,8 @@ class Choose(Handler):
current_line_length = 0
current_line: List[Tuple[str, str]] = []
lines: List[List[Tuple[str, str]]] = []
sep, sep_sz = ' ', 2
sep = ' '
sep_sz = len(sep) + 2 # for the borders
for choice in choices:
self.clickable_ranges[choice.letter] = []
@@ -272,7 +319,7 @@ class Choose(Handler):
current_line = []
current_line_length = 0
current_line.append((choice.letter, text))
current_line_length += sz
current_line_length += sz + sep_sz
if current_line:
lines.append(current_line)
@@ -311,10 +358,12 @@ class Choose(Handler):
self.print(' ' * offset, line, sep='', end='' if is_last else '\r\n')
y += 1
self.cmd.set_line_wrapping(False)
for boxed_line in lines:
print_line(top, *boxed_line)
print_line(middle, *boxed_line)
print_line(bottom, *boxed_line, is_last=boxed_line is lines[-1])
self.cmd.set_line_wrapping(True)
def draw_choice(self, y: int) -> None:
if y + 3 <= self.screen_size.rows:
@@ -370,6 +419,14 @@ class Choose(Handler):
self.quit_loop(0)
elif self.cli_opts.type == 'yesno':
self.on_interrupt()
elif self.hidden_text and text == self.cli_opts.unhide_key:
self.unhide()
def unhide(self) -> None:
if self.hidden_text and self.message:
self.message = self.message[:self.hidden_text_start_pos] + self.hidden_text + self.message[self.hidden_text_end_pos:]
self.hidden_text = ''
self.draw_screen()
def on_key(self, key_event: KeyEventType) -> None:
if key_event.matches('esc'):
@@ -385,6 +442,8 @@ class Choose(Handler):
self.response = letter
self.quit_loop(0)
return
if self.hidden_text and self.replacement_range.has_point(ev.cell_x, ev.cell_y):
self.unhide()
def on_resize(self, screen_size: ScreenSize) -> None:
self.screen_size = screen_size
@@ -393,6 +452,18 @@ class Choose(Handler):
def on_interrupt(self) -> None:
self.quit_loop(1)
on_eot = on_interrupt
# }}}
@run_once
def init_readline() -> None:
import readline
with suppress(OSError):
readline.read_init_file()
if 'libedit' in readline.__doc__:
readline.parse_and_bind("bind ^I rl_complete")
else:
readline.parse_and_bind('tab: complete')
def main(args: List[str]) -> Response:
@@ -402,11 +473,11 @@ def main(args: List[str]) -> Response:
global readline
msg = 'Ask the user for input'
try:
cli_opts, items = parse_args(args[1:], option_text, '', msg, 'kitty ask', result_class=AskCLIOptions)
cli_opts, items = parse_args(args[1:], option_text, '', msg, 'kitty +kitten ask', result_class=AskCLIOptions)
except SystemExit as e:
if e.code != 0:
print(e.args[0])
input('Press enter to quit...')
input('Press Enter to quit')
raise SystemExit(e.code)
if cli_opts.type in ('yesno', 'choices'):
@@ -424,17 +495,22 @@ def main(args: List[str]) -> Response:
loop.loop(phandler)
return {'items': items, 'response': phandler.response}
import readline as rl
readline = rl
from kitty.shell import init_readline
init_readline()
response = None
# we do this file descriptor dance to get readline to work even when STDOUT
# is redirected
orig_stdout = os.dup(sys.stdout.fileno())
try:
with open(os.ctermid(), 'r') as tty:
os.dup2(tty.fileno(), sys.stdin.fileno())
with open(os.ctermid(), 'w') as tty:
os.dup2(tty.fileno(), sys.stdout.fileno())
import readline as rl
readline = rl
init_readline()
response = None
with alternate_screen(), HistoryCompleter(cli_opts.name):
if cli_opts.message:
print(styled(cli_opts.message, bold=True))
with suppress(KeyboardInterrupt, EOFError):
with alternate_screen(), HistoryCompleter(cli_opts.name), suppress(KeyboardInterrupt, EOFError):
if cli_opts.message:
print(styled(cli_opts.message, bold=True))
if cli_opts.default:
def prefill_text() -> None:
readline.insert_text(cli_opts.default or '')
@@ -444,6 +520,10 @@ def main(args: List[str]) -> Response:
readline.set_pre_input_hook()
else:
response = input(prompt)
sys.stdout.flush()
os.dup2(orig_stdout, sys.stdout.fileno())
finally:
os.close(orig_stdout)
return {'items': items, 'response': response}
@@ -457,4 +537,5 @@ def handle_result(args: List[str], data: Response, target_window_id: int, boss:
if __name__ == '__main__':
ans = main(sys.argv)
if ans:
print(ans)
import json
print(json.dumps(ans))

View File

@@ -31,6 +31,7 @@ class Broadcast(Handler):
def __init__(self, opts: BroadcastCLIOptions, initial_strings: List[str]) -> None:
self.opts = opts
self.hide_input = False
self.initial_strings = initial_strings
self.payload = {'exclude_active': True, 'data': '', 'match': opts.match, 'match_tab': opts.match_tab, 'session_id': uuid4()}
self.line_edit = LineEdit()
@@ -40,7 +41,7 @@ class Broadcast(Handler):
def initialize(self) -> None:
self.write_broadcast_session()
self.print('Type the text to broadcast below, press', styled('Ctrl+Esc', fg='yellow'), 'to quit:')
self.print('Type the text to broadcast below, press', styled(self.opts.end_session, fg='yellow'), 'to quit:')
for x in self.initial_strings:
self.write_broadcast_text(x)
self.write(SAVE_CURSOR)
@@ -56,7 +57,8 @@ class Broadcast(Handler):
def on_text(self, text: str, in_bracketed_paste: bool = False) -> None:
self.write_broadcast_text(text)
self.line_edit.on_text(text, in_bracketed_paste)
if not self.hide_input:
self.line_edit.on_text(text, in_bracketed_paste)
self.commit_line()
def on_interrupt(self) -> None:
@@ -68,22 +70,33 @@ class Broadcast(Handler):
self.write_broadcast_text('\x04')
def on_key(self, key_event: KeyEventType) -> None:
if self.line_edit.on_key(key_event):
if key_event.matches(self.opts.hide_input_toggle):
self.hide_input ^= True
self.cmd.set_cursor_visible(not self.hide_input)
if self.hide_input:
self.end_line()
self.print('Input hidden, press', styled(self.opts.hide_input_toggle, fg='yellow'), 'to unhide:')
self.end_line()
return
if key_event.matches(self.opts.end_session):
self.quit_loop(0)
return
if not self.hide_input and self.line_edit.on_key(key_event):
self.commit_line()
if key_event.matches('enter'):
self.write_broadcast_text('\r')
self.print('')
self.line_edit.clear()
self.write(SAVE_CURSOR)
return
if key_event.matches('ctrl+esc'):
self.quit_loop(0)
self.end_line()
return
ek = encode_key_event(key_event)
ek = standard_b64encode(ek.encode('utf-8')).decode('ascii')
self.write_broadcast_data('kitty-key:' + ek)
def end_line(self) -> None:
self.print('')
self.line_edit.clear()
self.write(SAVE_CURSOR)
def write_broadcast_text(self, text: str) -> None:
self.write_broadcast_data('base64:' + standard_b64encode(text.encode('utf-8')).decode('ascii'))
@@ -98,8 +111,20 @@ class Broadcast(Handler):
self.write(session_command(self.payload, start))
OPTIONS = (MATCH_WINDOW_OPTION + '\n\n' + MATCH_TAB_OPTION.replace('--match -m', '--match-tab -t')).format
help_text = 'Broadcast typed text to all kitty windows. By default text is sent to all windows, unless one of the matching options is specified'
OPTIONS = ('''
--hide-input-toggle
default=Ctrl+Alt+Esc
Key to press that will toggle hiding of the input in the broadcast window itself.
Useful while typing a password, prevents the password from being visible on the screen.
--end-session
default=Ctrl+Esc
Key to press to end the broadcast session.
''' + MATCH_WINDOW_OPTION + '\n\n' + MATCH_TAB_OPTION.replace('--match -m', '--match-tab -t')).format
help_text = 'Broadcast typed text to kitty windows. By default text is sent to all windows, unless one of the matching options is specified'
usage = '[initial text to send ...]'

View File

@@ -231,11 +231,11 @@ static PyMethodDef module_methods[] = {
};
static struct PyModuleDef module = {
.m_base = PyModuleDef_HEAD_INIT,
.m_name = "subseq_matcher", /* name of module */
.m_doc = NULL,
.m_size = -1,
.m_methods = module_methods
.m_base = PyModuleDef_HEAD_INIT,
.m_name = "subseq_matcher", /* name of module */
.m_doc = NULL,
.m_size = -1,
.m_methods = module_methods
};
EXPORTED PyMODINIT_FUNC

View File

@@ -1,6 +1,5 @@
from typing import List, Optional, Tuple
def match(
lines: List[bytes], levels: Tuple[str, str, str], needle: str,
output_positions: bool, limit: int, num_threads: int, mark_before: str,

View File

@@ -1,112 +1,91 @@
#!/usr/bin/env python3
# License: GPL v3 Copyright: 2018, Kovid Goyal <kovid at kovidgoyal.net>
import os
import sys
from typing import List, NoReturn, Optional
from kitty.cli import parse_args
from kitty.cli_stub import ClipboardCLIOptions
from ..tui.handler import Handler
from ..tui.loop import Loop
class Clipboard(Handler):
def __init__(self, data_to_send: Optional[bytes], args: ClipboardCLIOptions):
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:
self.cmd.write_to_clipboard(self.data_to_send, self.args.use_primary)
if not self.args.get_clipboard:
if self.args.wait_for_completion:
# ask kitty for the TN terminfo capability and
# only quit after a response is received
self.print('\x1bP+q544e\x1b\\', end='')
self.print('Waiting for completion...')
return
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)
def on_capability_response(self, name: str, val: str) -> None:
self.quit_loop(0)
def on_interrupt(self) -> None:
self.quit_loop(1)
def on_eot(self) -> None:
self.quit_loop(1)
OPTIONS = r'''
--get-clipboard
default=False
--get-clipboard -g
type=bool-set
Output the current contents of the clipboard to STDOUT. Note that by default
kitty will prompt you asking to allow access to the clipboard. Can be controlled
kitty will prompt for permission to access the clipboard. Can be controlled
by :opt:`clipboard_control`.
--use-primary
default=False
--use-primary -p
type=bool-set
Use the primary selection rather than the clipboard on systems that support it,
such as X11.
such as Linux.
--mime -m
type=list
The mimetype of the specified file. Useful when the auto-detected mimetype is
likely to be incorrect or the filename has no extension and therefore no mimetype
can be detected. If more than one file is specified, this option should be specified multiple
times, once for each specified file. When copying data from the clipboard, you can use wildcards
to match MIME types. For example: :code:`--mime 'text/*'` will match any textual MIME type
available on the clipboard, usually the first matching MIME type is copied. The special MIME
type :code:`.` will return the list of available MIME types currently on the system clipboard.
--alias -a
type=list
Specify aliases for MIME types. Aliased MIME types are considered equivalent.
When copying to clipboard both the original and alias are made available on the
clipboard. When copying from clipboard if the original is not found, the alias
is used, as a fallback. Can be specified multiple times to create multiple
aliases. For example: :code:`--alias text/plain=text/x-rst` makes :code:`text/plain` an alias
of :code:`text/rst`. Aliases are not used in filter mode. An alias for
:code:`text/plain` is automatically created if :code:`text/plain` is not present in the input data, but some
other :code:`text/*` MIME is present.
--wait-for-completion
default=False
type=bool-set
Wait till the copy to clipboard is complete before exiting. Useful if running
the kitten in a dedicated, ephemeral window.
the kitten in a dedicated, ephemeral window. Only needed in filter mode.
'''.format
help_text = '''\
Read or write to the system clipboard.
To set the clipboard text, pipe in the new text on STDIN. Use the
:option:`--get-clipboard` option to output the current clipboard contents to
:file:`stdout`. Note that reading the clipboard will cause a permission
This kitten operates most simply in :italic:`filter mode`.
To set the clipboard text, pipe in the new text on :file:`STDIN`. Use the
:option:`--get-clipboard` option to output the current clipboard text content to
:file:`STDOUT`. Note that copying from the clipboard will cause a permission
popup, see :opt:`clipboard_control` for details.
For more control, specify filename arguments. Then, different MIME types can be copied to/from
the clipboard. Some examples:
.. code:: sh
# Copy an image to the clipboard:
kitty +kitten clipboard picture.png
# Copy an image and some text to the clipboard:
kitty +kitten clipboard picture.jpg text.txt
# Copy text from STDIN and an image to the clipboard:
echo hello | kitty +kitten clipboard picture.png /dev/stdin
# Copy any raster image available on the clipboard to a PNG file:
kitty +kitten clipboard -g picture.png
# Copy an image to a file and text to STDOUT:
kitty +kitten clipboard -g picture.png /dev/stdout
# List the formats available on the system clipboard
kitty +kitten clipboard -g -m . /dev/stdout
'''
usage = ''
def main(args: List[str]) -> NoReturn:
cli_opts, items = parse_args(args[1:], OPTIONS, usage, help_text, 'kitty +kitten clipboard', result_class=ClipboardCLIOptions)
if items:
raise SystemExit('Unrecognized extra command line arguments')
data: Optional[bytes] = None
if not sys.stdin.isatty():
data = sys.stdin.buffer.read()
sys.stdin = open(os.ctermid())
loop = Loop()
handler = Clipboard(data, cli_opts)
loop.loop(handler)
if loop.return_code == 0 and handler.clipboard_contents:
sys.stdout.write(handler.clipboard_contents)
sys.stdout.flush()
raise SystemExit(loop.return_code)
usage = '[files to copy to/from]'
if __name__ == '__main__':
main(sys.argv)
raise SystemExit('This should be run as kitten clipboard')
elif __name__ == '__doc__':
from kitty.cli import CompletionSpec
cd = sys.cli_docs # type: ignore
cd['usage'] = usage
cd['options'] = OPTIONS
cd['help_text'] = help_text
cd['short_desc'] = 'Copy/paste with the system clipboard, even over SSH'
cd['args_completion'] = CompletionSpec.from_string('type:file mime:* group:Files')

Some files were not shown because too many files have changed in this diff Show More