Skip to content
Advertisement

How to write a transparent wrapper to terminal application?

Wrapper should handle special control characters and do something but otherwise not interfere with the actual application. (trying to build a tmux like app)

So far I have the below modifying example in doc: https://docs.python.org/3/library/pty.html#example

import pty
import os

def handle_special_cmd(data):
    # TODO
    raise NotImplementedError

def inread(fd):
    data = os.read(fd, 1024)
    if b'x02' in data: # ctrl B
        return handle_special_cmd(data)
    return data

def main():
    cmd="vim"
    pty.spawn(cmd, stdin_read=inread)

if __name__=='__main__':
    main()

The above code works but the vim opened does not cover the entire terminal window. It starts vim with reduced rows and columns bad vim

If I just type vim from the shell it works fine: good vim

Why does this occur and how to fix it? My goal is not just fix the rows and columns but the wrapper should be truely transparent except trap the special ctrl character and do some stuff. whatever tty / colors and other settings the current shell has should be passed on to the actual executable. It should work as if I typed vim. (Linux specific solution is fine. Need not work in all posix. If it needs a c extension is also fine).

Advertisement

Answer

The window size is, uniquely, a property of the PTY itself. You can get and set it using the TIOCGWINSZ and TIOCSWINSZ ioctls:

import sys, fcntl, termios, struct

buf = bytearray(4)
fcntl.ioctl(sys.stdin.fileno(), termios.TIOCGWINSZ, buf)
(h, w) = struct.unpack("HH", buf)
print("Terminal is {w} x {h}".format(w=w, h=h))

[...]

fcntl.ioctl(child_pty.fileno(), termios.TIOCSWINSZ, struct.pack("HH", h, w))
User contributions licensed under: CC BY-SA
6 People found this is helpful
Advertisement