remote-control.rst 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353
  1. Control kitty from scripts
  2. ----------------------------
  3. .. highlight:: sh
  4. |kitty| can be controlled from scripts or the shell prompt. You can open new
  5. windows, send arbitrary text input to any window, change the title of windows
  6. and tabs, etc.
  7. Let's walk through a few examples of controlling |kitty|.
  8. Tutorial
  9. ------------
  10. Start by running |kitty| as::
  11. kitty -o allow_remote_control=yes -o enabled_layouts=tall
  12. In order for control to work, :opt:`allow_remote_control` or
  13. :opt:`remote_control_password` must be enabled in :file:`kitty.conf`. Here we
  14. turn it on explicitly at the command line.
  15. Now, in the new |kitty| window, enter the command::
  16. kitten @ launch --title Output --keep-focus cat
  17. This will open a new window, running the :program:`cat` program that will appear
  18. next to the current window.
  19. Let's send some text to this new window::
  20. kitten @ send-text --match cmdline:cat Hello, World
  21. This will make ``Hello, World`` show up in the window running the :program:`cat`
  22. program. The :option:`kitten @ send-text --match` option is very powerful, it
  23. allows selecting windows by their titles, the command line of the program
  24. running in the window, the working directory of the program running in the
  25. window, etc. See :ref:`kitten @ send-text --help <at-send-text>` for details.
  26. More usefully, you can pipe the output of a command running in one window to
  27. another window, for example::
  28. ls | kitten @ send-text --match 'title:^Output' --stdin
  29. This will show the output of :program:`ls` in the output window instead of the
  30. current window. You can use this technique to, for example, show the output of
  31. running :program:`make` in your editor in a different window. The possibilities
  32. are endless.
  33. You can even have things you type show up in a different window. Run::
  34. kitten @ send-text --match 'title:^Output' --stdin
  35. And type some text, it will show up in the output window, instead of the current
  36. window. Type :kbd:`Ctrl+D` when you are ready to stop.
  37. Now, let's open a new tab::
  38. kitten @ launch --type=tab --tab-title "My Tab" --keep-focus bash
  39. This will open a new tab running the bash shell with the title "My Tab".
  40. We can change the title of the tab to "New Title" with::
  41. kitten @ set-tab-title --match 'title:^My' New Title
  42. Let's change the title of the current tab::
  43. kitten @ set-tab-title Master Tab
  44. Now lets switch to the newly opened tab::
  45. kitten @ focus-tab --match 'title:^New'
  46. Similarly, to focus the previously opened output window (which will also switch
  47. back to the old tab, automatically)::
  48. kitten @ focus-window --match 'title:^Output'
  49. You can get a listing of available tabs and windows, by running::
  50. kitten @ ls
  51. This outputs a tree of data in JSON format. The top level of the tree is all
  52. :term:`OS windows <os_window>`. Each OS window has an id and a list of
  53. :term:`tabs <tab>`. Each tab has its own id, a title and a list of :term:`kitty
  54. windows <window>`. Each window has an id, title, current working directory,
  55. process id (PID) and command-line of the process running in the window. You can
  56. use this information with :option:`kitten @ focus-window --match` to control
  57. individual windows.
  58. As you can see, it is very easy to control |kitty| using the ``kitten @``
  59. messaging system. This tutorial touches only the surface of what is possible.
  60. See ``kitten @ --help`` for more details.
  61. In the example's above, ``kitten @`` messaging works only when run
  62. inside a |kitty| window, not anywhere. But, within a |kitty| window it even
  63. works over SSH. If you want to control |kitty| from programs/scripts not running
  64. inside a |kitty| window, see the section on :ref:`using a socket for remote control <rc_via_socket>`
  65. below.
  66. Note that if all you want to do is run a single |kitty| "daemon" and have
  67. subsequent |kitty| invocations appear as new top-level windows, you can use the
  68. simpler :option:`kitty --single-instance` option, see ``kitty --help`` for that.
  69. .. _rc_via_socket:
  70. Remote control via a socket
  71. --------------------------------
  72. First, start |kitty| as::
  73. kitty -o allow_remote_control=yes --listen-on unix:/tmp/mykitty
  74. The :option:`kitty --listen-on` option tells |kitty| to listen for control
  75. messages at the specified UNIX-domain socket. See ``kitty --help`` for details.
  76. Now you can control this instance of |kitty| using the :option:`kitten @ --to`
  77. command line argument to ``kitten @``. For example::
  78. kitten @ --to unix:/tmp/mykitty ls
  79. The builtin kitty shell
  80. --------------------------
  81. You can explore the |kitty| command language more easily using the builtin
  82. |kitty| shell. Run ``kitten @`` with no arguments and you will be dropped into
  83. the |kitty| shell with completion for |kitty| command names and options.
  84. You can even open the |kitty| shell inside a running |kitty| using a simple
  85. keyboard shortcut (:sc:`kitty_shell` by default).
  86. .. note:: Using the keyboard shortcut has the added advantage that you don't need to use
  87. :opt:`allow_remote_control` to make it work.
  88. Allowing only some windows to control kitty
  89. ----------------------------------------------
  90. If you do not want to allow all programs running in |kitty| to control it, you
  91. can selectively enable remote control for only some |kitty| windows. Simply
  92. create a shortcut such as::
  93. map ctrl+k launch --allow-remote-control some_program
  94. Then programs running in windows created with that shortcut can use ``kitten @``
  95. to control kitty. Note that any program with the right level of permissions can
  96. still write to the pipes of any other program on the same computer and therefore
  97. can control |kitty|. It can, however, be useful to block programs running on
  98. other computers (for example, over SSH) or as other users.
  99. .. note:: You don't need :opt:`allow_remote_control` to make this work as it is
  100. limited to only programs running in that specific window. Be careful with
  101. what programs you run in such windows, since they can effectively control
  102. kitty, as if you were running with :opt:`allow_remote_control` turned on.
  103. You can further restrict what is allowed in these windows by using
  104. :option:`kitten @ launch --remote-control-password`.
  105. Fine grained permissions for remote control
  106. ----------------------------------------------
  107. .. versionadded:: 0.26.0
  108. The :opt:`allow_remote_control` option discussed so far is a blunt
  109. instrument, granting the ability to any program running on your computer
  110. or even on remote computers via SSH the ability to use remote control.
  111. You can instead define remote control passwords that can be used to grant
  112. different levels of control to different places. You can even write your
  113. own script to decide which remote control requests are allowed. This is
  114. done using the :opt:`remote_control_password` option in :file:`kitty.conf`.
  115. Set :opt:`allow_remote_control` to :code:`password` to use this feature.
  116. Let's see some examples:
  117. .. code-block:: conf
  118. remote_control_password "control colors" get-colors set-colors
  119. Now, using this password, you can, in scripts run the command::
  120. kitten @ --password="control colors" set-colors background=red
  121. Any script with access to the password can now change colors in kitty using
  122. remote control, but only that and nothing else. You can even supply the
  123. password via the :envvar:`KITTY_RC_PASSWORD` environment variable, or the
  124. file :file:`~/.config/kitty/rc-password` to avoid having to type it repeatedly.
  125. See :option:`kitten @ --password-file` and :option:`kitten @ --password-env`.
  126. The :opt:`remote_control_password` can be specified multiple times to create
  127. different passwords with different capabilities. Run the following to get a
  128. list of all action names::
  129. kitten @ --help
  130. You can even use glob patterns to match action names, for example:
  131. .. code-block:: conf
  132. remote_control_password "control colors" *-colors
  133. If no action names are specified, all actions are allowed.
  134. If ``kitten @`` is run with a password that is not present in
  135. :file:`kitty.conf`, then kitty will interactively prompt the user to allow or
  136. disallow the remote control request. The user can choose to allow or disallow
  137. either just that request or all requests using that password. The user's
  138. decision is remembered for the duration of that kitty instance.
  139. .. note::
  140. For password based authentication to work over SSH, you must pass the
  141. :envvar:`KITTY_PUBLIC_KEY` environment variable to the remote host. The
  142. :doc:`ssh kitten <kittens/ssh>` does this for you automatically. When
  143. using a password, :ref:`rc_crypto` is used to ensure the password
  144. is kept secure. This does mean that using password based authentication
  145. is slower as the entire command is encrypted before transmission. This
  146. can be noticeable when using a command like ``kitten @ set-background-image``
  147. which transmits large amounts of image data. Also, the clock on the remote
  148. system must match (within a few minutes) the clock on the local system.
  149. kitty uses a time based nonce to minimise the potential for replay attacks.
  150. .. _rc_custom_auth:
  151. Customizing authorization with your own program
  152. ____________________________________________________________
  153. If the ability to control access by action names is not fine grained enough,
  154. you can define your own Python script to examine every remote control command
  155. and allow/disallow it. To do so create a file in the kitty configuration
  156. directory, :file:`~/.config/kitty/my_rc_auth.py` and add the following
  157. to :file:`kitty.conf`:
  158. .. code-block:: conf
  159. remote_control_password "testing custom auth" my_rc_auth.py
  160. :file:`my_rc_auth.py` should define a :code:`is_cmd_allowed` function
  161. as shown below:
  162. .. code-block:: py
  163. def is_cmd_allowed(pcmd, window, from_socket, extra_data):
  164. cmd_name = pcmd['cmd'] # the name of the command
  165. cmd_payload = pcmd['payload'] # the arguments to the command
  166. # examine the cmd_name and cmd_payload and return True to allow
  167. # the command or False to disallow it. Return None to have no
  168. # effect on the command.
  169. # The command payload will vary from command to command, see
  170. # the rc protocol docs for details. Below is an example of
  171. # restricting the launch command to allow only running the
  172. # default shell.
  173. if cmd_name != 'launch':
  174. return None
  175. if cmd_payload.get('args') or cmd_payload.get('env') or cmd_payload.get('copy_cmdline') or cmd_payload.get('copy_env'):
  176. return False
  177. # prints in this function go to the parent kitty process STDOUT
  178. print('Allowing launch command:', cmd_payload)
  179. return True
  180. .. _rc_mapping:
  181. Mapping key presses to remote control commands
  182. --------------------------------------------------
  183. If you wish to trigger a remote control command easily with just a keypress,
  184. you can map it in :file:`kitty.conf`. For example::
  185. map f1 remote_control set-spacing margin=30
  186. Then pressing the :kbd:`F1` key will set the active window margins to
  187. :code:`30`. The syntax for what follows :ac:`remote_control` is exactly the same
  188. as the syntax for what follows :code:`kitten @` above.
  189. If you wish to ignore errors from the command, prefix the command with an
  190. ``!``. For example, the following will not return an error when no windows
  191. are matched::
  192. map f1 remote_control !focus-window --match XXXXXX
  193. If you wish to run a more complex script, you can use::
  194. map f1 remote_control_script /path/to/myscript
  195. In this script you can use ``kitten @`` to run as many remote
  196. control commands as you like and process their output.
  197. :ac:`remote_control_script` is similar to the
  198. :ac:`launch` command with ``--type=background --allow-remote-control``.
  199. For more advanced usage, including fine grained permissions, setting
  200. env vars, command line interpolation, passing data to STDIN, etc.
  201. the :doc:`launch <launch>` command should be used.
  202. .. note:: You do not need :opt:`allow_remote_control` to use these mappings,
  203. as they are not actual remote programs, but are simply a way to reuse the
  204. remote control infrastructure via keybings.
  205. Broadcasting what you type to all kitty windows
  206. --------------------------------------------------
  207. As a simple illustration of the power of remote control, lets
  208. have what we type sent to all open kitty windows. To do that define the
  209. following mapping in :file:`kitty.conf`::
  210. map f1 launch --allow-remote-control kitty +kitten broadcast
  211. Now press :kbd:`F1` and start typing, what you type will be sent to all windows,
  212. live, as you type it.
  213. The remote control protocol
  214. -----------------------------------------------
  215. If you wish to develop your own client to talk to |kitty|, you can use the
  216. :doc:`remote control protocol specification <rc_protocol>`. Note that there
  217. is a statically compiled, standalone executable, ``kitten`` available that
  218. can be used as a remote control client on any UNIX like computer. This can be
  219. downloaded and used directly from the `kitty releases
  220. <https://github.com/kovidgoyal/kitty/releases>`__ page::
  221. kitten @ --help
  222. .. _search_syntax:
  223. Matching windows and tabs
  224. ----------------------------
  225. Many remote control operations operate on windows or tabs. To select these, the
  226. :code:`--match` option is often used. This allows matching using various
  227. sophisticated criteria such as title, ids, command lines, etc. These criteria are
  228. expressions of the form :code:`field:query`. Where :italic:`field` is the field
  229. against which to match and :italic:`query` is the expression to match. They can
  230. be further combined using Boolean operators, best illustrated with some
  231. examples::
  232. title:"My special window" or id:43
  233. title:bash and env:USER=kovid
  234. not id:1
  235. (id:2 or id:3) and title:something
  236. .. include:: generated/matching.rst
  237. .. toctree::
  238. :hidden:
  239. rc_protocol
  240. .. include:: generated/cli-kitten-at.rst