python - Keep stdin line at top or bottom of terminal screen -
so writing project run program receives/sends messages other computers running same program.
the receiver/sender of data running on thread , prints stdout. stuff this:
[info] user 'blah' wants send message you. [info] other info [msg rec] message 'hello' received blah.
now issue wish input commands terminal, problem when try enter command , new info message or msg rec
printed stdout. have commands such quit
, status
etc.
>> indicates input line.
something may happen:
[info] user 'blah' wants send message you. [info] other info [msg rec] message 'hello' received blah. >> stat[msg rec] message 'sup' received bob.
then press enter , command status
gets executed looks poor in terminal. message appears every 2-4 seconds issue. there way solve this? tried using ansi cursor commands try , insert new line before last line last line remain input line , type in "stat", wait while , finish "us" without issues.
i saw people recommend curses
attempting integrate program messed formatting of output among other things (and think overkill perhaps).
so there easy way make thread insert new msg rec
lines 1 line above last line last line remain input line >> , whatever else have typed in.
using python2.7 on linux.
edit: change made james mills answer work: had use whenever thread printing new line.
myy, myx = stdscr.getyx(); str = "blah blah"; #my message want print stdscr.addstr(len(lines), 0, str) lines.append(str) stdscr.move(myy, myx) #move cursor proper position
here basic example:
code:
#!/usr/bin/env python string import printable curses import erasechar, wrapper printable = map(ord, printable) def input(stdscr): erase = input.erase = getattr(input, "erase", ord(erasechar())) y, x = stdscr.getyx() s = [] while true: c = stdscr.getch() if c in (13, 10): break elif c == erase: y, x = stdscr.getyx() if x > x: del s[-1] stdscr.move(y, (x - 1)) stdscr.clrtoeol() stdscr.refresh() elif c in printable: s.append(chr(c)) stdscr.addch(c) return "".join(s) def prompt(stdscr, y, x, prompt=">>> "): stdscr.move(y, x) stdscr.clrtoeol() stdscr.addstr(y, x, prompt) return input(stdscr) def main(stdscr): y, x = stdscr.getmaxyx() lines = [] max_lines = (y - 3) stdscr.clear() while true: s = prompt(stdscr, (y - 1), 0) # noqa if s == ":q": break # scroll if len(lines) > max_lines: lines = lines[1:] stdscr.clear() i, line in enumerate(lines): stdscr.addstr(i, 0, line) stdscr.addstr(len(lines), 0, s) lines.append(s) stdscr.refresh() wrapper(main)
this sets demo curses app prompts user input , displays prompt @ (24, 0)
. demo terminates on user entering :q
. other input appends input top of screen. enjoy! (<backsapce>
works!) :)
see: curses; of api used in example straight standard library. whilst using curses may or may not "overkill" ihmo recommend use of urwid if complexity of application starts outgrow plain 'ol curses.
Comments
Post a Comment