magmax/python-readchar

ctrl+v paste does not copy text correctly in linux(wsl)

Opened this issue ยท 7 comments

Take this sample

import sys

import readchar

while True:
    sys.stdout.write(readchar.readchar())
    sys.stdout.flush()

if I copy the text ClientMessage.to_server and paste it into the program terminal in linux(wsl) I would get unordered characters
or missing characters like this ClientMto_seerrv

on windows cmd it works fine

On first read this sounds related to #73 (comment). Readchar can only guarantee character recognition inside its own function and behaviour outside of them is not defined.

So for your example, the first character will be read and returned by readchar, but its not clear what will happen to the rest of the input during the printing and flushing code...

Readchar is currently not really ready to handle input streams, only human input which is guaranteed to be slow enough.

I am working on this on the context-mamager branch, which would allow for exacly this kind of behaviour, but this faces its own issue currently.

Understandable, can you put this feature in your list of functionality of your progress. And close this afterwards

Anyways... Have you tried to use the terminal functionality, by pressing CTRL+SHIFT+V?

this should be solved as soon as the feature is merged, but I currently cant get it to work consistently in all cases ๐Ÿ˜ข

you can however install the developent version in your enviroment and test if it allready solves your usecase. simply run:

pip install git+https://github.com/magmax/python-readchar@contexmanager

I removed the old install and installed from the contextmanager and no change happened bug still exists,
however I tried a code snippet from the issue you mentioned (I removed delay but it works even with delay) and the input did not have problems ( i copied big text file)

import os
import time
import fcntl
import termios

class NonBlockingInput(object):

    def __enter__(self):
        # canonical mode, no echo
        self.old = termios.tcgetattr(sys.stdin)
        new = termios.tcgetattr(sys.stdin)
        new[3] = new[3] & ~(termios.ICANON | termios.ECHO)
        termios.tcsetattr(sys.stdin, termios.TCSADRAIN, new)

        # set for non-blocking io
        # orig_fl = fcntl.fcntl(sys.stdin, fcntl.F_GETFL)
        # fcntl.fcntl(sys.stdin, fcntl.F_SETFL, orig_fl | os.O_NONBLOCK)

    def __exit__(self, *args):
        # restore terminal to previous state
        termios.tcsetattr(sys.stdin, termios.TCSADRAIN, self.old)

with NonBlockingInput():
    while True:
        sys.stdout.write(sys.stdin.read(1))
        sys.stdout.flush()

it would be nice to have this non-blocking input added as an activated functionality with a function call for example to activate it and another to deactivate. or just simply by using with keyword
disclaimer: i don't understand anything how that works, it just solves the problem maybe you can see if it's good to be added and does not cause other bugs...

looking into the pr it seems you added a class "Readchar" that has that code but can't use it in import because it is not exported in __init__ module __all__ i modified the source file and added it
and tried this and the issue was fixed

import sys

from readchar import ReadChar

reader = ReadChar()
with reader:
    while True:
        sys.stdout.write(reader.char())
        sys.stdout.flush()

but can't use it in import because it is not exported in init module all

Yea its not jet externalised and you have to import it directly from the submodules, from readchar._read_posix import Readchar would have worked. Its still under development ๐Ÿ˜…

But good to know that it allready fixes your issue