From f0a53f02a10b1383be8cd7929edb24214562a3ca Mon Sep 17 00:00:00 2001 From: David Lawrence Ramsey Date: Mon, 3 Jan 2005 19:56:56 +0000 Subject: [PATCH] readd get_byte_kbinput(), modify get_word_kbinput() to handle hexadecimal instead of decimal values, make normal input use get_byte_kbinput(), make verbatim input use get_word_kbinput(), and update faq.html to mention these changes git-svn-id: svn://svn.savannah.gnu.org/nano/trunk/nano@2221 35c25a1d-7b9e-4130-9fde-d3aeb78583b8 --- ChangeLog | 32 +++---- doc/faq.html | 4 +- src/nano.c | 6 +- src/proto.h | 5 ++ src/winio.c | 230 ++++++++++++++++++++++++++++++++++----------------- 5 files changed, 179 insertions(+), 98 deletions(-) diff --git a/ChangeLog b/ChangeLog index 39a4f04f..6fc29c9d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -34,21 +34,20 @@ CVS code - properly again. (DLR, found by Arthur Ivanov) - Massively overhaul the input and output routines to support buffered input and output, the first steps toward - wide/multibyte character input and output, and - double-Escape/verbatim input of double-byte Unicode characters - instead of single-byte ASCII characters. New functions - is_byte_char(), get_buffer(), get_buffer_len(), - buffer_to_keys(), unget_input(), get_input(), parse_kbinput(), - and parse_verbatim_kbinput(); new macro charcpy(); changes to - do_char() (renamed to do_output()), get_edit_input() (renamed - to do_input() and moved to nano.c), get_edit_mouse() (renamed - do_mouse() and moved to nano.c), do_verbatim_input(), - do_tab(), main(), and get_ascii_kbinput() (renamed to - get_word_kbinput()). The wide version of ncurses is required - in order for wide/multibyte input and output to work properly. - (DLR; buffered input/output based on ideas from mutt 1.4.2.1; - double-Escape input of Unicode characters suggested by Michael - Piefel) + wide/multibyte character input and output, and verbatim input + of double-byte Unicode characters instead of single-byte ASCII + characters. New functions is_byte_char(), get_buffer(), + get_buffer_len(), buffer_to_keys(), unget_input(), + get_input(), parse_kbinput(), and parse_verbatim_kbinput(); + new macro charcpy(); changes to do_char() (renamed to + do_output()), get_edit_input() (renamed to do_input() and + moved to nano.c), get_edit_mouse() (renamed do_mouse() and + moved to nano.c), do_verbatim_input(), do_tab(), main(), and + get_ascii_kbinput() (renamed to get_word_kbinput()). The wide + version of ncurses is required in order for wide/multibyte + input and output to work properly. (DLR; buffered input/output + based on ideas from mutt 1.4.2.1; input of Unicode characters + in hexadecimal suggested by Michael Piefel) - More steps toward wide character/multibyte character support. Movement and cursor display in the edit window should now work properly with files containing multibyte characters, and text @@ -190,7 +189,8 @@ CVS code - - Typo fixes. (DLR) - doc/faq.html: - Remove now-inaccurate note about verbatim input's not working - at prompts. (DLR) + at prompts, and update its description to mention that it + handles hexadecimal values now. (DLR) - doc/nanorc.sample: - Add return to the "c-file" regexes. (DLR) diff --git a/doc/faq.html b/doc/faq.html index fa7a55db..906f6bd8 100644 --- a/doc/faq.html +++ b/doc/faq.html @@ -166,7 +166,7 @@

You can move between the buffers you have open with the Meta-< and Meta-> keys, or more easily with Meta-, and Meta-. (clear as mud, right? =-). When you have more than one file buffer open, the ^X shortcut will say "Close", instead of the normal "Exit" when only one buffer is open.

3.8. Tell me more about this verbatim input stuff!

To use verbatim input, you must be using nano 1.3.1 or newer. When you want to insert a literal character into the file you're editing, such as a control character that nano usually treats as a command, first press Meta-V. (If you're not at a prompt, you'll get the message "Verbatim input".) Then press the key(s) that generate the character you want.

-

Alternatively, you can press Meta-V and then type a three-digit ASCII code from 000 to 255, and the character with that ASCII code will be inserted instead.

+

Alternatively, you can press Meta-V and then type a four-digit hexadecimal code from 0000 to ffff (case-insensitive), and the character with the corresponding value will be inserted instead.

3.9. How do I make a .nanorc file that nano will read when I start it?

It's not hard at all! But, your version of nano must have been compiled with --enable-nanorc, and again must be version 1.1.12 or newer (use nano -V to check your version and compiled features). Then simply copy the nanorc.sample that came with the nano source or your nano package (most likely in /usr/doc/nano) to .nanorc in your home directory. If you didn't get one, the syntax is simple. Flags are turned on and off by using the word set and the getopt_long flag for the feature, for example "set nowrap" or "set suspend".


@@ -244,7 +244,7 @@

8. ChangeLog

-2005/01/02 - Remove now-inaccurate note about verbatim input's not working at prompts. (DLR) +2005/01/03 - Remove now-inaccurate note about verbatim input's not working at prompts, and update its description to mention that it handles hexadecimal values now. (DLR) 2004/11/21 - List sh as an example of a Bourne shell. (DLR) 2004/11/05 - Fixed inaccuracy: Pico compatibility mode was made the default in nano 1.1.99pre1, not 1.2.2. Also added question about how to type F13-F16 on terminals lacking keys past F12 (suggested by Chris), question about how to select text for the clipboard in X terminals with nano's mouse support turned on (answer found by Joseph Birthisel), and misc. fixes and link updates. (DLR)
2004/04/07 - Removed NumLock glitch question, as it's no longer needed. (DLR)
diff --git a/src/nano.c b/src/nano.c index 866e7ecf..021d3097 100644 --- a/src/nano.c +++ b/src/nano.c @@ -372,9 +372,9 @@ void help_init(void) "(M) symbol and can be entered using either the Esc, Alt or " "Meta key depending on your keyboard setup. Also, pressing Esc " "twice and then typing a three-digit number from 000 to 255 " - "will enter the character with the corresponding ASCII code. " - "The following keystrokes are available in the main editor " - "window. Alternative keys are shown in parentheses:\n\n"); + "will enter the character with the corresponding value. The " + "following keystrokes are available in the main editor window. " + "Alternative keys are shown in parentheses:\n\n"); htx = _(htx); diff --git a/src/proto.h b/src/proto.h index bd6fd72a..6801d0a6 100644 --- a/src/proto.h +++ b/src/proto.h @@ -555,6 +555,11 @@ int parse_kbinput(WINDOW *win, bool *meta_key, bool *func_key int get_escape_seq_kbinput(const int *sequence, size_t seq_len, bool *ignore_seq); int get_escape_seq_abcd(int kbinput); +int get_byte_kbinput(int kbinput +#ifndef NANO_SMALL + , bool reset +#endif + ); int get_word_kbinput(int kbinput #ifndef NANO_SMALL , bool reset diff --git a/src/winio.c b/src/winio.c index 79e2f16e..a4df2577 100644 --- a/src/winio.c +++ b/src/winio.c @@ -121,6 +121,7 @@ static bool resetstatuspos = FALSE; void reset_kbinput(void) { parse_kbinput(NULL, NULL, NULL, TRUE); + get_byte_kbinput(0, TRUE); get_word_kbinput(0, TRUE); } #endif @@ -439,14 +440,14 @@ int parse_kbinput(WINDOW *win, bool *meta_key, bool *func_key ) { - static int escapes = 0, word_digits = 0; + static int escapes = 0, byte_digits = 0; buffer *kbinput; int retval = ERR; #ifndef NANO_SMALL if (reset) { escapes = 0; - word_digits = 0; + byte_digits = 0; return ERR; } #endif @@ -646,48 +647,47 @@ int parse_kbinput(WINDOW *win, bool *meta_key, bool *func_key break; case 2: /* Two escapes followed by one or more decimal - * digits: word sequence mode. If the word - * sequence's range is limited to 6XXXX (the - * first digit is in the '0' to '6' range and - * it's the first digit, or it's in the '0' to - * '9' range and it's not the first digit), - * increment the word sequence counter and - * interpret the digit. If the word sequence's - * range is not limited to 6XXXX, fall - * through. */ + * digits: byte sequence mode. If the word + * sequence's range is limited to 2XX (the first + * digit is in the '0' to '2' range and it's the + * first digit, or it's in the '0' to '9' range + * and it's not the first digit), increment the + * byte sequence counter and interpret the + * digit. If the byte sequence's range is not + * limited to 2XX, fall through. */ if (('0' <= kbinput->key && kbinput->key <= '6' - && word_digits == 0) || + && byte_digits == 0) || ('0' <= kbinput->key && kbinput->key <= '9' - && word_digits > 0)) { - int word_kbinput; + && byte_digits > 0)) { + int byte_kbinput; - word_digits++; - word_kbinput = get_word_kbinput(kbinput->key + byte_digits++; + byte_kbinput = get_byte_kbinput(kbinput->key #ifndef NANO_SMALL , FALSE #endif ); - if (word_kbinput != ERR) { - /* If we've read in a complete word - * sequence, reset the word sequence + if (byte_kbinput != ERR) { + /* If we've read in a complete byte + * sequence, reset the byte sequence * counter and the escape counter, - * and put back the corresponding word + * and put back the corresponding byte * value. */ - word_digits = 0; + byte_digits = 0; escapes = 0; - unget_kbinput(word_kbinput, FALSE, + unget_kbinput(byte_kbinput, FALSE, FALSE); } } else { /* Reset the escape counter. */ escapes = 0; - if (word_digits == 0) + if (byte_digits == 0) /* Two escapes followed by a non-decimal * digit or a decimal digit that would - * create a word sequence greater than - * 6XXXX, and we're not in the middle of - * a word sequence: control character + * create a byte sequence greater than + * 2XX, and we're not in the middle of a + * byte sequence: control character * sequence mode. Interpret the control * sequence and save the corresponding * control character as the result. */ @@ -697,7 +697,7 @@ int parse_kbinput(WINDOW *win, bool *meta_key, bool *func_key * sequence, reset the word sequence * counter and save the character we got * as the result. */ - word_digits = 0; + byte_digits = 0; retval = kbinput->key; } } @@ -715,7 +715,7 @@ int parse_kbinput(WINDOW *win, bool *meta_key, bool *func_key retval = kbinput->key; #ifdef DEBUG - fprintf(stderr, "parse_kbinput(): kbinput->key = %d, meta_key = %d, func_key = %d, escapes = %d, word_digits = %d, retval = %d\n", kbinput->key, (int)*meta_key, (int)*func_key, escapes, word_digits, retval); + fprintf(stderr, "parse_kbinput(): kbinput->key = %d, meta_key = %d, func_key = %d, escapes = %d, byte_digits = %d, retval = %d\n", kbinput->key, (int)*meta_key, (int)*func_key, escapes, byte_digits, retval); #endif /* Return the result. */ @@ -1250,8 +1250,93 @@ int get_escape_seq_abcd(int kbinput) } } -/* Translate a word sequence: turn a five-digit decimal number from - * 00000 to 65535 into its corresponding word value. */ +/* Translate a byte sequence: turn a three-digit decimal number from + * 000 to 255 into its corresponding byte value. */ +int get_byte_kbinput(int kbinput +#ifndef NANO_SMALL + , bool reset +#endif + ) +{ + static int byte_digits = 0, byte_kbinput = 0; + int retval = ERR; + +#ifndef NANO_SMALL + if (reset) { + byte_digits = 0; + byte_kbinput = 0; + return ERR; + } +#endif + + /* Increment the byte digit counter. */ + byte_digits++; + + switch (byte_digits) { + case 1: + /* One digit: reset the byte sequence holder and add the + * digit we got to the 100's position of the byte sequence + * holder. */ + byte_kbinput = 0; + if ('0' <= kbinput && kbinput <= '2') + byte_kbinput += (kbinput - '0') * 100; + else + /* If the character we got isn't a decimal digit, or if + * it is and it would put the byte sequence out of byte + * range, save it as the result. */ + retval = kbinput; + break; + case 2: + /* Two digits: add the digit we got to the 10's position of + * the byte sequence holder. */ + if (('0' <= kbinput && kbinput <= '5') || + (byte_kbinput < 200 && '6' <= kbinput && + kbinput <= '9')) + byte_kbinput += (kbinput - '0') * 10; + else + /* If the character we got isn't a decimal digit, or if + * it is and it would put the byte sequence out of byte + * range, save it as the result. */ + retval = kbinput; + break; + case 3: + /* Three digits: add the digit we got to the 1's position of + * the byte sequence holder, and save the corresponding word + * value as the result. */ + if (('0' <= kbinput && kbinput <= '5') || + (byte_kbinput < 250 && '6' <= kbinput && + kbinput <= '9')) { + byte_kbinput += (kbinput - '0'); + retval = byte_kbinput; + } else + /* If the character we got isn't a decimal digit, or if + * it is and it would put the word sequence out of word + * range, save it as the result. */ + retval = kbinput; + break; + default: + /* More than three digits: save the character we got as the + * result. */ + retval = kbinput; + break; + } + + /* If we have a result, reset the byte digit counter and the byte + * sequence holder. */ + if (retval != ERR) { + byte_digits = 0; + byte_kbinput = 0; + } + +#ifdef DEBUG + fprintf(stderr, "get_byte_kbinput(): kbinput = %d, byte_digits = %d, byte_kbinput = %d, retval = %d\n", kbinput, byte_digits, byte_kbinput, retval); +#endif + + return retval; +} + +/* Translate a word sequence: turn a four-digit hexadecimal number from + * 0000 to ffff (case-insensitive) into its corresponding word value. */ int get_word_kbinput(int kbinput #ifndef NANO_SMALL , bool reset @@ -1275,73 +1360,64 @@ int get_word_kbinput(int kbinput switch (word_digits) { case 1: /* One digit: reset the word sequence holder and add the - * digit we got to the 10000's position of the word sequence + * digit we got to the 4096's position of the word sequence * holder. */ word_kbinput = 0; - if ('0' <= kbinput && kbinput <= '6') - word_kbinput += (kbinput - '0') * 10000; + if ('0' <= kbinput && kbinput <= '9') + word_kbinput += (kbinput - '0') * 4096; + else if ('a' <= tolower(kbinput) && tolower(kbinput) <= 'f') + word_kbinput += (tolower(kbinput) + 10 - 'a') * 4096; else - /* If the character we got isn't a decimal digit, or if - * it is and it would put the word sequence out of word - * range, save it as the result. */ + /* If the character we got isn't a hexadecimal digit, or + * if it is and it would put the word sequence out of + * word range, save it as the result. */ retval = kbinput; break; case 2: - /* Two digits: add the digit we got to the 1000's position - * of the word sequence holder. */ - if (('0' <= kbinput && kbinput <= '5') || - (word_kbinput < 60000 && '6' <= kbinput && - kbinput <= '9')) - word_kbinput += (kbinput - '0') * 1000; + /* Two digits: add the digit we got to the 256's position of + * the word sequence holder. */ + if ('0' <= kbinput && kbinput <= '9') + word_kbinput += (kbinput - '0') * 256; + else if ('a' <= tolower(kbinput) && tolower(kbinput) <= 'f') + word_kbinput += (tolower(kbinput) + 10 - 'a') * 256; else - /* If the character we got isn't a decimal digit, or if - * it is and it would put the word sequence out of word - * range, save it as the result. */ + /* If the character we got isn't a hexadecimal digit, or + * if it is and it would put the word sequence out of + * word range, save it as the result. */ retval = kbinput; break; case 3: - /* Three digits: add the digit we got to the 100's position + /* Three digits: add the digit we got to the 16's position * of the word sequence holder. */ - if (('0' <= kbinput && kbinput <= '5') || - (word_kbinput < 65000 && '6' <= kbinput && - kbinput <= '9')) - word_kbinput += (kbinput - '0') * 100; + if ('0' <= kbinput && kbinput <= '9') + word_kbinput += (kbinput - '0') * 16; + else if ('a' <= tolower(kbinput) && tolower(kbinput) <= 'f') + word_kbinput += (tolower(kbinput) + 10 - 'a') * 16; else - /* If the character we got isn't a decimal digit, or if - * it is and it would put the word sequence out of word - * range, save it as the result. */ + /* If the character we got isn't a hexadecimal digit, or + * if it is and it would put the word sequence out of + * word range, save it as the result. */ retval = kbinput; break; case 4: - /* Four digits: add the digit we got to the 10's position of - * the word sequence holder. */ - if (('0' <= kbinput && kbinput <= '3') || - (word_kbinput < 65500 && '4' <= kbinput && - kbinput <= '9')) - word_kbinput += (kbinput - '0') * 10; - else - /* If the character we got isn't a decimal digit, or if - * it is and it would put the word sequence out of word - * range, save it as the result. */ - retval = kbinput; - break; - case 5: - /* Five digits: add the digit we got to the 1's position of + /* Four digits: add the digit we got to the 1's position of * the word sequence holder, and save the corresponding word * value as the result. */ - if (('0' <= kbinput && kbinput <= '5') || - (word_kbinput < 65530 && '6' <= kbinput && - kbinput <= '9')) { + if ('0' <= kbinput && kbinput <= '9') { word_kbinput += (kbinput - '0'); retval = word_kbinput; + } else if ('a' <= tolower(kbinput) && + tolower(kbinput) <= 'f') { + word_kbinput += (tolower(kbinput) + 10 - 'a'); + retval = word_kbinput; } else - /* If the character we got isn't a decimal digit, or if - * it is and it would put the word sequence out of word - * range, save it as the result. */ + /* If the character we got isn't a hexadecimal digit, or + * if it is and it would put the word sequence out of + * word range, save it as the result. */ retval = kbinput; break; default: - /* More than three digits: save the character we got as the + /* More than four digits: save the character we got as the * result. */ retval = kbinput; break; @@ -1444,15 +1520,15 @@ int *parse_verbatim_kbinput(WINDOW *win, size_t *kbinput_len) /* Read in the first keystroke. */ while ((kbinput = get_input(win, 1)) == NULL); - /* Check whether the first keystroke is a decimal digit. */ + /* Check whether the first keystroke is a hexadecimal digit. */ word = get_word_kbinput(kbinput->key #ifndef NANO_SMALL , FALSE #endif ); - /* If the first keystroke isn't a decimal digit, put back the first - * keystroke. */ + /* If the first keystroke isn't a hexadecimal digit, put back the + * first keystroke. */ if (word != ERR) unget_input(kbinput, 1); /* Otherwise, read in keystrokes until we have a complete word