Fix libedit history behaviour
This commit is contained in:
		
							parent
							
								
									3cf3c0215e
								
							
						
					
					
						commit
						c1b6918db3
					
				
							
								
								
									
										2
									
								
								LICENSE
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								LICENSE
									
									
									
									
									
								
							| @ -1,4 +1,4 @@ | ||||
| Copyright (c) 2014 - 2020, Přemysl Eric Janouch <p@janouch.name> | ||||
| Copyright (c) 2014 - 2022, Přemysl Eric Janouch <p@janouch.name> | ||||
| 
 | ||||
| Permission to use, copy, modify, and/or distribute this software for any | ||||
| purpose with or without fee is hereby granted. | ||||
|  | ||||
| @ -140,8 +140,7 @@ the higher-level protocol (the "Sec-Ws-Protocol" HTTP field). | ||||
| 
 | ||||
| Bugs | ||||
| ---- | ||||
| The editline (libedit) frontend is more of a proof of concept that mostly seems | ||||
| to work but exhibits bugs that are not our fault. | ||||
| The editline (libedit) frontend may exhibit some unexpected behaviour. | ||||
| 
 | ||||
| Examples | ||||
| -------- | ||||
|  | ||||
| @ -1,7 +1,7 @@ | ||||
| /*
 | ||||
|  * json-rpc-shell.c: a shell for JSON-RPC 2.0 | ||||
|  * | ||||
|  * Copyright (c) 2014 - 2020, Přemysl Eric Janouch <p@janouch.name> | ||||
|  * Copyright (c) 2014 - 2022, Přemysl Eric Janouch <p@janouch.name> | ||||
|  * | ||||
|  * Permission to use, copy, modify, and/or distribute this software for any | ||||
|  * purpose with or without fee is hereby granted. | ||||
| @ -515,6 +515,7 @@ struct input_el | ||||
| 	char *entered_line;                 ///< Buffers the entered line
 | ||||
| 
 | ||||
| 	bool active;                        ///< Interface has been started
 | ||||
| 	bool need_restart;                  ///< Need to clear history state
 | ||||
| 	char *prompt;                       ///< The prompt we use
 | ||||
| 	int prompt_shown;                   ///< Whether the prompt is shown now
 | ||||
| 
 | ||||
| @ -540,12 +541,24 @@ input_el_redisplay (struct input_el *self) | ||||
| { | ||||
| 	// See rl_redisplay(), however NetBSD editline's map.c v1.54 breaks VREPRINT
 | ||||
| 	// so we bind redisplay somewhere else in input_el_start()
 | ||||
| 	char x[] = { 'q' & 31, 0 }; | ||||
| 	el_push (self->editline, x); | ||||
| 	wchar_t x[] = { L'q' & 31, 0 }; | ||||
| 	el_wpush (self->editline, x); | ||||
| 
 | ||||
| 	// We have to do this or it gets stuck and nothing is done
 | ||||
| 	int count = 0; | ||||
| 	(void) el_wgets (self->editline, &count); | ||||
| 	int dummy_count = 0; | ||||
| 	(void) el_wgets (self->editline, &dummy_count); | ||||
| } | ||||
| 
 | ||||
| // Editline keeping its own history position (look for "eventno" there).
 | ||||
| // This is the only sane way of resetting it.
 | ||||
| static void | ||||
| input_el_start_over (struct input_el *self) | ||||
| { | ||||
| 	wchar_t x[] = { L'c' & 31, 0 }; | ||||
| 	el_wpush (self->editline, x); | ||||
| 
 | ||||
| 	int dummy_count = 0; | ||||
| 	(void) el_wgets (self->editline, &dummy_count); | ||||
| } | ||||
| 
 | ||||
| static char * | ||||
| @ -603,13 +616,14 @@ input_el_on_return (EditLine *editline, int key) | ||||
| 	self->entered_line = xstrndup | ||||
| 		(info_mb->buffer, info_mb->lastchar - info_mb->buffer); | ||||
| 
 | ||||
| 	// Now we need to force editline to actually print the newline
 | ||||
| 	// Now we need to force editline into actually printing the newline
 | ||||
| 	el_cursor (editline, len++ - point); | ||||
| 	el_insertstr (editline, "\n"); | ||||
| 	input_el_redisplay (self); | ||||
| 
 | ||||
| 	// Finally we need to discard the old line's contents
 | ||||
| 	el_wdeletestr (editline, len); | ||||
| 	self->need_restart = true; | ||||
| 	return CC_NEWLINE; | ||||
| } | ||||
| 
 | ||||
| @ -673,8 +687,6 @@ input_el_start (struct input *input, const char *program_name) | ||||
| 	el_set (self->editline, EL_BIND, "^w", "ed-delete-prev-word", NULL); | ||||
| 	// Just what are you doing?
 | ||||
| 	el_set (self->editline, EL_BIND, "^u", "vi-kill-line-prev",   NULL); | ||||
| 	// See input_el_redisplay(), functionally important
 | ||||
| 	el_set (self->editline, EL_BIND, "^q", "ed-redisplay",        NULL); | ||||
| 
 | ||||
| 	// It's probably better to handle these ourselves
 | ||||
| 	input_el_addbind (self->editline, "send-line", "Send line", | ||||
| @ -690,6 +702,11 @@ input_el_start (struct input *input, const char *program_name) | ||||
| 	// Source the user's defaults file
 | ||||
| 	el_source (self->editline, NULL); | ||||
| 
 | ||||
| 	// See input_el_redisplay(), functionally important
 | ||||
| 	el_set (self->editline, EL_BIND, "^q", "ed-redisplay",        NULL); | ||||
| 	// This is what buffered el_wgets() does, functionally important
 | ||||
| 	el_set (self->editline, EL_BIND, "^c", "ed-start-over",       NULL); | ||||
| 
 | ||||
| 	self->active = true; | ||||
| 	self->prompt_shown = 1; | ||||
| } | ||||
| @ -977,6 +994,16 @@ input_el_on_tty_readable (struct input *input) | ||||
| 	// We bind the return key to process it how we need to
 | ||||
| 	struct input_el *self = (struct input_el *) input; | ||||
| 
 | ||||
| 	int unbuffered = 0; | ||||
| 	(void) el_get (self->editline, EL_UNBUFFERED, &unbuffered); | ||||
| 
 | ||||
| 	// We must invoke ch_reset(), which isn't done for us with EL_UNBUFFERED.
 | ||||
| 	if (unbuffered && self->need_restart) | ||||
| 	{ | ||||
| 		self->need_restart = false; | ||||
| 		input_el_start_over (self); | ||||
| 	} | ||||
| 
 | ||||
| 	// el_gets() with EL_UNBUFFERED doesn't work with UTF-8,
 | ||||
| 	// we must use the wide-character interface
 | ||||
| 	int count = 0; | ||||
| @ -984,8 +1011,7 @@ input_el_on_tty_readable (struct input *input) | ||||
| 
 | ||||
| 	// Editline works in a funny NO_TTY mode when the input is not a tty,
 | ||||
| 	// we cannot use EL_UNBUFFERED and expect sane results then
 | ||||
| 	int unbuffered = 0; | ||||
| 	if (!el_get (self->editline, EL_UNBUFFERED, &unbuffered) && !unbuffered) | ||||
| 	if (!unbuffered) | ||||
| 	{ | ||||
| 		char *entered_line = buf ? input_el_wcstombs (buf) : NULL; | ||||
| 		self->super.on_input (entered_line, self->super.user_data); | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user