in parse_kbinput(), properly handle combined meta and escape sequences,
so that e.g. Meta-+ will work properly when the + is on the numeric keypad and NumLock is off git-svn-id: svn://svn.savannah.gnu.org/nano/trunk/nano@3805 35c25a1d-7b9e-4130-9fde-d3aeb78583b8master
parent
006fc2338c
commit
a44ca78a50
|
@ -131,6 +131,10 @@ CVS code -
|
||||||
- Remove the marking of the file as modified, as do_insertfile()
|
- Remove the marking of the file as modified, as do_insertfile()
|
||||||
now handles that. (DLR)
|
now handles that. (DLR)
|
||||||
- winio.c:
|
- winio.c:
|
||||||
|
parse_kbinput()
|
||||||
|
- Properly handle combined meta and escape sequences, so that
|
||||||
|
e.g. Meta-+ will work properly when the + is on the numeric
|
||||||
|
keypad and NumLock is off. (DLR)
|
||||||
display_string()
|
display_string()
|
||||||
- Properly handle buf[start_index]'s being a null terminator.
|
- Properly handle buf[start_index]'s being a null terminator.
|
||||||
(DLR)
|
(DLR)
|
||||||
|
|
157
src/winio.c
157
src/winio.c
|
@ -505,19 +505,20 @@ int parse_kbinput(WINDOW *win, bool *meta_key, bool *func_key)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
/* One escape followed by a non-escape: escape
|
/* Reset the escape counter. */
|
||||||
* sequence mode. Reset the escape counter. If
|
|
||||||
* there aren't any other keys waiting, we have a
|
|
||||||
* meta key sequence, so set meta_key to TRUE and
|
|
||||||
* save the lowercase version of the non-escape
|
|
||||||
* character as the result. If there are other keys
|
|
||||||
* waiting, we have a true escape sequence, so
|
|
||||||
* interpret it. */
|
|
||||||
escapes = 0;
|
escapes = 0;
|
||||||
if (get_key_buffer_len() == 0) {
|
if (get_key_buffer_len() == 0) {
|
||||||
|
/* One escape followed by a non-escape, and
|
||||||
|
* there aren't any other keys waiting: meta key
|
||||||
|
* sequence mode. Set meta_key to TRUE and save
|
||||||
|
* the lowercase version of the non-escape
|
||||||
|
* character as the result. */
|
||||||
*meta_key = TRUE;
|
*meta_key = TRUE;
|
||||||
retval = tolower(*kbinput);
|
retval = tolower(*kbinput);
|
||||||
} else {
|
} else {
|
||||||
|
/* One escape followed by a non-escape, and
|
||||||
|
* there are other keys waiting: escape sequence
|
||||||
|
* mode. Interpret the escape sequence. */
|
||||||
bool ignore_seq;
|
bool ignore_seq;
|
||||||
|
|
||||||
retval = parse_escape_seq_kbinput(*kbinput,
|
retval = parse_escape_seq_kbinput(*kbinput,
|
||||||
|
@ -533,70 +534,96 @@ int parse_kbinput(WINDOW *win, bool *meta_key, bool *func_key)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
/* Two escapes followed by one or more decimal
|
if (get_key_buffer_len() == 0) {
|
||||||
* digits: byte sequence mode. If the byte
|
if (('0' <= *kbinput && *kbinput <= '2' &&
|
||||||
* sequence's range is limited to 2XX (the first
|
byte_digits == 0) || ('0' <= *kbinput &&
|
||||||
* digit is in the '0' to '2' range and it's the
|
*kbinput <= '9' && byte_digits > 0)) {
|
||||||
* first digit, or it's in the '0' to '9' range and
|
/* Two escapes followed by one or more
|
||||||
* it's not the first digit), increment the byte
|
* decimal digits, and there aren't any
|
||||||
* sequence counter and interpret the digit. If the
|
* other keys waiting: byte sequence mode.
|
||||||
* byte sequence's range is not limited to 2XX, fall
|
* If the byte sequence's range is limited
|
||||||
* through. */
|
* to 2XX (the first digit is in the '0' to
|
||||||
if (('0' <= *kbinput && *kbinput <= '2' &&
|
* '2' range and it's the first digit, or
|
||||||
byte_digits == 0) || ('0' <= *kbinput &&
|
* it's in the '0' to '9' range and it's not
|
||||||
*kbinput <= '9' && byte_digits > 0)) {
|
* the first digit), increment the byte
|
||||||
int byte;
|
* sequence counter and interpret the digit.
|
||||||
|
* If the byte sequence's range is not
|
||||||
|
* limited to 2XX, fall through. */
|
||||||
|
int byte;
|
||||||
|
|
||||||
byte_digits++;
|
byte_digits++;
|
||||||
byte = get_byte_kbinput(*kbinput);
|
byte = get_byte_kbinput(*kbinput);
|
||||||
|
|
||||||
if (byte != ERR) {
|
if (byte != ERR) {
|
||||||
char *byte_mb;
|
char *byte_mb;
|
||||||
int byte_mb_len, *seq, i;
|
int byte_mb_len, *seq, i;
|
||||||
|
|
||||||
/* If we've read in a complete byte
|
/* If we've read in a complete byte
|
||||||
* sequence, reset the byte sequence counter
|
* sequence, reset the escape counter
|
||||||
* and the escape counter, and put back the
|
* and the byte sequence counter, and
|
||||||
* corresponding byte value. */
|
* put back the corresponding byte
|
||||||
byte_digits = 0;
|
* value. */
|
||||||
|
escapes = 0;
|
||||||
|
byte_digits = 0;
|
||||||
|
|
||||||
|
/* Put back the multibyte equivalent of
|
||||||
|
* the byte value. */
|
||||||
|
byte_mb = make_mbchar((long)byte,
|
||||||
|
&byte_mb_len);
|
||||||
|
|
||||||
|
seq = (int *)nmalloc(byte_mb_len *
|
||||||
|
sizeof(int));
|
||||||
|
|
||||||
|
for (i = 0; i < byte_mb_len; i++)
|
||||||
|
seq[i] = (unsigned char)byte_mb[i];
|
||||||
|
|
||||||
|
unget_input(seq, byte_mb_len);
|
||||||
|
|
||||||
|
free(byte_mb);
|
||||||
|
free(seq);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* Reset the escape counter. */
|
||||||
escapes = 0;
|
escapes = 0;
|
||||||
|
if (byte_digits == 0)
|
||||||
/* Put back the multibyte equivalent of the
|
/* Two escapes followed by a non-decimal
|
||||||
* byte value. */
|
* digit or a decimal digit that would
|
||||||
byte_mb = make_mbchar((long)byte,
|
* create a byte sequence greater than
|
||||||
&byte_mb_len);
|
* 2XX, we're not in the middle of a
|
||||||
|
* byte sequence, and there aren't any
|
||||||
seq = (int *)nmalloc(byte_mb_len *
|
* other keys waiting: control character
|
||||||
sizeof(int));
|
* sequence mode. Interpret the control
|
||||||
|
* sequence and save the corresponding
|
||||||
for (i = 0; i < byte_mb_len; i++)
|
* control character as the result. */
|
||||||
seq[i] = (unsigned char)byte_mb[i];
|
retval = get_control_kbinput(*kbinput);
|
||||||
|
else {
|
||||||
unget_input(seq, byte_mb_len);
|
/* If we're in the middle of a byte
|
||||||
|
* sequence, reset the byte sequence
|
||||||
free(byte_mb);
|
* counter and save the character we got
|
||||||
free(seq);
|
* as the result. */
|
||||||
|
byte_digits = 0;
|
||||||
|
retval = *kbinput;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* Reset the escape counter. */
|
/* Two escapes followed by a non-escape, and
|
||||||
|
* there are other keys waiting: combined meta
|
||||||
|
* and escape sequence mode. Reset the escape
|
||||||
|
* counter, set meta_key to TRUE, and interpret
|
||||||
|
* the escape sequence. */
|
||||||
|
bool ignore_seq;
|
||||||
|
|
||||||
escapes = 0;
|
escapes = 0;
|
||||||
if (byte_digits == 0)
|
*meta_key = TRUE;
|
||||||
/* Two escapes followed by a non-decimal
|
retval = parse_escape_seq_kbinput(*kbinput,
|
||||||
* digit or a decimal digit that would
|
&ignore_seq);
|
||||||
* create a byte sequence greater than 2XX,
|
|
||||||
* and we're not in the middle of a byte
|
/* If the escape sequence is unrecognized and
|
||||||
* sequence: control character sequence
|
* not ignored, throw it out. */
|
||||||
* mode. Interpret the control sequence and
|
if (retval == ERR && !ignore_seq) {
|
||||||
* save the corresponding control character
|
if (win == edit)
|
||||||
* as the result. */
|
statusbar(_("Unknown Command"));
|
||||||
retval = get_control_kbinput(*kbinput);
|
beep();
|
||||||
else {
|
|
||||||
/* If we're in the middle of a byte
|
|
||||||
* sequence, reset the byte sequence counter
|
|
||||||
* and save the character we got as the
|
|
||||||
* result. */
|
|
||||||
byte_digits = 0;
|
|
||||||
retval = *kbinput;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
Loading…
Reference in New Issue