Provide an explicit termkey_canonicalise() function; canonicalise Space/SP in both directions

This commit is contained in:
Paul LeoNerd Evans 2011-08-27 19:59:02 +01:00
parent 83ca948d78
commit 46eefda073
7 changed files with 106 additions and 6 deletions

51
t/20canon.c Normal file
View File

@ -0,0 +1,51 @@
#include "../termkey.h"
#include "taplib.h"
int main(int argc, char *argv[])
{
TermKey *tk;
TermKeyKey key;
char *endp;
#define CLEAR_KEY do { key.type = -1; key.code.codepoint = -1; key.modifiers = -1; key.utf8[0] = 0; } while(0)
plan_tests(18);
tk = termkey_new(0, TERMKEY_FLAG_NOTERMIOS);
CLEAR_KEY;
endp = termkey_strpkey(tk, " ", &key, 0);
is_int(key.type, TERMKEY_TYPE_UNICODE, "key.type for SP/unicode");
is_int(key.code.codepoint, ' ', "key.code.codepoint for SP/unicode");
is_int(key.modifiers, 0, "key.modifiers for SP/unicode");
is_str(key.utf8, " ", "key.utf8 for SP/unicode");
is_str(endp, "", "consumed entire input for SP/unicode");
CLEAR_KEY;
endp = termkey_strpkey(tk, "Space", &key, 0);
is_int(key.type, TERMKEY_TYPE_UNICODE, "key.type for Space/unicode");
is_int(key.code.codepoint, ' ', "key.code.codepoint for Space/unicode");
is_int(key.modifiers, 0, "key.modifiers for Space/unicode");
is_str(key.utf8, " ", "key.utf8 for Space/unicode");
is_str(endp, "", "consumed entire input for Space/unicode");
termkey_set_flags(tk, termkey_get_flags(tk) | TERMKEY_FLAG_SPACESYMBOL);
CLEAR_KEY;
endp = termkey_strpkey(tk, " ", &key, 0);
is_int(key.type, TERMKEY_TYPE_KEYSYM, "key.type for SP/symbol");
is_int(key.code.sym, TERMKEY_SYM_SPACE, "key.code.codepoint for SP/symbol");
is_int(key.modifiers, 0, "key.modifiers for SP/symbol");
is_str(endp, "", "consumed entire input for SP/symbol");
CLEAR_KEY;
endp = termkey_strpkey(tk, "Space", &key, 0);
is_int(key.type, TERMKEY_TYPE_KEYSYM, "key.type for Space/symbol");
is_int(key.code.sym, TERMKEY_SYM_SPACE, "key.code.codepoint for Space/symbol");
is_int(key.modifiers, 0, "key.modifiers for Space/symbol");
is_str(endp, "", "consumed entire input for Space/symbol");
termkey_destroy(tk);
return exit_status();
}

View File

@ -538,12 +538,6 @@ static void emit_codepoint(TermKey *tk, long codepoint, TermKeyKey *key)
key->type = TERMKEY_TYPE_KEYSYM;
}
}
else if(codepoint == 0x20 && (tk->flags & TERMKEY_FLAG_SPACESYMBOL)) {
// ASCII space
key->type = TERMKEY_TYPE_KEYSYM;
key->code.sym = TERMKEY_SYM_SPACE;
key->modifiers = 0;
}
else if(codepoint == 0x7f && !(tk->flags & TERMKEY_FLAG_NOINTERPRET)) {
// ASCII DEL
key->type = TERMKEY_TYPE_KEYSYM;
@ -569,10 +563,31 @@ static void emit_codepoint(TermKey *tk, long codepoint, TermKeyKey *key)
key->modifiers = 0;
}
termkey_canonicalise(tk, key);
if(key->type == TERMKEY_TYPE_UNICODE)
fill_utf8(key);
}
void termkey_canonicalise(TermKey *tk, TermKeyKey *key)
{
int flags = tk->flags;
if(flags & TERMKEY_FLAG_SPACESYMBOL) {
if(key->type == TERMKEY_TYPE_UNICODE && key->code.number == 0x20) {
key->type = TERMKEY_TYPE_KEYSYM;
key->code.sym = TERMKEY_SYM_SPACE;
}
}
else {
if(key->type == TERMKEY_TYPE_KEYSYM && key->code.sym == TERMKEY_SYM_SPACE) {
key->type = TERMKEY_TYPE_UNICODE;
key->code.number = 0x20;
fill_utf8(key);
}
}
}
static TermKeyResult peekkey(TermKey *tk, TermKeyKey *key, int force, size_t *nbytep)
{
int again = 0;
@ -1178,6 +1193,8 @@ char *termkey_strpkey(TermKey *tk, const char *str, TermKeyKey *key, TermKeyForm
else
return NULL;
termkey_canonicalise(tk, key);
return (char *)str;
}

View File

@ -163,6 +163,8 @@ void termkey_set_flags(TermKey *tk, int newflags);
int termkey_get_waittime(TermKey *tk);
void termkey_set_waittime(TermKey *tk, int msec);
void termkey_canonicalise(TermKey *tk, TermKeyKey *key);
TermKeyResult termkey_getkey(TermKey *tk, TermKeyKey *key);
TermKeyResult termkey_getkey_force(TermKey *tk, TermKeyKey *key);
TermKeyResult termkey_waitkey(TermKey *tk, TermKeyKey *key);

24
termkey_canonicalise.3 Normal file
View File

@ -0,0 +1,24 @@
.TH TERMKEY_CANONICALISE 3
.SH NAME
termkey_canonicalise \- canonicalise a key event
.SH SYNOPSIS
.nf
.B #include <termkey.h>
.sp
.BI "void termkey_canonicalise(TermKey *" tk ", TermKeyKey *" key );
.fi
.sp
Link with \fI-ltermkey\fP.
.SH DESCRIPTION
\fBtermkey_canonicalise\fP(3) modifies the key event structure given by \fIkey\fP according to the flags set on the given \fItk\fP instance. This operation is performed implicitly by \fBtermkey_getkey\fP(3), \fBtermkey_waitkey\fP(3) and \fBtermkey_strpkey\fP(3), and is also provided explicitly by this function.
.PP
The canonicalisation operation is affected by the following flags:
.TP
.B TERMKEY_FLAG_SPACESYMBOL
If this flag is set then a Unicode space character is represented using the \fBTERMKEY_SYM_SPACE\fP symbol. If this flag is not set, it is represented by the U+0020 Unicode codepoint.
.SH "RETURN VALUE"
\fBtermkey_canonicalise\fP() returns no value.
.SH "SEE ALSO"
.BR termkey_new (3),
.BR termkey_waitkey (3),
.BR termkey_strpkey (3)

View File

@ -32,6 +32,8 @@ no bytes are waiting in the buffer.
.PP
Neither of these functions will block or perform any IO operations on the underlying filehandle. To use the instance in an asynchronous program, see \fBtermkey_advisereadable\fP(3). For a blocking call suitable for use in a synchronous program, use \fBtermkey_waitkey\fP(3) instead of \fBtermkey_getkey\fP().
.PP
Before returning, this function canonicalises the \fIkey\fP structure according to the rules given for \fBtermkey_canonicalise\fP(3).
.PP
The \fITermKeyKey\fP structure is defined as follows:
.PP
.in +4n

View File

@ -24,6 +24,8 @@ If the only modifier is \fBTERMKEY_MOD_CTRL\fP on a plain letter, accept it as "
.B TERMKEY_FORMAT_ALTISMETA
Use the name "Meta" or the letter "M" instead of "Alt" or "A".
.PP
Before returning, this function canonicalises the \fIkey\fP structure according to the rules given for \fBtermkey_canonicalise\fP(3).
.PP
The \fBTERMKEY_FORMAT_WRAPBRACKET\fP and \fBTERMKEY_FORMAT_MOUSE_POS\fP options are currently not supported by \fBtermkey_strpkey\fP(). When returning a \fBTERMKEY_TYPE_UNICODE\fP key structure, this function will fill in the \fIutf8\fP member.
.SH "RETURN VALUE"
After a successful parse, \fBtermkey_strpkey\fP() returns a pointer to the first character of the input it did not consume. If the input string contains more characters then this will point at the first character beyond. If the entire input string was consumed, then this will point at a null byte. If \fBtermkey_strpkey\fP() fails to parse, it returns \fBNULL\fP. After a failed parse, the \fIkey\fP structure may contain partial or invalid results. The structure will only be valid if the function returns a non-\fBNULL\fP result.

View File

@ -14,6 +14,8 @@ Link with \fI-ltermkey\fP.
.SH DESCRIPTION
\fBtermkey_waitkey\fP(3) attempts to retrieve a single keypress event from the buffer, and put it in the structure referred to by \fIkey\fP. If successful it will return \fBTERMKEY_RES_KEY\fP to indicate that the structure now contains a new keypress event. If nothing is in the buffer it will block until one is available. If no events are ready and the input stream is now closed, will return \fBTERMKEY_RES_EOF\fP.
.PP
Before returning, this function canonicalises the \fIkey\fP structure according to the rules given for \fBtermkey_canonicalise\fP(3).
.PP
For details of the \fITermKeyKey\fP structure, see \fBtermkey_getkey\fP(3).
.PP
Some keypresses generate multiple bytes from the terminal. Because there may be network or other delays between the terminal and an application using termkey, \fBtermkey_waitkey\fP() will attempt to wait for the remaining bytes to arrive if it detects the start of a multibyte sequence. If no more bytes arrive within a certain time, then the bytes will be reported as they stand, even if this results in interpreting a partially-complete Escape sequence as a literal Escape key followed by some normal letters or other symbols. The amount of time to wait can be set by \fBtermkey_set_waittime\fP(3).