diff --git a/docs/conf.py b/docs/conf.py index a6cfa49e2..0ea3b7ed8 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -255,6 +255,8 @@ if you specify a program-to-run you can use the special placeholder 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: @@ -263,7 +265,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 `_.') + 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( diff --git a/docs/kittens/clipboard.rst b/docs/kittens/clipboard.rst index 0a8e052fe..ea70acc11 100644 --- a/docs/kittens/clipboard.rst +++ b/docs/kittens/clipboard.rst @@ -11,14 +11,40 @@ 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 + +Normally, the kitten guesses MIME types based on the file names. To control the +MIME types precisely, use the :option:`--mime ` option. .. program:: kitty +kitten clipboard diff --git a/gen-go-code.py b/gen-go-code.py index a62eb8ae6..45c326772 100755 --- a/gen-go-code.py +++ b/gen-go-code.py @@ -301,7 +301,8 @@ def kitten_clis() -> None: print('ans := root.AddSubCommand(&cli.Command{') print(f'Name: "{kitten}",') print(f'ShortDescription: "{serialize_as_go_string(kcd["short_desc"])}",') - print(f'Usage: "{serialize_as_go_string(kcd["usage"])}",') + 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{}') diff --git a/kittens/clipboard/main.py b/kittens/clipboard/main.py index d0106c5cf..e444b86c8 100644 --- a/kittens/clipboard/main.py +++ b/kittens/clipboard/main.py @@ -40,18 +40,39 @@ of :code:`text/rst`. Aliases are not used in filter mode. --wait-for-completion 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 ''' -usage = '' +usage = '[files to copy to/from]' if __name__ == '__main__': raise SystemExit('This should be run as kitty-tool clipboard') elif __name__ == '__doc__': diff --git a/kitty/fast_data_types.pyi b/kitty/fast_data_types.pyi index c1a48050f..5407c73c3 100644 --- a/kitty/fast_data_types.pyi +++ b/kitty/fast_data_types.pyi @@ -1492,5 +1492,5 @@ def get_clipboard_mime(ct: int, mime: Optional[str], callback: Callable[[bytes], def run_with_activation_token(func: Callable[[str], None]) -> None: ... def make_x11_window_a_dock_window(x11_window_id: int, strut: Tuple[int, int, int, int, int, int, int, int, int, int, int, int]) -> None: ... def unicode_database_version() -> Tuple[int, int, int]: ... -def wrapped_kittens() -> List[str]: ... +def wrapped_kitten_names() -> List[str]: ... def expand_ansi_c_escapes(test: str) -> str: ... diff --git a/tools/cli/option-from-string.go b/tools/cli/option-from-string.go index d306fbb6f..ba355f020 100644 --- a/tools/cli/option-from-string.go +++ b/tools/cli/option-from-string.go @@ -195,28 +195,65 @@ func prepare_help_text_for_display(raw string) string { help := strings.Builder{} help.Grow(len(raw) + 256) prev_indent := 0 - for _, line := range utils.Splitlines(raw) { - if line != "" { - current_indent := indent_of_line(line) - if current_indent > 1 { - if prev_indent == 0 { - help.WriteString("\n") - } else { - line = strings.TrimSpace(line) - } - } - prev_indent = current_indent - if help.Len() > 0 && !strings.HasSuffix(help.String(), "\n") { - help.WriteString(" ") - } - help.WriteString(line) - } else { - prev_indent = 0 - help.WriteString("\n") - if !strings.HasSuffix(help.String(), "::") { + in_code_block := false + lines := utils.Splitlines(raw) + + handle_non_empty_line := func(i int, line string) int { + if strings.HasPrefix(line, ".. code::") { + in_code_block = true + return i + 1 + } + current_indent := indent_of_line(line) + if current_indent > 1 { + if prev_indent == 0 { help.WriteString("\n") + } else { + line = strings.TrimSpace(line) } } + prev_indent = current_indent + if help.Len() > 0 && !strings.HasSuffix(help.String(), "\n") { + help.WriteString(" ") + } + help.WriteString(line) + return i + } + + handle_empty_line := func(i int, line string) int { + prev_indent = 0 + help.WriteString("\n") + if !strings.HasSuffix(help.String(), "::") { + help.WriteString("\n") + } + return i + } + + handle_code_block_line := func(i int, line string) int { + if line == "" { + help.WriteString("\n") + return i + } + current_indent := indent_of_line(line) + if current_indent == 0 { + in_code_block = false + return handle_non_empty_line(i, line) + } + help.WriteString(line[4:]) + help.WriteString("\n") + return i + } + + for i := 0; i < len(lines); i++ { + line := lines[i] + if in_code_block { + i = handle_code_block_line(i, line) + continue + } + if line != "" { + i = handle_non_empty_line(i, line) + } else { + i = handle_empty_line(i, line) + } } return help.String() }