vi: handle chars 0x80, 0x81... correctly
This commit is contained in:
parent
078323010b
commit
4c9e9c4314
125
editors/vi.c
125
editors/vi.c
@ -57,29 +57,33 @@ enum {
|
|||||||
MAX_SCR_ROWS = CONFIG_FEATURE_VI_MAX_LEN,
|
MAX_SCR_ROWS = CONFIG_FEATURE_VI_MAX_LEN,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Misc. non-Ascii keys that report an escape sequence
|
// "Keycodes" that report an escape sequence.
|
||||||
#define VI_K_UP (char)128 // cursor key Up
|
// We use something which fits into signed char,
|
||||||
#define VI_K_DOWN (char)129 // cursor key Down
|
// yet doesn't represent any valid Unicode characher.
|
||||||
#define VI_K_RIGHT (char)130 // Cursor Key Right
|
enum {
|
||||||
#define VI_K_LEFT (char)131 // cursor key Left
|
VI_K_UP = -1, // cursor key Up
|
||||||
#define VI_K_HOME (char)132 // Cursor Key Home
|
VI_K_DOWN = -2, // cursor key Down
|
||||||
#define VI_K_END (char)133 // Cursor Key End
|
VI_K_RIGHT = -3, // Cursor Key Right
|
||||||
#define VI_K_INSERT (char)134 // Cursor Key Insert
|
VI_K_LEFT = -4, // cursor key Left
|
||||||
#define VI_K_DELETE (char)135 // Cursor Key Insert
|
VI_K_HOME = -5, // Cursor Key Home
|
||||||
#define VI_K_PAGEUP (char)136 // Cursor Key Page Up
|
VI_K_END = -6, // Cursor Key End
|
||||||
#define VI_K_PAGEDOWN (char)137 // Cursor Key Page Down
|
VI_K_INSERT = -7, // Cursor Key Insert
|
||||||
#define VI_K_FUN1 (char)138 // Function Key F1
|
VI_K_DELETE = -8, // Cursor Key Insert
|
||||||
#define VI_K_FUN2 (char)139 // Function Key F2
|
VI_K_PAGEUP = -9, // Cursor Key Page Up
|
||||||
#define VI_K_FUN3 (char)140 // Function Key F3
|
VI_K_PAGEDOWN = -10, // Cursor Key Page Down
|
||||||
#define VI_K_FUN4 (char)141 // Function Key F4
|
VI_K_FUN1 = -11, // Function Key F1
|
||||||
#define VI_K_FUN5 (char)142 // Function Key F5
|
VI_K_FUN2 = -12, // Function Key F2
|
||||||
#define VI_K_FUN6 (char)143 // Function Key F6
|
VI_K_FUN3 = -13, // Function Key F3
|
||||||
#define VI_K_FUN7 (char)144 // Function Key F7
|
VI_K_FUN4 = -14, // Function Key F4
|
||||||
#define VI_K_FUN8 (char)145 // Function Key F8
|
VI_K_FUN5 = -15, // Function Key F5
|
||||||
#define VI_K_FUN9 (char)146 // Function Key F9
|
VI_K_FUN6 = -16, // Function Key F6
|
||||||
#define VI_K_FUN10 (char)147 // Function Key F10
|
VI_K_FUN7 = -17, // Function Key F7
|
||||||
#define VI_K_FUN11 (char)148 // Function Key F11
|
VI_K_FUN8 = -18, // Function Key F8
|
||||||
#define VI_K_FUN12 (char)149 // Function Key F12
|
VI_K_FUN9 = -19, // Function Key F9
|
||||||
|
VI_K_FUN10 = -20, // Function Key F10
|
||||||
|
VI_K_FUN11 = -21, // Function Key F11
|
||||||
|
VI_K_FUN12 = -22, // Function Key F12
|
||||||
|
};
|
||||||
|
|
||||||
/* vt102 typical ESC sequence */
|
/* vt102 typical ESC sequence */
|
||||||
/* terminal standout start/normal ESC sequence */
|
/* terminal standout start/normal ESC sequence */
|
||||||
@ -171,9 +175,9 @@ struct globals {
|
|||||||
char *screen; // pointer to the virtual screen buffer
|
char *screen; // pointer to the virtual screen buffer
|
||||||
int screensize; // and its size
|
int screensize; // and its size
|
||||||
int tabstop;
|
int tabstop;
|
||||||
|
int last_forward_char; // last char searched for with 'f' (int because of Unicode)
|
||||||
char erase_char; // the users erase character
|
char erase_char; // the users erase character
|
||||||
char last_input_char; // last char read from user
|
char last_input_char; // last char read from user
|
||||||
char last_forward_char; // last char searched for with 'f'
|
|
||||||
|
|
||||||
#if ENABLE_FEATURE_VI_DOT_CMD
|
#if ENABLE_FEATURE_VI_DOT_CMD
|
||||||
smallint adding2q; // are we currently adding user input to q
|
smallint adding2q; // are we currently adding user input to q
|
||||||
@ -298,7 +302,7 @@ struct globals {
|
|||||||
|
|
||||||
static int init_text_buffer(char *); // init from file or create new
|
static int init_text_buffer(char *); // init from file or create new
|
||||||
static void edit_file(char *); // edit one file
|
static void edit_file(char *); // edit one file
|
||||||
static void do_cmd(char); // execute a command
|
static void do_cmd(int); // execute a command
|
||||||
static int next_tabstop(int);
|
static int next_tabstop(int);
|
||||||
static void sync_cursor(char *, int *, int *); // synchronize the screen cursor to dot
|
static void sync_cursor(char *, int *, int *); // synchronize the screen cursor to dot
|
||||||
static char *begin_line(char *); // return pointer to cur line B-o-l
|
static char *begin_line(char *); // return pointer to cur line B-o-l
|
||||||
@ -334,8 +338,8 @@ static void rawmode(void); // set "raw" mode on tty
|
|||||||
static void cookmode(void); // return to "cooked" mode on tty
|
static void cookmode(void); // return to "cooked" mode on tty
|
||||||
// sleep for 'h' 1/100 seconds, return 1/0 if stdin is (ready for read)/(not ready)
|
// sleep for 'h' 1/100 seconds, return 1/0 if stdin is (ready for read)/(not ready)
|
||||||
static int mysleep(int);
|
static int mysleep(int);
|
||||||
static char readit(void); // read (maybe cursor) key from stdin
|
static int readit(void); // read (maybe cursor) key from stdin
|
||||||
static char get_one_char(void); // read 1 char from stdin
|
static int get_one_char(void); // read 1 char from stdin
|
||||||
static int file_size(const char *); // what is the byte size of "fn"
|
static int file_size(const char *); // what is the byte size of "fn"
|
||||||
#if ENABLE_FEATURE_VI_READONLY
|
#if ENABLE_FEATURE_VI_READONLY
|
||||||
static int file_insert(const char *, char *, int);
|
static int file_insert(const char *, char *, int);
|
||||||
@ -524,7 +528,7 @@ static void edit_file(char *fn)
|
|||||||
#if ENABLE_FEATURE_VI_YANKMARK
|
#if ENABLE_FEATURE_VI_YANKMARK
|
||||||
#define cur_line edit_file__cur_line
|
#define cur_line edit_file__cur_line
|
||||||
#endif
|
#endif
|
||||||
char c;
|
int c;
|
||||||
int size;
|
int size;
|
||||||
#if ENABLE_FEATURE_VI_USE_SIGNALS
|
#if ENABLE_FEATURE_VI_USE_SIGNALS
|
||||||
int sig;
|
int sig;
|
||||||
@ -622,8 +626,10 @@ static void edit_file(char *fn)
|
|||||||
// These are commands that change text[].
|
// These are commands that change text[].
|
||||||
// Remember the input for the "." command
|
// Remember the input for the "." command
|
||||||
if (!adding2q && ioq_start == NULL
|
if (!adding2q && ioq_start == NULL
|
||||||
&& cmd_mode == 0 /* command mode */
|
&& cmd_mode == 0 // command mode
|
||||||
&& c != '\0' && strchr(modifying_cmds, c)
|
&& c > '\0' // exclude NUL and non-ASCII chars
|
||||||
|
&& c < 0x7f // (Unicode and such)
|
||||||
|
&& strchr(modifying_cmds, c)
|
||||||
) {
|
) {
|
||||||
start_new_cmd_q(c);
|
start_new_cmd_q(c);
|
||||||
}
|
}
|
||||||
@ -1198,7 +1204,7 @@ static void colon(char *buf)
|
|||||||
|
|
||||||
static void Hit_Return(void)
|
static void Hit_Return(void)
|
||||||
{
|
{
|
||||||
char c;
|
int c;
|
||||||
|
|
||||||
standout_start();
|
standout_start();
|
||||||
write1("[Hit return to continue]");
|
write1("[Hit return to continue]");
|
||||||
@ -2191,15 +2197,15 @@ static int mysleep(int hund) // sleep for 'h' 1/100 seconds
|
|||||||
}
|
}
|
||||||
|
|
||||||
//----- IO Routines --------------------------------------------
|
//----- IO Routines --------------------------------------------
|
||||||
static char readit(void) // read (maybe cursor) key from stdin
|
static int readit(void) // read (maybe cursor) key from stdin
|
||||||
{
|
{
|
||||||
char c;
|
int c;
|
||||||
int n;
|
int n;
|
||||||
|
|
||||||
// Known escape sequences for cursor and function keys.
|
// Known escape sequences for cursor and function keys.
|
||||||
static const struct esc_cmds {
|
static const struct esc_cmds {
|
||||||
const char seq[4];
|
const char seq[4];
|
||||||
char val; //TODO: int? Need to make it at least 8-bit clean!
|
signed char val;
|
||||||
} esccmds[] = {
|
} esccmds[] = {
|
||||||
{"OA" , VI_K_UP }, // Cursor Key Up
|
{"OA" , VI_K_UP }, // Cursor Key Up
|
||||||
{"OB" , VI_K_DOWN }, // Cursor Key Down
|
{"OB" , VI_K_DOWN }, // Cursor Key Down
|
||||||
@ -2256,7 +2262,7 @@ static char readit(void) // read (maybe cursor) key from stdin
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Grab character to return from buffer
|
// Grab character to return from buffer
|
||||||
c = readbuffer[0];
|
c = (unsigned char)readbuffer[0];
|
||||||
// Returning NUL from this routine would be bad.
|
// Returning NUL from this routine would be bad.
|
||||||
if (c == '\0')
|
if (c == '\0')
|
||||||
c = ' ';
|
c = ' ';
|
||||||
@ -2302,7 +2308,7 @@ static char readit(void) // read (maybe cursor) key from stdin
|
|||||||
break; // try next seq
|
break; // try next seq
|
||||||
i++;
|
i++;
|
||||||
if (i == 4 || !eindex->seq[i]) { // entire seq matched
|
if (i == 4 || !eindex->seq[i]) { // entire seq matched
|
||||||
c = eindex->val;
|
c = eindex->val; // sign extended!
|
||||||
n = 0;
|
n = 0;
|
||||||
// n -= i; memmove(...);
|
// n -= i; memmove(...);
|
||||||
// would be more correct,
|
// would be more correct,
|
||||||
@ -2322,9 +2328,9 @@ static char readit(void) // read (maybe cursor) key from stdin
|
|||||||
}
|
}
|
||||||
|
|
||||||
//----- IO Routines --------------------------------------------
|
//----- IO Routines --------------------------------------------
|
||||||
static char get_one_char(void)
|
static int get_one_char(void)
|
||||||
{
|
{
|
||||||
char c;
|
int c;
|
||||||
|
|
||||||
#if ENABLE_FEATURE_VI_DOT_CMD
|
#if ENABLE_FEATURE_VI_DOT_CMD
|
||||||
if (!adding2q) {
|
if (!adding2q) {
|
||||||
@ -2335,7 +2341,8 @@ static char get_one_char(void)
|
|||||||
c = readit(); // get the users input
|
c = readit(); // get the users input
|
||||||
} else {
|
} else {
|
||||||
// there is a queue to get chars from first
|
// there is a queue to get chars from first
|
||||||
c = *ioq++;
|
// careful with correct sign expansion!
|
||||||
|
c = (unsigned char)*ioq++;
|
||||||
if (c == '\0') {
|
if (c == '\0') {
|
||||||
// the end of the q, read from STDIN
|
// the end of the q, read from STDIN
|
||||||
free(ioq_start);
|
free(ioq_start);
|
||||||
@ -2365,7 +2372,7 @@ static char *get_input_line(const char *prompt)
|
|||||||
// char [MAX_INPUT_LEN]
|
// char [MAX_INPUT_LEN]
|
||||||
#define buf get_input_line__buf
|
#define buf get_input_line__buf
|
||||||
|
|
||||||
char c;
|
int c;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
strcpy(buf, prompt);
|
strcpy(buf, prompt);
|
||||||
@ -2384,7 +2391,8 @@ static char *get_input_line(const char *prompt)
|
|||||||
write1("\b \b"); // erase char on screen
|
write1("\b \b"); // erase char on screen
|
||||||
if (i <= 0) // user backs up before b-o-l, exit
|
if (i <= 0) // user backs up before b-o-l, exit
|
||||||
break;
|
break;
|
||||||
} else {
|
} else if (c > 0 && c < 256) { // exclude Unicode
|
||||||
|
// (TODO: need to handle Unicode)
|
||||||
buf[i] = c;
|
buf[i] = c;
|
||||||
buf[++i] = '\0';
|
buf[++i] = '\0';
|
||||||
bb_putchar(c);
|
bb_putchar(c);
|
||||||
@ -2987,13 +2995,14 @@ static void refresh(int full_screen)
|
|||||||
//---------------------------------------------------------------------
|
//---------------------------------------------------------------------
|
||||||
|
|
||||||
//----- Execute a Vi Command -----------------------------------
|
//----- Execute a Vi Command -----------------------------------
|
||||||
static void do_cmd(char c)
|
static void do_cmd(int c)
|
||||||
{
|
{
|
||||||
const char *msg = msg; // for compiler
|
const char *msg = msg; // for compiler
|
||||||
char c1, *p, *q, *save_dot;
|
char *p, *q, *save_dot;
|
||||||
char buf[12];
|
char buf[12];
|
||||||
int dir = dir; // for compiler
|
int dir = dir; // for compiler
|
||||||
int cnt, i, j;
|
int cnt, i, j;
|
||||||
|
int c1;
|
||||||
|
|
||||||
// c1 = c; // quiet the compiler
|
// c1 = c; // quiet the compiler
|
||||||
// cnt = yf = 0; // quiet the compiler
|
// cnt = yf = 0; // quiet the compiler
|
||||||
@ -3173,21 +3182,18 @@ static void do_cmd(char c)
|
|||||||
break;
|
break;
|
||||||
#if ENABLE_FEATURE_VI_YANKMARK
|
#if ENABLE_FEATURE_VI_YANKMARK
|
||||||
case '"': // "- name a register to use for Delete/Yank
|
case '"': // "- name a register to use for Delete/Yank
|
||||||
c1 = get_one_char();
|
c1 = (get_one_char() | 0x20) - 'a'; // | 0x20 is tolower()
|
||||||
c1 = tolower(c1);
|
if ((unsigned)c1 <= 25) { // a-z?
|
||||||
if (islower(c1)) {
|
YDreg = c1;
|
||||||
YDreg = c1 - 'a';
|
|
||||||
} else {
|
} else {
|
||||||
indicate_error(c);
|
indicate_error(c);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case '\'': // '- goto a specific mark
|
case '\'': // '- goto a specific mark
|
||||||
c1 = get_one_char();
|
c1 = (get_one_char() | 0x20) - 'a';
|
||||||
c1 = tolower(c1);
|
if ((unsigned)c1 <= 25) { // a-z?
|
||||||
if (islower(c1)) {
|
|
||||||
c1 = c1 - 'a';
|
|
||||||
// get the b-o-l
|
// get the b-o-l
|
||||||
q = mark[(unsigned char) c1];
|
q = mark[c1];
|
||||||
if (text <= q && q < end) {
|
if (text <= q && q < end) {
|
||||||
dot = q;
|
dot = q;
|
||||||
dot_begin(); // go to B-o-l
|
dot_begin(); // go to B-o-l
|
||||||
@ -3206,12 +3212,10 @@ static void do_cmd(char c)
|
|||||||
// between text[0] and dot then this mark will not point to the
|
// between text[0] and dot then this mark will not point to the
|
||||||
// correct location! It could be off by many lines!
|
// correct location! It could be off by many lines!
|
||||||
// Well..., at least its quick and dirty.
|
// Well..., at least its quick and dirty.
|
||||||
c1 = get_one_char();
|
c1 = (get_one_char() | 0x20) - 'a';
|
||||||
c1 = tolower(c1);
|
if ((unsigned)c1 <= 25) { // a-z?
|
||||||
if (islower(c1)) {
|
|
||||||
c1 = c1 - 'a';
|
|
||||||
// remember the line
|
// remember the line
|
||||||
mark[(int) c1] = dot;
|
mark[c1] = dot;
|
||||||
} else {
|
} else {
|
||||||
indicate_error(c);
|
indicate_error(c);
|
||||||
}
|
}
|
||||||
@ -3546,12 +3550,11 @@ static void do_cmd(char c)
|
|||||||
end_cmd_q(); // stop adding to q
|
end_cmd_q(); // stop adding to q
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
case 'g': // 'gg' goto a line number (from vim)
|
case 'g': // 'gg' goto a line number (vim) (default: very first line)
|
||||||
// (default to first line in file)
|
|
||||||
c1 = get_one_char();
|
c1 = get_one_char();
|
||||||
if (c1 != 'g') {
|
if (c1 != 'g') {
|
||||||
buf[0] = 'g';
|
buf[0] = 'g';
|
||||||
buf[1] = c1;
|
buf[1] = c1; // TODO: if Unicode?
|
||||||
buf[2] = '\0';
|
buf[2] = '\0';
|
||||||
not_implemented(buf);
|
not_implemented(buf);
|
||||||
break;
|
break;
|
||||||
@ -3804,7 +3807,7 @@ static void do_cmd(char c)
|
|||||||
do_cmd(';');
|
do_cmd(';');
|
||||||
if (*dot == last_forward_char)
|
if (*dot == last_forward_char)
|
||||||
dot_left();
|
dot_left();
|
||||||
last_forward_char= 0;
|
last_forward_char = 0;
|
||||||
break;
|
break;
|
||||||
case 'w': // w- forward a word
|
case 'w': // w- forward a word
|
||||||
if (cmdcnt-- > 1) {
|
if (cmdcnt-- > 1) {
|
||||||
|
Loading…
Reference in New Issue
Block a user