Skip to content

Instantly share code, notes, and snippets.

@nnsense
Created June 2, 2021 18:29
Show Gist options
  • Save nnsense/6866cfc86995833f219c96b862e36bc7 to your computer and use it in GitHub Desktop.
Save nnsense/6866cfc86995833f219c96b862e36bc7 to your computer and use it in GitHub Desktop.
Python3 and curses: Multi-window test
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from threading import Thread
import curses, time, subprocess, io
commands = {'output': ""}
def input_window(window, r, c, prompt_string):
window.clear()
window.addstr(r, c, prompt_string)
try:
# Set the cursor 1 character from the top and 2 from the left of the first pane as we have a "> " at the beginning
input = window.getstr(r + 1, c + 2)
window.refresh()
except KeyboardInterrupt:
curses_cleanup()
exit()
return input
def output_window(window):
while True:
# Clear the current pane from any previous text
window.clear()
# Scroll up one line if we hit the bottom of the screen (tail like behaviour)
window.scrollok(True)
# use hardware line editing facilities
window.idlok(True)
try:
# The output is at the beginnging of the second pane - the dict is used to report the output without using global vars
window.addstr(0, 0, "Output:\n" + commands['output'])
except Exception as e:
commands['output'] = str(e)
window.refresh()
time.sleep(0.1)
def curses_cleanup():
curses.nocbreak()
curses.echo(True)
curses.endwin()
def main(stdscr):
# Set echo to work in this window (wrapper disable it by default)
curses.echo(True)
# Set to use the default colors (it would be grey-ish otherwise)
curses.use_default_colors()
# Disable the cursor blinking
curses.curs_set(0)
y = curses.LINES
x = curses.COLS
# The 2 panes' height are half of the screen, the second one is set at the middle of the screen
command_window = curses.newwin(int(y/3), x - 1, 0, 0)
display_window = curses.newwin(int(y/2), x - 1, int(y/3), 0)
# thread to refresh display_window
cursed_screen = Thread( target=output_window, args=(display_window,), name='cursed')
cursed_screen.daemon = True
cursed_screen.start()
# main thread, waiting for user's command.
while True:
# The command starts at the top/left corner of the screen
command = input_window(command_window, 0, 0, 'Enter your command :\n> ')
if command == "quit":
curses_cleanup()
exit()
else:
try:
commands['output'] = subprocess.check_output(command.split()).decode("utf-8")
except Exception as e:
commands['output'] = str(e)
curses.wrapper(main)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment