Deprecate pipe in favor of launch

This commit is contained in:
Kovid Goyal 2019-11-13 16:08:48 +05:30
parent 75d66d1048
commit 1724f11429
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
7 changed files with 62 additions and 30 deletions

View File

@ -415,7 +415,7 @@ comfortably within the pager.
Additionally, you can pipe the contents of the scrollback buffer to an Additionally, you can pipe the contents of the scrollback buffer to an
arbitrary, command running in a new window, tab or overlay, for example:: arbitrary, command running in a new window, tab or overlay, for example::
map f1 pipe @ansi window less +G -R map f1 launch --stdin-source=@screen_scrollback --stdin-add-formatting less +G -R
Would open the scrollback buffer in a new window when you press the :kbd:`F1` Would open the scrollback buffer in a new window when you press the :kbd:`F1`
key. See :sc:`show_scrollback` for details. key. See :sc:`show_scrollback` for details.

View File

@ -35,6 +35,20 @@ To pass the contents of the current screen and scrollback to the started process
There are many more powerful options, refer to the complete list below. There are many more powerful options, refer to the complete list below.
The piping environment
--------------------------
When using :option:`launch --stdin-source`, the program to which the data is
piped has a special environment variable declared, ``KITTY_PIPE_DATA`` whose
contents are::
KITTY_PIPE_DATA={scrolled_by}:{cursor_x},{cursor_y}:{lines},{columns}
where ``scrolled_by`` is the number of lines kitty is currently scrolled by,
``cursor_(x|y)`` is the position of the cursor on the screen with ``(1,1)``
being the top left corner and ``{lines},{columns}`` being the number of rows
and columns of the screen.
Syntax reference Syntax reference
------------------ ------------------

View File

@ -1,6 +1,9 @@
Working with the screen and history buffer contents Working with the screen and history buffer contents
====================================================== ======================================================
.. warning::
The pipe action has been deprecated in favor of the
:doc:`launch <launch>` action which is more powerful.
You can pipe the contents of the current screen and history buffer as You can pipe the contents of the current screen and history buffer as
:file:`STDIN` to an arbitrary program using the ``pipe`` function. The program :file:`STDIN` to an arbitrary program using the ``pipe`` function. The program

View File

@ -914,6 +914,25 @@ class Boss:
overlay_for = w.id if as_overlay and w.overlay_for is None else None overlay_for = w.id if as_overlay and w.overlay_for is None else None
return SpecialWindow(cmd, stdin, cwd_from=cwd_from, overlay_for=overlay_for, env=env) return SpecialWindow(cmd, stdin, cwd_from=cwd_from, overlay_for=overlay_for, env=env)
def run_background_process(self, cmd, cwd=None, env=None, stdin=None, cwd_from=None):
import subprocess
if cwd_from:
with suppress(Exception):
cwd = cwd_of_process(cwd_from)
if stdin:
r, w = safe_pipe(False)
try:
subprocess.Popen(cmd, env=env, stdin=r, cwd=cwd)
except Exception:
os.close(w)
else:
thread_write(w, stdin)
finally:
os.close(r)
else:
subprocess.Popen(cmd, env=env, cwd=cwd)
def pipe(self, source, dest, exe, *args): def pipe(self, source, dest, exe, *args):
cmd = [exe] + list(args) cmd = [exe] + list(args)
window = self.active_window window = self.active_window
@ -939,24 +958,8 @@ class Boss:
func = set_clipboard_string if dest == 'clipboard' else set_primary_selection func = set_clipboard_string if dest == 'clipboard' else set_primary_selection
func(stdin) func(stdin)
else: else:
import subprocess
env, stdin = self.process_stdin_source(stdin=source, window=window) env, stdin = self.process_stdin_source(stdin=source, window=window)
cwd = None self.run_background_process(cmd, cwd_from=cwd_from, stdin=stdin, env=env)
if cwd_from:
with suppress(Exception):
cwd = cwd_of_process(cwd_from)
if stdin:
r, w = safe_pipe(False)
try:
subprocess.Popen(cmd, env=env, stdin=r, cwd=cwd)
except Exception:
os.close(w)
else:
thread_write(w, stdin)
finally:
os.close(r)
else:
subprocess.Popen(cmd, env=env, cwd=cwd)
def args_to_special_window(self, args, cwd_from=None): def args_to_special_window(self, args, cwd_from=None):
args = list(args) args = list(args)

View File

@ -792,7 +792,7 @@ Do not print out the id of the newly created window.
type=bool-set type=bool-set
If specified the tab containing the window this command is run in is used If specified the tab containing the window this command is run in is used
instead of the active tab instead of the active tab
''' + '\n\n' + launch_options_spec(), ''' + '\n\n' + launch_options_spec().replace(':option:`launch', ':option:`kitty @ launch'),
argspec='[CMD ...]' argspec='[CMD ...]'
) )
def cmd_launch(global_opts, opts, args): def cmd_launch(global_opts, opts, args):
@ -841,7 +841,7 @@ def launch(boss, window, payload):
tabs = [window.tabref()] tabs = [window.tabref()]
tab = tabs[0] tab = tabs[0]
w = do_launch(boss, opts, pg(payload, 'args') or None, target_tab=tab) w = do_launch(boss, opts, pg(payload, 'args') or None, target_tab=tab)
return None if pg(payload, 'no_response') else str(w.id) return None if pg(payload, 'no_response') else str(getattr(w, 'id', 0))
# }}} # }}}

View File

@ -1073,13 +1073,13 @@ if is_macos:
k('show_scrollback', 'kitty_mod+h', 'show_scrollback', _('Browse scrollback buffer in less'), long_text=_(''' k('show_scrollback', 'kitty_mod+h', 'show_scrollback', _('Browse scrollback buffer in less'), long_text=_('''
You can pipe the contents of the current screen + history buffer as You can pipe the contents of the current screen + history buffer as
:file:`STDIN` to an arbitrary program using the ``pipe`` function. For example, :file:`STDIN` to an arbitrary program using the ``launch`` function. For example,
the following opens the scrollback buffer in less in an overlay window:: the following opens the scrollback buffer in less in an overlay window::
map f1 pipe @ansi overlay less +G -R map f1 launch --stdin-source=@screen_scrollback --stdin-add-formatting --type=overlay less +G -R
For more details on piping screen and buffer contents to external programs, For more details on piping screen and buffer contents to external programs,
see :doc:`pipe`. see :doc:`launch`.
''')) '''))

View File

@ -4,6 +4,8 @@
from kitty.cli import parse_args from kitty.cli import parse_args
from kitty.fast_data_types import set_clipboard_string
from kitty.utils import set_primary_selection
def options_spec(): def options_spec():
@ -22,11 +24,14 @@ of the actie window in the tab is used as the tab title.
--type --type
type=choices type=choices
default=window default=window
choices=window,tab,os-window,overlay choices=window,tab,os-window,overlay,background,clipboard,primary
Where to launch the child process, in a new kitty window in the current tab, Where to launch the child process, in a new kitty window in the current tab,
a new tab, or a new OS window or an overlay over the current window. a new tab, or a new OS window or an overlay over the current window.
Note that if the current window already has an overlay, then it will Note that if the current window already has an overlay, then it will
open a new window. open a new window. The value of none means the process will be
run in the background. The values clipboard and primary are meant
to work with :option:`launch --stdin-source` to copy data to the system
clipboard or primary selection.
--keep-focus --keep-focus
@ -197,6 +202,13 @@ def launch(boss, opts, args, target_tab=None):
if penv: if penv:
env.update(penv) env.update(penv)
if opts.type == 'background':
boss.run_background_process(kw['cmd'], cwd=kw.get('cwd'), cwd_from=kw.get('cwd_from'), env=env or None, stdin=kw.get('stdin'))
elif opts.type in ('clipboard', 'primary'):
if 'stdin' in kw:
func = set_clipboard_string if opts.type == 'clipboard' else set_primary_selection
func(kw['stdin'])
else:
tab = tab_for_window(boss, opts, target_tab) tab = tab_for_window(boss, opts, target_tab)
new_window = tab.new_window(env=env or None, **kw) new_window = tab.new_window(env=env or None, **kw)
if opts.keep_focus and active: if opts.keep_focus and active: