common-lispansi-common-lisp

How does Common Lisp represent control modifiers for character keys?


According to CLTL2, all of functions that deal with key modifiers seem to be removed from the standard. SBCL does not seem to have any of those.

What is the printing representation of characters with modifiers, and how do I specify them in character notation, if there is such a notation in Common Lisp?

In other words, does Common Lisp have a notation to read characters and sequences of characters with modifiers similar to what they do in Emacs: ?\C-q (Ctrl-q) or ?\M-\S-o (Alt-Shift-o).

Is it advisable to implement something as those functions that are deleted from the standard, if I would to implement my own, or is there something in wider use? As a side question: is it known why are those functions removed from the standard?


Solution

  • Presumably you are talking about the character control-bit functions described here.

    The related Issue Writeup in the HyperSpec only says:

    Earlier versions of Common LISP incorporated FONT and BITS as attributes of character objects. These and other supported attributes are considered implementation-defined attributes and if supported by an implementation effect the action of selected functions.

    In any case, the Standard does not forbid implementations from doing something like this:

    Additional, implementation-defined attributes of characters are also permitted so that, for example, two characters with the same code may differ in some other, implementation-defined way.

    There is no standard printed representation for characters with modifiers since Common Lisp implementations aren't required to support these "characters."

    It is probably best not to think of them as characters at all, but as keypresses. Ordinarily pressing a key with modifiers is intended to signal something rather than to generate a character. The usual way to handle this is to put the terminal or console into raw mode so that a program isn't waiting for a user to press Enter before it can get the input. This requires interacting with the environment, which you can do from C by manipulating the termios struct in Linux. Here is a tutorial about getting that working.

    You can interface with the C code to do this from Lisp. SBCL has some Posix extensions that allow you to manipulate termios structs so that you don't need to go through C. Or you can use a library that does this for you, for example you could use trivial-raw-io or terminal-keypress.