mirror of
				https://github.com/troglobit/editline.git
				synced 2025-10-31 16:28:15 +08:00 
			
		
		
		
	Merge branch 'echoprotocol-simple_multiline'
This commit is contained in:
		
							
								
								
									
										143
									
								
								src/editline.c
									
									
									
									
									
								
							
							
						
						
									
										143
									
								
								src/editline.c
									
									
									
									
									
								
							| @@ -113,6 +113,9 @@ static int        Searching = 0; | ||||
| static const char *(*search_move)(void); | ||||
| static const char *old_prompt = NULL; | ||||
| static rl_vcpfunc_t *line_handler = NULL; | ||||
| static char       *line_up = "\x1b[A"; | ||||
| static char       *line_down = "\x1b[B"; | ||||
| int prompt_len = 0; | ||||
|  | ||||
| int               el_no_echo = 0; /* e.g., under Emacs */ | ||||
| int               el_no_hist = 0; | ||||
| @@ -134,7 +137,6 @@ extern char     *tgetstr(const char *, char **); | ||||
| extern int      tgetent(char *, const char *); | ||||
| extern int      tgetnum(const char *); | ||||
| #endif | ||||
|  | ||||
|  | ||||
| /* | ||||
| **  Misc. local helper functions. | ||||
| @@ -206,8 +208,13 @@ static void tty_show(unsigned char c) | ||||
|  | ||||
| static void tty_string(char *p) | ||||
| { | ||||
|     while (*p) | ||||
|     int i = rl_point + prompt_len + 1; | ||||
|  | ||||
|     while (*p) { | ||||
|         tty_show(*p++); | ||||
|         if ((i++) % tty_cols == 0) | ||||
|             tty_put('\n'); | ||||
|     } | ||||
| } | ||||
|  | ||||
| static void tty_push(int c) | ||||
| @@ -255,7 +262,6 @@ static void tty_info(void) | ||||
| { | ||||
|     rl_reset_terminal(NULL); | ||||
| } | ||||
|  | ||||
|  | ||||
| /* | ||||
| **  Glue routines to rl_ttyset() | ||||
| @@ -291,8 +297,10 @@ void el_print_columns(int ac, char **av) | ||||
|         if ((j = strlen((char *)av[i])) > longest) | ||||
|             longest = j; | ||||
|     } | ||||
|  | ||||
|     colwidth = longest + 3; | ||||
|     if (colwidth > tty_cols) colwidth = tty_cols; | ||||
|     if (colwidth > tty_cols) | ||||
|         colwidth = tty_cols; | ||||
|     cols = tty_cols / colwidth; | ||||
|  | ||||
|     tty_puts(NEWLINE); | ||||
| @@ -311,20 +319,92 @@ void el_print_columns(int ac, char **av) | ||||
|     } | ||||
| } | ||||
|  | ||||
| static void reposition(void) | ||||
| static void reposition(int key) | ||||
| { | ||||
|     int i; | ||||
|     int len_with_prompt = prompt_len + rl_end; | ||||
|     int n =  len_with_prompt / tty_cols;                  /* determine the number of lines */ | ||||
|     int i = 0; | ||||
|  | ||||
|     tty_put('\r'); | ||||
|  | ||||
|     if (n > 0) { | ||||
|         int line; | ||||
|  | ||||
| 	/* determine num of current line */ | ||||
|         if (key == CTL('A') || key == CTL('E') || key == rl_kill) | ||||
|             line = (prompt_len + old_point) / tty_cols; | ||||
|         else | ||||
|             line = len_with_prompt / tty_cols; | ||||
|  | ||||
| 	/* move to end of line(s) */ | ||||
|         if (key == CTL('E')) { | ||||
| 	    int k; | ||||
|  | ||||
|             for (k = line; k < n; k++) | ||||
|                 tty_puts(line_down); | ||||
|  | ||||
| 	    /* determine reminder of last line and redraw only it */ | ||||
|             i = rl_point - (len_with_prompt % tty_cols); | ||||
|         } else { | ||||
| 	    int k; | ||||
|  | ||||
| 	    /* CTRL-A, CTRL-U, insert (end, middle), remove (end, middle) */ | ||||
|             for (k = line; k > 0; k--) | ||||
|                 tty_puts(line_up); /* redraw characters until changed data */ | ||||
|  | ||||
|             tty_puts(rl_prompt); | ||||
|     for (i = 0; i < rl_point; i++) | ||||
|         } | ||||
|     } else if (n == 0) { | ||||
|         tty_puts(rl_prompt); | ||||
|     } | ||||
|  | ||||
|     for (; i < rl_point; i++) { | ||||
|         tty_show(rl_line_buffer[i]); | ||||
|  | ||||
| 	/* move to the next line */ | ||||
|         if ((i + prompt_len + 1) % tty_cols == 0) | ||||
|             tty_put('\n'); | ||||
|     } | ||||
| } | ||||
|  | ||||
| void itoa(int val, char* buf) | ||||
| { | ||||
|     int digits = 0; | ||||
|     int temp = val; | ||||
|  | ||||
|     while (temp != 0) { | ||||
|         temp = temp / 10; | ||||
|         ++digits; | ||||
|     } | ||||
|  | ||||
|     *(buf+digits) = 'C'; | ||||
|     int i = 5; digits--; | ||||
|     for(; val && i ; --i, val /= 10) { | ||||
|         *(buf+digits) = "0123456789"[val % 10]; | ||||
|         digits--; | ||||
|     } | ||||
| } | ||||
|  | ||||
| static void move_cursor_forward(int columns) | ||||
| { | ||||
|     const char* line_forward = "\x1b["; | ||||
|     char buf[12] = {0}; | ||||
|  | ||||
|     strcpy(buf, line_forward); | ||||
|     itoa(columns, buf + 2); | ||||
|     tty_puts(buf); | ||||
| } | ||||
|  | ||||
| static void left(el_status_t Change) | ||||
| { | ||||
|     if (rl_point) { | ||||
|         if ((rl_point + prompt_len) % tty_cols == 0) { | ||||
|             tty_puts(line_up); | ||||
|             move_cursor_forward(tty_cols); | ||||
|         } else { | ||||
|             tty_back(); | ||||
|         } | ||||
|  | ||||
|         if (ISMETA(rl_line_buffer[rl_point - 1])) { | ||||
|             if (rl_meta_chars) { | ||||
|                 tty_back(); | ||||
| @@ -341,6 +421,9 @@ static void left(el_status_t Change) | ||||
|  | ||||
| static void right(el_status_t Change) | ||||
| { | ||||
|     if ((rl_point + prompt_len + 1) % tty_cols == 0) | ||||
|         tty_put('\n'); | ||||
|     else | ||||
|         tty_show(rl_line_buffer[rl_point]); | ||||
|  | ||||
|     if (Change == CSmove) | ||||
| @@ -461,10 +544,14 @@ static void ceol(void) | ||||
|     while (rl_point < 0) { | ||||
|         tty_put(' '); | ||||
|         rl_point++; | ||||
| 	extras++; | ||||
|     } | ||||
|  | ||||
|     for (i = rl_point, p = &rl_line_buffer[i]; i <= rl_end; i++, p++) { | ||||
|         if ((i + prompt_len + 1) % tty_cols == 0){ | ||||
|             tty_put(' '); | ||||
|             tty_put('\n'); | ||||
|         } | ||||
|         else | ||||
|             tty_put(' '); | ||||
|         if (ISMETA(*p)) { | ||||
|             if (rl_meta_chars) { | ||||
| @@ -478,15 +565,32 @@ static void ceol(void) | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     for (i += extras; i > rl_point; i--) | ||||
|     for (i += extras; i > rl_point; i--) { | ||||
|         if ((i + prompt_len) % tty_cols == 0) { | ||||
|             tty_puts(line_up); | ||||
|             move_cursor_forward(tty_cols); | ||||
|         } else { | ||||
|             tty_back(); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| static void clear_line(void) | ||||
| { | ||||
|     int n = (rl_point + prompt_len) / tty_cols; | ||||
|     rl_point = -(int)strlen(rl_prompt); | ||||
|  | ||||
|     if (n > 0) { | ||||
|         for(int k = 0; k < n; k++) | ||||
|             tty_puts(line_up); | ||||
|         tty_put('\r'); | ||||
|     } | ||||
|     else { | ||||
|         tty_put('\r'); | ||||
|     } | ||||
|  | ||||
|     ceol(); | ||||
|  | ||||
|     rl_point = 0; | ||||
|     rl_end = 0; | ||||
|     rl_line_buffer[0] = '\0'; | ||||
| @@ -538,14 +642,15 @@ int rl_insert_text(const char *text) | ||||
|  | ||||
| static el_status_t redisplay(int cls) | ||||
| { | ||||
|     if (cls && rl_point == 0 && rl_end == 0) | ||||
|     if (cls) | ||||
|         tty_puts(CLEAR); | ||||
|     else | ||||
|         tty_puts("\r\e[K"); | ||||
|  | ||||
|     tty_puts(rl_prompt); | ||||
|     rl_point = 0; | ||||
|     tty_string(rl_line_buffer); | ||||
|  | ||||
|     rl_point = rl_end; | ||||
|     return CSmove; | ||||
| } | ||||
|  | ||||
| @@ -565,7 +670,6 @@ static el_status_t toggle_meta_mode(void) | ||||
|     rl_meta_chars = ! rl_meta_chars; | ||||
|     return redisplay(0); | ||||
| } | ||||
|  | ||||
|  | ||||
| const char *el_next_hist(void) | ||||
| { | ||||
| @@ -585,7 +689,7 @@ static el_status_t do_insert_hist(const char *p) | ||||
|     clear_line(); | ||||
|  | ||||
|     rl_point = 0; | ||||
|     reposition(); | ||||
|     reposition(-1); | ||||
|     rl_end = 0; | ||||
|  | ||||
|     return insert_string(p); | ||||
| @@ -792,6 +896,7 @@ static el_status_t delete_string(int count) | ||||
|     for (p = &rl_line_buffer[rl_point], i = rl_end - (rl_point + count) + 1; --i >= 0; p++) | ||||
|         p[0] = p[count]; | ||||
|     ceol(); | ||||
|  | ||||
|     rl_end -= count; | ||||
|     tty_string(&rl_line_buffer[rl_point]); | ||||
|  | ||||
| @@ -832,7 +937,7 @@ static el_status_t kill_line(void) | ||||
|         if (Repeat < rl_point) { | ||||
|             i = rl_point; | ||||
|             rl_point = Repeat; | ||||
|             reposition(); | ||||
|             reposition(-1); | ||||
|             delete_string(i - rl_point); | ||||
|         } else if (Repeat > rl_point) { | ||||
|             right(CSmove); | ||||
| @@ -1059,8 +1164,9 @@ static el_status_t tty_special(int c) | ||||
|  | ||||
|     if (c == rl_kill) { | ||||
|         if (rl_point != 0) { | ||||
|             old_point = rl_point; | ||||
|             rl_point = 0; | ||||
|             reposition(); | ||||
|             reposition(c); | ||||
|         } | ||||
|         Repeat = NO_ARG; | ||||
|  | ||||
| @@ -1095,7 +1201,7 @@ static char *editinput(int complete) | ||||
|             return (char *)""; | ||||
|  | ||||
|         case CSmove: | ||||
| 	    reposition(); | ||||
|             reposition(c); | ||||
|             break; | ||||
|  | ||||
|         case CSdispatch: | ||||
| @@ -1110,7 +1216,7 @@ static char *editinput(int complete) | ||||
|                 return (char *)""; | ||||
|  | ||||
|             case CSmove: | ||||
| 		reposition(); | ||||
|                 reposition(c); | ||||
|                 break; | ||||
|  | ||||
|             case CSdispatch: | ||||
| @@ -1334,6 +1440,8 @@ static int el_prep(const char *prompt) | ||||
|         return -1; | ||||
|  | ||||
|     rl_prompt = prompt ? prompt : NILSTR; | ||||
|     prompt_len = strlen(rl_prompt); | ||||
|  | ||||
|     if (el_no_echo) { | ||||
|         int old = el_no_echo; | ||||
|  | ||||
| @@ -1529,7 +1637,6 @@ int write_history(const char *filename) | ||||
|  | ||||
|     return errno; | ||||
| } | ||||
|  | ||||
|  | ||||
| /* | ||||
| **  Move back to the beginning of the current word and return an | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Joachim Nilsson
					Joachim Nilsson