Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

missing echo after ctrl-v paste of command #72

Closed
wangxuw opened this issue Jul 3, 2020 · 3 comments
Closed

missing echo after ctrl-v paste of command #72

wangxuw opened this issue Jul 3, 2020 · 3 comments

Comments

@wangxuw
Copy link

wangxuw commented Jul 3, 2020

As described in #70 , it is somewhat weird when paste something to runtime cli using ctrl-v, the whole content would not echo until a next keyboard is triggered.

@wangxuw
Copy link
Author

wangxuw commented Jul 8, 2020

I think it is because the select() would not be notified unless there's keyboard event, even though there are still some in the buffer to be read. cli read the stdin in a byte-wise manner, by using ctrl-v, only the first is read, and the later would not be read until a next keyboard event.

As a workaround, I added another fd to select() , and write to this fd when a KeyType::ascii is read. By doing this, we can explicitly get returned from select(). I tested in MacOs, and this surely works.
Here is the snippet modified in linuxkeyboard.h:

class LinuxKeyboard : public InputDevice {

~LinuxKeyboard() {
    // ...
    close(pipe_fd[0]);
    close(pipe_fd[1]);
}

void Read() {
    // open a pipe
    if(pipe(pipe_fd) < 0) ;
 // ...
}

std::pair<KeyType,char> Get() {
    // ...
    default: // ascii
    {
        const char c = static_cast<char>(ch);
        // there might be many to Get()
        write(pipe_fd[1], "x", 1); // to trigger `select() on pipe_fd[0]
        return std::make_pair(KeyType::ascii,c);
    }
}

int KbHit() { // change to non-static
    // ...
    FD_SET(pipe_fd[0], &rdfs);
    select(pipe_fd[0]+1, &rdfs, NULL, NULL, &tv);
    return FD_ISSET(STDIN_FILENO, &rdfs) || FD_ISSET(pipe_fd[0], &rdfs);
}

    int pipe_fd[2]
    // ... other data member

I thought this might help. As an another workaround, how about change the interface from std::pair<KeyType, char> to the std::pair<KeyType, std::string> so that the whole pasted content could be passed to the handler. @daniele77

@SirfGuru
Copy link

SirfGuru commented Dec 3, 2020

maybe a dumb question: why do we even need to wait for keyboard hit?
https://github.com/daniele77/cli/blob/master/include/cli/detail/linuxkeyboard.h#L81
multiple calls to getchar() will get the next char correctly.
I just commented out the above line, it seems to work for me.
of course, this is with 5 seconds test. Maybe this change disabled some feature which i still have not tested.

@daniele77
Copy link
Owner

@SirfGuru it seems you're right.
The function KbHit() is useless, and in fact, prevents the correct working of paste.
I'm gonna fix it right now with the commit 802bc1a
Thanks a lot.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants