parent
bc202aec6e
commit
fa327d618d
194
docs/index.rst
194
docs/index.rst
@ -53,200 +53,6 @@ kitty
|
|||||||
* :doc:`graphics-protocol`
|
* :doc:`graphics-protocol`
|
||||||
* :doc:`keyboard-protocol`
|
* :doc:`keyboard-protocol`
|
||||||
* Lots more in :doc:`protocol-extensions`
|
* Lots more in :doc:`protocol-extensions`
|
||||||
=======
|
|
||||||
:doc:`Panel <kittens/panel>`
|
|
||||||
Draw a GPU accelerated dock panel on your desktop showing the output
|
|
||||||
from an arbitrary terminal program.
|
|
||||||
|
|
||||||
|
|
||||||
:doc:`Clipboard <kittens/clipboard>`
|
|
||||||
Copy/paste to the clipboard from shell scripts, even over SSH.
|
|
||||||
|
|
||||||
You can also :doc:`Learn to create your own kittens <kittens/custom>`.
|
|
||||||
|
|
||||||
|
|
||||||
Configuring kitty
|
|
||||||
-------------------
|
|
||||||
|
|
||||||
|kitty| is highly configurable, everything from keyboard shortcuts to
|
|
||||||
painting frames-per-second. 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>`.
|
|
||||||
|
|
||||||
|
|
||||||
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.
|
|
||||||
|
|
||||||
.. _sessions:
|
|
||||||
|
|
||||||
Startup Sessions
|
|
||||||
------------------
|
|
||||||
|
|
||||||
You can control the :term:`tabs <tab>`, `:term:`kitty window <window>` layout,
|
|
||||||
working directory, startup programs,
|
|
||||||
etc. by creating a "session" file and using the :option:`kitty --session`
|
|
||||||
command line flag or the :opt:`startup_session` option in :file:`kitty.conf`.
|
|
||||||
For example:
|
|
||||||
|
|
||||||
.. code-block:: session
|
|
||||||
|
|
||||||
# Set the layout for the current tab
|
|
||||||
layout tall
|
|
||||||
# Set the working directory for windows in the current tab
|
|
||||||
cd ~
|
|
||||||
# Create a window and run the specified command in it
|
|
||||||
launch zsh
|
|
||||||
# Create a window with some environment variables set and run
|
|
||||||
# vim in it
|
|
||||||
launch --env FOO=BAR vim
|
|
||||||
# Set the title for the next window
|
|
||||||
launch --title "Chat with x" irssi --profile x
|
|
||||||
|
|
||||||
# Create a new tab (the part after new_tab is the optional tab
|
|
||||||
# name which will be displayed in the tab bar, if omitted, the
|
|
||||||
# title of the active window will be used instead)
|
|
||||||
new_tab my tab
|
|
||||||
cd ~/somewhere
|
|
||||||
# Set the layouts allowed in this tab
|
|
||||||
enabled_layouts tall, stack
|
|
||||||
# Set the current layout
|
|
||||||
layout stack
|
|
||||||
launch zsh
|
|
||||||
|
|
||||||
# Create a new OS window
|
|
||||||
new_os_window
|
|
||||||
# set new window size to 80x25 cells
|
|
||||||
os_window_size 80c 25c
|
|
||||||
# set the --class for the new OS window
|
|
||||||
os_window_class mywindow
|
|
||||||
launch sh
|
|
||||||
# Make the current window the active (focused) window
|
|
||||||
focus
|
|
||||||
launch emacs
|
|
||||||
|
|
||||||
.. note::
|
|
||||||
The :doc:`launch <launch>` command when used in a session file
|
|
||||||
cannot create new OS windows, or tabs.
|
|
||||||
|
|
||||||
|
|
||||||
Mouse features
|
|
||||||
-------------------
|
|
||||||
|
|
||||||
* You can click on a URL to open it in a browser.
|
|
||||||
* You can double click to select a word and then drag to select more words.
|
|
||||||
* You can triple click to select a line and then drag to select more lines.
|
|
||||||
* You can triple click while holding :kbd:`ctrl+alt` to select from clicked
|
|
||||||
point to end of line.
|
|
||||||
* You can right click to extend a previous selection.
|
|
||||||
* You can hold down :kbd:`ctrl+alt` and drag with the mouse to select in
|
|
||||||
columns.
|
|
||||||
* Selecting text automatically copies it to the primary clipboard (on
|
|
||||||
platforms with a primary clipboard).
|
|
||||||
* You can middle click to paste from the primary clipboard (on platforms
|
|
||||||
with a primary clipboard).
|
|
||||||
* You can select text with kitty even when a terminal program has grabbed
|
|
||||||
the mouse by holding down the :kbd:`shift` key.
|
|
||||||
|
|
||||||
All these actions can be customized in :file:`kitty.conf` as described
|
|
||||||
:ref:`here <conf-kitty-mouse.mousemap>`.
|
|
||||||
|
|
||||||
|
|
||||||
Font control
|
|
||||||
-----------------
|
|
||||||
|
|
||||||
|kitty| has extremely flexible and powerful font selection features. You can
|
|
||||||
specify individual families for the regular, bold, italic and bold+italic
|
|
||||||
fonts. You can even specify specific font families for specific ranges of
|
|
||||||
unicode characters. This allows precise control over text rendering. It can
|
|
||||||
come in handy for applications like powerline, without the need to use patched
|
|
||||||
fonts. See the various font related configuration directives in
|
|
||||||
:ref:`conf-kitty-fonts`.
|
|
||||||
|
|
||||||
|
|
||||||
.. _scrollback:
|
|
||||||
|
|
||||||
The scrollback buffer
|
|
||||||
-----------------------
|
|
||||||
|
|
||||||
|kitty| supports scrolling back to view history, just like most terminals. You
|
|
||||||
can use either keyboard shortcuts or the mouse scroll wheel to do so. However,
|
|
||||||
|kitty| has an extra, neat feature. Sometimes you need to explore the
|
|
||||||
scrollback buffer in more detail, maybe search for some text or refer to it
|
|
||||||
side-by-side while typing in a follow-up command. |kitty| allows you to do this
|
|
||||||
by pressing the :sc:`show_scrollback` key-combination, which will open the
|
|
||||||
scrollback buffer in your favorite pager program (which is ``less`` by default).
|
|
||||||
Colors and text formatting are preserved. You can explore the scrollback buffer
|
|
||||||
comfortably within the pager.
|
|
||||||
|
|
||||||
Additionally, you can pipe the contents of the scrollback buffer to an
|
|
||||||
arbitrary, command running in a new :term:`window`, :term:`tab` or :term:`overlay`,
|
|
||||||
for example::
|
|
||||||
|
|
||||||
map f1 launch --stdin-source=@screen_scrollback --stdin-add-formatting less +G -R
|
|
||||||
|
|
||||||
Would open the scrollback buffer in a new :term:`window` when you press the :kbd:`F1`
|
|
||||||
key. See :sc:`show_scrollback` for details.
|
|
||||||
|
|
||||||
If you want to use it with an editor such as vim to get more powerful features,
|
|
||||||
you can see tips for doing so, in
|
|
||||||
`this thread <https://github.com/kovidgoyal/kitty/issues/719>`_.
|
|
||||||
|
|
||||||
If you wish to store very large amounts of scrollback to view using the piping or
|
|
||||||
:sc:`show_scrollback` features, you can use the :opt:`scrollback_pager_history_size`
|
|
||||||
option.
|
|
||||||
|
|
||||||
You can also view the output of the last command to run in the shell, by
|
|
||||||
pressing :sc:`show_last_command_output`. See :ref:`shell_integration` for
|
|
||||||
details.
|
|
||||||
|
|
||||||
.. _cpbuf:
|
|
||||||
|
|
||||||
Multiple copy/paste buffers
|
|
||||||
-----------------------------
|
|
||||||
|
|
||||||
In addition to being able to copy/paste from the system clipboard, in |kitty| you
|
|
||||||
can also setup an arbitrary number of copy paste buffers. To do so, simply add
|
|
||||||
something like the following to your :file:`kitty.conf`::
|
|
||||||
|
|
||||||
map f1 copy_to_buffer a
|
|
||||||
map f2 paste_from_buffer a
|
|
||||||
|
|
||||||
This will allow you to press :kbd:`F1` to copy the current selection to an
|
|
||||||
internal buffer named ``a`` and :kbd:`F2` to paste from that buffer. The buffer
|
|
||||||
names are arbitrary strings, so you can define as many such buffers as you
|
|
||||||
need.
|
|
||||||
|
|
||||||
Marks
|
|
||||||
-------------
|
|
||||||
|
|
||||||
kitty has the ability to mark text on the screen based on regular expressions.
|
|
||||||
This can be useful to highlight words or phrases when browsing output from long
|
|
||||||
running programs or similar. To learn how this feature works, see :doc:`marks`.
|
|
||||||
|
|
||||||
|
|
||||||
Frequently Asked Questions
|
|
||||||
---------------------------------
|
|
||||||
|
|
||||||
The list of Frequently Asked Questions (*FAQ*) is :doc:`available here <faq>`.
|
|
||||||
|
|
||||||
|
|
||||||
Cool integrations for kitty with other CLI tools
|
|
||||||
--------------------------------------------------
|
|
||||||
|
|
||||||
kitty provides extremely powerful interfaces such as :doc:`remote-control` and
|
|
||||||
:doc:`kittens/custom` and :doc:`kittens/icat`
|
|
||||||
that allow it to be integrated with other tools seamlessly. For a list of such
|
|
||||||
user created integrations, see: :doc:`integrations`.
|
|
||||||
|
|
||||||
|
|
||||||
>>>>>>> 1d167ada (Move shell integration docs into own file)
|
|
||||||
|
|
||||||
|
|
||||||
.. figure:: screenshots/screenshot.png
|
.. figure:: screenshots/screenshot.png
|
||||||
|
|||||||
@ -1193,6 +1193,10 @@ def click_mouse_url(os_window_id: int, tab_id: int, window_id: int) -> bool:
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def move_cursor_to_mouse_if_in_prompt(os_window_id: int, tab_id: int, window_id: int) -> bool:
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
def mouse_selection(os_window_id: int, tab_id: int, window_id: int, code: int, button: int) -> None:
|
def mouse_selection(os_window_id: int, tab_id: int, window_id: int, code: int, button: int) -> None:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|||||||
@ -410,6 +410,15 @@ mouse_open_url(Window *w) {
|
|||||||
return screen_open_url(screen);
|
return screen_open_url(screen);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
move_cursor_to_mouse_if_at_shell_prompt(Window *w) {
|
||||||
|
Screen *screen = w->render_data.screen;
|
||||||
|
int y = screen_cursor_at_a_shell_prompt(screen);
|
||||||
|
if (y < 0 || (unsigned)y > w->mouse_pos.cell_y) return false;
|
||||||
|
return screen_fake_move_cursor_to_position(screen, w->mouse_pos.cell_x, w->mouse_pos.cell_y);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
typedef struct PendingClick {
|
typedef struct PendingClick {
|
||||||
id_type window_id;
|
id_type window_id;
|
||||||
int button, count, modifiers;
|
int button, count, modifiers;
|
||||||
|
|||||||
@ -507,16 +507,26 @@ Useful, for instance, to remove the default mouse actions.
|
|||||||
'''
|
'''
|
||||||
)
|
)
|
||||||
|
|
||||||
mma('Click the link under the mouse cursor when no selection is created',
|
mma('Click the link under the mouse or move the cursor',
|
||||||
'click_url_or_select left click ungrabbed mouse_click_url_or_select',
|
'click_url_or_select left click ungrabbed mouse_handle_click selection link prompt',
|
||||||
|
long_text='''
|
||||||
|
First check for a selection and if one exists do nothing. Then check for a link
|
||||||
|
under the mouse cursor and if one exists, click it. Finally check if the click happened at
|
||||||
|
the current shell prompt and if so, move the cursor to the click location. Note that this
|
||||||
|
requires :doc:`shell-integration` to work.
|
||||||
|
'''
|
||||||
)
|
)
|
||||||
|
|
||||||
mma('Click the link under the mouse cursor when no selection is created even if grabbed',
|
mma('Click the link under the mouse or move the cursor even when grabbed',
|
||||||
'click_url_or_select_grabbed shift+left click grabbed,ungrabbed mouse_click_url_or_select',
|
'click_url_or_select_grabbed shift+left click grabbed,ungrabbed mouse_handle_click selection link prompt',
|
||||||
|
long_text='''
|
||||||
|
Same as above, except that the action is performed even when the mouse is grabbed
|
||||||
|
by the program running in the terminal.
|
||||||
|
'''
|
||||||
)
|
)
|
||||||
|
|
||||||
mma('Click the link under the mouse cursor',
|
mma('Click the link under the mouse cursor',
|
||||||
'click_url ctrl+shift+left release grabbed,ungrabbed mouse_click_url',
|
'click_url ctrl+shift+left release grabbed,ungrabbed mouse_handle_click link',
|
||||||
long_text='Variant with :kbd:`ctrl+shift` is present because the simple'
|
long_text='Variant with :kbd:`ctrl+shift` is present because the simple'
|
||||||
' click based version has an unavoidable delay of :opt:`click_interval`, to disambiguate clicks from double clicks.'
|
' click based version has an unavoidable delay of :opt:`click_interval`, to disambiguate clicks from double clicks.'
|
||||||
)
|
)
|
||||||
|
|||||||
10
kitty/options/types.py
generated
10
kitty/options/types.py
generated
@ -876,15 +876,15 @@ if is_macos:
|
|||||||
defaults.map.append(KeyDefinition(False, KeyAction('debug_config'), 10, False, 44, ()))
|
defaults.map.append(KeyDefinition(False, KeyAction('debug_config'), 10, False, 44, ()))
|
||||||
defaults.mouse_map = [
|
defaults.mouse_map = [
|
||||||
# click_url_or_select
|
# click_url_or_select
|
||||||
MouseMapping(0, 0, -2, False, KeyAction('mouse_click_url_or_select')),
|
MouseMapping(0, 0, -2, False, KeyAction('mouse_handle_click', ('selection', 'link', 'prompt'))),
|
||||||
# click_url_or_select_grabbed
|
# click_url_or_select_grabbed
|
||||||
MouseMapping(0, 1, -2, True, KeyAction('mouse_click_url_or_select')),
|
MouseMapping(0, 1, -2, True, KeyAction('mouse_handle_click', ('selection', 'link', 'prompt'))),
|
||||||
# click_url_or_select_grabbed
|
# click_url_or_select_grabbed
|
||||||
MouseMapping(0, 1, -2, False, KeyAction('mouse_click_url_or_select')),
|
MouseMapping(0, 1, -2, False, KeyAction('mouse_handle_click', ('selection', 'link', 'prompt'))),
|
||||||
# click_url
|
# click_url
|
||||||
MouseMapping(0, 5, -1, True, KeyAction('mouse_click_url')),
|
MouseMapping(0, 5, -1, True, KeyAction('mouse_handle_click', ('link',))),
|
||||||
# click_url
|
# click_url
|
||||||
MouseMapping(0, 5, -1, False, KeyAction('mouse_click_url')),
|
MouseMapping(0, 5, -1, False, KeyAction('mouse_handle_click', ('link',))),
|
||||||
# click_url_discard
|
# click_url_discard
|
||||||
MouseMapping(0, 5, 1, True, KeyAction('discard_event')),
|
MouseMapping(0, 5, 1, True, KeyAction('discard_event')),
|
||||||
# paste_selection
|
# paste_selection
|
||||||
|
|||||||
@ -52,7 +52,7 @@ class InvalidMods(ValueError):
|
|||||||
@func_with_args(
|
@func_with_args(
|
||||||
'pass_selection_to_program', 'new_window', 'new_tab', 'new_os_window',
|
'pass_selection_to_program', 'new_window', 'new_tab', 'new_os_window',
|
||||||
'new_window_with_cwd', 'new_tab_with_cwd', 'new_os_window_with_cwd',
|
'new_window_with_cwd', 'new_tab_with_cwd', 'new_os_window_with_cwd',
|
||||||
'launch'
|
'launch', 'mouse_handle_click'
|
||||||
)
|
)
|
||||||
def shlex_parse(func: str, rest: str) -> FuncArgsType:
|
def shlex_parse(func: str, rest: str) -> FuncArgsType:
|
||||||
return func, to_cmdline(rest)
|
return func, to_cmdline(rest)
|
||||||
|
|||||||
@ -25,6 +25,7 @@
|
|||||||
#include "wcwidth-std.h"
|
#include "wcwidth-std.h"
|
||||||
#include "control-codes.h"
|
#include "control-codes.h"
|
||||||
#include "charsets.h"
|
#include "charsets.h"
|
||||||
|
#include "keys.h"
|
||||||
|
|
||||||
static const ScreenModes empty_modes = {0, .mDECAWM=true, .mDECTCEM=true, .mDECARM=true};
|
static const ScreenModes empty_modes = {0, .mDECAWM=true, .mDECTCEM=true, .mDECARM=true};
|
||||||
|
|
||||||
@ -1346,6 +1347,45 @@ screen_cursor_to_line(Screen *self, unsigned int line) {
|
|||||||
screen_cursor_position(self, line, self->cursor->x + 1);
|
screen_cursor_position(self, line, self->cursor->x + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
screen_cursor_at_a_shell_prompt(const Screen *self) {
|
||||||
|
if (self->cursor->y >= self->lines || self->linebuf != self->main_linebuf) return false;
|
||||||
|
for (index_type y=self->cursor->y + 1; y-- > 0; ) {
|
||||||
|
linebuf_init_line(self->linebuf, y);
|
||||||
|
if (self->linebuf->line->is_output_start) return -1;
|
||||||
|
if (self->linebuf->line->is_prompt_start) return y;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
screen_fake_move_cursor_to_position(Screen *self, index_type x, index_type y) {
|
||||||
|
SelectionBoundary a = {.x=x, .y=y}, b = {.x=self->cursor->x, .y=self->cursor->y};
|
||||||
|
SelectionBoundary *start, *end; int key;
|
||||||
|
if (a.y < b.y || (a.y == b.y && a.x < b.x)) { start = &a; end = &b; key = GLFW_FKEY_LEFT; }
|
||||||
|
else { start = &b; end = &a; key = GLFW_FKEY_RIGHT; }
|
||||||
|
unsigned count = 0;
|
||||||
|
|
||||||
|
for (unsigned y = start->y, x = start->x; y <= end->y; y++) {
|
||||||
|
unsigned x_limit = y == end->y ? end->x : self->columns;
|
||||||
|
while (x < x_limit) {
|
||||||
|
unsigned w = MAX(1u, linebuf_char_width_at(self->linebuf, x, y));
|
||||||
|
x += w;
|
||||||
|
count += w;
|
||||||
|
}
|
||||||
|
x = 0;
|
||||||
|
}
|
||||||
|
if (count) {
|
||||||
|
GLFWkeyevent ev = { .key = key, .action = GLFW_PRESS };
|
||||||
|
char output[KEY_BUFFER_SIZE+1] = {0};
|
||||||
|
int num = encode_glfw_key_event(&ev, false, 0, output);
|
||||||
|
if (num != SEND_TEXT_TO_CHILD) {
|
||||||
|
for (unsigned i = 0; i < count; i++) write_to_child(self, output, num);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return count > 0;
|
||||||
|
}
|
||||||
|
|
||||||
// }}}
|
// }}}
|
||||||
|
|
||||||
// Editing {{{
|
// Editing {{{
|
||||||
@ -1919,7 +1959,6 @@ screen_update_cell_data(Screen *self, void *address, FONTS_DATA_HANDLE fonts_dat
|
|||||||
if (was_dirty) clear_selection(&self->url_ranges);
|
if (was_dirty) clear_selection(&self->url_ranges);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
selection_boundary_less_than(const SelectionBoundary *a, const SelectionBoundary *b) {
|
selection_boundary_less_than(const SelectionBoundary *a, const SelectionBoundary *b) {
|
||||||
// y -values must be absolutized (aka adjusted with scrolled_by)
|
// y -values must be absolutized (aka adjusted with scrolled_by)
|
||||||
|
|||||||
@ -241,6 +241,8 @@ uint8_t screen_current_key_encoding_flags(Screen *self);
|
|||||||
void screen_report_key_encoding_flags(Screen *self);
|
void screen_report_key_encoding_flags(Screen *self);
|
||||||
void screen_xtmodkeys(Screen *self, uint32_t p1, uint32_t p2);
|
void screen_xtmodkeys(Screen *self, uint32_t p1, uint32_t p2);
|
||||||
bool screen_detect_url(Screen *screen, unsigned int x, unsigned int y);
|
bool screen_detect_url(Screen *screen, unsigned int x, unsigned int y);
|
||||||
|
int screen_cursor_at_a_shell_prompt(const Screen *);
|
||||||
|
bool screen_fake_move_cursor_to_position(Screen *, index_type x, index_type y);
|
||||||
#define DECLARE_CH_SCREEN_HANDLER(name) void screen_##name(Screen *screen);
|
#define DECLARE_CH_SCREEN_HANDLER(name) void screen_##name(Screen *screen);
|
||||||
DECLARE_CH_SCREEN_HANDLER(bell)
|
DECLARE_CH_SCREEN_HANDLER(bell)
|
||||||
DECLARE_CH_SCREEN_HANDLER(backspace)
|
DECLARE_CH_SCREEN_HANDLER(backspace)
|
||||||
|
|||||||
@ -1029,6 +1029,16 @@ click_mouse_url(id_type os_window_id, id_type tab_id, id_type window_id) {
|
|||||||
return clicked;
|
return clicked;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
move_cursor_to_mouse_if_in_prompt(id_type os_window_id, id_type tab_id, id_type window_id) {
|
||||||
|
bool moved = false;
|
||||||
|
WITH_WINDOW(os_window_id, tab_id, window_id);
|
||||||
|
moved = move_cursor_to_mouse_if_at_shell_prompt(window);
|
||||||
|
END_WITH_WINDOW;
|
||||||
|
return moved;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static PyObject*
|
static PyObject*
|
||||||
pymouse_selection(PyObject *self UNUSED, PyObject *args) {
|
pymouse_selection(PyObject *self UNUSED, PyObject *args) {
|
||||||
id_type os_window_id, tab_id, window_id;
|
id_type os_window_id, tab_id, window_id;
|
||||||
@ -1050,6 +1060,7 @@ THREE_ID_OBJ(update_window_title)
|
|||||||
THREE_ID(remove_window)
|
THREE_ID(remove_window)
|
||||||
THREE_ID(detach_window)
|
THREE_ID(detach_window)
|
||||||
THREE_ID(attach_window)
|
THREE_ID(attach_window)
|
||||||
|
THREE_ID(move_cursor_to_mouse_if_in_prompt)
|
||||||
PYWRAP1(resolve_key_mods) { int mods, kitty_mod; PA("ii", &kitty_mod, &mods); return PyLong_FromLong(resolve_mods(kitty_mod, mods)); }
|
PYWRAP1(resolve_key_mods) { int mods, kitty_mod; PA("ii", &kitty_mod, &mods); return PyLong_FromLong(resolve_mods(kitty_mod, mods)); }
|
||||||
PYWRAP1(add_tab) { return PyLong_FromUnsignedLongLong(add_tab(PyLong_AsUnsignedLongLong(args))); }
|
PYWRAP1(add_tab) { return PyLong_FromUnsignedLongLong(add_tab(PyLong_AsUnsignedLongLong(args))); }
|
||||||
PYWRAP1(add_window) { PyObject *title; id_type a, b; PA("KKO", &a, &b, &title); return PyLong_FromUnsignedLongLong(add_window(a, b, title)); }
|
PYWRAP1(add_window) { PyObject *title; id_type a, b; PA("KKO", &a, &b, &title); return PyLong_FromUnsignedLongLong(add_window(a, b, title)); }
|
||||||
@ -1069,6 +1080,7 @@ static PyMethodDef module_methods[] = {
|
|||||||
MW(set_options, METH_VARARGS),
|
MW(set_options, METH_VARARGS),
|
||||||
MW(get_options, METH_NOARGS),
|
MW(get_options, METH_NOARGS),
|
||||||
MW(click_mouse_url, METH_VARARGS),
|
MW(click_mouse_url, METH_VARARGS),
|
||||||
|
MW(move_cursor_to_mouse_if_in_prompt, METH_VARARGS),
|
||||||
MW(mouse_selection, METH_VARARGS),
|
MW(mouse_selection, METH_VARARGS),
|
||||||
MW(set_in_sequence_mode, METH_O),
|
MW(set_in_sequence_mode, METH_O),
|
||||||
MW(resolve_key_mods, METH_VARARGS),
|
MW(resolve_key_mods, METH_VARARGS),
|
||||||
|
|||||||
@ -303,6 +303,7 @@ void update_os_window_title(OSWindow *os_window);
|
|||||||
void fake_scroll(Window *w, int amount, bool upwards);
|
void fake_scroll(Window *w, int amount, bool upwards);
|
||||||
Window* window_for_window_id(id_type kitty_window_id);
|
Window* window_for_window_id(id_type kitty_window_id);
|
||||||
bool mouse_open_url(Window *w);
|
bool mouse_open_url(Window *w);
|
||||||
|
bool move_cursor_to_mouse_if_at_shell_prompt(Window *w);
|
||||||
void mouse_selection(Window *w, int code, int button);
|
void mouse_selection(Window *w, int code, int button);
|
||||||
const char* format_mods(unsigned mods);
|
const char* format_mods(unsigned mods);
|
||||||
void send_pending_click_to_window_id(id_type, void*);
|
void send_pending_click_to_window_id(id_type, void*);
|
||||||
|
|||||||
@ -29,9 +29,10 @@ from .fast_data_types import (
|
|||||||
SCROLL_PAGE, STRIKETHROUGH, TINT_PROGRAM, KeyEvent, Screen, add_timer,
|
SCROLL_PAGE, STRIKETHROUGH, TINT_PROGRAM, KeyEvent, Screen, add_timer,
|
||||||
add_window, cell_size_for_window, click_mouse_url, compile_program,
|
add_window, cell_size_for_window, click_mouse_url, compile_program,
|
||||||
encode_key_for_tty, get_boss, get_clipboard_string, get_options,
|
encode_key_for_tty, get_boss, get_clipboard_string, get_options,
|
||||||
init_cell_program, mouse_selection, pt_to_px, set_clipboard_string,
|
init_cell_program, mouse_selection, move_cursor_to_mouse_if_in_prompt,
|
||||||
set_titlebar_color, set_window_padding, set_window_render_data,
|
pt_to_px, set_clipboard_string, set_titlebar_color, set_window_padding,
|
||||||
update_window_title, update_window_visibility, viewport_for_window
|
set_window_render_data, update_window_title, update_window_visibility,
|
||||||
|
viewport_for_window
|
||||||
)
|
)
|
||||||
from .keys import keyboard_mode_name, mod_mask
|
from .keys import keyboard_mode_name, mod_mask
|
||||||
from .notify import NotificationCommand, handle_notification_cmd
|
from .notify import NotificationCommand, handle_notification_cmd
|
||||||
@ -777,6 +778,7 @@ class Window:
|
|||||||
|
|
||||||
def handle_remote_print(self, msg: bytes) -> None:
|
def handle_remote_print(self, msg: bytes) -> None:
|
||||||
from base64 import standard_b64decode
|
from base64 import standard_b64decode
|
||||||
|
|
||||||
from .cli import green
|
from .cli import green
|
||||||
text = standard_b64decode(msg).decode('utf-8')
|
text = standard_b64decode(msg).decode('utf-8')
|
||||||
text = text.replace('\x1b', green(r'\e')).replace('\a', green(r'\a')).replace('\0', green(r'\0'))
|
text = text.replace('\x1b', green(r'\e')).replace('\a', green(r'\a')).replace('\0', green(r'\0'))
|
||||||
@ -851,15 +853,37 @@ class Window:
|
|||||||
# }}}
|
# }}}
|
||||||
|
|
||||||
# mouse actions {{{
|
# mouse actions {{{
|
||||||
|
@ac('mouse', '''
|
||||||
|
Handle a mouse click
|
||||||
|
|
||||||
|
Try to perform the specified actions one after the other till one of them is successful.
|
||||||
|
Supported actions are::
|
||||||
|
|
||||||
|
selection - check for a selection and if one exists abort processing
|
||||||
|
link - if a link exists under the mouse, click it
|
||||||
|
prompt - if the mouse click happens at a shell prompt move the cursor to the mouse location
|
||||||
|
|
||||||
|
For examples, see :ref:`conf-kitty-mouse.mousemap`
|
||||||
|
''')
|
||||||
|
def mouse_handle_click(self, *actions: str) -> None:
|
||||||
|
for a in actions:
|
||||||
|
if a == 'selection':
|
||||||
|
if self.screen.has_selection():
|
||||||
|
break
|
||||||
|
if a == 'link':
|
||||||
|
if click_mouse_url(self.os_window_id, self.tab_id, self.id):
|
||||||
|
break
|
||||||
|
if a == 'prompt':
|
||||||
|
if move_cursor_to_mouse_if_in_prompt(self.os_window_id, self.tab_id, self.id):
|
||||||
|
break
|
||||||
|
|
||||||
@ac('mouse', 'Click the URL under the mouse')
|
@ac('mouse', 'Click the URL under the mouse')
|
||||||
def mouse_click_url(self) -> None:
|
def mouse_click_url(self) -> None:
|
||||||
click_mouse_url(self.os_window_id, self.tab_id, self.id)
|
self.mouse_handle_click('link')
|
||||||
|
|
||||||
@ac('mouse', 'Click the URL under the mouse only if the screen has no selection')
|
@ac('mouse', 'Click the URL under the mouse only if the screen has no selection')
|
||||||
def mouse_click_url_or_select(self) -> None:
|
def mouse_click_url_or_select(self) -> None:
|
||||||
if not self.screen.has_selection():
|
self.mouse_handle_click('selection', 'link')
|
||||||
if not click_mouse_url(self.os_window_id, self.tab_id, self.id):
|
|
||||||
pass # no URL found
|
|
||||||
|
|
||||||
@ac('mouse', '''
|
@ac('mouse', '''
|
||||||
Manipulate the selection based on the current mouse position
|
Manipulate the selection based on the current mouse position
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user