Skip to content

Instantly share code, notes, and snippets.

@saulpw
Created November 29, 2016 23:03
Show Gist options
  • Save saulpw/9c9f523d1b831c99844f3b9ca223ef23 to your computer and use it in GitHub Desktop.
Save saulpw/9c9f523d1b831c99844f3b9ca223ef23 to your computer and use it in GitHub Desktop.
#!/usr/bin/python3
import curses
def ctrl(ch):
return ord(ch) & 31 # convert from 'a' to ^A keycode
ENTER = ctrl('j')
ESC = 27
def editText(scr, y, x, w, attr=None, prompt='', value='', fillchar=' ', unprintable='.'):
def splice(v, i, s): # splices s into the string v at i (v[i] = s[0])
return v if i < 0 else v[:i] + s + v[i:]
def clean(s):
return ''.join(c if c.isprintable() else unprintable for c in s)
def delchar(s, i, remove=1):
return s[:i] + s[i+remove:]
if prompt:
scr.addstr(y, x, prompt)
x += len(prompt)
w -= len(prompt)
v = value # value under edit
i = 0 # index into v
while True:
dispval = clean(v)
dispi = i
if len(v) < w:
dispval += fillchar*(w-len(v))
elif i >= w:
dispi = w-1
dispval = dispval[i-w:]
scr.addstr(y, x, dispval, attr)
scr.move(y, x+dispi)
ch = scr.getch()
if ch == ctrl('a') or ch == curses.KEY_HOME: i = 0
elif ch == ctrl('b') or ch == curses.KEY_LEFT: i -= 1
elif ch == ctrl('c') or ch == ESC: return None
elif ch == ctrl('d') or ch == curses.KEY_DC: v = delchar(v, i)
elif ch == ctrl('e') or ch == curses.KEY_END: i = len(v)
elif ch == ctrl('f') or ch == curses.KEY_RIGHT: i += 1
elif ch == ctrl('h') or ch == curses.KEY_BACKSPACE: i -= 1 if i > 0 else 0; v = delchar(v, i)
elif ch == ctrl('j') or ch == ENTER: break
elif ch == ctrl('k'): v = v[:i]
elif ch == ctrl('r'): v = value
elif ch == ctrl('t'): v = delchar(splice(v, i-2, v[i-1]), i)
elif ch == ctrl('u'): v = v[i:]; i = 0
elif ch == ctrl('v'): v = splice(v, i, chr(scr.getch())); i+= 1
else:
v = splice(v, i, chr(ch))
i += 1
if i < 0: i = 0
if i > len(v): i = len(v)
return v
def curses_main(scr):
return editText(scr, 0, 10, 20, attr=curses.A_BOLD, prompt='text: ', value='default', fillchar='_')
if __name__ == '__main__':
print(curses.wrapper(curses_main)) 
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment