michael-lazar / rtv

Browse Reddit from your terminal
MIT License
4.65k stars 274 forks source link

input is broken under xonsh #614

Closed zyocum closed 6 years ago

zyocum commented 6 years ago

xonsh is a Python-based alternative shell. Unfortunately, running rtv under a xonsh session is only minimally usable. All keypresses are echoed to the screen, overwriting the rtv textual UI. Some keypresses are not acknowledged until you press return (e.g., movement keys). Other functionality, such as pressing u to log in, doesn’t work at all. I have no idea what the underlying issue is, but xonsh uses prompt_toolkit2 if available, falling back to readline, otherwise. I don’t have these issues running other curses based apps under xonsh, just rtv so far.

michael-lazar commented 6 years ago

Hi, thanks for posting an issue!

I was able to reproduce this with python 3.7.0 and xonsh/0.7.9 and it looks like xonsh simply isn't respecting curses settings. Specifically, curses.noecho() and curses.cbreak() are being set in the rtv initialization, but they're not taking effect for some reason. This is why you're seeing the keypress echos and you have to press the enter key.

I was able to reproduce this with a simple python script which should help narrow down the problem.

#!/usr/bin/env python3
import curses

try:
    stdscr = curses.initscr()
    curses.curs_set(0)
    curses.noecho()
    curses.cbreak()

    # Capture a keystroke and print it at coordinates (5, 5)
    # This works on all terminals except for xonsh
    while True:
        ch = stdscr.getch()
        stdscr.clear()
        stdscr.addch(5, 5, ch, curses.A_REVERSE)
        stdscr.refresh()

finally:
    curses.echo()
    curses.nocbreak()
    curses.endwin()
zyocum commented 6 years ago

Yep, test case works. It must be the Python curses wrapper that is at issue, then? htop, newsboat, etc. work fine, but your test case, rtv, and my tic-tac-toe program don’t work.

zyocum commented 6 years ago

Turns out this is a known issue in xonsh. The solution as listed there is to add to your .xonshrc:

from xonsh.commands_cache import predict_false
__xonsh_commands_cache__.threadable_predictors['rtv'] = predict_false

(Adding other curses apps in the same way seems to fix them as well, such as newsboat.)