Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python: curses key codes to readable (vim-like?) syntax

Tags:

python

vim

curses

I want to provide keybindings in a curses-based python program. The ideal solution would be to have an abstraction layer around getch() that yields readable strings, maybe in a vim-like format.

In pythonese:

def get_keycomb(wind):
    string = read_keycomb(wind) # read with wind.getch() as needed
    return string # something like '<C-S-a>'

Then I could easily implement mappings by using the strings as keys in a dict function.

Is there a python library that provides this sort of functionality, or an easier way to achieve it than manually providing names for everything?

like image 493
slezica Avatar asked May 26 '12 19:05

slezica


People also ask

What is curses in Python?

What is curses? ¶ The curses library supplies a terminal-independent screen-painting and keyboard-handling facility for text-based terminals; such terminals include VT100s, the Linux console, and the simulated terminal provided by various programs.

What is curses module?

The curses module provides an interface to the curses library, the de-facto standard for portable advanced terminal handling. While curses is most widely used in the Unix environment, versions are available for Windows, DOS, and possibly other systems as well.

Does Python curses work on Windows?

windows-curses 2.3. 1 Adds support for the standard Python curses module on Windows. Based on these wheels. Uses the PDCurses curses implementation. The wheels are built from this GitHub repository.


2 Answers

The codes for all the non-specials keys are the ascii codes of the characters, so that part of the table is easy to build.

char_codes = {chr(i):i for i in range(256)}

The codes for all the specials letters are available in the curses modules as KEY_* constants, so we can get them all this way :

specials_codes = {name[4:]: value for name, value in vars(curses).items()
    if name.startswith('KEY_')}

So you can build you mapping with this code :

import curses

mapping = {chr(i):i for i in range(256)}
mapping.update((name[4:], value) for name, value in vars(curses).items()
    if name.startswith('KEY_'))

print(mapping)
like image 103
madjar Avatar answered Sep 24 '22 08:09

madjar


Rather than using curses for input, if you use libtermkey then it provides easy functions for converting key structures to and from human-readable strings, in just this form. Specifically the functions termkey_strfkey and termkey_strpkey.

http://www.leonerd.org.uk/code/libtermkey/doc/termkey_strfkey.3.html

http://www.leonerd.org.uk/code/libtermkey/doc/termkey_strpkey.3.html

This is a C library, but it does have a Python binding; see

https://github.com/temoto/ctypes_libtermkey

like image 43
LeoNerd Avatar answered Sep 23 '22 08:09

LeoNerd