## File: 3rdparty/base64/README.md

# Fast Base64 stream encoder/decoder

[](https://github.com/aklomp/base64/actions/workflows/test.yml)

This is an implementation of a base64 stream encoding/decoding library in C99
with SIMD (AVX2, AVX512, NEON, AArch64/NEON, SSSE3, SSE4.1, SSE4.2, AVX) and
[OpenMP](http://www.openmp.org) acceleration. It also contains wrapper functions
to encode/decode simple length-delimited strings. This library aims to be:

- FAST;
- easy to use;
- elegant.

On x86, the library does runtime feature detection. The first time it's called,
the library will determine the appropriate encoding/decoding routines for the
machine. It then remembers them for the lifetime of the program. If your
processor supports AVX2, SSSE3, SSE4.1, SSE4.2 or AVX instructions, the library
will pick an optimized codec that lets it encode/decode 12 or 24 bytes at a
time, which gives a speedup of four or more times compared to the "plain"
bytewise codec.

AVX512 support is only for encoding at present, utilizing the AVX512 VL and VBMI
instructions. Decoding part reused AVX2 implementations. For CPUs later than
Cannonlake (manufactured in 2018) supports these instructions.

NEON support is hardcoded to on or off at compile time, because portable
runtime feature detection is unavailable on ARM.

Even if your processor does not support SIMD instructions, this is a very fast
library. The fallback routine can process 32 or 64 bits of input in one round,
depending on your processor's word width, which still makes it significantly
faster than naive bytewise implementations. On some 64-bit machines, the 64-bit
routines even outperform the SSSE3 ones.

To the author's knowledge, at the time of original release, this was the only
Base64 library to offer SIMD acceleration. The author wrote
[an article](http://www.alfredklomp.com/programming/sse-base64) explaining one
possible SIMD approach to encoding/decoding Base64. The article can help figure
out what the code is doing, and why.

Notable features:

- Really fast on x86 and ARM systems by using SIMD vector processing;
- Can use [OpenMP](http://www.openmp.org) for even more parallel speedups;
- Really fast on other 32 or 64-bit platforms through optimized routines;
- Reads/writes blocks of streaming data;
- Does not dynamically allocate memory;
- Valid C99 that compiles with pedantic options on;
- Re-entrant and threadsafe;
- Unit tested;
- Uses Duff's Device.

## Acknowledgements

The original AVX2, NEON and Aarch64/NEON codecs were generously contributed by
[Inkymail](https://github.com/inkymail/base64), who, in their fork, also
implemented some additional features. Their work is slowly being backported
into this project.

The SSSE3 and AVX2 codecs were substantially improved by using some very clever
optimizations described by Wojciech Muła in a
[series](http://0x80.pl/notesen/2016-01-12-sse-base64-encoding.html) of
[articles](http://0x80.pl/notesen/2016-01-17-sse-base64-decoding.html).
His own code is [here](https://github.com/WojciechMula/toys/tree/master/base64).

The AVX512 encoder is based on code from Wojciech Muła's
[base64simd](https://github.com/WojciechMula/base64simd) library.

The OpenMP implementation was added by Ferry Toth (@htot) from [Exalon Delft](http://www.exalondelft.nl).

## Building

The `lib` directory contains the code for the actual library.
Typing `make` in the toplevel directory will build `lib/libbase64.o` and `bin/base64`.
The first is a single, self-contained object file that you can link into your own project.
The second is a standalone test binary that works similarly to the `base64` system utility.

The matching header file needed to use this library is in `include/libbase64.h`.

To compile just the "plain" library without SIMD codecs, type:

```sh
make lib/libbase64.o
```

Optional SIMD codecs can be included by specifying the `AVX2_CFLAGS`, `AVX512_CFLAGS`,
`NEON32_CFLAGS`, `NEON64_CFLAGS`, `SSSE3_CFLAGS`, `SSE41_CFLAGS`, `SSE42_CFLAGS` and/or `AVX_CFLAGS` environment variables.
A typical build invocation on x86 looks like this:

```sh
AVX2_CFLAGS=-mavx2 SSSE3_CFLAGS=-mssse3 SSE41_CFLAGS=-msse4.1 SSE42_CFLAGS=-msse4.2 AVX_CFLAGS=-mavx make lib/libbase64.o
```

### AVX2

To build and include the AVX2 codec, set the `AVX2_CFLAGS` environment variable to a value that will turn on AVX2 support in your compiler, typically `-mavx2`.
Example:

```sh
AVX2_CFLAGS=-mavx2 make
```

### AVX512

To build and include the AVX512 codec, set the `AVX512_CFLAGS` environment variable to a value that will turn on AVX512 support in your compiler, typically `-mavx512vl -mavx512vbmi`.
Example:

```sh
AVX512_CFLAGS="-mavx512vl -mavx512vbmi" make
```

The codec will only be used if runtime feature detection shows that the target machine supports AVX2.

### SSSE3

To build and include the SSSE3 codec, set the `SSSE3_CFLAGS` environment variable to a value that will turn on SSSE3 support in your compiler, typically `-mssse3`.
Example:

```sh
SSSE3_CFLAGS=-mssse3 make
```

The codec will only be used if runtime feature detection shows that the target machine supports SSSE3.

### NEON

This library includes two NEON codecs: one for regular 32-bit ARM and one for the 64-bit AArch64 with NEON, which has double the amount of SIMD registers and can do full 64-byte table lookups.
These codecs encode in 48-byte chunks and decode in massive 64-byte chunks, so they had to be augmented with an uint32/64 codec to stay fast on smaller inputs!

Use LLVM/Clang for compiling the NEON codecs.
The code generation of at least GCC 4.6 (the version shipped with Raspbian and used for testing) contains a bug when compiling `vstq4_u8()`, and the generated assembly code is of low quality.
NEON intrinsics are a known weak area of GCC.
Clang does a better job.

NEON support can unfortunately not be portably detected at runtime from userland (the `mrc` instruction is privileged), so the default value for using the NEON codec is determined at compile-time.
But you can do your own runtime detection.
You can include the NEON codec and make it the default, then do a runtime check if the CPU has NEON support, and if not, force a downgrade to non-NEON with `BASE64_FORCE_PLAIN`.

These are your options:

1. Don't include NEON support;
2. build NEON support and make it the default, but build all other code without NEON flags so that you can override the default at runtime with `BASE64_FORCE_PLAIN`;
3. build everything with NEON support and make it the default;
4. build everything with NEON support, but don't make it the default (which makes no sense).

For option 1, simply don't specify any NEON-specific compiler flags at all, like so:

```sh
CC=clang CFLAGS="-march=armv6" make
```

For option 2, keep your `CFLAGS` plain, but set the `NEON32_CFLAGS` environment variable to a value that will build NEON support.
The line below, for instance, will build all the code at ARMv6 level, except for the NEON codec, which is built at ARMv7.
It will also make the NEON codec the default.
For ARMv6 platforms, override that default at runtime with the `BASE64_FORCE_PLAIN` flag.
No ARMv7/NEON code will then be touched.

```sh
CC=clang CFLAGS="-march=armv6" NEON32_CFLAGS="-march=armv7 -mfpu=neon" make
```

For option 3, put everything in your `CFLAGS` and use a stub, but non-empty, `NEON32_CFLAGS`.
This example works for the Raspberry Pi 2B V1.1, which has NEON support:

```sh
CC=clang CFLAGS="-march=armv7 -mtune=cortex-a7" NEON32_CFLAGS="-mfpu=neon" make
```

To build and include the NEON64 codec, use `CFLAGS` as usual to define the platform and set `NEON64_CFLAGS` to a nonempty stub.
(The AArch64 target has mandatory NEON64 support.)
Example:

```sh
CC=clang CFLAGS="--target=aarch64-linux-gnu -march=armv8-a" NEON64_CFLAGS=" " make
```

### OpenMP

To enable OpenMP on GCC you need to build with `-fopenmp`. This can be by setting the `OPENMP` environment variable to `1`.

Example:

```sh
OPENMP=1 make
```

This will let the compiler define `_OPENMP`, which in turn will include the OpenMP optimized `lib_openmp.c` into `lib.c`.

By default the number of parallel threads will be equal to the number of cores of the processor.
On a quad core with hyperthreading eight cores will be detected, but hyperthreading will not increase the performance.

To get verbose information about OpenMP start the program with `OMP_DISPLAY_ENV=VERBOSE`, for instance

```sh
OMP_DISPLAY_ENV=VERBOSE test/benchmark
```

To put a limit on the number of threads, start the program with `OMP_THREAD_LIMIT=n`, for instance

```sh
OMP_THREAD_LIMIT=2 test/benchmark
```

An example of running a benchmark with OpenMP, SSSE3 and AVX2 enabled:

```sh
make clean && OPENMP=1 SSSE3_CFLAGS=-mssse3 AVX2_CFLAGS=-mavx2 make && OPENMP=1 make -C test
```

## API reference

Strings are represented as a pointer and a length; they are not
zero-terminated. This was a conscious design decision. In the decoding step,
relying on zero-termination would make no sense since the output could contain
legitimate zero bytes. In the encoding step, returning the length saves the
overhead of calling `strlen()` on the output. If you insist on the trailing
zero, you can easily add it yourself at the given offset.

### Flags

Some API calls take a `flags` argument.
That argument can be used to force the use of a specific codec, even if that codec is a no-op in the current build.
Mainly there for testing purposes, this is also useful on ARM where the only way to do runtime NEON detection is to ask the OS if it's available.
The following constants can be used:

- `BASE64_FORCE_AVX2`
- `BASE64_FORCE_AVX512`
- `BASE64_FORCE_NEON32`
- `BASE64_FORCE_NEON64`
- `BASE64_FORCE_PLAIN`
- `BASE64_FORCE_SSSE3`
- `BASE64_FORCE_SSE41`
- `BASE64_FORCE_SSE42`
- `BASE64_FORCE_AVX`

Set `flags` to `0` for the default behavior, which is runtime feature detection on x86, a compile-time fixed codec on ARM, and the plain codec on other platforms.

### Encoding

#### base64_encode

```c
void base64_encode
    ( const char  *src
    , size_t       srclen
    , char        *out
    , size_t      *outlen
    , int          flags
    ) ;
```

Wrapper function to encode a plain string of given length.
Output is written to `out` without trailing zero.
Output length in bytes is written to `outlen`.
The buffer in `out` has been allocated by the caller and is at least 4/3 the size of the input.

#### base64_stream_encode_init

```c
void base64_stream_encode_init
    ( struct base64_state  *state
    , int                   flags
    ) ;
```

Call this before calling `base64_stream_encode()` to init the state.

#### base64_stream_encode

```c
void base64_stream_encode
    ( struct base64_state  *state
    , const char           *src
    , size_t                srclen
    , char                 *out
    , size_t               *outlen
    ) ;
```

Encodes the block of data of given length at `src`, into the buffer at `out`.
Caller is responsible for allocating a large enough out-buffer; it must be at least 4/3 the size of the in-buffer, but take some margin.
Places the number of new bytes written into `outlen` (which is set to zero when the function starts).
Does not zero-terminate or finalize the output.

#### base64_stream_encode_final

```c
void base64_stream_encode_final
    ( struct base64_state  *state
    , char                 *out
    , size_t               *outlen
    ) ;
```

Finalizes the output begun by previous calls to `base64_stream_encode()`.
Adds the required end-of-stream markers if appropriate.
`outlen` is modified and will contain the number of new bytes written at `out` (which will quite often be zero).

### Decoding

#### base64_decode

```c
int base64_decode
    ( const char  *src
    , size_t       srclen
    , char        *out
    , size_t      *outlen
    , int          flags
    ) ;
```

Wrapper function to decode a plain string of given length.
Output is written to `out` without trailing zero. Output length in bytes is written to `outlen`.
The buffer in `out` has been allocated by the caller and is at least 3/4 the size of the input.
Returns `1` for success, and `0` when a decode error has occured due to invalid input.
Returns `-1` if the chosen codec is not included in the current build.

#### base64_stream_decode_init

```c
void base64_stream_decode_init
    ( struct base64_state  *state
    , int                   flags
    ) ;
```

Call this before calling `base64_stream_decode()` to init the state.

#### base64_stream_decode

```c
int base64_stream_decode
    ( struct base64_state  *state
    , const char           *src
    , size_t                srclen
    , char                 *out
    , size_t               *outlen
    ) ;
```

Decodes the block of data of given length at `src`, into the buffer at `out`.
Caller is responsible for allocating a large enough out-buffer; it must be at least 3/4 the size of the in-buffer, but take some margin.
Places the number of new bytes written into `outlen` (which is set to zero when the function starts).
Does not zero-terminate the output.
Returns 1 if all is well, and 0 if a decoding error was found, such as an invalid character.
Returns -1 if the chosen codec is not included in the current build.
Used by the test harness to check whether a codec is available for testing.

## Examples

A simple example of encoding a static string to base64 and printing the output
to stdout:

```c
#include <stdio.h>	/* fwrite */
#include "libbase64.h"

int main ()
{
	char src[] = "hello world";
	char out[20];
	size_t srclen = sizeof(src) - 1;
	size_t outlen;

	base64_encode(src, srclen, out, &outlen, 0);

	fwrite(out, outlen, 1, stdout);

	return 0;
}
```

A simple example (no error checking, etc) of stream encoding standard input to
standard output:

```c
#include <stdio.h>
#include "libbase64.h"

int main ()
{
	size_t nread, nout;
	char buf[12000], out[16000];
	struct base64_state state;

	// Initialize stream encoder:
	base64_stream_encode_init(&state, 0);

	// Read contents of stdin into buffer:
	while ((nread = fread(buf, 1, sizeof(buf), stdin)) > 0) {

		// Encode buffer:
		base64_stream_encode(&state, buf, nread, out, &nout);

		// If there's output, print it to stdout:
		if (nout) {
			fwrite(out, nout, 1, stdout);
		}

		// If an error occurred, exit the loop:
		if (feof(stdin)) {
			break;
		}
	}

	// Finalize encoding:
	base64_stream_encode_final(&state, out, &nout);

	// If the finalizing resulted in extra output bytes, print them:
	if (nout) {
		fwrite(out, nout, 1, stdout);
	}

	return 0;
}
```

Also see `bin/base64.c` for a simple re-implementation of the `base64` utility.
A file or standard input is fed through the encoder/decoder, and the output is
written to standard output.

## Tests

See `tests/` for a small test suite. Testing is automated with
[GitHub Actions](https://github.com/aklomp/base64/actions), which builds and
tests the code across various architectures.

## Benchmarks

Benchmarks can be run with the built-in benchmark program as follows:

```sh
make -C test benchmark  && test/benchmark
```

It will run an encoding and decoding benchmark for all of the compiled-in codecs.

The tables below contain some results on random machines. All numbers measured with a 10MB buffer in MB/sec, rounded to the nearest integer.

\*: Update needed

x86 processors

| Processor                                 | Plain enc | Plain dec | SSSE3 enc | SSSE3 dec | AVX enc | AVX dec | AVX2 enc | AVX2 dec |
|-------------------------------------------|----------:|----------:|----------:|----------:|--------:|--------:|---------:|---------:|
| i7-4771 @ 3.5 GHz                         | 833\*     | 1111\*    | 3333\*    | 4444\*    | TBD     | TBD     | 4999\*   | 6666\*   |
| i7-4770 @ 3.4 GHz DDR1600                 | 1790\*    | 3038\*    | 4899\*    | 4043\*    | 4796\*  | 5709\*  | 4681\*   | 6386\*   |
| i7-4770 @ 3.4 GHz DDR1600 OPENMP 1 thread | 1784\*    | 3041\*    | 4945\*    | 4035\*    | 4776\*  | 5719\*  | 4661\*   | 6294\*   |
| i7-4770 @ 3.4 GHz DDR1600 OPENMP 2 thread | 3401\*    | 5729\*    | 5489\*    | 7444\*    | 5003\*  | 8624\*  | 5105\*   | 8558\*   |
| i7-4770 @ 3.4 GHz DDR1600 OPENMP 4 thread | 4884\*    | 7099\*    | 4917\*    | 7057\*    | 4799\*  | 7143\*  | 4902\*   | 7219\*   |
| i7-4770 @ 3.4 GHz DDR1600 OPENMP 8 thread | 5212\*    | 8849\*    | 5284\*    | 9099\*    | 5289\*  | 9220\*  | 4849\*   | 9200\*   |
| i7-4870HQ @ 2.5 GHz                       | 1471\*    | 3066\*    | 6721\*    | 6962\*    | 7015\*  | 8267\*  | 8328\*   | 11576\*  |
| i5-4590S @ 3.0 GHz                        | 3356      | 3197      | 4363      | 6104      | 4243\*  | 6233    | 4160\*   | 6344     |
| Xeon X5570 @ 2.93 GHz                     | 2161      | 1508      | 3160      | 3915      | -       | -       | -        | -        |
| Pentium4 @ 3.4 GHz                        | 896       | 740       | -         | -         | -       | -       | -        | -        |
| Atom N270                                 | 243       | 266       | 508       | 387       | -       | -       | -        | -        |
| AMD E-450                                 | 645       | 564       | 625       | 634       | -       | -       | -        | -        |
| Intel Edison @ 500 MHz                    | 79\*      | 92\*      | 152\*     | 172\*     | -       | -       | -        | -        |
| Intel Edison @ 500 MHz OPENMP 2 thread    | 158\*     | 184\*     | 300\*     | 343\*     | -       | -       | -        | -        |
| Intel Edison @ 500 MHz (x86-64)           | 162       | 119       | 209       | 164       | -       | -       | -        | -        |
| Intel Edison @ 500 MHz (x86-64) 2 thread  | 319       | 237       | 412       | 329       | -       | -       | -        | -        |

ARM processors

| Processor                                 | Plain enc | Plain dec | NEON32 enc | NEON32 dec | NEON64 enc | NEON64 dec |
|-------------------------------------------|----------:|----------:|-----------:|-----------:|-----------:|-----------:|
| Raspberry PI B+ V1.2                      | 46\*      | 40\*      | -          | -          | -          | -          |
| Raspberry PI 2 B V1.1                     | 85        | 141       | 300        | 225        | -          | -          |
| Apple iPhone SE armv7                     | 1056\*    | 895\*     | 2943\*     | 2618\*     | -          | -          |
| Apple iPhone SE arm64                     | 1061\*    | 1239\*    | -          | -          | 4098\*     | 3983\*     |

PowerPC processors

| Processor                                 | Plain enc | Plain dec |
|-------------------------------------------|----------:|----------:|
| PowerPC E6500 @ 1.8GHz                    | 270\*     | 265\*     |


Benchmarks on i7-4770 @ 3.4 GHz DDR1600 with varrying buffer sizes:


Note: optimal buffer size to take advantage of the cache is in the range of 100 kB to 1 MB, leading to 12x faster AVX encoding/decoding compared to Plain, or a throughput of 24/27GB/sec.
Also note the performance degradation when the buffer size is less than 10 kB due to thread creation overhead.
To prevent this from happening `lib_openmp.c` defines `OMP_THRESHOLD 20000`, requiring at least a 20000 byte buffer to enable multithreading.

## License

This repository is licensed under the
[BSD 2-clause License](http://opensource.org/licenses/BSD-2-Clause). See the
LICENSE file.

---

## File: docs/kittens/broadcast.rst

broadcast
==================================================

.. only:: man

    Overview
    --------------

*Type text in all kitty windows simultaneously*

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 kitten broadcast

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.

For example, only broadcast to other windows in the current tab::

    map f1 launch --allow-remote-control kitten broadcast --match-tab state:focused

.. program:: kitty +kitten broadcast


.. include:: /generated/cli-kitten-broadcast.rst

---

## File: docs/kittens/choose-fonts.rst

Changing kitty fonts
========================

.. only:: man

    Overview
    --------------

Terminal aficionados spend all day staring at text, as such, getting text
rendering just right is very important. kitty has extremely powerful facilities
for fine-tuning text rendering. It supports `OpenType features
<https://en.wikipedia.org/wiki/List_of_typographic_features>`__ to select
alternate glyph shapes, and `Variable fonts
<https://en.wikipedia.org/wiki/Variable_font>`__ to control the weight or
spacing of a font precisely. You can also :opt:`select which font is used to
render particular unicode codepoints <symbol_map>` and you can :opt:`modify
font metrics <modify_font>` and even :opt:`adjust the gamma curves
<text_composition_strategy>` used for rendering text onto the background color.

The first step is to select the font faces kitty will use for rendering
regular, bold and italic text. kitty comes with a convenient UI for choosing fonts,
in the form of the *choose-fonts* kitten. Simply run::

    kitten choose-fonts

and follow the on screen prompts.

First, choose the family you want, the list of families can be easily filtered by
typing a few letters from the family name you are looking for. The family
selection screen shows you a preview of how the family looks.

.. image:: ../screenshots/family-selection.png
   :alt: Choosing a family with the choose fonts kitten
   :width: 600

Once you select a family by pressing the :kbd:`Enter` key, you
are shown previews of what the regular, bold and italic faces look like
for that family. You can choose to fine tune any of the faces. Start with
fine-tuning the regular face by pressing the :kbd:`R` key. The other styles
will be automatically adjusted based on what you select for the regular face.

.. image:: ../screenshots/font-fine-tune.png
   :alt: Fine tune a font by choosing a precise weight and features
   :width: 600

You can choose a specific style or font feature by clicking on it. A precise
value for any variable axes can be selected using the slider, in the screenshot
above, the font supports precise weight adjustment. If you are lucky the font
designer has included descriptive names for font features, which will be
displayed, if not, consult the documentation of the font to see what each feature does.

.. _font_spec_syntax:

The font specification syntax
--------------------------------

If you don't like the choose fonts kitten or simply want to understand and
write font selection options into :file:`kitty.conf` yourself, read on.

There are four font face selection keys: `font_family`, `bold_font`,
`italic_font` and `bold_italic_font`. Each of these supports the syntax
described below. Their values can be of three types, either a
font family name, the keyword ``auto`` or an extended ``key=value`` syntax
for specifying font selection precisely.

If a font family name is specified kitty will use Operating System APIs to
search for a matching font. The keyword ``auto`` means kitty will choose a font
completely automatically, typically this is used for automatically selecting
bold/italic variants once the :opt:`font_family` is set. The bold and italic
variants will then automatically use the same set of features as the main face.

To specify font face selection more precisely, a ``key=value`` syntax is used.
First, let's look at a few examples::

    # Select by family only, actual face selection is automatic
    font_family family="Fira Code"
    # Select an exact face by Postscript name
    font_family postscript_name=FiraCode
    # Select an exact face by family with features and variable weight
    font_family family=SourceCodeVF variable_name=SourceCodeUpright features="+zero cv01=2" wght=380

The following are the known keys, any other keys are names of *variable axes*,
that is, they are used to set the variable value for some font characteristic.

``family``
    A font family name. A family typically has multiple actual font faces, such
    as bold and italic variants. One or more of the faces can even be variable,
    allowing fine tuning of font characteristics.

``style``
    A style name to choose a particular font from a given family. Useful only
    with the ``family`` key, when no more precise methods for face selection
    are specified. Can also be used to specify a named variable style for
    variable fonts.

``postscript_name``
    The actual postscript name for a font face. This allows selecting a
    particular variant within a font family. But note that postscript names
    are usually insufficient for selecting variable fonts.

``full_name``
    This can be used to select a particular font face in a family. However, it
    is less precise than ``postscript_name`` and should not generally be used.

``variable_name``
    Some families with variable fonts actually contain multiple font files. For
    example, a family could have variable weights with one font file containing
    upright variable weight faces and another containing italic variable weight
    faces. Well designed fonts use a *variable name* to distinguish between
    such files. Should be used in conjunction with ``family`` to select a
    particular variable font file.

``features``
    A space separated list of OpenType font features to enable/disable or
    select a value of, for this font. Consult the documentation for the font
    family to see what features it supports and their effects. The exact syntax
    for specifying features is `documented by HarfBuzz
    <https://harfbuzz.github.io/harfbuzz-hb-common.html#hb-feature-from-string>`__

``system``
    This can be used to pass an arbitrary string, usually a family or full name
    to the OS font selection APIs. Should not be used in conjunction with any
    other keys. Is the same as specifying just the font name without any keys.


In addition to these keys, any four letter key is treated as the name of a
variable characteristic of the font. Its value is used to set the value for
the name.

---

## File: docs/kittens/clipboard.rst

clipboard
==================================================

.. only:: man

    Overview
    --------------

    *Copy/paste to the system clipboard from shell scripts*

.. highlight:: sh


The ``clipboard`` kitten can be used to read or write to the system clipboard
from the shell. It even works over SSH. Using it is as simple as::

    echo hooray | kitten clipboard

All text received on :file:`STDIN` is copied to the clipboard.

To get text from the clipboard::

    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:
    kitten clipboard picture.png

    # Copy an image and some text to the clipboard:
    kitten clipboard picture.jpg text.txt

    # Copy text from STDIN and an image to the clipboard:
    echo hello | kitten clipboard picture.png /dev/stdin

    # Copy any raster image available on the clipboard to a PNG file:
    kitten clipboard -g picture.png

    # Copy an image to a file and text to STDOUT:
    kitten clipboard -g picture.png /dev/stdout

    # List the formats available on the system clipboard
    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


.. include:: /generated/cli-kitten-clipboard.rst

---

## File: docs/kittens/custom.rst

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.

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 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

    from kitty.boss import Boss

    def main(args: list[str]) -> str:
        # this is the main entry point of the kitten, it will be executed in
        # the overlay window when the kitten is launched
        answer = input('Enter some text: ')
        # whatever this function returns will be available in the
        # handle_result() function
        return answer

    def handle_result(args: list[str], answer: str, target_window_id: int, boss: Boss) -> None:
        # get the kitty window into which to paste answer
        w = boss.window_id_map.get(target_window_id)
        if w is not None:
            w.paste_text(answer)


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 :repo_folder:`kittens sub-directory <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 ``kitten @``. 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', f'--match=id:{w.id}', 'hello world'))

.. note::
   Inside handle_result() the active window is still the window in which the
   kitten was run, therefore when using call_remote_control() be sure to pass
   the appropriate option to select the target window, usually ``--match`` as
   shown above or ``--self``.


Run, ``kitten @ --help`` in a kitty terminal, to see all the remote control
commands available to you.

Passing arguments to kittens
------------------------------

You can pass arguments to kittens by defining them in the map directive in
:file:`kitty.conf`. For example::

    map ctrl+k kitten mykitten.py arg1 arg2

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.


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:

.. code-block:: py

    from kitty.boss import Boss

    # in main, STDIN is for the kitten process and will contain
    # the contents of the screen
    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: 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:

.. table:: Types of input to kittens
    :align: left

    =========================== ========================================================================================
    Keyword                     Type of :file:`STDIN` input
    =========================== ========================================================================================
    ``text``                    Plain text of active window
    ``ansi``                    Formatted text of active window
    ``screen``                  Plain text of active window with line wrap markers
    ``screen-ansi``             Formatted text of active window with line wrap markers

    ``history``                 Plain text of active window and its scrollback
    ``ansi-history``            Formatted text of active window and its scrollback
    ``screen-history``          Plain text of active window and its scrollback with line wrap markers
    ``screen-ansi-history``     Formatted text of active window and its scrollback with line wrap markers

    ``output``                  Plain text of the output from the last run command
    ``output-screen``           Plain text of the output from the last run command with wrap markers
    ``output-ansi``             Formatted text of the output from the last run command
    ``output-screen-ansi``      Formatted text of the output from the last run command with wrap markers

    ``selection``               The text currently selected with the mouse
    =========================== ========================================================================================

In addition to ``output``, that gets the output of the last run command,
``last_visited_output`` gives the output of the command last jumped to
and ``first_output`` gives the output of the first command currently on screen.
These can also be combined with ``screen`` and ``ansi`` for formatting.

.. note::
   For the types based on the output of a command, :ref:`shell_integration` is
   required.


Using kittens to script kitty, without any terminal UI
-----------------------------------------------------------

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.

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 Python file in the :ref:`kitty config directory <confloc>`,
:file:`~/.config/kitty/zoom_toggle.py`

.. code-block:: py

    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: 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':
                tab.last_used_layout()
            else:
                tab.goto_layout('stack')


Now in :file:`kitty.conf` add::

    map f11 kitten zoom_toggle.py

Pressing :kbd:`F11` will now act as a zoom toggle function. You can get even
more fancy, switching the kitty OS window to fullscreen as well as changing the
layout, by simply adding the line::

    boss.toggle_fullscreen()


to the ``handle_result()`` function, above.


.. _send_mouse_event:

Sending mouse events
--------------------

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
    send_mouse_event(screen, x, y, button, action, mods)

``screen`` is the ``screen`` attribute of the window you want to send the event
to. ``x`` and ``y`` are the 0-indexed coordinates. ``button`` is a number using
the same numbering as X11 (left: ``1``, middle: ``2``, right: ``3``, scroll up:
``4``, scroll down: ``5``, scroll left: ``6``, scroll right: ``7``, back:
``8``, forward: ``9``). ``action`` is one of ``PRESS``, ``RELEASE``, ``DRAG``
or ``MOVE``. ``mods`` is a bitmask of ``GLFW_MOD_{mod}`` where ``{mod}`` is one
of ``SHIFT``, ``CONTROL`` or ``ALT``. All the mentioned constants are imported
from ``kitty.fast_data_types``.

For example, to send a left click at position x: 2, y: 3 to the active window::

    from kitty.fast_data_types import send_mouse_event, PRESS
    send_mouse_event(boss.active_window.screen, 2, 3, 1, PRESS, 0)

The function will only send the event if the program is receiving events of
that type, and will return ``True`` if it sent the event, and ``False`` if not.


.. _kitten_main_rc:

Using remote control inside the main() kitten function
------------------------------------------------------------

You can use kitty's remote control features inside the main() function of a
kitten, even without enabling remote control. This is useful if you want to
probe kitty for more information before presenting some UI to the user or if
you want the user to be able to control kitty from within your kitten's UI
rather than after it has finished running. To enable it, simply tell kitty your kitten
requires remote control, as shown in the example below::

    import json
    import sys
    from pprint import pprint

    from kittens.tui.handler import kitten_ui

    @kitten_ui(allow_remote_control=True)
    def main(args: list[str]) -> str:
        # get the result of running kitten @ ls
        cp = main.remote_control(['ls'], capture_output=True)
        if cp.returncode != 0:
            sys.stderr.buffer.write(cp.stderr)
            raise SystemExit(cp.returncode)
        output = json.loads(cp.stdout)
        pprint(output)
        # open a new tab with a title specified by the user
        title = input('Enter the name of tab: ')
        window_id = main.remote_control(['launch', '--type=tab', '--tab-title', title], check=True, capture_output=True).stdout.decode()
        return window_id

:code:`allow_remote_control=True` tells kitty to run this kitten with remote
control enabled, regardless of whether it is enabled globally or not.
To run a remote control command use the :code:`main.remote_control()` function
which is a thin wrapper around Python's :code:`subprocess.run` function. Note
that by default, for security, child processes launched by your kitten cannot use remote
control, thus it is necessary to use :code:`main.remote_control()`. If you wish
to enable child processes to use remote control, call
:code:`main.allow_indiscriminate_remote_control()`.

Remote control access can be further secured by using
:code:`kitten_ui(allow_remote_control=True, remote_control_password='ls set-colors')`.
This will use a secure generated password to restrict remote control.
You can specify a space separated list of remote control commands to allow, see
:opt:`remote_control_password` for details. The password value is accessible
as :code:`main.password` and is used by :code:`main.remote_control()`
automatically.


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::

    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
running.

The ``handle_result()`` part of the kitten runs inside the kitty process.
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.


Developing builtin kittens for inclusion with kitty
----------------------------------------------------------

There is documentation for :doc:`developing-builtin-kittens` which are written in the Go
language.


.. _external_kittens:

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.

`smart-scroll <https://github.com/yurikhan/kitty-smart-scroll>`_
    Makes the kitty scroll bindings work in full screen applications

`kitty-tab-switcher <https://github.com/OsiPog/kitty-tab-switcher>`__
    Fuzzy finder for kitty tabs with previews

`gattino <https://github.com/salvozappa/gattino>`__
    Integrate kitty with an LLM to convert plain language prompts into shell commands.

:iss:`insert password <1222>`
    Insert a password from a CLI password manager, taking care to only do it at
    a password prompt.

`weechat-hints <https://github.com/GermainZ/kitty-weechat-hints>`_
    URL hints kitten for WeeChat that works without having to use WeeChat's
    raw-mode.

`pdf-kitten <https://github.com/gelaechter/pdf-kitten>`__
    Allows you to export kitty's output to PDF, making use of weasyprint.

`kitty-action-menu <https://github.com/olispeedy/kitty-action-menu>`__
    A pop-up action menu (copy selection, copy link/path, paste, new tab, split,
    close) opened by right-click or any mapping.

---

## File: docs/kittens/developing-builtin-kittens.rst

Developing builtin kittens
=============================

Builtin kittens in kitty are written in the Go language, with small Python
wrapper scripts to define command line options and handle UI integration.

Getting started
-----------------------

To get started with creating a builtin kitten, one that will become part of kitty
and be available as ``kitten my-kitten``, create a directory named
:file:`my_kitten` in the :file:`kittens` directory. Then, in this directory
add three files: :file:`__init__.py` (an empty file), :file:`main.py` and
:file:`main.go`.

Template for `main.py`
^^^^^^^^^^^^^^^^^^^^^^

The file :file:`main.py` contains the command line option definitions for your kitten. Change the actual options and help text below as needed.

.. code-block:: python

    #!/usr/bin/env python
    # License: GPL v3 Copyright: 2018, Kovid Goyal <kovid at kovidgoyal.net>

    import sys

    # See the file kitty/cli.py in the kitty sourcecode for more examples of
    # the syntax for defining options
    OPTIONS = r'''
    --some-string-option -s
    default=my_default_value
    Help text for a simple option taking a string value.


    --some-boolean-option -b
    type=bool-set
    Help text for a boolean option defaulting to false.


    --some-inverted-boolean-option
    type=bool-unset
    Help text for a boolean option defaulting to true.


    --an-integer-option
    type=int
    default=13
    bla bla


    --an-enum-option
    choices=a,b,c,d
    default=a
    This option can only take the values a, b, c, or d
    '''.format

    help_text = '''\
    The introductory help text for your kitten.

    Can contain multiple paragraphs with :bold:`bold`
    :green:`colored`, :code:`code`, :link:`links <http://url>` etc.
    formatting.

    Option help strings can also use this formatting.
    '''

    # The usage string for your kitten
    usage = 'TITLE [BODY ...]'
    short_description = 'A short description of your kitten'

    if __name__ == '__main__':
        raise SystemExit('This should be run as kitten my-kitten')
    elif __name__ == '__doc__':
        cd = sys.cli_docs  # type: ignore
        cd['usage'] = usage
        cd['options'] = OPTIONS
        cd['help_text'] = help_text
        cd['short_desc'] = short_description


Template for `main.go`
^^^^^^^^^^^^^^^^^^^^^^

.. code-block:: go

    package my_kitten

    import (
        "fmt"

        "github.com/kovidgoyal/kitty/tools/cli"
    )

    var _ = fmt.Print

    func main(_ *cli.Command, opts *Options, args []string) (rc int, err error) {
        // Here rc is the exit code for the kitten which should be 1 or higher if err is not nil
        fmt.Println("Hello world!")
        fmt.Println(args)
        fmt.Println(fmt.Sprintf("%#v", opts))
        return
    }

    func EntryPoint(parent *cli.Command) {
        create_cmd(parent, main)
    }

Edit :file:`tools/cmd/tool/main.go`
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Add the entry point of the kitten into :file:`tools/cmd/tool/main.go`.

First, import the kitten into this file. To do this, add :code:`"github.com/kovidgoyal/kitty/kittens/my_kitten"` into the :code:`import ( ... )` section at the top.
Then, add ``my_kitten.EntryPoint(root)`` into ``func KittyToolEntryPoints(root *cli.Command)`` and you are done. After running make you should
be able to test your kitten by running::

    kitten my-kitten

---

## File: docs/kittens/diff.rst

kitty-diff
================================================================================

*A fast side-by-side diff tool with syntax highlighting and images*

.. highlight:: sh

Major Features
-----------------

.. container:: major-features

    * Displays diffs side-by-side in the kitty terminal

    * Does syntax highlighting of the displayed diffs, asynchronously, for
      maximum speed

    * Displays images as well as text diffs, even over SSH

    * Does recursive directory diffing


.. figure:: ../screenshots/diff.png
   :alt: Screenshot, showing a sample diff
   :align: center
   :width: 100%

   Screenshot, showing a sample diff


Installation
---------------

Simply :ref:`install kitty <quickstart>`.


Usage
--------

In the kitty terminal, run::

    kitten diff file1 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:

.. code-block:: sh

    alias d="kitten diff"

Now all you need to do to diff two files is::

    d file1 file2

You can also pass directories instead of files to see the recursive diff of the
directory contents.


Keyboard controls
----------------------

===========================       ===========================
Action                            Shortcut
===========================       ===========================
Quit                              :kbd:`Q`
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`, :kbd:`Ctrl+F`
Scroll to previous page           :kbd:`PgUp`, :kbd:`Ctrl+B`
Scroll down half page             :kbd:`Ctrl+D`
Scroll up half page               :kbd:`Ctrl+U`
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`
Restore default context           :kbd:`=`
Search forwards                   :kbd:`/`
Search backwards                  :kbd:`?`
Clear search or exit              :kbd:`Esc`
Scroll to next match              :kbd:`>`, :kbd:`.`
Scroll to previous match          :kbd:`<`, :kbd:`,`
Copy selection to clipboard       :kbd:`y`
Copy selection or exit            :kbd:`Ctrl+C`
===========================       ===========================


Integrating with git
-----------------------

Add the following to :file:`~/.gitconfig`:

.. code-block:: ini

    [diff]
        tool = kitty
        guitool = kitty.gui
    [difftool]
        prompt = false
        trustExitCode = true
    [difftool "kitty"]
        cmd = kitten diff $LOCAL $REMOTE
    [difftool "kitty.gui"]
        cmd = kitten diff $LOCAL $REMOTE

Now to use kitty-diff to view git diffs, you can simply do::

    git difftool --no-symlinks --dir-diff

Once again, creating an alias for this command is useful.

Alternatively, `git-kitten-diff <https://github.com/eureka-cpu/kitty-diff-git>`__
is a git plugin that forwards ``git diff`` arguments to kitty-diff without
needing any :file:`~/.gitconfig` changes. Once installed, simply run::

    git kitten diff


Why does this work only in kitty?
----------------------------------------

The diff kitten makes use of various features that are :doc:`kitty only
`, 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 3000 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.


.. include:: /generated/conf-kitten-diff.rst


.. include:: /generated/cli-kitten-diff.rst


Sample diff.conf
-----------------

You can download a sample :file:`diff.conf` file with all default settings and
comments describing each setting by clicking: :download:`sample diff.conf
</generated/conf/diff.conf>`.

---

## File: docs/kittens/hints.rst

Hints
==========

.. only:: man

    Overview
    --------------


|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
    :alt: URL hints mode
    :align: center
    :width: 100%

    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 :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
your default editor at the specified line number (opening at line number will
work only if your editor supports the +linenum command line syntax or is a
"known" editor). 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 <https://neovim.io/>`__
when you press :kbd:`Ctrl+G`.

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``. 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
   starting with that letter are displayed. Pressing the second letter will
   select that hint or press :kbd:`Enter` or :kbd:`Space` to select the empty
   hint.

For mouse lovers, the hints kitten also allows you to click on any matched text to
select it instead of typing the hint character.

The hints kitten is very powerful to see more detailed help on its various
options and modes of operation, see below. You can use these options to
create mappings in :file:`kitty.conf` to select various different text
snippets. See :sc:`insert_selected_path ` for examples.


Completely customizing the matching and actions of the kitten
---------------------------------------------------------------

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 :ref:`kitty config directory <confloc>` with the following contents:

.. code-block:: python

    import re

    def mark(text, args, Mark, extra_cli_args, *a):
        # This function is responsible for finding all
        # matching text. extra_cli_args are any extra arguments
        # passed on the command line when invoking the kitten.
        # We mark all individual word for potential selection
        for idx, m in enumerate(re.finditer(r'\w+', text)):
            start, end = m.span()
            mark_text = text[start:end].replace('\n', '').replace('\0', '')
            # The empty dictionary below will be available as groupdicts
            # in handle_result() and can contain string keys and arbitrary JSON
            # serializable values.
            yield Mark(idx, start, end, mark_text, {})


    def handle_result(args, data, target_window_id, boss, extra_cli_args, *a):
        # This function is responsible for performing some
        # action on the selected text.
        # matches is a list of the selected entries and groupdicts contains
        # the arbitrary data associated with each entry in mark() above
        matches, groupdicts = [], []
        for m, g in zip(data['match'], data['groupdicts']):
            if m:
                matches.append(m), groupdicts.append(g)
        for word, match_data in zip(matches, groupdicts):
            # Lookup the word in a dictionary, the open_url function
            # will open the provided url in the system browser
            boss.open_url(f'https://www.google.com/search?q=define:{word}')

Now run kitty with::

    kitty -o 'map f1 kitten hints --customize-processing custom-hints.py'

When you press the :kbd:`F1` key you will be able to select a word to
look it up in the Google dictionary.

.. include:: ../generated/cli-kitten-hints.rst

.. note::

    To avoid having to specify the same command line options on every
    invocation, you can use the :opt:`action_alias` option in
    :file:`kitty.conf`, creating aliases that have common sets of options.
    For example::

        action_alias myhints kitten hints --alphabet qfjdkslaureitywovmcxzpq1234567890
        map f1 myhints --customize-processing custom-hints.py

---

## File: docs/kittens/hyperlinked_grep.rst

Hyperlinked grep
=================

.. only:: man

    Overview
    --------------


.. note::

   As of ripgrep versions newer than 13.0 it supports hyperlinks
   natively so you can just add the following alias in your shell rc file:
   ``alias rg="rg --hyperlink-format=kitty"`` no need to use this kitten.
   But, see below for instructions on how to customize kitty to have it open
   the hyperlinks from ripgrep in your favorite editor.

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.

.. versionadded:: 0.19.0

To set it up, first create :file:`~/.config/kitty/open-actions.conf` with the
following contents:

.. code:: conf

    # Open any file with a fragment in vim, fragments are generated
    # by the hyperlink-grep kitten and nothing else so far.
    protocol file
    fragment_matches [0-9]+
    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 --cwd=current -- ${EDITOR} -- ${FILE_PATH}

Now, run a search with::

    kitten hyperlinked-grep something

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. To open links with the keyboard instead, use
:sc:`open_selected_hyperlink`.

Finally, add an alias to your shell's rc files to invoke the kitten as
:command:`hg`::

    alias hg="kitten hyperlinked-grep"


You can now run searches with::

    hg some-search-term

To learn more about kitty's powerful framework for customizing URL click
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 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.


.. note::
   While you can pass any of ripgrep's command line options to the kitten and
   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.