Implement automatic tmux passthrough for icat

This commit is contained in:
Kovid Goyal
2023-03-04 13:01:23 +05:30
parent 8bd814444c
commit defac0c061
5 changed files with 84 additions and 15 deletions

View File

@@ -190,7 +190,17 @@ func main(cmd *cli.Command, o *Options, args []string) (rc int, err error) {
}
}
if opts.TransferMode == "detect" || opts.DetectSupport {
passthrough_mode := no_passthrough
switch opts.Passthrough {
case "tmux":
passthrough_mode = tmux_passthrough
case "detect":
if tui.TmuxSocketAddress() != "" {
passthrough_mode = tmux_passthrough
}
}
if passthrough_mode == no_passthrough && (opts.TransferMode == "detect" || opts.DetectSupport) {
memory, files, direct, err := DetectSupport(time.Duration(opts.DetectionTimeout * float64(time.Second)))
if err != nil {
return 1, err
@@ -210,6 +220,12 @@ func main(cmd *cli.Command, o *Options, args []string) (rc int, err error) {
transfer_by_file = unsupported
}
}
if passthrough_mode != no_passthrough {
// tmux doesnt allow responses from the terminal so we cant detect if memory or file based transferring is supported
transfer_by_memory = unsupported
transfer_by_file = unsupported
transfer_by_stream = supported
}
if opts.DetectSupport {
if transfer_by_memory == supported {
print_error("memory")
@@ -221,9 +237,13 @@ func main(cmd *cli.Command, o *Options, args []string) (rc int, err error) {
return 0, nil
}
use_unicode_placeholder := opts.UnicodePlaceholder
if passthrough_mode != no_passthrough {
use_unicode_placeholder = true
}
for num_of_items > 0 {
imgd := <-output_channel
imgd.use_unicode_placeholder = use_unicode_placeholder
imgd.passthrough_mode = passthrough_mode
num_of_items--
if imgd.err != nil {
print_error("Failed to process \x1b[31m%s\x1b[39m: %s\r\n", imgd.source_name, imgd.err)

View File

@@ -187,6 +187,7 @@ type image_data struct {
move_to struct{ x, y int }
width_cells, height_cells int
use_unicode_placeholder bool
passthrough_mode passthrough_type
// for error reporting
err error

View File

@@ -16,6 +16,7 @@ import (
"path/filepath"
"strings"
"kitty/tools/tui"
"kitty/tools/tui/graphics"
"kitty/tools/tui/loop"
"kitty/tools/utils"
@@ -25,8 +26,26 @@ import (
var _ = fmt.Print
func gc_for_image(imgd *image_data, frame_num int, frame *image_frame) *graphics.GraphicsCommand {
type passthrough_type int
const (
no_passthrough passthrough_type = iota
tmux_passthrough
)
func new_graphics_command(imgd *image_data) *graphics.GraphicsCommand {
gc := graphics.GraphicsCommand{}
switch imgd.passthrough_mode {
case tmux_passthrough:
gc.WrapPrefix = "\033Ptmux;"
gc.WrapSuffix = "\033\\"
gc.EncodeSerializedDataFunc = func(x string) string { return strings.ReplaceAll(x, "\033", "\033\033") }
}
return &gc
}
func gc_for_image(imgd *image_data, frame_num int, frame *image_frame) *graphics.GraphicsCommand {
gc := new_graphics_command(imgd)
gc.SetDataWidth(uint64(frame.width)).SetDataHeight(uint64(frame.height))
gc.SetQuiet(graphics.GRT_quiet_silent)
gc.SetFormat(frame.transmission_format)
@@ -63,7 +82,7 @@ func gc_for_image(imgd *image_data, frame_num int, frame *image_frame) *graphics
}
gc.SetLeftEdge(uint64(frame.left)).SetTopEdge(uint64(frame.top))
}
return &gc
return gc
}
func transmit_shm(imgd *image_data, frame_num int, frame *image_frame) (err error) {
@@ -315,6 +334,13 @@ func transmit_image(imgd *image_data) {
imgd.err = fmt.Errorf("Image too large to be displayed using Unicode placeholders. Maximum size is %dx%d cells", len(images.NumberToDiacritic), len(images.NumberToDiacritic))
return
}
switch imgd.passthrough_mode {
case tmux_passthrough:
imgd.err = tui.TmuxAllowPassthrough()
if imgd.err != nil {
return
}
}
fmt.Print("\r")
if !imgd.use_unicode_placeholder {
if imgd.move_x_by > 0 {
@@ -324,7 +350,7 @@ func transmit_image(imgd *image_data) {
fmt.Printf(loop.MoveCursorToTemplate, imgd.move_to.y, imgd.move_to.x)
}
}
frame_control_cmd := graphics.GraphicsCommand{}
frame_control_cmd := new_graphics_command(imgd)
frame_control_cmd.SetAction(graphics.GRT_action_animate)
if imgd.image_id != 0 {
frame_control_cmd.SetImageId(imgd.image_id)