mirror of
https://github.com/kovidgoyal/kitty.git
synced 2026-09-27 16:14:59 +00:00
Fix explicit stdin sources in the DnD kitten
This commit is contained in:
parent
9ee01568f9
commit
9c557f917b
3 changed files with 56 additions and 10 deletions
|
|
@ -350,6 +350,8 @@ func dnd_main(cmd *cli.Command, opts *Options, args []string) (rc int, err error
|
|||
}
|
||||
}
|
||||
drag_sources := make(map[string]*drag_source)
|
||||
var stdin_data []byte
|
||||
stdin_read := false
|
||||
for _, spec := range opts.Drag {
|
||||
mime, src, found := strings.Cut(spec, ":")
|
||||
if !found {
|
||||
|
|
@ -357,13 +359,14 @@ func dnd_main(cmd *cli.Command, opts *Options, args []string) (rc int, err error
|
|||
}
|
||||
s := &drag_source{human_name: src, mime_type: mime}
|
||||
if src == "-" || src == "/dev/stdin" {
|
||||
data, err := io.ReadAll(os.Stdin)
|
||||
if err != nil {
|
||||
return 1, err
|
||||
}
|
||||
if len(data) > 0 {
|
||||
drag_sources["text/plain"] = &drag_source{human_name: "STDIN", mime_type: "text/plain", data: data}
|
||||
if !stdin_read {
|
||||
stdin_data, err = io.ReadAll(os.Stdin)
|
||||
if err != nil {
|
||||
return 1, err
|
||||
}
|
||||
stdin_read = true
|
||||
}
|
||||
s.human_name, s.data = "STDIN", stdin_data
|
||||
} else {
|
||||
path, err := filepath.Abs(utils.Expanduser(src))
|
||||
if err != nil {
|
||||
|
|
@ -374,7 +377,7 @@ func dnd_main(cmd *cli.Command, opts *Options, args []string) (rc int, err error
|
|||
drag_sources[mime] = s
|
||||
}
|
||||
|
||||
if _, has_plain := drag_sources["text/plain"]; os.Stdin != nil && !has_plain && !tty.IsTerminal(os.Stdin.Fd()) {
|
||||
if _, has_plain := drag_sources["text/plain"]; os.Stdin != nil && !stdin_read && !has_plain && !tty.IsTerminal(os.Stdin.Fd()) {
|
||||
data, err := io.ReadAll(os.Stdin)
|
||||
if err != nil {
|
||||
return 1, err
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ type=list
|
|||
When starting a drag, use the specified file as the data source for the specified
|
||||
MIME type. Syntax is: mime-type:path/to/file. For example image/jpeg:mypic.jpg
|
||||
Can be specified multiple times to drag multiple MIME types.
|
||||
Use :code:`-` or :file:`/dev/stdin` to read from STDIN. The same input can be used for multiple MIME types.
|
||||
|
||||
|
||||
--drop
|
||||
|
|
@ -82,7 +83,7 @@ If the text/uri-list MIME type is dropped onto this window, the files and direct
|
|||
copied into the current working directory. When dragging from this window, if a move operation is
|
||||
performed when dropping and the drop is to a remote machine, the files and directories to drag and deleted.
|
||||
|
||||
If data is present on STDIN it is set as text/plain when dragging, unless text/plain is specified via --drag.
|
||||
If data is present on STDIN it is set as text/plain when dragging, unless STDIN is used explicitly via --drag or text/plain is specified via --drag.
|
||||
Any text/plain data that is dropped onto this window is output to STDOUT, if STDOUT is connected to a file, otherwise it
|
||||
is discarded.
|
||||
|
||||
|
|
|
|||
|
|
@ -123,10 +123,10 @@ class TestDnDKitten(BaseTest):
|
|||
self.pty.write_to_child(chunk)
|
||||
self.pty.write_to_child(b'\x1b\\', flush=is_last and flush)
|
||||
|
||||
def finish_setup(self, remote_client: bool = False, cli_args=()):
|
||||
def finish_setup(self, remote_client: bool = False, cli_args=(), stdin_fd=None):
|
||||
cmd = [kitten_exe(), 'dnd']
|
||||
cmd += list(cli_args)
|
||||
self.pty = self.enterContext(PTY(argv=cmd, cwd=self.kitten_wd, rows=25, columns=80, window_id=self.capture.window_id))
|
||||
self.pty = self.enterContext(PTY(argv=cmd, cwd=self.kitten_wd, rows=25, columns=80, window_id=self.capture.window_id, stdin_fd=stdin_fd))
|
||||
self.capture.pty = self.pty
|
||||
self.pty.callbacks.printbuf = self
|
||||
self.screen = self.pty.screen
|
||||
|
|
@ -393,6 +393,48 @@ class TestDnDKitten(BaseTest):
|
|||
with open(a, 'rb') as fa, open(b, 'rb') as fb:
|
||||
self.assertEqual(fa.read(), fb.read(), f'{a} ({os.path.getsize(a)}) != {b} ({os.path.getsize(b)})')
|
||||
|
||||
def test_dnd_kitten_stdin(self):
|
||||
from .graphics import png_data
|
||||
|
||||
drag_thumbnail = os.path.join(self.test_dir, 'drag.png')
|
||||
with open(drag_thumbnail, 'wb') as f:
|
||||
f.write(png_data)
|
||||
file_path = os.path.join(self.kitten_wd, 'text.txt')
|
||||
file_data = b'file contents'
|
||||
with open(file_path, 'wb') as f:
|
||||
f.write(file_data)
|
||||
stdin_data = b'<b>hello</b>\x00\xff'
|
||||
for cli_args, expected in (
|
||||
((), {'text/plain': stdin_data}),
|
||||
(('--drag=text/plain:-',), {'text/plain': stdin_data}),
|
||||
(('--drag=text/plain:/dev/stdin',), {'text/plain': stdin_data}),
|
||||
(('--drag=text/html:-',), {'text/html': stdin_data}),
|
||||
(('--drag=text/html:/dev/stdin',), {'text/html': stdin_data}),
|
||||
(('--drag=text/html:-', '--drag=text/plain:/dev/stdin'), {'text/html': stdin_data, 'text/plain': stdin_data}),
|
||||
((f'--drag=text/plain:{file_path}', '--drag=text/html:-'), {'text/plain': file_data, 'text/html': stdin_data}),
|
||||
((f'--drag=text/html:{file_path}',), {'text/plain': stdin_data, 'text/html': file_data}),
|
||||
((f'--drag=text/plain:{file_path}', '--drag=text/plain:-'), {'text/plain': stdin_data}),
|
||||
(('--drag=text/plain:-', f'--drag=text/plain:{file_path}'), {'text/plain': file_data}),
|
||||
):
|
||||
with self.subTest(cli_args=cli_args):
|
||||
read_fd, write_fd = os.pipe()
|
||||
with os.fdopen(write_fd, 'wb') as f:
|
||||
f.write(stdin_data)
|
||||
self.finish_setup(cli_args=(f'--drag-thumbnail={drag_thumbnail}',) + cli_args, stdin_fd=read_fd)
|
||||
try:
|
||||
self.assertTrue(self.probe_state('can_offer'))
|
||||
copy, move = self.get_button_geometry()
|
||||
dnd_test_start_drag_offer(self.capture.window_id, copy[0] + 1, copy[1] + 1)
|
||||
self.send_dnd_command_to_kitten('DRAG_ACTIVE')
|
||||
self.wait_for_responses('DRAG_ACTIVE')
|
||||
self.send_dnd_command_to_kitten('DRAG_OK')
|
||||
self.wait_for_responses('DRAG_OK')
|
||||
self.assertEqual(set(self.probe_state('drag_mimes')), set(expected))
|
||||
for mime, payload in expected.items():
|
||||
self.assertEqual(self.read_drag_data(mime), payload)
|
||||
finally:
|
||||
self.exit_kitten()
|
||||
|
||||
def test_dnd_kitten_drag(self):
|
||||
from .graphics import png_data
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue